@warmio/ui 1.3.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/fluid-functionalism.txt +24 -0
- package/README.md +9 -5
- package/dist/badge.js +1 -1
- package/dist/button.js +1 -1
- package/dist/chunks/{chunk-IOUIACNV.js → chunk-2CO2BZLI.js} +20 -85
- package/dist/chunks/{chunk-ICC7GQXS.js → chunk-3AVFUXCV.js} +8 -6
- package/dist/chunks/{chunk-DHZWXYDX.js → chunk-6V6K5G72.js} +7 -13
- package/dist/chunks/{chunk-YTDMREDR.js → chunk-A2NLFM6R.js} +62 -36
- package/dist/chunks/chunk-B47G2BJV.js +534 -0
- package/dist/chunks/chunk-F74Y4WRX.js +239 -0
- package/dist/chunks/chunk-GY4XJ6EX.js +129 -0
- package/dist/chunks/chunk-HQTC542T.js +1079 -0
- package/dist/chunks/{chunk-BG6USQSY.js → chunk-IK5RHPN3.js} +20 -8
- package/dist/chunks/chunk-JXSJTIX7.js +133 -0
- package/dist/chunks/{chunk-CIYWFBEJ.js → chunk-OU7YQUU2.js} +15 -32
- package/dist/dropdown-menu.js +3 -1
- package/dist/index.js +11 -9
- package/dist/logo.js +1 -1
- package/dist/product-header.js +1 -1
- package/dist/product-header.types.d.ts +12 -10
- package/dist/sheet.js +3 -2
- package/dist/sidebar.js +4 -2
- package/dist/text.js +1 -1
- package/package.json +5 -3
- package/types/badge.d.ts +10 -2
- package/types/index.d.ts +113 -8
- package/types/sidebar.d.ts +1 -0
- package/types/text.d.ts +3 -0
- package/dist/chunks/chunk-GKEYV2XW.js +0 -10
- package/dist/chunks/chunk-LHHUTDZR.js +0 -749
- package/dist/chunks/chunk-P3AJ2REZ.js +0 -1083
|
@@ -1,1083 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
cn
|
|
3
|
-
} from "./chunk-VIB7OX7D.js";
|
|
4
|
-
|
|
5
|
-
// ../ui/src/warmio/flame-mascot.tsx
|
|
6
|
-
import { useCallback, useRef, useState, useSyncExternalStore } from "react";
|
|
7
|
-
|
|
8
|
-
// ../ui/src/warmio/flame-mascot-states.ts
|
|
9
|
-
var WARM_FLAME_MASCOT_EXPRESSION_CONFIGS = [
|
|
10
|
-
{
|
|
11
|
-
id: "calm",
|
|
12
|
-
name: "Calm",
|
|
13
|
-
chip: "soft",
|
|
14
|
-
eye: {
|
|
15
|
-
kind: "ellipse",
|
|
16
|
-
lx: 88,
|
|
17
|
-
ly: 191,
|
|
18
|
-
lrx: 8,
|
|
19
|
-
lry: 10.8,
|
|
20
|
-
rx: 144,
|
|
21
|
-
ry: 191,
|
|
22
|
-
rrx: 8,
|
|
23
|
-
rry: 10.8
|
|
24
|
-
},
|
|
25
|
-
mouth: { kind: "path", d: "M102 213C109 221 123 221 130 213", width: 5.5 },
|
|
26
|
-
cheekOpacity: 0.24,
|
|
27
|
-
floatDuration: "3.4s",
|
|
28
|
-
floatLift: "-1.8%",
|
|
29
|
-
floatScaleY: 1.024,
|
|
30
|
-
blinkDuration: "4.8s"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
id: "happy",
|
|
34
|
-
name: "Happy",
|
|
35
|
-
chip: "win",
|
|
36
|
-
eye: { kind: "happy" },
|
|
37
|
-
mouth: { kind: "laugh", d: "M95 208C104 228 128 228 137 208" },
|
|
38
|
-
cheekOpacity: 0.44,
|
|
39
|
-
floatDuration: "2s",
|
|
40
|
-
floatLift: "-4%",
|
|
41
|
-
floatScaleY: 1.05,
|
|
42
|
-
blinkDuration: "3.7s"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
id: "focused",
|
|
46
|
-
name: "Focused",
|
|
47
|
-
chip: "review",
|
|
48
|
-
eye: {
|
|
49
|
-
kind: "ellipse",
|
|
50
|
-
lx: 88,
|
|
51
|
-
ly: 191,
|
|
52
|
-
lrx: 7.2,
|
|
53
|
-
lry: 8.8,
|
|
54
|
-
rx: 144,
|
|
55
|
-
ry: 191,
|
|
56
|
-
rrx: 7.2,
|
|
57
|
-
rry: 8.8,
|
|
58
|
-
lines: ["M78 179C85 176 93 177 99 182", "M133 182C139 177 147 176 154 179"]
|
|
59
|
-
},
|
|
60
|
-
mouth: { kind: "path", d: "M104 214C111 219 121 219 128 214", width: 5.3 },
|
|
61
|
-
cheekOpacity: 0.18,
|
|
62
|
-
floatDuration: "3.2s",
|
|
63
|
-
floatLift: "-1.9%",
|
|
64
|
-
floatScaleY: 1.016,
|
|
65
|
-
blinkDuration: "4.4s"
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
id: "relieved",
|
|
69
|
-
name: "Relieved",
|
|
70
|
-
chip: "clear",
|
|
71
|
-
eye: { kind: "closed" },
|
|
72
|
-
mouth: { kind: "path", d: "M101 214C109 222 123 222 131 214", width: 5.5 },
|
|
73
|
-
cheekOpacity: 0.22,
|
|
74
|
-
floatDuration: "3.9s",
|
|
75
|
-
floatLift: "-1.6%",
|
|
76
|
-
floatScaleY: 1.018,
|
|
77
|
-
blinkDuration: "5s"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
id: "password-retry",
|
|
81
|
-
name: "Password retry",
|
|
82
|
-
chip: "retry",
|
|
83
|
-
eye: {
|
|
84
|
-
kind: "ellipse",
|
|
85
|
-
lx: 88,
|
|
86
|
-
ly: 192,
|
|
87
|
-
lrx: 7.5,
|
|
88
|
-
lry: 10,
|
|
89
|
-
rx: 144,
|
|
90
|
-
ry: 191,
|
|
91
|
-
rrx: 7.5,
|
|
92
|
-
rry: 10.5,
|
|
93
|
-
lines: ["M78 181C85 176 94 177 100 183", "M134 183C141 177 151 176 158 181"]
|
|
94
|
-
},
|
|
95
|
-
mouth: { kind: "path", d: "M103 220C110 214 122 214 129 220", width: 5.4 },
|
|
96
|
-
cheekOpacity: 0.18,
|
|
97
|
-
floatDuration: "3.5s",
|
|
98
|
-
floatLift: "-1.5%",
|
|
99
|
-
floatScaleY: 1.014,
|
|
100
|
-
blinkDuration: "4.9s"
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
id: "frustrated",
|
|
104
|
-
name: "Frustrated",
|
|
105
|
-
chip: "blocked",
|
|
106
|
-
eye: {
|
|
107
|
-
kind: "ellipse",
|
|
108
|
-
lx: 88,
|
|
109
|
-
ly: 191,
|
|
110
|
-
lrx: 6.4,
|
|
111
|
-
lry: 7.8,
|
|
112
|
-
rx: 145,
|
|
113
|
-
ry: 190,
|
|
114
|
-
rrx: 6.8,
|
|
115
|
-
rry: 8.2,
|
|
116
|
-
lines: ["M77 179C85 181 93 181 101 178", "M133 178C142 181 151 181 159 179"]
|
|
117
|
-
},
|
|
118
|
-
mouth: {
|
|
119
|
-
kind: "path",
|
|
120
|
-
d: "M101 219C106 215 111 223 116 219C121 215 126 223 131 219",
|
|
121
|
-
width: 5.3
|
|
122
|
-
},
|
|
123
|
-
cheekOpacity: 0.08,
|
|
124
|
-
floatDuration: "2.35s",
|
|
125
|
-
floatLift: "-2.6%",
|
|
126
|
-
floatScaleY: 1.024,
|
|
127
|
-
blinkDuration: "3.8s"
|
|
128
|
-
}
|
|
129
|
-
];
|
|
130
|
-
var WARM_FLAME_MASCOT_DEFAULT_EXPRESSION_CONFIG = WARM_FLAME_MASCOT_EXPRESSION_CONFIGS[0];
|
|
131
|
-
function getWarmFlameMascotExpressionConfig(expression) {
|
|
132
|
-
return WARM_FLAME_MASCOT_EXPRESSION_CONFIGS.find((state) => state.id === expression) ?? WARM_FLAME_MASCOT_DEFAULT_EXPRESSION_CONFIG;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// ../ui/src/warmio/flame-mascot-config.ts
|
|
136
|
-
var WARM_FLAME_MASCOT_ENABLED = false;
|
|
137
|
-
function isWarmFlameMascotEnabled() {
|
|
138
|
-
return WARM_FLAME_MASCOT_ENABLED;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// ../ui/src/warmio/flame-mascot.tsx
|
|
142
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
143
|
-
var WARM_FLAME_MASCOT_SHADER_CONFIG = {
|
|
144
|
-
color1: { r: 255, g: 199, b: 86 },
|
|
145
|
-
color2: { r: 242, g: 139, b: 53 },
|
|
146
|
-
color3: { r: 255, g: 255, b: 255 },
|
|
147
|
-
speed: 3,
|
|
148
|
-
scale: 0.5,
|
|
149
|
-
noise: 0.1,
|
|
150
|
-
stripeX: 9,
|
|
151
|
-
stripeY: 8,
|
|
152
|
-
bend: 0.5,
|
|
153
|
-
highlightStart: 0,
|
|
154
|
-
highlightStrength: 1,
|
|
155
|
-
glowStrength: 0.6
|
|
156
|
-
};
|
|
157
|
-
var flameShapePath = "M115.7 288C50.2 288 7.8 250.5 7.8 205.1C7.8 166.8 38.7 139.2 73.2 108.4C104.7 80.3 121.2 49 124.8 12C143.8 39.2 174.8 58.3 188.6 91C201.4 121.8 191 149 170 168C190 165 207 151 215 131C224 164 221 195 212.5 219C198 260 165 288 115.7 288Z";
|
|
158
|
-
var flameMaskSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 231 289"><path fill="black" d="${flameShapePath}"/></svg>`;
|
|
159
|
-
var flameMaskImage = `url("data:image/svg+xml,${encodeURIComponent(flameMaskSvg)}")`;
|
|
160
|
-
var sizeByName = {
|
|
161
|
-
default: 72,
|
|
162
|
-
hero: 88
|
|
163
|
-
};
|
|
164
|
-
var vertexShaderSource = `
|
|
165
|
-
attribute vec2 a_position;
|
|
166
|
-
varying vec2 v_uv;
|
|
167
|
-
|
|
168
|
-
void main() {
|
|
169
|
-
v_uv = a_position * 0.5 + 0.5;
|
|
170
|
-
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
171
|
-
}
|
|
172
|
-
`;
|
|
173
|
-
var fragmentShaderSource = `
|
|
174
|
-
precision mediump float;
|
|
175
|
-
|
|
176
|
-
varying vec2 v_uv;
|
|
177
|
-
|
|
178
|
-
uniform float u_time;
|
|
179
|
-
uniform vec2 u_resolution;
|
|
180
|
-
uniform vec3 u_color1;
|
|
181
|
-
uniform vec3 u_color2;
|
|
182
|
-
uniform vec3 u_color3;
|
|
183
|
-
uniform float u_speed;
|
|
184
|
-
uniform float u_scale;
|
|
185
|
-
uniform float u_noise;
|
|
186
|
-
uniform float u_stripe_x;
|
|
187
|
-
uniform float u_stripe_y;
|
|
188
|
-
uniform float u_bend;
|
|
189
|
-
uniform float u_highlight_start;
|
|
190
|
-
uniform float u_highlight_strength;
|
|
191
|
-
uniform float u_glow_strength;
|
|
192
|
-
|
|
193
|
-
float hash(vec2 point) {
|
|
194
|
-
return fract(sin(dot(point, vec2(127.1, 311.7))) * 43758.5453123);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
float noise(vec2 point) {
|
|
198
|
-
vec2 index = floor(point);
|
|
199
|
-
vec2 fractPoint = fract(point);
|
|
200
|
-
vec2 curve = fractPoint * fractPoint * (3.0 - 2.0 * fractPoint);
|
|
201
|
-
|
|
202
|
-
float bottomLeft = hash(index);
|
|
203
|
-
float bottomRight = hash(index + vec2(1.0, 0.0));
|
|
204
|
-
float topLeft = hash(index + vec2(0.0, 1.0));
|
|
205
|
-
float topRight = hash(index + vec2(1.0, 1.0));
|
|
206
|
-
|
|
207
|
-
return mix(
|
|
208
|
-
mix(bottomLeft, bottomRight, curve.x),
|
|
209
|
-
mix(topLeft, topRight, curve.x),
|
|
210
|
-
curve.y
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
float fbm(vec2 point) {
|
|
215
|
-
float value = 0.0;
|
|
216
|
-
float amplitude = 0.5;
|
|
217
|
-
vec2 shift = vec2(37.2, 17.7);
|
|
218
|
-
|
|
219
|
-
for (int i = 0; i < 4; i++) {
|
|
220
|
-
value += amplitude * noise(point);
|
|
221
|
-
point = point * 2.0 + shift;
|
|
222
|
-
amplitude *= 0.5;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return value;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
void main() {
|
|
229
|
-
vec2 uv = v_uv;
|
|
230
|
-
float time = u_time * u_speed;
|
|
231
|
-
float scale = max(u_scale, 0.001);
|
|
232
|
-
vec2 point = (uv - 0.5) / scale + 0.5;
|
|
233
|
-
float upward = uv.y - time * 0.24;
|
|
234
|
-
|
|
235
|
-
float animated = fbm(vec2(
|
|
236
|
-
point.x * 3.2 + sin(upward * 2.2) * 0.22,
|
|
237
|
-
point.y * 4.2 - time * 1.35
|
|
238
|
-
));
|
|
239
|
-
float bend = sin((point.y * u_stripe_y) - time * 1.7) * u_bend;
|
|
240
|
-
float stripe = sin(
|
|
241
|
-
(point.x * u_stripe_x) +
|
|
242
|
-
(point.y * u_stripe_y) +
|
|
243
|
-
bend -
|
|
244
|
-
time * 2.2
|
|
245
|
-
) * 0.5 + 0.5;
|
|
246
|
-
float softNoise = fbm((point * 5.5) + vec2(0.0, -time * 0.64));
|
|
247
|
-
float flow = mix(animated, stripe, 0.34);
|
|
248
|
-
flow = mix(flow, softNoise, u_noise);
|
|
249
|
-
|
|
250
|
-
vec2 aspect = vec2(u_resolution.x / max(u_resolution.y, 1.0), 1.0);
|
|
251
|
-
vec2 lowerCenter = (uv - vec2(0.49, 0.25)) * aspect;
|
|
252
|
-
vec2 faceGlowCenter = (uv - vec2(0.49, 0.34)) * aspect;
|
|
253
|
-
float lowerGlow = smoothstep(0.66, 0.0, length(lowerCenter));
|
|
254
|
-
float faceGlow = smoothstep(0.42, 0.0, length(faceGlowCenter));
|
|
255
|
-
float topWarmth = smoothstep(1.0, 0.05, uv.y);
|
|
256
|
-
float whiteHighlight = clamp(
|
|
257
|
-
lowerGlow * u_glow_strength +
|
|
258
|
-
faceGlow * 0.38 +
|
|
259
|
-
smoothstep(u_highlight_start, 1.0, flow) * u_highlight_strength * 0.18,
|
|
260
|
-
0.0,
|
|
261
|
-
1.0
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
vec3 warm = mix(u_color1, u_color2, clamp(uv.y * 0.74 + flow * 0.34, 0.0, 1.0));
|
|
265
|
-
warm = mix(warm, u_color1, topWarmth * 0.18);
|
|
266
|
-
vec3 color = mix(warm, u_color3, whiteHighlight);
|
|
267
|
-
|
|
268
|
-
gl_FragColor = vec4(color, 1.0);
|
|
269
|
-
}
|
|
270
|
-
`;
|
|
271
|
-
var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
272
|
-
var mascotEyeOffsetConfig = {
|
|
273
|
-
xScale: 6.5,
|
|
274
|
-
yScale: 6,
|
|
275
|
-
xMax: 3,
|
|
276
|
-
yMax: 2.5
|
|
277
|
-
};
|
|
278
|
-
function resolvePixelSize(size) {
|
|
279
|
-
return sizeByName[size];
|
|
280
|
-
}
|
|
281
|
-
function createShader(gl, type, source) {
|
|
282
|
-
const shader = gl.createShader(type);
|
|
283
|
-
if (!shader) {
|
|
284
|
-
throw new Error("Unable to create Warm flame shader.");
|
|
285
|
-
}
|
|
286
|
-
gl.shaderSource(shader, source);
|
|
287
|
-
gl.compileShader(shader);
|
|
288
|
-
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
289
|
-
const message = gl.getShaderInfoLog(shader);
|
|
290
|
-
gl.deleteShader(shader);
|
|
291
|
-
throw new Error(message ?? "Unable to compile Warm flame shader.");
|
|
292
|
-
}
|
|
293
|
-
return shader;
|
|
294
|
-
}
|
|
295
|
-
function createProgram(gl, vertexShader, fragmentShader) {
|
|
296
|
-
const program = gl.createProgram();
|
|
297
|
-
if (!program) {
|
|
298
|
-
throw new Error("Unable to create Warm flame shader program.");
|
|
299
|
-
}
|
|
300
|
-
gl.attachShader(program, vertexShader);
|
|
301
|
-
gl.attachShader(program, fragmentShader);
|
|
302
|
-
gl.linkProgram(program);
|
|
303
|
-
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
304
|
-
const message = gl.getProgramInfoLog(program);
|
|
305
|
-
gl.deleteProgram(program);
|
|
306
|
-
throw new Error(message ?? "Unable to link Warm flame shader program.");
|
|
307
|
-
}
|
|
308
|
-
return program;
|
|
309
|
-
}
|
|
310
|
-
function unitColor(color) {
|
|
311
|
-
return [color.r / 255, color.g / 255, color.b / 255];
|
|
312
|
-
}
|
|
313
|
-
function resizeCanvas(canvas, gl) {
|
|
314
|
-
const rect = canvas.getBoundingClientRect();
|
|
315
|
-
const pixelRatio = Math.min(window.devicePixelRatio || 1, 2);
|
|
316
|
-
const width = Math.max(1, Math.round(rect.width * pixelRatio));
|
|
317
|
-
const height = Math.max(1, Math.round(rect.height * pixelRatio));
|
|
318
|
-
if (canvas.width !== width || canvas.height !== height) {
|
|
319
|
-
canvas.width = width;
|
|
320
|
-
canvas.height = height;
|
|
321
|
-
}
|
|
322
|
-
gl.viewport(0, 0, width, height);
|
|
323
|
-
return { width, height };
|
|
324
|
-
}
|
|
325
|
-
function addMotionPreferenceListener(query, listener) {
|
|
326
|
-
if (typeof query.addEventListener === "function") {
|
|
327
|
-
query.addEventListener("change", listener);
|
|
328
|
-
return () => query.removeEventListener("change", listener);
|
|
329
|
-
}
|
|
330
|
-
query.addListener(listener);
|
|
331
|
-
return () => query.removeListener(listener);
|
|
332
|
-
}
|
|
333
|
-
var mascotEyeTrackers = /* @__PURE__ */ new Set();
|
|
334
|
-
var mascotLivelyTriggerSelector = "[data-mascot-lively-trigger]";
|
|
335
|
-
var mascotVisualDebounceMs = 200;
|
|
336
|
-
var mascotLivelyTriggerSubscribers = /* @__PURE__ */ new Set();
|
|
337
|
-
var latestPointerTarget = null;
|
|
338
|
-
var latestFocusElement = null;
|
|
339
|
-
var activeMascotEyeTarget = "pointer";
|
|
340
|
-
var mascotLivelyTriggerActive = false;
|
|
341
|
-
var mascotLivelyTriggerPointerActive = false;
|
|
342
|
-
var mascotLivelyTriggerFocusActive = false;
|
|
343
|
-
var mascotEyeTrackingFrame = 0;
|
|
344
|
-
var removeMascotEyeTrackingListeners = null;
|
|
345
|
-
var removeMascotLivelyTriggerListeners = null;
|
|
346
|
-
function isSameMascotVisualState(left, right) {
|
|
347
|
-
return left.expression === right.expression && left.intensity === right.intensity;
|
|
348
|
-
}
|
|
349
|
-
function createMascotVisualStateStore(initialState) {
|
|
350
|
-
const subscribers = /* @__PURE__ */ new Set();
|
|
351
|
-
let currentState = initialState;
|
|
352
|
-
let targetState = initialState;
|
|
353
|
-
let targetTimer = null;
|
|
354
|
-
const clearTargetTimer = () => {
|
|
355
|
-
if (targetTimer !== null && typeof window !== "undefined") {
|
|
356
|
-
window.clearTimeout(targetTimer);
|
|
357
|
-
}
|
|
358
|
-
targetTimer = null;
|
|
359
|
-
};
|
|
360
|
-
const commitTargetState = () => {
|
|
361
|
-
targetTimer = null;
|
|
362
|
-
if (isSameMascotVisualState(currentState, targetState)) {
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
currentState = targetState;
|
|
366
|
-
subscribers.forEach((subscriber) => subscriber());
|
|
367
|
-
};
|
|
368
|
-
return {
|
|
369
|
-
getSnapshot: () => currentState,
|
|
370
|
-
getServerSnapshot: () => initialState,
|
|
371
|
-
setTarget: (nextState) => {
|
|
372
|
-
targetState = nextState;
|
|
373
|
-
if (isSameMascotVisualState(currentState, targetState)) {
|
|
374
|
-
clearTargetTimer();
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
if (typeof window === "undefined") {
|
|
378
|
-
commitTargetState();
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
clearTargetTimer();
|
|
382
|
-
targetTimer = window.setTimeout(commitTargetState, mascotVisualDebounceMs);
|
|
383
|
-
},
|
|
384
|
-
subscribe: (subscriber) => {
|
|
385
|
-
subscribers.add(subscriber);
|
|
386
|
-
return () => {
|
|
387
|
-
subscribers.delete(subscriber);
|
|
388
|
-
if (subscribers.size === 0) {
|
|
389
|
-
clearTargetTimer();
|
|
390
|
-
}
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
function viewportCenterTarget() {
|
|
396
|
-
return {
|
|
397
|
-
x: window.innerWidth / 2,
|
|
398
|
-
y: window.innerHeight / 2
|
|
399
|
-
};
|
|
400
|
-
}
|
|
401
|
-
function elementCenterTarget(element) {
|
|
402
|
-
if (!element || element === document.body || element === document.documentElement) {
|
|
403
|
-
return null;
|
|
404
|
-
}
|
|
405
|
-
const rect = element.getBoundingClientRect();
|
|
406
|
-
if (rect.width <= 0 || rect.height <= 0) {
|
|
407
|
-
return null;
|
|
408
|
-
}
|
|
409
|
-
return {
|
|
410
|
-
x: rect.left + rect.width / 2,
|
|
411
|
-
y: rect.top + rect.height / 2
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
function activeFocusElement() {
|
|
415
|
-
const activeElement = document.activeElement;
|
|
416
|
-
return activeElement && activeElement !== document.body ? activeElement : null;
|
|
417
|
-
}
|
|
418
|
-
function eventTargetElement(event) {
|
|
419
|
-
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
420
|
-
for (const item of path) {
|
|
421
|
-
if (item instanceof Element) {
|
|
422
|
-
return item;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
return event.target instanceof Element ? event.target : null;
|
|
426
|
-
}
|
|
427
|
-
function mascotLivelyTriggerFromEvent(event) {
|
|
428
|
-
return eventTargetElement(event)?.closest(mascotLivelyTriggerSelector) ?? null;
|
|
429
|
-
}
|
|
430
|
-
function eventRelatedTarget(event) {
|
|
431
|
-
return event.relatedTarget instanceof Element ? event.relatedTarget : null;
|
|
432
|
-
}
|
|
433
|
-
function setMascotLivelyTriggerActive(nextActive) {
|
|
434
|
-
if (mascotLivelyTriggerActive === nextActive) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
mascotLivelyTriggerActive = nextActive;
|
|
438
|
-
mascotLivelyTriggerSubscribers.forEach((subscriber) => subscriber());
|
|
439
|
-
}
|
|
440
|
-
function updateMascotLivelyTriggerActive() {
|
|
441
|
-
setMascotLivelyTriggerActive(mascotLivelyTriggerPointerActive || mascotLivelyTriggerFocusActive);
|
|
442
|
-
}
|
|
443
|
-
function setMascotLivelyTriggerPointerActive(nextActive) {
|
|
444
|
-
if (mascotLivelyTriggerPointerActive === nextActive) {
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
mascotLivelyTriggerPointerActive = nextActive;
|
|
448
|
-
updateMascotLivelyTriggerActive();
|
|
449
|
-
}
|
|
450
|
-
function setMascotLivelyTriggerFocusActive(nextActive) {
|
|
451
|
-
if (mascotLivelyTriggerFocusActive === nextActive) {
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
mascotLivelyTriggerFocusActive = nextActive;
|
|
455
|
-
updateMascotLivelyTriggerActive();
|
|
456
|
-
}
|
|
457
|
-
function handleMascotLivelyPointerOver(event) {
|
|
458
|
-
if (mascotLivelyTriggerFromEvent(event)) {
|
|
459
|
-
setMascotLivelyTriggerPointerActive(true);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
function handleMascotLivelyPointerMove(event) {
|
|
463
|
-
setMascotLivelyTriggerPointerActive(mascotLivelyTriggerFromEvent(event) !== null);
|
|
464
|
-
}
|
|
465
|
-
function handleMascotLivelyPointerOut(event) {
|
|
466
|
-
const trigger = mascotLivelyTriggerFromEvent(event);
|
|
467
|
-
if (!trigger) {
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
const relatedTarget = eventRelatedTarget(event);
|
|
471
|
-
if (relatedTarget && trigger.contains(relatedTarget)) {
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
setMascotLivelyTriggerPointerActive(false);
|
|
475
|
-
}
|
|
476
|
-
function handleMascotLivelyFocusIn(event) {
|
|
477
|
-
if (mascotLivelyTriggerFromEvent(event)) {
|
|
478
|
-
setMascotLivelyTriggerFocusActive(true);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
function handleMascotLivelyFocusOut(event) {
|
|
482
|
-
const trigger = mascotLivelyTriggerFromEvent(event);
|
|
483
|
-
if (!trigger) {
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
const relatedTarget = eventRelatedTarget(event);
|
|
487
|
-
if (relatedTarget && trigger.contains(relatedTarget)) {
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
setMascotLivelyTriggerFocusActive(false);
|
|
491
|
-
}
|
|
492
|
-
function ensureMascotLivelyTriggerListeners() {
|
|
493
|
-
if (removeMascotLivelyTriggerListeners || typeof window === "undefined" || typeof document === "undefined") {
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
496
|
-
document.addEventListener("pointerover", handleMascotLivelyPointerOver, { passive: true });
|
|
497
|
-
document.addEventListener("pointermove", handleMascotLivelyPointerMove, { passive: true });
|
|
498
|
-
document.addEventListener("pointerout", handleMascotLivelyPointerOut, { passive: true });
|
|
499
|
-
document.addEventListener("focusin", handleMascotLivelyFocusIn);
|
|
500
|
-
document.addEventListener("focusout", handleMascotLivelyFocusOut);
|
|
501
|
-
removeMascotLivelyTriggerListeners = () => {
|
|
502
|
-
document.removeEventListener("pointerover", handleMascotLivelyPointerOver);
|
|
503
|
-
document.removeEventListener("pointermove", handleMascotLivelyPointerMove);
|
|
504
|
-
document.removeEventListener("pointerout", handleMascotLivelyPointerOut);
|
|
505
|
-
document.removeEventListener("focusin", handleMascotLivelyFocusIn);
|
|
506
|
-
document.removeEventListener("focusout", handleMascotLivelyFocusOut);
|
|
507
|
-
removeMascotLivelyTriggerListeners = null;
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
function getMascotLivelyTriggerSnapshot() {
|
|
511
|
-
return mascotLivelyTriggerActive;
|
|
512
|
-
}
|
|
513
|
-
var getServerMascotLivelyTriggerSnapshot = () => false;
|
|
514
|
-
function subscribeMascotLivelyTrigger(subscriber) {
|
|
515
|
-
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
516
|
-
return () => void 0;
|
|
517
|
-
}
|
|
518
|
-
mascotLivelyTriggerSubscribers.add(subscriber);
|
|
519
|
-
ensureMascotLivelyTriggerListeners();
|
|
520
|
-
return () => {
|
|
521
|
-
mascotLivelyTriggerSubscribers.delete(subscriber);
|
|
522
|
-
if (mascotLivelyTriggerSubscribers.size === 0) {
|
|
523
|
-
mascotLivelyTriggerActive = false;
|
|
524
|
-
mascotLivelyTriggerPointerActive = false;
|
|
525
|
-
mascotLivelyTriggerFocusActive = false;
|
|
526
|
-
removeMascotLivelyTriggerListeners?.();
|
|
527
|
-
}
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
function currentMascotEyeTarget() {
|
|
531
|
-
if (activeMascotEyeTarget === "focus") {
|
|
532
|
-
const focusedTarget = elementCenterTarget(latestFocusElement ?? activeFocusElement());
|
|
533
|
-
if (focusedTarget) {
|
|
534
|
-
return focusedTarget;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
return latestPointerTarget ?? elementCenterTarget(activeFocusElement()) ?? viewportCenterTarget();
|
|
538
|
-
}
|
|
539
|
-
function updateMascotEyes() {
|
|
540
|
-
mascotEyeTrackingFrame = 0;
|
|
541
|
-
const target = currentMascotEyeTarget();
|
|
542
|
-
mascotEyeTrackers.forEach((tracker) => tracker.update(target));
|
|
543
|
-
}
|
|
544
|
-
function scheduleMascotEyeUpdate() {
|
|
545
|
-
if (mascotEyeTrackingFrame || typeof window === "undefined") {
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
mascotEyeTrackingFrame = window.requestAnimationFrame(updateMascotEyes);
|
|
549
|
-
}
|
|
550
|
-
function handleMascotPointerMove(event) {
|
|
551
|
-
latestPointerTarget = { x: event.clientX, y: event.clientY };
|
|
552
|
-
activeMascotEyeTarget = "pointer";
|
|
553
|
-
scheduleMascotEyeUpdate();
|
|
554
|
-
}
|
|
555
|
-
function handleMascotTouchMove(event) {
|
|
556
|
-
const touch = event.touches.item(0);
|
|
557
|
-
if (!touch) {
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
560
|
-
latestPointerTarget = { x: touch.clientX, y: touch.clientY };
|
|
561
|
-
activeMascotEyeTarget = "pointer";
|
|
562
|
-
scheduleMascotEyeUpdate();
|
|
563
|
-
}
|
|
564
|
-
function handleMascotFocusIn(event) {
|
|
565
|
-
latestFocusElement = eventTargetElement(event);
|
|
566
|
-
activeMascotEyeTarget = "focus";
|
|
567
|
-
scheduleMascotEyeUpdate();
|
|
568
|
-
}
|
|
569
|
-
function handleMascotFocusOut() {
|
|
570
|
-
latestFocusElement = activeFocusElement();
|
|
571
|
-
if (!latestFocusElement) {
|
|
572
|
-
activeMascotEyeTarget = "pointer";
|
|
573
|
-
}
|
|
574
|
-
scheduleMascotEyeUpdate();
|
|
575
|
-
}
|
|
576
|
-
function ensureMascotEyeTrackingListeners() {
|
|
577
|
-
if (removeMascotEyeTrackingListeners || typeof window === "undefined") {
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
latestFocusElement = activeFocusElement();
|
|
581
|
-
document.addEventListener("pointermove", handleMascotPointerMove, { passive: true });
|
|
582
|
-
document.addEventListener("touchmove", handleMascotTouchMove, { passive: true });
|
|
583
|
-
document.addEventListener("focusin", handleMascotFocusIn);
|
|
584
|
-
document.addEventListener("focusout", handleMascotFocusOut);
|
|
585
|
-
window.addEventListener("resize", scheduleMascotEyeUpdate, { passive: true });
|
|
586
|
-
window.addEventListener("scroll", scheduleMascotEyeUpdate, { passive: true, capture: true });
|
|
587
|
-
removeMascotEyeTrackingListeners = () => {
|
|
588
|
-
document.removeEventListener("pointermove", handleMascotPointerMove);
|
|
589
|
-
document.removeEventListener("touchmove", handleMascotTouchMove);
|
|
590
|
-
document.removeEventListener("focusin", handleMascotFocusIn);
|
|
591
|
-
document.removeEventListener("focusout", handleMascotFocusOut);
|
|
592
|
-
window.removeEventListener("resize", scheduleMascotEyeUpdate);
|
|
593
|
-
window.removeEventListener("scroll", scheduleMascotEyeUpdate, { capture: true });
|
|
594
|
-
removeMascotEyeTrackingListeners = null;
|
|
595
|
-
};
|
|
596
|
-
}
|
|
597
|
-
function registerMascotEyeTracker(tracker) {
|
|
598
|
-
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
599
|
-
return () => void 0;
|
|
600
|
-
}
|
|
601
|
-
mascotEyeTrackers.add(tracker);
|
|
602
|
-
ensureMascotEyeTrackingListeners();
|
|
603
|
-
tracker.update(currentMascotEyeTarget());
|
|
604
|
-
return () => {
|
|
605
|
-
mascotEyeTrackers.delete(tracker);
|
|
606
|
-
if (mascotEyeTrackers.size === 0) {
|
|
607
|
-
if (mascotEyeTrackingFrame) {
|
|
608
|
-
window.cancelAnimationFrame(mascotEyeTrackingFrame);
|
|
609
|
-
mascotEyeTrackingFrame = 0;
|
|
610
|
-
}
|
|
611
|
-
removeMascotEyeTrackingListeners?.();
|
|
612
|
-
}
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
function WarmFlameMascotEyes({ state }) {
|
|
616
|
-
const eye = state.eye;
|
|
617
|
-
if (eye.kind === "happy") {
|
|
618
|
-
return /* @__PURE__ */ jsxs("g", { className: "warm-flame-eyes", fill: "currentColor", children: [
|
|
619
|
-
/* @__PURE__ */ jsx("ellipse", { className: "warm-flame-eye", cx: 88, cy: 186, rx: 6, ry: 8 }),
|
|
620
|
-
/* @__PURE__ */ jsx("ellipse", { className: "warm-flame-eye", cx: 144, cy: 186, rx: 6, ry: 8 })
|
|
621
|
-
] });
|
|
622
|
-
}
|
|
623
|
-
if (eye.kind === "closed") {
|
|
624
|
-
return /* @__PURE__ */ jsxs(
|
|
625
|
-
"g",
|
|
626
|
-
{
|
|
627
|
-
className: "warm-flame-eyes",
|
|
628
|
-
fill: "none",
|
|
629
|
-
stroke: "currentColor",
|
|
630
|
-
strokeLinecap: "round",
|
|
631
|
-
strokeWidth: "7",
|
|
632
|
-
children: [
|
|
633
|
-
/* @__PURE__ */ jsx("path", { className: "warm-flame-eye", d: "M78 190C83 195 93 195 98 190" }),
|
|
634
|
-
/* @__PURE__ */ jsx("path", { className: "warm-flame-eye", d: "M134 190C139 195 149 195 154 190" })
|
|
635
|
-
]
|
|
636
|
-
}
|
|
637
|
-
);
|
|
638
|
-
}
|
|
639
|
-
return /* @__PURE__ */ jsxs("g", { className: "warm-flame-eyes", children: [
|
|
640
|
-
eye.lines?.map((line) => /* @__PURE__ */ jsx(
|
|
641
|
-
"path",
|
|
642
|
-
{
|
|
643
|
-
className: "warm-flame-brow",
|
|
644
|
-
d: line,
|
|
645
|
-
fill: "none",
|
|
646
|
-
opacity: "0.72",
|
|
647
|
-
stroke: "currentColor",
|
|
648
|
-
strokeLinecap: "round",
|
|
649
|
-
strokeWidth: "4.5"
|
|
650
|
-
},
|
|
651
|
-
line
|
|
652
|
-
)),
|
|
653
|
-
/* @__PURE__ */ jsx(
|
|
654
|
-
"ellipse",
|
|
655
|
-
{
|
|
656
|
-
className: "warm-flame-eye",
|
|
657
|
-
cx: eye.lx,
|
|
658
|
-
cy: eye.ly,
|
|
659
|
-
fill: "currentColor",
|
|
660
|
-
rx: eye.lrx,
|
|
661
|
-
ry: eye.lry
|
|
662
|
-
}
|
|
663
|
-
),
|
|
664
|
-
/* @__PURE__ */ jsx(
|
|
665
|
-
"ellipse",
|
|
666
|
-
{
|
|
667
|
-
className: "warm-flame-eye",
|
|
668
|
-
cx: eye.rx,
|
|
669
|
-
cy: eye.ry,
|
|
670
|
-
fill: "currentColor",
|
|
671
|
-
rx: eye.rrx,
|
|
672
|
-
ry: eye.rry
|
|
673
|
-
}
|
|
674
|
-
)
|
|
675
|
-
] });
|
|
676
|
-
}
|
|
677
|
-
function WarmFlameMascotMouth({ mouth }) {
|
|
678
|
-
if (mouth.kind === "laugh") {
|
|
679
|
-
return /* @__PURE__ */ jsx("path", { className: "warm-flame-mouth warm-flame-mouth--filled", d: mouth.d });
|
|
680
|
-
}
|
|
681
|
-
return /* @__PURE__ */ jsx(
|
|
682
|
-
"path",
|
|
683
|
-
{
|
|
684
|
-
className: "warm-flame-mouth",
|
|
685
|
-
d: mouth.d,
|
|
686
|
-
stroke: "currentColor",
|
|
687
|
-
strokeWidth: mouth.width
|
|
688
|
-
}
|
|
689
|
-
);
|
|
690
|
-
}
|
|
691
|
-
function setupWarmFlameShader(canvas) {
|
|
692
|
-
const gl = canvas.getContext("webgl", {
|
|
693
|
-
alpha: true,
|
|
694
|
-
antialias: true,
|
|
695
|
-
premultipliedAlpha: true
|
|
696
|
-
}) ?? canvas.getContext("experimental-webgl", { alpha: true });
|
|
697
|
-
if (!gl) {
|
|
698
|
-
return () => void 0;
|
|
699
|
-
}
|
|
700
|
-
try {
|
|
701
|
-
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
|
|
702
|
-
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
|
|
703
|
-
const program = createProgram(gl, vertexShader, fragmentShader);
|
|
704
|
-
const positionBuffer = gl.createBuffer();
|
|
705
|
-
if (!positionBuffer) {
|
|
706
|
-
throw new Error("Unable to create Warm flame shader buffer.");
|
|
707
|
-
}
|
|
708
|
-
gl.useProgram(program);
|
|
709
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
710
|
-
gl.bufferData(
|
|
711
|
-
gl.ARRAY_BUFFER,
|
|
712
|
-
new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),
|
|
713
|
-
gl.STATIC_DRAW
|
|
714
|
-
);
|
|
715
|
-
const positionLocation = gl.getAttribLocation(program, "a_position");
|
|
716
|
-
gl.enableVertexAttribArray(positionLocation);
|
|
717
|
-
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
|
|
718
|
-
const uniforms = {
|
|
719
|
-
time: gl.getUniformLocation(program, "u_time"),
|
|
720
|
-
resolution: gl.getUniformLocation(program, "u_resolution"),
|
|
721
|
-
color1: gl.getUniformLocation(program, "u_color1"),
|
|
722
|
-
color2: gl.getUniformLocation(program, "u_color2"),
|
|
723
|
-
color3: gl.getUniformLocation(program, "u_color3"),
|
|
724
|
-
speed: gl.getUniformLocation(program, "u_speed"),
|
|
725
|
-
scale: gl.getUniformLocation(program, "u_scale"),
|
|
726
|
-
noise: gl.getUniformLocation(program, "u_noise"),
|
|
727
|
-
stripeX: gl.getUniformLocation(program, "u_stripe_x"),
|
|
728
|
-
stripeY: gl.getUniformLocation(program, "u_stripe_y"),
|
|
729
|
-
bend: gl.getUniformLocation(program, "u_bend"),
|
|
730
|
-
highlightStart: gl.getUniformLocation(program, "u_highlight_start"),
|
|
731
|
-
highlightStrength: gl.getUniformLocation(program, "u_highlight_strength"),
|
|
732
|
-
glowStrength: gl.getUniformLocation(program, "u_glow_strength")
|
|
733
|
-
};
|
|
734
|
-
const [color1R, color1G, color1B] = unitColor(WARM_FLAME_MASCOT_SHADER_CONFIG.color1);
|
|
735
|
-
const [color2R, color2G, color2B] = unitColor(WARM_FLAME_MASCOT_SHADER_CONFIG.color2);
|
|
736
|
-
const [color3R, color3G, color3B] = unitColor(WARM_FLAME_MASCOT_SHADER_CONFIG.color3);
|
|
737
|
-
const motionQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
738
|
-
let frame = 0;
|
|
739
|
-
let disposed = false;
|
|
740
|
-
const render = (now) => {
|
|
741
|
-
frame = 0;
|
|
742
|
-
if (disposed) return;
|
|
743
|
-
const { width, height } = resizeCanvas(canvas, gl);
|
|
744
|
-
gl.clearColor(0, 0, 0, 0);
|
|
745
|
-
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
746
|
-
gl.useProgram(program);
|
|
747
|
-
gl.uniform1f(uniforms.time, motionQuery.matches ? 0 : now * 1e-3);
|
|
748
|
-
gl.uniform2f(uniforms.resolution, width, height);
|
|
749
|
-
gl.uniform3f(uniforms.color1, color1R, color1G, color1B);
|
|
750
|
-
gl.uniform3f(uniforms.color2, color2R, color2G, color2B);
|
|
751
|
-
gl.uniform3f(uniforms.color3, color3R, color3G, color3B);
|
|
752
|
-
gl.uniform1f(uniforms.speed, WARM_FLAME_MASCOT_SHADER_CONFIG.speed);
|
|
753
|
-
gl.uniform1f(uniforms.scale, WARM_FLAME_MASCOT_SHADER_CONFIG.scale);
|
|
754
|
-
gl.uniform1f(uniforms.noise, WARM_FLAME_MASCOT_SHADER_CONFIG.noise);
|
|
755
|
-
gl.uniform1f(uniforms.stripeX, WARM_FLAME_MASCOT_SHADER_CONFIG.stripeX);
|
|
756
|
-
gl.uniform1f(uniforms.stripeY, WARM_FLAME_MASCOT_SHADER_CONFIG.stripeY);
|
|
757
|
-
gl.uniform1f(uniforms.bend, WARM_FLAME_MASCOT_SHADER_CONFIG.bend);
|
|
758
|
-
gl.uniform1f(uniforms.highlightStart, WARM_FLAME_MASCOT_SHADER_CONFIG.highlightStart);
|
|
759
|
-
gl.uniform1f(uniforms.highlightStrength, WARM_FLAME_MASCOT_SHADER_CONFIG.highlightStrength);
|
|
760
|
-
gl.uniform1f(uniforms.glowStrength, WARM_FLAME_MASCOT_SHADER_CONFIG.glowStrength);
|
|
761
|
-
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
762
|
-
if (!motionQuery.matches) {
|
|
763
|
-
frame = window.requestAnimationFrame(render);
|
|
764
|
-
}
|
|
765
|
-
};
|
|
766
|
-
const requestRender = () => {
|
|
767
|
-
if (frame || disposed) return;
|
|
768
|
-
frame = window.requestAnimationFrame(render);
|
|
769
|
-
};
|
|
770
|
-
const handleMotionPreferenceChange = () => {
|
|
771
|
-
canvas.closest('[data-slot="warm-flame-mascot"]')?.setAttribute("data-reduced-motion", motionQuery.matches ? "true" : "false");
|
|
772
|
-
requestRender();
|
|
773
|
-
};
|
|
774
|
-
const removeMotionPreferenceListener = addMotionPreferenceListener(
|
|
775
|
-
motionQuery,
|
|
776
|
-
handleMotionPreferenceChange
|
|
777
|
-
);
|
|
778
|
-
handleMotionPreferenceChange();
|
|
779
|
-
requestRender();
|
|
780
|
-
return () => {
|
|
781
|
-
disposed = true;
|
|
782
|
-
if (frame) window.cancelAnimationFrame(frame);
|
|
783
|
-
removeMotionPreferenceListener();
|
|
784
|
-
gl.deleteBuffer(positionBuffer);
|
|
785
|
-
gl.deleteProgram(program);
|
|
786
|
-
gl.deleteShader(vertexShader);
|
|
787
|
-
gl.deleteShader(fragmentShader);
|
|
788
|
-
};
|
|
789
|
-
} catch {
|
|
790
|
-
return () => void 0;
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
function WarmFlameMascot(props) {
|
|
794
|
-
if (!isWarmFlameMascotEnabled()) {
|
|
795
|
-
return null;
|
|
796
|
-
}
|
|
797
|
-
return /* @__PURE__ */ jsx(WarmFlameMascotInner, { ...props });
|
|
798
|
-
}
|
|
799
|
-
function WarmFlameMascotInner({
|
|
800
|
-
size = "default",
|
|
801
|
-
intensity = "calm",
|
|
802
|
-
expression = "calm",
|
|
803
|
-
mood,
|
|
804
|
-
hoverExpression,
|
|
805
|
-
trackCursor = false,
|
|
806
|
-
label = "Warm flame mascot",
|
|
807
|
-
className: _className,
|
|
808
|
-
style: _style
|
|
809
|
-
}) {
|
|
810
|
-
const cleanupRef = useRef(null);
|
|
811
|
-
const isMascotLivelyTriggerActive = useSyncExternalStore(
|
|
812
|
-
subscribeMascotLivelyTrigger,
|
|
813
|
-
getMascotLivelyTriggerSnapshot,
|
|
814
|
-
getServerMascotLivelyTriggerSnapshot
|
|
815
|
-
);
|
|
816
|
-
const selectedExpression = mood ?? expression;
|
|
817
|
-
const requestedIntensity = isMascotLivelyTriggerActive ? "lively" : intensity;
|
|
818
|
-
const requestedExpression = isMascotLivelyTriggerActive ? "happy" : selectedExpression;
|
|
819
|
-
const requestedVisualState = {
|
|
820
|
-
intensity: requestedIntensity,
|
|
821
|
-
expression: requestedExpression
|
|
822
|
-
};
|
|
823
|
-
const [visualStateStore] = useState(() => createMascotVisualStateStore(requestedVisualState));
|
|
824
|
-
const renderedVisualState = useSyncExternalStore(
|
|
825
|
-
visualStateStore.subscribe,
|
|
826
|
-
visualStateStore.getSnapshot,
|
|
827
|
-
visualStateStore.getServerSnapshot
|
|
828
|
-
);
|
|
829
|
-
const renderedIntensity = renderedVisualState.intensity;
|
|
830
|
-
const renderedExpression = renderedVisualState.expression;
|
|
831
|
-
const pixelSize = resolvePixelSize(size);
|
|
832
|
-
const motionConfig = WARM_FLAME_MASCOT_DEFAULT_EXPRESSION_CONFIG;
|
|
833
|
-
const expressionConfig = getWarmFlameMascotExpressionConfig(renderedExpression);
|
|
834
|
-
const rootStyle = {
|
|
835
|
-
"--warm-flame-mascot-default-size": `${pixelSize}px`,
|
|
836
|
-
"--warm-flame-float-duration": motionConfig.floatDuration,
|
|
837
|
-
"--warm-flame-float-lift": motionConfig.floatLift,
|
|
838
|
-
"--warm-flame-float-scale-y": motionConfig.floatScaleY,
|
|
839
|
-
"--warm-flame-blink-duration": expressionConfig.blinkDuration,
|
|
840
|
-
width: "var(--warm-flame-mascot-size, var(--warm-flame-mascot-default-size))",
|
|
841
|
-
aspectRatio: "231 / 289"
|
|
842
|
-
};
|
|
843
|
-
const rootRef = useCallback(
|
|
844
|
-
(node) => {
|
|
845
|
-
cleanupRef.current?.();
|
|
846
|
-
cleanupRef.current = null;
|
|
847
|
-
if (!node || typeof window === "undefined") return;
|
|
848
|
-
const canvas = node.querySelector("[data-warm-flame-body]");
|
|
849
|
-
if (!canvas) return;
|
|
850
|
-
const shaderCleanup = setupWarmFlameShader(canvas);
|
|
851
|
-
const updateEyes = ({ x, y }) => {
|
|
852
|
-
const rootRect = node.getBoundingClientRect();
|
|
853
|
-
const rootX = rootRect.left + rootRect.width / 2;
|
|
854
|
-
const rootY = rootRect.top + rootRect.height * 0.64;
|
|
855
|
-
const eyeX = clamp(
|
|
856
|
-
(x - rootX) / Math.max(rootRect.width, 1) * mascotEyeOffsetConfig.xScale,
|
|
857
|
-
-mascotEyeOffsetConfig.xMax,
|
|
858
|
-
mascotEyeOffsetConfig.xMax
|
|
859
|
-
);
|
|
860
|
-
const eyeY = clamp(
|
|
861
|
-
(y - rootY) / Math.max(rootRect.height, 1) * mascotEyeOffsetConfig.yScale,
|
|
862
|
-
-mascotEyeOffsetConfig.yMax,
|
|
863
|
-
mascotEyeOffsetConfig.yMax
|
|
864
|
-
);
|
|
865
|
-
node.style.setProperty("--warm-flame-eye-x", `${eyeX.toFixed(2)}px`);
|
|
866
|
-
node.style.setProperty("--warm-flame-eye-y", `${eyeY.toFixed(2)}px`);
|
|
867
|
-
};
|
|
868
|
-
if (!trackCursor) {
|
|
869
|
-
node.style.setProperty("--warm-flame-eye-x", "0px");
|
|
870
|
-
node.style.setProperty("--warm-flame-eye-y", "0px");
|
|
871
|
-
cleanupRef.current = shaderCleanup;
|
|
872
|
-
return;
|
|
873
|
-
}
|
|
874
|
-
const trackingCleanup = registerMascotEyeTracker({ update: updateEyes });
|
|
875
|
-
cleanupRef.current = () => {
|
|
876
|
-
shaderCleanup();
|
|
877
|
-
trackingCleanup();
|
|
878
|
-
};
|
|
879
|
-
},
|
|
880
|
-
[trackCursor]
|
|
881
|
-
);
|
|
882
|
-
const syncVisualStateRef = useCallback(
|
|
883
|
-
(node) => {
|
|
884
|
-
if (!node) return;
|
|
885
|
-
visualStateStore.setTarget({
|
|
886
|
-
intensity: requestedIntensity,
|
|
887
|
-
expression: requestedExpression
|
|
888
|
-
});
|
|
889
|
-
},
|
|
890
|
-
[requestedExpression, requestedIntensity, visualStateStore]
|
|
891
|
-
);
|
|
892
|
-
return /* @__PURE__ */ jsx(
|
|
893
|
-
"div",
|
|
894
|
-
{
|
|
895
|
-
ref: rootRef,
|
|
896
|
-
className: cn(
|
|
897
|
-
"warm-flame-mascot pointer-events-none inline-flex shrink-0 select-none items-center justify-center",
|
|
898
|
-
renderedIntensity === "lively" && "warm-flame-mascot-lively",
|
|
899
|
-
hoverExpression === "mouth-open" && "warm-flame-mascot--mouth-open-hover"
|
|
900
|
-
),
|
|
901
|
-
style: rootStyle,
|
|
902
|
-
role: label ? "img" : void 0,
|
|
903
|
-
"aria-label": label ?? void 0,
|
|
904
|
-
"aria-hidden": label ? void 0 : true,
|
|
905
|
-
"data-slot": "warm-flame-mascot",
|
|
906
|
-
"data-expression": renderedExpression,
|
|
907
|
-
children: /* @__PURE__ */ jsxs("div", { ref: syncVisualStateRef, className: "warm-flame-art", "aria-hidden": "true", children: [
|
|
908
|
-
/* @__PURE__ */ jsx(
|
|
909
|
-
"canvas",
|
|
910
|
-
{
|
|
911
|
-
className: "warm-flame-body",
|
|
912
|
-
"data-warm-flame-body": "",
|
|
913
|
-
style: {
|
|
914
|
-
WebkitMaskImage: flameMaskImage,
|
|
915
|
-
maskImage: flameMaskImage
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
),
|
|
919
|
-
/* @__PURE__ */ jsx(
|
|
920
|
-
"svg",
|
|
921
|
-
{
|
|
922
|
-
className: "warm-flame-face",
|
|
923
|
-
viewBox: "0 0 231 289",
|
|
924
|
-
fill: "none",
|
|
925
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
926
|
-
children: WARM_FLAME_MASCOT_EXPRESSION_CONFIGS.map((state) => /* @__PURE__ */ jsxs(
|
|
927
|
-
"g",
|
|
928
|
-
{
|
|
929
|
-
className: "warm-flame-expression-face",
|
|
930
|
-
"data-expression-id": state.id,
|
|
931
|
-
"data-expression-active": state.id === renderedExpression ? "true" : void 0,
|
|
932
|
-
children: [
|
|
933
|
-
/* @__PURE__ */ jsx(WarmFlameMascotEyes, { state }),
|
|
934
|
-
/* @__PURE__ */ jsx(WarmFlameMascotMouth, { mouth: state.mouth }),
|
|
935
|
-
/* @__PURE__ */ jsx(
|
|
936
|
-
"ellipse",
|
|
937
|
-
{
|
|
938
|
-
className: "warm-flame-cheek",
|
|
939
|
-
cx: "74",
|
|
940
|
-
cy: "212",
|
|
941
|
-
fill: "var(--mascot-blush)",
|
|
942
|
-
opacity: state.cheekOpacity,
|
|
943
|
-
rx: "9",
|
|
944
|
-
ry: "6"
|
|
945
|
-
}
|
|
946
|
-
),
|
|
947
|
-
/* @__PURE__ */ jsx(
|
|
948
|
-
"ellipse",
|
|
949
|
-
{
|
|
950
|
-
className: "warm-flame-cheek",
|
|
951
|
-
cx: "158",
|
|
952
|
-
cy: "212",
|
|
953
|
-
fill: "var(--mascot-blush)",
|
|
954
|
-
opacity: state.cheekOpacity,
|
|
955
|
-
rx: "9",
|
|
956
|
-
ry: "6"
|
|
957
|
-
}
|
|
958
|
-
)
|
|
959
|
-
]
|
|
960
|
-
},
|
|
961
|
-
state.id
|
|
962
|
-
))
|
|
963
|
-
}
|
|
964
|
-
)
|
|
965
|
-
] })
|
|
966
|
-
}
|
|
967
|
-
);
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
// ../ui/src/warmio/logo.tsx
|
|
971
|
-
import {
|
|
972
|
-
Logo,
|
|
973
|
-
WarmLogoIcon
|
|
974
|
-
} from "@warmio/design/logo";
|
|
975
|
-
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
976
|
-
var brandedLogoShellClassNameBySize = {
|
|
977
|
-
sm: "size-8",
|
|
978
|
-
md: "size-10",
|
|
979
|
-
lg: "size-14"
|
|
980
|
-
};
|
|
981
|
-
var brandedLogoIconClassNameBySize = {
|
|
982
|
-
sm: "size-5",
|
|
983
|
-
md: "size-6",
|
|
984
|
-
lg: "size-8"
|
|
985
|
-
};
|
|
986
|
-
var _WarmLogoGlyph = /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
987
|
-
/* @__PURE__ */ jsx2(
|
|
988
|
-
"path",
|
|
989
|
-
{
|
|
990
|
-
d: "M 33.500 40.660 C 20.206 42.744, 0 48.560, -0 50.302 C -0 51.759, 123.955 348.889, 127.738 356.500 C 142.182 385.561, 169.450 410.275, 198.946 421.040 C 218.922 428.330, 243.683 430.825, 264.526 427.648 C 277.151 425.724, 294.628 420.011, 294.194 417.952 C 293.790 416.040, 172.732 124.599, 168.522 115.405 C 161.779 100.679, 149.168 84.171, 135.093 71.646 C 119.358 57.644, 98.880 47.362, 77 42.478 C 69.645 40.836, 40.220 39.606, 33.500 40.660",
|
|
991
|
-
fill: "currentColor"
|
|
992
|
-
}
|
|
993
|
-
),
|
|
994
|
-
/* @__PURE__ */ jsx2(
|
|
995
|
-
"path",
|
|
996
|
-
{
|
|
997
|
-
d: "M 229.651 41.597 C 217.916 43.718, 202.443 49.144, 202.744 51.035 C 203.418 55.268, 329.689 356.584, 333.687 363.500 C 340.525 375.327, 345.293 381.483, 355.408 391.538 C 374.603 410.619, 398.878 423.014, 425.907 427.533 C 439.649 429.831, 463.594 429.132, 476 426.072 C 489.892 422.645, 497.188 419.815, 496.703 418.043 C 495.416 413.331, 371.058 116.094, 367.406 109 C 349.467 74.149, 313.008 47.875, 273.752 41.509 C 262.281 39.648, 240.195 39.693, 229.651 41.597",
|
|
998
|
-
fill: "currentColor"
|
|
999
|
-
}
|
|
1000
|
-
),
|
|
1001
|
-
/* @__PURE__ */ jsx2(
|
|
1002
|
-
"path",
|
|
1003
|
-
{
|
|
1004
|
-
d: "M 463 40.593 C 451.670 42.545, 447.288 43.569, 439 46.203 C 433.775 47.864, 429.338 49.372, 429.140 49.555 C 428.942 49.737, 434.670 64.021, 441.868 81.297 C 455.574 114.190, 462.215 131.660, 468.447 151.208 C 475.360 172.892, 486.124 186.213, 503.834 194.997 C 530.956 208.450, 564.982 201.679, 583.654 179.112 C 604.399 154.041, 605.407 121.944, 586.291 95.155 C 567.827 69.280, 539.107 50.114, 508 42.907 C 500.680 41.212, 494.713 40.644, 482 40.434 C 472.925 40.284, 464.375 40.356, 463 40.593",
|
|
1005
|
-
fill: "currentColor"
|
|
1006
|
-
}
|
|
1007
|
-
)
|
|
1008
|
-
] });
|
|
1009
|
-
function WarmBrandedLogoMark({
|
|
1010
|
-
size = "md",
|
|
1011
|
-
className,
|
|
1012
|
-
logoClassName
|
|
1013
|
-
}) {
|
|
1014
|
-
return /* @__PURE__ */ jsxs2(
|
|
1015
|
-
"span",
|
|
1016
|
-
{
|
|
1017
|
-
className: cn(
|
|
1018
|
-
"relative inline-flex shrink-0 items-center justify-center",
|
|
1019
|
-
brandedLogoShellClassNameBySize[size],
|
|
1020
|
-
className
|
|
1021
|
-
),
|
|
1022
|
-
"aria-hidden": "true",
|
|
1023
|
-
children: [
|
|
1024
|
-
/* @__PURE__ */ jsx2("span", { className: "pointer-events-none absolute inset-0 scale-[1.35] opacity-90", children: /* @__PURE__ */ jsx2(WarmFlameMascot, { intensity: "calm", label: null }) }),
|
|
1025
|
-
/* @__PURE__ */ jsx2(
|
|
1026
|
-
"svg",
|
|
1027
|
-
{
|
|
1028
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1029
|
-
viewBox: "0 0 600 469",
|
|
1030
|
-
className: cn(
|
|
1031
|
-
"relative z-10 drop-shadow-sm",
|
|
1032
|
-
brandedLogoIconClassNameBySize[size],
|
|
1033
|
-
logoClassName
|
|
1034
|
-
),
|
|
1035
|
-
"aria-hidden": "true",
|
|
1036
|
-
children: _WarmLogoGlyph
|
|
1037
|
-
}
|
|
1038
|
-
)
|
|
1039
|
-
]
|
|
1040
|
-
}
|
|
1041
|
-
);
|
|
1042
|
-
}
|
|
1043
|
-
function WarmBrandedLogoLink({
|
|
1044
|
-
href,
|
|
1045
|
-
ariaLabel = "Warm home",
|
|
1046
|
-
size = "md",
|
|
1047
|
-
className,
|
|
1048
|
-
logoClassName
|
|
1049
|
-
}) {
|
|
1050
|
-
return /* @__PURE__ */ jsx2("a", { href, "aria-label": ariaLabel, className: "inline-flex shrink-0 items-center", children: /* @__PURE__ */ jsx2(WarmBrandedLogoMark, { size, className, logoClassName }) });
|
|
1051
|
-
}
|
|
1052
|
-
function WarmBrandedLogoMarkStatic({
|
|
1053
|
-
className,
|
|
1054
|
-
logoClassName
|
|
1055
|
-
}) {
|
|
1056
|
-
return /* @__PURE__ */ jsxs2("span", { className: cn("relative inline-flex size-8 items-center justify-center", className), children: [
|
|
1057
|
-
/* @__PURE__ */ jsx2(
|
|
1058
|
-
"span",
|
|
1059
|
-
{
|
|
1060
|
-
"aria-hidden": "true",
|
|
1061
|
-
className: "absolute inset-0 rounded-full bg-gradient-to-br from-primary/90 via-warning/80 to-primary/70"
|
|
1062
|
-
}
|
|
1063
|
-
),
|
|
1064
|
-
/* @__PURE__ */ jsx2(
|
|
1065
|
-
"svg",
|
|
1066
|
-
{
|
|
1067
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1068
|
-
viewBox: "0 0 600 469",
|
|
1069
|
-
className: cn("relative z-10 size-5 drop-shadow-sm", logoClassName),
|
|
1070
|
-
"aria-hidden": "true",
|
|
1071
|
-
children: _WarmLogoGlyph
|
|
1072
|
-
}
|
|
1073
|
-
)
|
|
1074
|
-
] });
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
export {
|
|
1078
|
-
WarmBrandedLogoMark,
|
|
1079
|
-
WarmBrandedLogoLink,
|
|
1080
|
-
WarmBrandedLogoMarkStatic,
|
|
1081
|
-
Logo,
|
|
1082
|
-
WarmLogoIcon
|
|
1083
|
-
};
|