handler-playable-sdk 0.1.0 → 0.1.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/dist/chunk-HFNWDPEC.mjs +17 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/pixi/index.js +1 -1
- package/dist/pixi/index.mjs +1 -1
- package/dist/three/index.d.mts +493 -0
- package/dist/three/index.d.ts +493 -0
- package/dist/three/index.js +109 -0
- package/dist/three/index.mjs +93 -0
- package/package.json +14 -3
- package/dist/chunk-CJIYY5BP.mjs +0 -17
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Handler SDK - Three.js Base Context
|
|
5
|
+
*
|
|
6
|
+
* Creates the base Three.js scene with Handler SDK lifecycle integration.
|
|
7
|
+
* Handles resize, pause/resume, and provides the overlay for UI elements.
|
|
8
|
+
*
|
|
9
|
+
* DO NOT EDIT - Handler SDK Core
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Theme configuration for Three.js base
|
|
14
|
+
*/
|
|
15
|
+
type ThreeTheme = {
|
|
16
|
+
background?: string;
|
|
17
|
+
text?: string;
|
|
18
|
+
text_muted?: string;
|
|
19
|
+
primary?: string;
|
|
20
|
+
cta_text?: string;
|
|
21
|
+
surface_shadow?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Context returned by createThreeBase
|
|
25
|
+
*/
|
|
26
|
+
type ThreeBaseContext = {
|
|
27
|
+
scene: THREE.Scene;
|
|
28
|
+
camera: THREE.OrthographicCamera;
|
|
29
|
+
renderer: THREE.WebGLRenderer;
|
|
30
|
+
overlay: HTMLElement;
|
|
31
|
+
applySize: (size?: {
|
|
32
|
+
width?: number;
|
|
33
|
+
height?: number;
|
|
34
|
+
}) => void;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Create the base Three.js context with Handler SDK integration
|
|
38
|
+
*
|
|
39
|
+
* @param root - The root HTML element to render into (from Handler.getRoot())
|
|
40
|
+
* @param theme - Optional theme configuration
|
|
41
|
+
* @returns Three.js scene context with overlay
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const root = Handler.getRoot();
|
|
46
|
+
* const { scene, camera, renderer, overlay } = await createThreeBase(root, {
|
|
47
|
+
* background: '#160a17',
|
|
48
|
+
* text: '#fef4dd',
|
|
49
|
+
* primary: '#ffb43b'
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare function createThreeBase(root: HTMLElement, theme?: ThreeTheme): Promise<ThreeBaseContext>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Handler SDK - GameObject System for Three.js
|
|
57
|
+
*
|
|
58
|
+
* Unity-style component-based architecture for Three.js objects.
|
|
59
|
+
* Automatically syncs config values to Three.js objects and enables hot-reload.
|
|
60
|
+
*
|
|
61
|
+
* DO NOT EDIT - Handler SDK Core
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Transform Component - Position, scale, rotation
|
|
66
|
+
*/
|
|
67
|
+
declare class Transform {
|
|
68
|
+
position: {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
};
|
|
72
|
+
scale: number;
|
|
73
|
+
rotation: number;
|
|
74
|
+
constructor(config?: {
|
|
75
|
+
position?: {
|
|
76
|
+
x: number;
|
|
77
|
+
y: number;
|
|
78
|
+
};
|
|
79
|
+
scale?: number;
|
|
80
|
+
rotation?: number;
|
|
81
|
+
});
|
|
82
|
+
update(config: {
|
|
83
|
+
position?: {
|
|
84
|
+
x: number;
|
|
85
|
+
y: number;
|
|
86
|
+
};
|
|
87
|
+
scale?: number;
|
|
88
|
+
rotation?: number;
|
|
89
|
+
}): void;
|
|
90
|
+
syncToThree(threeObject: THREE.Object3D): void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Renderer Component - Visual properties
|
|
94
|
+
*/
|
|
95
|
+
declare class Renderer {
|
|
96
|
+
z_index: number;
|
|
97
|
+
alpha: number;
|
|
98
|
+
visible: boolean;
|
|
99
|
+
tint: number | null;
|
|
100
|
+
constructor(config?: {
|
|
101
|
+
z_index?: number;
|
|
102
|
+
alpha?: number;
|
|
103
|
+
visible?: boolean;
|
|
104
|
+
tint?: number | null;
|
|
105
|
+
});
|
|
106
|
+
update(config: {
|
|
107
|
+
z_index?: number;
|
|
108
|
+
alpha?: number;
|
|
109
|
+
visible?: boolean;
|
|
110
|
+
tint?: number | null;
|
|
111
|
+
}): void;
|
|
112
|
+
syncToThree(threeObject: THREE.Object3D): void;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Base GameObject class - Unity-style entity with components
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const characterGO = gameObjectManager.create('character_1', characterMesh);
|
|
120
|
+
* characterGO.setPosition(100, 200);
|
|
121
|
+
* characterGO.setAlpha(0.8);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
declare class GameObject {
|
|
125
|
+
instanceId: string;
|
|
126
|
+
objectConfig: string;
|
|
127
|
+
threeObject: THREE.Object3D;
|
|
128
|
+
transform: Transform;
|
|
129
|
+
renderer: Renderer;
|
|
130
|
+
private _config;
|
|
131
|
+
constructor(instanceId: string, objectConfig: string, threeObject: THREE.Object3D, config: any);
|
|
132
|
+
/**
|
|
133
|
+
* Sync all components to Three.js object
|
|
134
|
+
*/
|
|
135
|
+
sync(): void;
|
|
136
|
+
/**
|
|
137
|
+
* Update config and sync (for hot-reload)
|
|
138
|
+
*/
|
|
139
|
+
updateConfig(newConfig: any): void;
|
|
140
|
+
/**
|
|
141
|
+
* Get component value
|
|
142
|
+
*/
|
|
143
|
+
getComponent<T>(componentName: string): T | undefined;
|
|
144
|
+
/**
|
|
145
|
+
* Get transform position
|
|
146
|
+
*/
|
|
147
|
+
getPosition(): {
|
|
148
|
+
x: number;
|
|
149
|
+
y: number;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Set transform position
|
|
153
|
+
*/
|
|
154
|
+
setPosition(x: number, y: number): void;
|
|
155
|
+
/**
|
|
156
|
+
* Get renderer alpha
|
|
157
|
+
*/
|
|
158
|
+
getAlpha(): number;
|
|
159
|
+
/**
|
|
160
|
+
* Set renderer alpha
|
|
161
|
+
*/
|
|
162
|
+
setAlpha(alpha: number): void;
|
|
163
|
+
/**
|
|
164
|
+
* Get renderer visible
|
|
165
|
+
*/
|
|
166
|
+
getVisible(): boolean;
|
|
167
|
+
/**
|
|
168
|
+
* Set renderer visible
|
|
169
|
+
*/
|
|
170
|
+
setVisible(visible: boolean): void;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* GameObject Manager - Manages all game objects and enables hot-reload
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const gameObjectManager = new GameObjectManager(config);
|
|
178
|
+
* const characterGO = gameObjectManager.create('character_1', characterMesh);
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
declare class GameObjectManager {
|
|
182
|
+
private objects;
|
|
183
|
+
private config;
|
|
184
|
+
constructor(config: any);
|
|
185
|
+
/**
|
|
186
|
+
* Create a GameObject from config
|
|
187
|
+
*/
|
|
188
|
+
create(instanceId: string, threeObject: THREE.Object3D): GameObject;
|
|
189
|
+
/**
|
|
190
|
+
* Get GameObject by instance ID
|
|
191
|
+
*/
|
|
192
|
+
get(instanceId: string): GameObject | undefined;
|
|
193
|
+
/**
|
|
194
|
+
* Update config and sync all objects (for hot-reload)
|
|
195
|
+
*/
|
|
196
|
+
updateConfig(newConfig: any): void;
|
|
197
|
+
/**
|
|
198
|
+
* Get all GameObjects
|
|
199
|
+
*/
|
|
200
|
+
getAll(): GameObject[];
|
|
201
|
+
/**
|
|
202
|
+
* Remove GameObject
|
|
203
|
+
*/
|
|
204
|
+
remove(instanceId: string): void;
|
|
205
|
+
/**
|
|
206
|
+
* Clear all GameObjects
|
|
207
|
+
*/
|
|
208
|
+
clear(): void;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Handler SDK - Font Registry
|
|
213
|
+
*
|
|
214
|
+
* Maps font IDs to actual font families/paths.
|
|
215
|
+
* UI config references fonts by ID only (e.g., "brand.primary").
|
|
216
|
+
* This registry resolves IDs to actual font values.
|
|
217
|
+
*
|
|
218
|
+
* Font paths and platform differences are handled here, NOT in config.
|
|
219
|
+
*
|
|
220
|
+
* DO NOT EDIT - Handler SDK Core
|
|
221
|
+
*/
|
|
222
|
+
type FontDefinition = {
|
|
223
|
+
family: string;
|
|
224
|
+
weight?: string | number;
|
|
225
|
+
style?: string;
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Resolve font ID to font family string
|
|
229
|
+
* @param fontId Font ID from UI config (e.g., "brand.primary")
|
|
230
|
+
* @returns CSS font-family string
|
|
231
|
+
*/
|
|
232
|
+
declare function resolveFont(fontId: string): string;
|
|
233
|
+
/**
|
|
234
|
+
* Resolve font ID to font weight
|
|
235
|
+
* @param fontId Font ID from UI config
|
|
236
|
+
* @returns Font weight (string or number)
|
|
237
|
+
*/
|
|
238
|
+
declare function resolveFontWeight(fontId: string): string | number;
|
|
239
|
+
/**
|
|
240
|
+
* Register a new font (for engine initialization)
|
|
241
|
+
* @param fontId Font ID
|
|
242
|
+
* @param definition Font definition
|
|
243
|
+
*/
|
|
244
|
+
declare function registerFont(fontId: string, definition: FontDefinition): void;
|
|
245
|
+
/**
|
|
246
|
+
* Get all registered font IDs
|
|
247
|
+
*/
|
|
248
|
+
declare function getRegisteredFontIds(): string[];
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Handler SDK - Type Definitions for Three.js Integration
|
|
252
|
+
*
|
|
253
|
+
* DO NOT EDIT - Handler SDK Core
|
|
254
|
+
*/
|
|
255
|
+
/**
|
|
256
|
+
* Object configuration from JSON files
|
|
257
|
+
*/
|
|
258
|
+
interface ObjectConfig {
|
|
259
|
+
object_config?: string;
|
|
260
|
+
transform?: {
|
|
261
|
+
position?: {
|
|
262
|
+
x: number;
|
|
263
|
+
y: number;
|
|
264
|
+
};
|
|
265
|
+
scale?: number;
|
|
266
|
+
rotation?: number;
|
|
267
|
+
offset?: {
|
|
268
|
+
x?: number;
|
|
269
|
+
y?: number;
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
render?: {
|
|
273
|
+
z_index?: number;
|
|
274
|
+
alpha?: number;
|
|
275
|
+
visible?: boolean;
|
|
276
|
+
tint?: number | string | null;
|
|
277
|
+
background_color?: string;
|
|
278
|
+
background_alpha?: number;
|
|
279
|
+
border_color?: string;
|
|
280
|
+
};
|
|
281
|
+
gameplay?: {
|
|
282
|
+
rules?: Record<string, unknown>;
|
|
283
|
+
tuning?: Record<string, unknown>;
|
|
284
|
+
};
|
|
285
|
+
ui?: {
|
|
286
|
+
text?: string;
|
|
287
|
+
font?: string;
|
|
288
|
+
fontSize?: number;
|
|
289
|
+
letterSpacing?: number;
|
|
290
|
+
align?: string;
|
|
291
|
+
};
|
|
292
|
+
effects?: Record<string, unknown>;
|
|
293
|
+
audio?: Record<string, unknown>;
|
|
294
|
+
physics?: Record<string, unknown>;
|
|
295
|
+
interaction?: Record<string, unknown>;
|
|
296
|
+
identity?: Record<string, unknown>;
|
|
297
|
+
visibility?: Record<string, unknown>;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Engine configuration
|
|
301
|
+
*/
|
|
302
|
+
interface EngineConfig {
|
|
303
|
+
assets?: Record<string, string>;
|
|
304
|
+
runtime?: {
|
|
305
|
+
ui?: Record<string, unknown>;
|
|
306
|
+
theme?: Record<string, unknown>;
|
|
307
|
+
ui_styles?: Record<string, unknown>;
|
|
308
|
+
timeline?: Record<string, number>;
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Theme configuration
|
|
313
|
+
*/
|
|
314
|
+
interface ThemeConfig {
|
|
315
|
+
background_color?: string;
|
|
316
|
+
text_color?: string;
|
|
317
|
+
square_color?: string;
|
|
318
|
+
cta_background?: string;
|
|
319
|
+
cta_text?: string;
|
|
320
|
+
melt_color?: string;
|
|
321
|
+
danger_color?: string;
|
|
322
|
+
brush_color?: string;
|
|
323
|
+
success_color?: string;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Gameplay configuration
|
|
327
|
+
*/
|
|
328
|
+
interface GameplayConfig {
|
|
329
|
+
[key: string]: unknown;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Object-centric configuration
|
|
333
|
+
* This is the main config type that students work with
|
|
334
|
+
*/
|
|
335
|
+
interface ObjectCentricConfig {
|
|
336
|
+
/** Map of object instance IDs to their configurations */
|
|
337
|
+
objects: Map<string, ObjectConfig>;
|
|
338
|
+
/** Engine configuration (assets, runtime settings) */
|
|
339
|
+
engine: EngineConfig;
|
|
340
|
+
/** Theme configuration */
|
|
341
|
+
theme: ThemeConfig;
|
|
342
|
+
/** Gameplay configuration */
|
|
343
|
+
gameplay: GameplayConfig;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Handler SDK - EndGame UI Panel for Three.js
|
|
348
|
+
*
|
|
349
|
+
* Success screen with logo, text, CTA button, and tutorial hand.
|
|
350
|
+
* Fully configurable via UI config system.
|
|
351
|
+
* Uses HTML overlay elements for UI, Three.js sprites for images.
|
|
352
|
+
*
|
|
353
|
+
* DO NOT EDIT - Handler SDK Core
|
|
354
|
+
*/
|
|
355
|
+
|
|
356
|
+
declare function createHTMLElementWrapper(element: HTMLElement): {
|
|
357
|
+
element: HTMLElement;
|
|
358
|
+
alpha: number;
|
|
359
|
+
visible: boolean;
|
|
360
|
+
position: {
|
|
361
|
+
set(x: number, y: number): void;
|
|
362
|
+
readonly x: number;
|
|
363
|
+
readonly y: number;
|
|
364
|
+
};
|
|
365
|
+
scale: {
|
|
366
|
+
set(x: number, y?: number): void;
|
|
367
|
+
readonly x: number;
|
|
368
|
+
};
|
|
369
|
+
};
|
|
370
|
+
interface EndGamePanelElements {
|
|
371
|
+
panel: ReturnType<typeof createHTMLElementWrapper> & {
|
|
372
|
+
element: HTMLElement;
|
|
373
|
+
};
|
|
374
|
+
logo: THREE.Sprite;
|
|
375
|
+
title: ReturnType<typeof createHTMLElementWrapper> & {
|
|
376
|
+
element: HTMLElement;
|
|
377
|
+
};
|
|
378
|
+
subtitle: ReturnType<typeof createHTMLElementWrapper> & {
|
|
379
|
+
element: HTMLElement;
|
|
380
|
+
};
|
|
381
|
+
footer: ReturnType<typeof createHTMLElementWrapper> & {
|
|
382
|
+
element: HTMLElement;
|
|
383
|
+
};
|
|
384
|
+
ctaButton: ReturnType<typeof createHTMLElementWrapper> & {
|
|
385
|
+
element: HTMLElement;
|
|
386
|
+
addEventListener: HTMLElement['addEventListener'];
|
|
387
|
+
};
|
|
388
|
+
ctaText: ReturnType<typeof createHTMLElementWrapper> & {
|
|
389
|
+
element: HTMLElement;
|
|
390
|
+
};
|
|
391
|
+
ctaHint: ReturnType<typeof createHTMLElementWrapper> & {
|
|
392
|
+
element: HTMLElement;
|
|
393
|
+
};
|
|
394
|
+
hand: THREE.Sprite;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Create EndGame success panel with all UI elements
|
|
398
|
+
*/
|
|
399
|
+
declare function createEndGamePanel(config: ObjectCentricConfig, handTexture: THREE.Texture | null, logoTexture: THREE.Texture | null): EndGamePanelElements;
|
|
400
|
+
/**
|
|
401
|
+
* Animate panel entrance with staggered animations
|
|
402
|
+
*/
|
|
403
|
+
declare function animatePanelEntrance(elements: EndGamePanelElements, config: ObjectCentricConfig, onComplete?: () => void): void;
|
|
404
|
+
/**
|
|
405
|
+
* Animate tutorial hand clicking CTA button
|
|
406
|
+
*/
|
|
407
|
+
declare function animateHandClick(hand: THREE.Sprite, ctaButton: ReturnType<typeof createHTMLElementWrapper> & {
|
|
408
|
+
element: HTMLElement;
|
|
409
|
+
}, config: ObjectCentricConfig, onClick: () => void): void;
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Handler SDK - Tutorial UI Components for Three.js
|
|
413
|
+
*
|
|
414
|
+
* Tutorial hand and label components for game tutorials.
|
|
415
|
+
* Config requirement: All UI properties from object-centric config.
|
|
416
|
+
*
|
|
417
|
+
* DO NOT EDIT - Handler SDK Core
|
|
418
|
+
*/
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Create hand tutorial sprite (Three.js Sprite)
|
|
422
|
+
* Hand properties from object-centric config (hand_tutorial_1)
|
|
423
|
+
*
|
|
424
|
+
* @param handTexture - Texture for the hand sprite
|
|
425
|
+
* @param config - Object-centric configuration
|
|
426
|
+
* @param baseCharacterPos - Base position of the character for animation reference
|
|
427
|
+
*/
|
|
428
|
+
declare function createHandTutorial(handTexture: THREE.Texture | null, config: ObjectCentricConfig, baseCharacterPos: {
|
|
429
|
+
x: number;
|
|
430
|
+
y: number;
|
|
431
|
+
}): THREE.Sprite;
|
|
432
|
+
/**
|
|
433
|
+
* Create tutorial label text (HTML overlay)
|
|
434
|
+
* Uses ui.tutorial config object with UI component schema
|
|
435
|
+
*
|
|
436
|
+
* @param config - Object-centric configuration
|
|
437
|
+
*/
|
|
438
|
+
declare function createTutorialLabel(config: ObjectCentricConfig): HTMLElement;
|
|
439
|
+
/**
|
|
440
|
+
* Update hand animation
|
|
441
|
+
* Animation parameters from object-centric config (hand_tutorial_1)
|
|
442
|
+
*
|
|
443
|
+
* @param hand - The hand sprite
|
|
444
|
+
* @param baseCharacterPos - Base character position
|
|
445
|
+
* @param time - Current time for animation
|
|
446
|
+
* @param isDragging - Whether the user is currently dragging
|
|
447
|
+
* @param config - Object-centric configuration
|
|
448
|
+
*/
|
|
449
|
+
declare function updateHandAnimation(hand: THREE.Sprite, baseCharacterPos: {
|
|
450
|
+
x: number;
|
|
451
|
+
y: number;
|
|
452
|
+
}, time: number, isDragging: boolean, config: ObjectCentricConfig): void;
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Handler SDK - Asset Loader Utilities for Three.js
|
|
456
|
+
*
|
|
457
|
+
* Asset loading and texture creation utilities for Three.js.
|
|
458
|
+
* Config requirement: All asset paths from config.assets, colors from config.theme.
|
|
459
|
+
*
|
|
460
|
+
* DO NOT EDIT - Handler SDK Core
|
|
461
|
+
*/
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Load an asset with fallback placeholder
|
|
465
|
+
* Asset path comes from config.assets
|
|
466
|
+
*
|
|
467
|
+
* @param path - Asset path
|
|
468
|
+
* @param renderer - Three.js renderer instance (for context if needed)
|
|
469
|
+
* @param fallbackColor - Color for fallback placeholder
|
|
470
|
+
* @param isChar - Whether this is a character sprite (affects placeholder shape)
|
|
471
|
+
*/
|
|
472
|
+
declare function loadAsset(path: string, renderer: THREE.WebGLRenderer, fallbackColor?: number, isChar?: boolean): Promise<THREE.Texture | null>;
|
|
473
|
+
/**
|
|
474
|
+
* Load character frames from sprite sheet
|
|
475
|
+
* Uses config.assets.character_sprite for path
|
|
476
|
+
* Character sheet dimensions come from config (cols: 3, rows: 2)
|
|
477
|
+
*
|
|
478
|
+
* @param path - Path to the sprite sheet
|
|
479
|
+
* @param renderer - Three.js renderer instance
|
|
480
|
+
* @param config - Object-centric configuration
|
|
481
|
+
*/
|
|
482
|
+
declare function loadCharacterFrames(path: string, renderer: THREE.WebGLRenderer, config: ObjectCentricConfig): Promise<THREE.Texture[]>;
|
|
483
|
+
/**
|
|
484
|
+
* Create brush texture
|
|
485
|
+
* Uses config.theme.brush_color for color
|
|
486
|
+
* Brush size comes from config.gameplay.brush
|
|
487
|
+
*
|
|
488
|
+
* @param renderer - Three.js renderer instance
|
|
489
|
+
* @param config - Object-centric configuration
|
|
490
|
+
*/
|
|
491
|
+
declare function createBrushTexture(renderer: THREE.WebGLRenderer, config: ObjectCentricConfig): THREE.Texture;
|
|
492
|
+
|
|
493
|
+
export { type EndGamePanelElements, GameObject, GameObjectManager, type ObjectCentricConfig, Renderer, type ThreeBaseContext, type ThreeTheme, Transform, animateHandClick, animatePanelEntrance, createBrushTexture, createEndGamePanel, createHandTutorial, createThreeBase, createTutorialLabel, getRegisteredFontIds, loadAsset, loadCharacterFrames, registerFont, resolveFont, resolveFontWeight, updateHandAnimation };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";var ni=Object.create;var Le=Object.defineProperty;var ai=Object.getOwnPropertyDescriptor;var ii=Object.getOwnPropertyNames;var si=Object.getPrototypeOf,oi=Object.prototype.hasOwnProperty;var ri=(e,t)=>{for(var n in t)Le(e,n,{get:t[n],enumerable:!0})},Rn=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of ii(t))!oi.call(e,i)&&i!==n&&Le(e,i,{get:()=>t[i],enumerable:!(a=ai(t,i))||a.enumerable});return e};var be=(e,t,n)=>(n=e!=null?ni(si(e)):{},Rn(t||!e||!e.__esModule?Le(n,"default",{value:e,enumerable:!0}):n,e)),li=e=>Rn(Le({},"__esModule",{value:!0}),e);var Ri={};ri(Ri,{GameObject:()=>Ce,GameObjectManager:()=>Ne,Renderer:()=>Ae,Transform:()=>Se,animateHandClick:()=>la,animatePanelEntrance:()=>ra,createBrushTexture:()=>fa,createEndGamePanel:()=>oa,createHandTutorial:()=>ca,createThreeBase:()=>aa,createTutorialLabel:()=>da,getRegisteredFontIds:()=>sa,loadAsset:()=>st,loadCharacterFrames:()=>ma,registerFont:()=>ia,resolveFont:()=>O,resolveFontWeight:()=>B,updateHandAnimation:()=>pa});module.exports=li(Ri);var fe=be(require("three"));var K={};function De(e,t,n=!1){K[e]||(K[e]=[]),K[e].push({fn:t,once:n})}function Qe(e,t){if(K[e]){if(!t){delete K[e];return}K[e]=K[e].filter(n=>n.fn!==t)}}function $e(e,...t){let n=K[e];if(n)for(let a of[...n])a.fn(...t),a.once&&Qe(e,a.fn)}function P(e,t){De(e,t,!0)}var Fe={name:"handler-playable-sdk",version:"0.1.2",description:"Handler Playable SDK v0.1 with contract-aligned surface (root sandbox, canonical event envelope).",main:"dist/index.js",module:"dist/index.mjs",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.js"},"./pixi":{types:"./dist/pixi/index.d.ts",import:"./dist/pixi/index.mjs",require:"./dist/pixi/index.js"},"./three":{types:"./dist/three/index.d.ts",import:"./dist/three/index.mjs",require:"./dist/three/index.js"}},scripts:{build:"tsup src/index.ts src/pixi/index.ts src/three/index.ts --format cjs,esm --dts --clean --minify",lint:"eslint 'src/**/*.{ts,tsx}'",typecheck:"tsc --noEmit",prepublishOnly:"npm run build"},author:"Handler",license:"MIT",publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/HandlerAIGames/handler-playable-sdk.git"},files:["dist","LICENSE","README.md"],peerDependencies:{"pixi.js":"^8.0.0",three:"^0.160.0"},peerDependenciesMeta:{"pixi.js":{optional:!0},three:{optional:!0}},devDependencies:{"@types/three":"^0.160.0",eslint:"^8.57.1","pixi.js":"^8.8.1",three:"^0.160.0","ts-node":"^10.9.2",tsup:"^8.4.0",typescript:"^5.7.2"}};var z=0,di=z++,Hn=z++,Mn=z++,kn=z++,Ln=z++,Dn=z++,$n=z++,Fn=z++,Pn=z++,zn=z++,Wn=z++,On=z++,b=di;function Bn(){return b===Hn}function Nn(){return b===Mn}function Yn(){return b===kn}function In(){return b===Ln}function re(){return b===Dn}function le(){return b===$n}function Gn(){return b===Fn}function jn(){return b===Pn}function Vn(){return b===zn}function Ze(){return b===Wn}function Ue(){return b===On}function qn(){let e=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none",t=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed";if(e==="mraid")try{mraid.getState(),b=Hn;return}catch{}else if(e==="dapi")try{dapi.isReady(),b=Mn;return}catch{}if(t==="facebook")try{typeof FbPlayableAd!="undefined"&&(b=kn)}catch{}else if(t==="google")try{typeof ExitApi!="undefined"&&(b=Ln)}catch{}else if(t==="mintegral")window.gameReady&&(b=Dn);else if(t==="tapjoy")window.TJ_API&&(b=$n);else if(t==="tiktok")window.openAppStore&&(b=Fn);else if(t==="smadex")try{window.smxTracking&&(b=Pn)}catch{}else if(t==="snapchat")try{window.ScPlayableAd&&(b=zn)}catch{}else t==="vungle"?b=Wn:(e==="nucleo"||t==="nucleo")&&(b=On)}var Un={mechanic_id:"TODO_mechanic_id",variant_id:"TODO_variant_id",deployment_id:"TODO_deployment_id",export_id:"TODO_export_id",profile_id:"TODO_profile_id",instance_id:"default"},pi=Math.random().toString(36).slice(2),ce=null,xe={...Un},ea="web_embed",ui={},et=!1,_e=!1,Te=!1,ta=!1,it=1,nt=0,Oe=!1,q=!1,We="",de=Math.floor(window.innerWidth),pe=Math.floor(window.innerHeight),at=de>pe,X=!1,we=!1,Xn=!1,Kn=!1,tt=!1,Pe=null;function Jn(){if(ce)return ce;let e=document.createElement("div");return e.id="handler-root",e.setAttribute("data-handler-root","true"),document.body.appendChild(e),ce=e,e}function ze(e){switch(e){case"interaction":return"engagement";case"finish":return"complete";case"install":return"cta_click";default:return e}}function na(e,t){return{event_name:e,ts:Date.now(),session_id:pi,deployment_id:xe.deployment_id,variant_id:xe.variant_id,export_profile_id:xe.profile_id,instance_id:xe.instance_id||"default",env:ea==="mraid"?"mraid":"web",payload:t}}function h(e,t){let n=ze(e),a=na(n,t);$e(n,a),n!==e&&$e(e,a)}function Ee(){Pe&&(Pe(de,pe),Pe=null)}function ue(e){it=e,h("volume",e)}function me(e){e&&(ta=!0),!Te&&(Te=!0,h("pause"),ue(0))}function ve(e){!e&&ta||Te&&(Te=!1,h("resume"),ue(it))}function Q(e,t){de=Math.floor(e||window.innerWidth),pe=Math.floor(t||window.innerHeight),at=de>pe,h("resize",{width:de,height:pe})}function mi(){if(Bn())try{let e=mraid.getMaxSize();Q(e.width,e.height);let t=()=>{mraid.isViewable()&&mraid.getState()!=="hidden"?ve():me()};if(mraid.addEventListener("viewableChange",t),mraid.addEventListener("stateChange",t),mraid.addEventListener("sizeChange",()=>{let n=mraid.getMaxSize();Q(n.width,n.height)}),mraid.getAudioVolume){let n=mraid.getAudioVolume();ue(n?1:0)}if(mraid.addEventListener("audioVolumeChange",n=>{n!==null&&ue(n>0?1:0)}),mraid.addEventListener("error",(n,a)=>{console.warn("mraid error:",n,"action:",a)}),Oe=!0,mraid.isViewable()&&mraid.getState()!=="hidden")X=!0,h("boot"),h("view"),h("ready"),q=!0,Ee();else{let n=()=>{X=!0,h("boot"),h("view"),h("ready"),q=!0,Ee()};mraid.addEventListener("ready",n)}}catch(e){console.warn("MRAID hook skipped",e)}}function fi(){if(Nn())try{let e=dapi.getScreenSize();Q(e.width,e.height),dapi.addEventListener("viewableChange",n=>{n.isViewable?ve():me()}),dapi.addEventListener("adResized",n=>{let a=dapi.getScreenSize();Q(n.width||a.width,n.height||a.height)});let t=dapi.getAudioVolume();if(ue(t?1:0),dapi.addEventListener("audioVolumeChange",n=>ue(n?1:0)),Oe=!0,dapi.isViewable())X=!0,h("boot"),h("view"),h("ready"),q=!0,Ee();else{let n=()=>{X=!0,h("boot"),h("view"),h("ready"),q=!0,Ee()};dapi.addEventListener("ready",n)}}catch(e){console.warn("DAPI hook skipped",e)}}function Qn(){let e=()=>{X||document.visibilityState==="visible"&&(document.readyState==="complete"||document.readyState==="interactive")&&(X=!0,h("boot"),h("view"),h("ready"),q=!0,Ee(),we&&(we=!1,J.start()))};window.addEventListener("resize",()=>Q()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?(ve(),e()):me()}),document.readyState==="complete"||document.readyState==="interactive"?e():window.addEventListener("load",e),Oe=!0}function yi(){let e=t=>{typeof TouchEvent!="undefined"&&t instanceof TouchEvent&&(Xn=!0),!(Xn&&t instanceof MouseEvent)&&(nt+=1,h("interaction",nt))};document.addEventListener("mousedown",e),document.addEventListener("touchstart",e)}function hi(e){var a,i,s,o,l,c,r,p,f,u,d,m;let t=typeof AD_PROTOCOL!="undefined"?AD_PROTOCOL:"none";if((typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed")==="google")try{(a=window.ExitApi)==null||a.exit();return}catch{}if(t==="mraid"&&typeof mraid!="undefined")mraid.open(e||"");else if(t==="dapi"&&typeof dapi!="undefined")dapi.openStoreUrl();else if(le())(s=(i=window.TJ_API)==null?void 0:i.click)==null||s.call(i);else if(Yn())(l=(o=window.FbPlayableAd)==null?void 0:o.onCTAClick)==null||l.call(o);else if(Vn())(r=(c=window.ScPlayableAd)==null?void 0:c.onCTAClick)==null||r.call(c);else if(jn())try{(f=(p=window.smxTracking)==null?void 0:p.redirect)==null||f.call(p)}catch(y){console.warn("Smadex redirect failed",y)}else if(In()){let y=window.ExitApi;y&&typeof y.exit=="function"?y.exit(e||We||""):e&&window.open(e)}else re()?(u=window.install)==null||u.call(window):Gn()?(d=window.openAppStore)==null||d.call(window):Ze()?(m=parent==null?void 0:parent.postMessage)==null||m.call(parent,"download","*"):e&&window.open(e)}function gi(){let e=typeof AD_NETWORK!="undefined"?AD_NETWORK:"web_embed",t=n=>{if(!n)return;let a=new Image;a.src=n};if(e==="bigabid"){let n=window.BIGABID_BIDTIMEMACROS;if(!n)return;P("view",()=>t(n.mraid_viewable)),P("start",()=>t(n.game_viewable)),P("engagement",()=>t(n.engagement));let a=()=>t(n.complete);P("complete",a),De("engagement",i=>{var s;((s=i==null?void 0:i.payload)==null?void 0:s.count)>3&&a()}),P("cta_click",()=>t(n.click))}else if(e==="inmobi"){let n=window.INMOBI_DSPMACROS;if(!n)return;P("view",()=>t(n.Ad_Load_Start)),P("start",()=>t(n.Ad_Viewable)),P("engagement",()=>t(n.First_Engagement)),P("complete",()=>t(n.Gameplay_Complete)),P("cta_click",()=>t(n.DSP_Click)),P("start",()=>{[5,10,15,20,25,30].forEach(a=>setTimeout(()=>t(n[`Spent_${a}_Seconds`]),a*1e3))})}}function bi(){if(!le())return;let e=window.TJ_API;e&&e.setPlayableAPI&&e.setPlayableAPI({skipAd:()=>{try{J.finish()}catch(t){console.warn("Tapjoy skip failed",t)}}})}function Zn(){var t,n,a;let e=window.TJ_API;(t=e==null?void 0:e.objectiveComplete)==null||t.call(e),(n=e==null?void 0:e.playableFinished)==null||n.call(e),(a=e==null?void 0:e.gameplayFinished)==null||a.call(e)}function _i(){re()&&(window.mintGameStart=()=>{ve(!0),Q()},window.mintGameClose=()=>{me(!0)})}function xi(){if(!Ue())return;let e=window.NUC;!e||!e.trigger||(J.on("cta_click",()=>{var t,n;return(n=(t=e.trigger).convert)==null?void 0:n.call(t,We)}),J.on("complete",()=>{var t,n;return(n=(t=e.trigger).tryAgain)==null?void 0:n.call(t)}))}var J={init(e={},t){if(ea=e.profile||"web_embed",ui=e.consent||{},xe={...Un,...e.ids||{}},ce=e.rootEl||ce,We=e.destinationUrl||(/android/i.test(navigator.userAgent)?"https://play.google.com/store":"https://www.apple.com/app-store/"),t&&(Pe=t),h("init"),document.body.oncontextmenu=()=>!1,Jn(),wi(ce),qn(),mi(),fi(),!Oe){if(document.readyState==="complete")Qn();else if(!Kn){Kn=!0;let n=()=>{Qn(),window.removeEventListener("load",n),document.removeEventListener("DOMContentLoaded",n)};window.addEventListener("load",n),document.addEventListener("DOMContentLoaded",n)}}yi(),gi(),bi(),_i(),xi(),console.log(`%c @handler/playable-sdk %c v${Fe.version||"0.0.0"} `,"background: #007acc; color: #fff; font-size: 14px; padding: 4px 8px; border-top-left-radius: 4px; border-bottom-left-radius: 4px;","background: #e1e4e8; color: #333; font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"),X&&!q&&(h("boot"),h("view"),h("ready"),we&&(we=!1,J.start()),q=!0),q=X},getRoot(){return Jn()},get version(){return Fe.version||"0.0.0"},get maxWidth(){return de},get maxHeight(){return pe},get isLandscape(){return at},get isReady(){return q},get isStarted(){return et},get isPaused(){return Te},get isFinished(){return _e},get volume(){return it},get interactions(){return nt},on(e,t){De(ze(e),t)},off(e,t){Qe(ze(e),t)},start(){var e,t;if(!et){if(!X){we=!0;return}if(et=!0,h("start"),Q(),re())me(),(e=window.gameReady)==null||e.call(window);else if(le()){let n=window.TJ_API;(t=n==null?void 0:n.setPlayableBuild)==null||t.call(n,{orientation:at?"landscape":"portrait",buildID:Fe.version||"dev"})}}},finish(){var e,t;_e||(_e=!0,h("complete"),re()?(e=window.gameEnd)==null||e.call(window):Ze()?(t=parent==null?void 0:parent.postMessage)==null||t.call(parent,"complete","*"):le()&&Zn())},install(e){if(!_e){_e=!0,le()?(Zn(),setTimeout(()=>J.install(e),300)):(h("complete"),setTimeout(()=>J.install(e),0));return}tt||(tt=!0,setTimeout(()=>tt=!1,500),h("cta_click"),h("conversion"),hi(e||We))},emit(e,t){let n=ze(e);if(!["view","boot","start","engagement","complete","cta_click","conversion","retry","pause","resume","resize","volume","error"].includes(n)&&!n.startsWith("custom."))throw new Error(`Event ${e} must be canonical or namespaced as custom.<mechanic_id>.<event>`);let a=na(n,t);$e(n,a)},retry(){var e,t,n;if(re())(e=window.gameRetry)==null||e.call(window);else if(Ue()){let a=window.NUC;(n=(t=a==null?void 0:a.trigger)==null?void 0:t.tryAgain)==null||n.call(t)}h("engagement",{action:"retry"})},pause(){me(!0)},resume(){ve(!0)},resize(e,t){Q(e,t)}},Be=J;function wi(e){let t=document.createElement("script");t.type="text/javascript",t.textContent=`
|
|
2
|
+
(function(){
|
|
3
|
+
var events = ['touchstart','touchend','mousedown','keydown'];
|
|
4
|
+
function unlock(){
|
|
5
|
+
if(window.AudioContext && AudioContext.prototype.resume){
|
|
6
|
+
if(!window.__handler_audio_ctx){
|
|
7
|
+
window.__handler_audio_ctx = new AudioContext();
|
|
8
|
+
}
|
|
9
|
+
if(window.__handler_audio_ctx.state === 'suspended'){
|
|
10
|
+
window.__handler_audio_ctx.resume();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
events.forEach(function(e){ document.removeEventListener(e, unlock); });
|
|
14
|
+
}
|
|
15
|
+
events.forEach(function(e){ document.addEventListener(e, unlock, false); });
|
|
16
|
+
})();
|
|
17
|
+
`,e.appendChild(t)}async function aa(e,t={}){let n=()=>{let d=e.style.width&&e.style.width!=="auto"?parseFloat(e.style.width):e.clientWidth||window.innerWidth||320,m=e.style.height&&e.style.height!=="auto"?parseFloat(e.style.height):e.clientHeight||window.innerHeight||480;return{width:d,height:m}};e.innerHTML="",e.style.position="relative",e.style.display="block",e.style.width=e.style.width||"100%",e.style.height=e.style.height||"100%",e.style.minHeight=e.style.minHeight||"100%",e.style.maxWidth="100%",e.style.maxHeight="100%",e.style.boxSizing="border-box",e.style.overflow="hidden",t.background&&(e.style.background=t.background);let a=document.createElement("div");a.setAttribute("style",["position:absolute","inset:0","width:100%","height:100%","display:block",`background:${t.background||"transparent"}`,"color:var(--h-text, #f4f6ff)",'font-family:var(--h-font-main, "Inter", "Helvetica Neue", Arial, sans-serif)',"box-sizing:border-box"].join(";")),e.appendChild(a);let i=document.createElement("div");i.setAttribute("style",["position:absolute","inset:0","width:100%","height:100%","pointer-events:auto"].join(";")),a.appendChild(i);let s=new fe.Scene,{width:o,height:l}=n(),c=new fe.OrthographicCamera(-o/2,o/2,l/2,-l/2,.1,1e3);c.position.set(0,0,1),c.lookAt(0,0,0);let r=new fe.WebGLRenderer({antialias:!0,alpha:!0,preserveDrawingBuffer:!0});r.setPixelRatio(window.devicePixelRatio||1),r.setSize(o,l),r.setClearColor(0,0),r.domElement.style.position="absolute",r.domElement.style.top="0",r.domElement.style.left="0",r.domElement.style.width="100%",r.domElement.style.height="100%",r.domElement.style.display="block",r.domElement.style.pointerEvents="auto",i.appendChild(r.domElement);let p=d=>{let m=n(),y=typeof(d==null?void 0:d.width)=="number"?d.width:m.width,g=typeof(d==null?void 0:d.height)=="number"?d.height:m.height;r.setSize(y,g),r.setPixelRatio(window.devicePixelRatio||1),c.left=-y/2,c.right=y/2,c.top=g/2,c.bottom=-g/2,c.updateProjectionMatrix()};requestAnimationFrame(()=>p());let f=!1;Be.on("pause",()=>{f=!0,document.querySelectorAll("audio").forEach(m=>m.pause())}),Be.on("resume",()=>{f=!1,document.querySelectorAll("audio").forEach(m=>{m.currentTime>0&&!m.ended&&m.play().catch(()=>{})})}),Be.on("resize",({payload:d})=>{p({width:d==null?void 0:d.width,height:d==null?void 0:d.height})}),window.addEventListener("resize",()=>p());let u=document.createElement("div");return u.setAttribute("style",["position:absolute","inset:0","display:flex","flex-direction:column","align-items:center","justify-content:flex-start","gap:12px","pointer-events:none","font-family:Arial,sans-serif","padding:20px 16px","padding-bottom:clamp(24px, 6vh, 96px)","box-sizing:border-box","z-index:2"].join(";")),e.appendChild(u),{scene:s,camera:c,renderer:r,overlay:u,applySize:p}}var A=be(require("three")),Se=class{constructor(t){var n,a;this.position=(t==null?void 0:t.position)||{x:0,y:0},this.scale=(n=t==null?void 0:t.scale)!=null?n:1,this.rotation=(a=t==null?void 0:t.rotation)!=null?a:0}update(t){t.position!==void 0&&(this.position={...t.position}),t.scale!==void 0&&(this.scale=t.scale),t.rotation!==void 0&&(this.rotation=t.rotation)}syncToThree(t){t.position.set(this.position.x,this.position.y,0),t.scale.set(this.scale,this.scale,this.scale),t.rotation.z=this.rotation}},Ae=class{constructor(t){var n,a,i,s;this.z_index=(n=t==null?void 0:t.z_index)!=null?n:0,this.alpha=(a=t==null?void 0:t.alpha)!=null?a:1,this.visible=(i=t==null?void 0:t.visible)!=null?i:!0,this.tint=(s=t==null?void 0:t.tint)!=null?s:null}update(t){t.z_index!==void 0&&(this.z_index=t.z_index),t.alpha!==void 0&&(this.alpha=t.alpha),t.visible!==void 0&&(this.visible=t.visible),t.tint!==void 0&&(this.tint=t.tint)}syncToThree(t){if(t.renderOrder=this.z_index,t.visible=this.visible,t instanceof A.Mesh&&t.material&&(Array.isArray(t.material)?t.material.forEach(n=>{n instanceof A.Material&&(n.opacity=this.alpha,n.transparent=this.alpha<1)}):t.material instanceof A.Material&&(t.material.opacity=this.alpha,t.material.transparent=this.alpha<1)),this.tint!==null&&t instanceof A.Mesh&&t.material){let n=typeof this.tint=="string"?new A.Color(this.tint):new A.Color(this.tint);Array.isArray(t.material)?t.material.forEach(a=>{(a instanceof A.MeshBasicMaterial||a instanceof A.MeshStandardMaterial)&&a.color.copy(n)}):(t.material instanceof A.MeshBasicMaterial||t.material instanceof A.MeshStandardMaterial)&&t.material.color.copy(n)}}},Ce=class{constructor(t,n,a,i){this.instanceId=t,this.objectConfig=n,this.threeObject=a,this._config=i,this.transform=new Se(i.transform),this.renderer=new Ae(i.render),this.sync()}sync(){this.transform.syncToThree(this.threeObject),this.renderer.syncToThree(this.threeObject)}updateConfig(t){this._config=t,t.transform&&this.transform.update(t.transform),t.render&&this.renderer.update(t.render),this.sync()}getComponent(t){return this._config[t]}getPosition(){return{...this.transform.position}}setPosition(t,n){this.transform.position={x:t,y:n},this.transform.syncToThree(this.threeObject)}getAlpha(){return this.renderer.alpha}setAlpha(t){this.renderer.alpha=t,this.renderer.syncToThree(this.threeObject)}getVisible(){return this.renderer.visible}setVisible(t){this.renderer.visible=t,this.renderer.syncToThree(this.threeObject)}},Ne=class{constructor(t){this.objects=new Map;this.config=t}create(t,n){let a=this.config.objects.get(t);if(!a)throw new Error(`Object config not found: ${t}`);let i=new Ce(t,a.object_config||t,n,a);return this.objects.set(t,i),i}get(t){return this.objects.get(t)}updateConfig(t){this.config=t;for(let[n,a]of this.objects.entries()){let i=t.objects.get(n);i&&a.updateConfig(i)}}getAll(){return Array.from(this.objects.values())}remove(t){this.objects.delete(t)}clear(){this.objects.clear()}};var Ye={"brand.primary":{family:"Arial, sans-serif",weight:"400"},"brand.warning":{family:"Arial Black, Arial, sans-serif",weight:"900"},"brand.heading":{family:"Arial Black, Arial, sans-serif",weight:"800"},"brand.body":{family:"Arial, sans-serif",weight:"400"}};function O(e){let t=Ye[e];return t?t.family:(console.warn(`Font ID "${e}" not found in registry, using fallback`),"Arial, sans-serif")}function B(e){var n;let t=Ye[e];return t&&(n=t.weight)!=null?n:"400"}function ia(e,t){Ye[e]=t}function sa(){return Object.keys(Ye)}var ye=be(require("three"));function ie(e){return{element:e,get alpha(){return parseFloat(e.style.opacity||"1")},set alpha(t){e.style.opacity=t.toString()},get visible(){return e.style.display!=="none"},set visible(t){e.style.display=t?"":"none"},position:{set(t,n){e.style.left=`${t}px`,e.style.top=`${n}px`},get x(){return parseFloat(e.style.left||"0")},get y(){return parseFloat(e.style.top||"0")}},scale:{set(t,n){e.style.transform=`scale(${t})`},get x(){let t=e.style.transform.match(/scale\(([^)]+)\)/);return t?parseFloat(t[1]):1}}}}function oa(e,t,n){var _t,xt,wt,Tt,Et,vt,St,At,Ct,Rt,Ht,Mt,kt,Lt,Dt,$t,Ft,Pt,zt,Wt,Ot,Bt,Nt,Yt,It,Gt,jt,Vt,qt,Xt,Kt,Jt,Qt,Zt,Ut,en,tn,nn,an,sn,on,rn,ln,cn,dn,pn,un,mn,fn,yn,hn,gn,bn,_n,xn,wn,Tn,En,vn,Sn,An,Cn;let a=e.objects.get("ui_endgame_1"),i=e.objects.get("ui_endgame_logo_1"),s=e.objects.get("ui_endgame_title_1"),o=e.objects.get("ui_endgame_subtitle_1"),l=e.objects.get("ui_endgame_footer_1"),c=e.objects.get("ui_endgame_cta_1"),r=e.objects.get("ui_endgame_cta_hint_1"),p=e.objects.get("ui_endgame_hand_1"),f=e.engine.runtime||{},u=((_t=a==null?void 0:a.gameplay)==null?void 0:_t.tuning)||{},d=(a==null?void 0:a.render)||{},m=(xt=u.panel_width)!=null?xt:320,y=(wt=u.panel_height)!=null?wt:400,g=(Tt=u.panel_padding)!=null?Tt:32,S=(Et=u.panel_radius)!=null?Et:24,x=d.background_color||u.panel_bg_color||"#1a0a0a",w=d.background_alpha!==void 0&&d.background_alpha!==null?d.background_alpha:(vt=u.panel_bg_alpha)!=null?vt:.98,_=d.border_color||u.panel_border_color||"#ffffff",E=(St=u.panel_border_width)!=null?St:2,H=(At=u.panel_border_alpha)!=null?At:.3,T=document.createElement("div");T.style.cssText=`
|
|
18
|
+
position: absolute;
|
|
19
|
+
width: ${m}px;
|
|
20
|
+
height: ${y}px;
|
|
21
|
+
background: ${x};
|
|
22
|
+
opacity: ${w};
|
|
23
|
+
border: ${E}px solid ${_};
|
|
24
|
+
border-opacity: ${H};
|
|
25
|
+
border-radius: ${S}px;
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: center;
|
|
30
|
+
transform: translate(-50%, -50%);
|
|
31
|
+
opacity: 0;
|
|
32
|
+
visibility: hidden;
|
|
33
|
+
pointer-events: auto;
|
|
34
|
+
`;let k=ie(T);k.element=T;let N=((Ct=i==null?void 0:i.gameplay)==null?void 0:Ct.tuning)||{},C=(i==null?void 0:i.transform)||{},M=(Rt=N.logo_size)!=null?Rt:56,W=(Ht=C.scale)!=null?Ht:1,Y=(kt=(Mt=C.offset)==null?void 0:Mt.y)!=null?kt:-130,se=(Lt=N.logo_alpha)!=null?Lt:1,Z=new ye.SpriteMaterial({map:n||void 0,transparent:!0,alphaTest:.1}),v=new ye.Sprite(Z);v.position.set(0,Y,0),v.material.opacity=0;let I=0,U=0;if(n&&(I=((Dt=n.image)==null?void 0:Dt.width)||100,U=(($t=n.image)==null?void 0:$t.height)||100),I>0&&U>0){let oe=I/U,Ke,Je;oe>1?(Ke=M,Je=M/oe):(Je=M,Ke=M*oe);let ei=Ke/I*W,ti=Je/U*W;v.scale.set(ei,ti,1)}else{let oe=M/100*W;v.scale.set(oe,oe,1)}v.targetAlpha=se,v.baseScaleX=v.scale.x,v.baseScaleY=v.scale.y;let L=s==null?void 0:s.ui,G=((Ft=s==null?void 0:s.gameplay)==null?void 0:Ft.tuning)||{},ya=(L==null?void 0:L.text)||"MISSION ACCOMPLISHED",ot=(L==null?void 0:L.font)||"brand.heading",ha=(L==null?void 0:L.fontSize)||24,ga=(Pt=L==null?void 0:L.letterSpacing)!=null?Pt:1,Re=(zt=s==null?void 0:s.render)==null?void 0:zt.tint,ba=typeof Re=="string"?Re:Re?`#${Re.toString(16).padStart(6,"0")}`:"#00FF88",_a=m-g*2-30,xa=G.font_weight_override?G.font_weight_override:B(ot),ee=document.createElement("div");ee.textContent=ya,ee.style.cssText=`
|
|
35
|
+
font-family: ${O(ot)};
|
|
36
|
+
font-size: ${ha}px;
|
|
37
|
+
font-weight: ${xa};
|
|
38
|
+
color: ${ba};
|
|
39
|
+
text-align: center;
|
|
40
|
+
letter-spacing: ${ga}px;
|
|
41
|
+
-webkit-text-stroke: ${(Wt=G.stroke_width)!=null?Wt:2}px ${G.stroke_color||"#000000"};
|
|
42
|
+
text-shadow: ${(Ot=G.shadow_distance)!=null?Ot:4}px ${(Bt=G.shadow_distance)!=null?Bt:4}px ${(Nt=G.shadow_blur)!=null?Nt:8}px rgba(0,0,0,${(Yt=G.shadow_alpha)!=null?Yt:.9});
|
|
43
|
+
opacity: 0;
|
|
44
|
+
position: absolute;
|
|
45
|
+
transform: translate(-50%, -50%);
|
|
46
|
+
white-space: nowrap;
|
|
47
|
+
max-width: ${_a}px;
|
|
48
|
+
`;let rt=(It=u.title_offset_y)!=null?It:30,wa=rt+((Gt=G.animation_start_y_offset)!=null?Gt:-20);ee.style.top=`${wa}px`,ee.style.left="50%";let lt=ie(ee);lt.element=ee,T.appendChild(ee);let D=o==null?void 0:o.ui,ct=((jt=o==null?void 0:o.gameplay)==null?void 0:jt.tuning)||{},Ta=(D==null?void 0:D.text)||"RESCUE COMPLETE",dt=(D==null?void 0:D.font)||"brand.body",Ea=(D==null?void 0:D.fontSize)||11,va=(Vt=D==null?void 0:D.letterSpacing)!=null?Vt:.5,He=(qt=o==null?void 0:o.render)==null?void 0:qt.tint,Sa=typeof He=="string"?He:He?`#${He.toString(16).padStart(6,"0")}`:"#B0B0B0",te=document.createElement("div");te.textContent=Ta,te.style.cssText=`
|
|
49
|
+
font-family: ${O(dt)};
|
|
50
|
+
font-size: ${Ea}px;
|
|
51
|
+
font-weight: ${B(dt)};
|
|
52
|
+
color: ${Sa};
|
|
53
|
+
text-align: center;
|
|
54
|
+
letter-spacing: ${va}px;
|
|
55
|
+
opacity: 0;
|
|
56
|
+
position: absolute;
|
|
57
|
+
transform: translate(-50%, -50%);
|
|
58
|
+
white-space: nowrap;
|
|
59
|
+
`;let Aa=rt+20+((Xt=ct.animation_start_y_offset)!=null?Xt:-10);te.style.top=`${Aa}px`,te.style.left="50%";let Ge=ie(te);Ge.element=te,Ge.animationStartYOffset=(Kt=ct.animation_start_y_offset)!=null?Kt:-10,T.appendChild(te);let j=l==null?void 0:l.ui,pt=((Jt=l==null?void 0:l.gameplay)==null?void 0:Jt.tuning)||{},Ca=(j==null?void 0:j.text)||((Qt=f.ui)==null?void 0:Qt.cta_hint)||"Continue the adventure!",ut=(j==null?void 0:j.font)||"brand.body",Ra=(j==null?void 0:j.fontSize)||16,Me=(Zt=l==null?void 0:l.render)==null?void 0:Zt.tint,Ha=typeof Me=="string"?Me:Me?`#${Me.toString(16).padStart(6,"0")}`:"#FFFFFF",Ma=(Ut=pt.max_width)!=null?Ut:m-g*2,ka=(en=pt.line_height)!=null?en:1.4,ne=document.createElement("div");ne.textContent=Ca,ne.style.cssText=`
|
|
60
|
+
font-family: ${O(ut)};
|
|
61
|
+
font-size: ${Ra}px;
|
|
62
|
+
font-weight: ${B(ut)};
|
|
63
|
+
color: ${Ha};
|
|
64
|
+
text-align: center;
|
|
65
|
+
opacity: 0;
|
|
66
|
+
position: absolute;
|
|
67
|
+
transform: translate(-50%, -50%);
|
|
68
|
+
max-width: ${Ma}px;
|
|
69
|
+
line-height: ${ka};
|
|
70
|
+
word-wrap: break-word;
|
|
71
|
+
`;let La=(tn=u.footer_offset_y)!=null?tn:120;ne.style.top=`${La}px`,ne.style.left="50%";let je=ie(ne);je.element=ne;let Da=((nn=l==null?void 0:l.render)==null?void 0:nn.alpha)!==void 0&&((an=l==null?void 0:l.render)==null?void 0:an.alpha)!==null?l.render.alpha:1;je.targetAlpha=Da,T.appendChild(ne);let V=((sn=c==null?void 0:c.gameplay)==null?void 0:sn.tuning)||{},$=c==null?void 0:c.ui,$a=(on=V.button_width)!=null?on:260,Fa=(rn=V.button_height)!=null?rn:56,Pa=(ln=V.button_radius)!=null?ln:16,za=V.button_bg_color||((cn=f.theme)==null?void 0:cn.cta_background)||"#ffb43b",Wa=(dn=V.button_bg_alpha)!=null?dn:1,Oa=V.button_border_color||"#ffffff",Ba=(pn=V.button_border_width)!=null?pn:2,Mi=(un=V.button_border_alpha)!=null?un:.2,Ve=(mn=u.cta_offset_y)!=null?mn:160,R=document.createElement("button");R.style.cssText=`
|
|
72
|
+
width: ${$a}px;
|
|
73
|
+
height: ${Fa}px;
|
|
74
|
+
background: ${za};
|
|
75
|
+
opacity: ${Wa};
|
|
76
|
+
border: ${Ba}px solid ${Oa};
|
|
77
|
+
border-radius: ${Pa}px;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
opacity: 0;
|
|
80
|
+
position: absolute;
|
|
81
|
+
transform: translate(-50%, -50%);
|
|
82
|
+
box-shadow: inset 0 0 1px rgba(0,0,0,0.15);
|
|
83
|
+
`,R.style.top=`${Ve}px`,R.style.left="50%";let mt=ie(R);mt.element=R,T.appendChild(R);let Na=($==null?void 0:$.text)||((fn=f.ui)==null?void 0:fn.cta_label_end)||"DOWNLOAD",ft=($==null?void 0:$.font)||"brand.heading",Ya=($==null?void 0:$.fontSize)||20,Ia=V.button_text_color||((yn=f.theme)==null?void 0:yn.cta_text)||"#1a0a0a";R.textContent=Na,R.style.fontFamily=O(ft),R.style.fontSize=`${Ya}px`,R.style.fontWeight=String(B(ft)),R.style.color=Ia,R.style.letterSpacing=`${(hn=$==null?void 0:$.letterSpacing)!=null?hn:1}px`;let yt=ie(R);yt.element=R;let F=r==null?void 0:r.ui,ht=((gn=r==null?void 0:r.gameplay)==null?void 0:gn.tuning)||{},Ga=(F==null?void 0:F.text)||"Play the full game",gt=(F==null?void 0:F.font)||"brand.body",ja=(F==null?void 0:F.fontSize)||11,Va=(bn=F==null?void 0:F.letterSpacing)!=null?bn:0,ke=(_n=r==null?void 0:r.render)==null?void 0:_n.tint,qa=typeof ke=="string"?ke:ke?`#${ke.toString(16).padStart(6,"0")}`:"#CCCCCC",ae=document.createElement("div");ae.textContent=Ga,ae.style.cssText=`
|
|
84
|
+
font-family: ${O(gt)};
|
|
85
|
+
font-size: ${ja}px;
|
|
86
|
+
font-weight: ${B(gt)};
|
|
87
|
+
color: ${qa};
|
|
88
|
+
text-align: center;
|
|
89
|
+
letter-spacing: ${Va}px;
|
|
90
|
+
opacity: 0;
|
|
91
|
+
position: absolute;
|
|
92
|
+
transform: translate(-50%, -50%);
|
|
93
|
+
white-space: nowrap;
|
|
94
|
+
`;let Xa=Ve+35+((xn=ht.animation_start_y_offset)!=null?xn:5);ae.style.top=`${Xa}px`,ae.style.left="50%";let qe=ie(ae);qe.element=ae,qe.animationStartYOffset=(wn=ht.animation_start_y_offset)!=null?wn:5,T.appendChild(ae);let Xe=((Tn=p==null?void 0:p.gameplay)==null?void 0:Tn.tuning)||{},Ka=(En=Xe.hand_offset_x)!=null?En:50,Ja=(vn=Xe.hand_offset_y)!=null?vn:50,Qa=(An=(Sn=p==null?void 0:p.transform)==null?void 0:Sn.scale)!=null?An:.1875,Za=(Cn=Xe.hand_scale_multiplier)!=null?Cn:2.5,Ua=new ye.SpriteMaterial({map:t||void 0,transparent:!0,alphaTest:.1}),ge=new ye.Sprite(Ua),bt=Qa*Za*100;return ge.scale.set(bt,bt,1),ge.position.set(Ka,Ve+Ja,0),ge.material.opacity=0,ge.visible=!1,{panel:k,logo:v,title:lt,subtitle:Ge,footer:je,ctaButton:mt,ctaText:yt,ctaHint:qe,hand:ge}}function ra(e,t,n){var H,T,k,N,C,M,W,Y;let a=t.objects.get("ui_endgame_1"),i=((H=a==null?void 0:a.gameplay)==null?void 0:H.tuning)||{},s=(T=i.animation_duration_ms)!=null?T:800,o=(k=i.fade_in_duration_ms)!=null?k:600,l=(N=i.scale_animation_intensity)!=null?N:.1,c=(C=i.logo_animation_delay_ms)!=null?C:100,r=(M=i.title_animation_delay_ms)!=null?M:200,p=(W=i.footer_animation_delay_ms)!=null?W:300,f=(Y=i.cta_animation_delay_ms)!=null?Y:400,{panel:u,logo:d,title:m,subtitle:y,footer:g,ctaButton:S,ctaText:x,ctaHint:w}=e;u.visible=!0,u.element.style.visibility="visible";let _=Date.now(),E=()=>{let se=Date.now()-_,Z=Math.min(se/o,1),v=1-Math.pow(1-Z,3);u.alpha=v,u.element.style.opacity=v.toString();let I=1+l*(1-v);u.element.style.transform=`translate(-50%, -50%) scale(${I})`,Z<1?requestAnimationFrame(E):(setTimeout(()=>Ti(d,s,t),c),setTimeout(()=>{Ei(m,s),setTimeout(()=>vi(y,s),50)},r),setTimeout(()=>Si(g,s),p),setTimeout(()=>{Ai(S,x,s),setTimeout(()=>Ci(w,s),50),n&&n()},f))};E()}function Ti(e,t,n){var u,d,m,y,g;let a=n==null?void 0:n.objects.get("ui_endgame_logo_1"),s=(d=(((u=a==null?void 0:a.gameplay)==null?void 0:u.tuning)||{}).animation_start_scale)!=null?d:1.2,o=Date.now(),l=e.material.opacity,c=(m=e.targetAlpha)!=null?m:1,r=(y=e.baseScaleX)!=null?y:e.scale.x,p=(g=e.baseScaleY)!=null?g:e.scale.y,f=()=>{let S=Date.now()-o,x=Math.min(S/t,1),w=1-Math.pow(1-x,2);e.material.opacity=l+(c-l)*w;let _=s+(1-s)*w;e.scale.set(r*_,p*_,1),x<1&&requestAnimationFrame(f)};f()}function Ei(e,t){let n=Date.now(),a=parseFloat(e.element.style.opacity||"0"),i=parseFloat(e.element.style.top||"0"),s=()=>{let o=Date.now()-n,l=Math.min(o/t,1),c=1-Math.pow(1-l,2);e.element.style.opacity=(a+(1-a)*c).toString(),e.element.style.top=`${i-20*(1-c)}px`,l<1&&requestAnimationFrame(s)};s()}function vi(e,t){var l;let n=Date.now(),a=parseFloat(e.element.style.opacity||"0"),i=parseFloat(e.element.style.top||"0"),s=i-((l=e.animationStartYOffset)!=null?l:-10),o=()=>{let c=Date.now()-n,r=Math.min(c/t,1),p=1-Math.pow(1-r,2);e.element.style.opacity=(a+(1-a)*p).toString(),e.element.style.top=`${i+(s-i)*p}px`,r<1&&requestAnimationFrame(o)};o()}function Si(e,t){var o;let n=Date.now(),a=parseFloat(e.element.style.opacity||"0"),i=(o=e.targetAlpha)!=null?o:1,s=()=>{let l=Date.now()-n,c=Math.min(l/t,1),r=1-Math.pow(1-c,2);e.element.style.opacity=(a+(i-a)*r).toString(),c<1&&requestAnimationFrame(s)};s()}function Ai(e,t,n){let a=Date.now(),i=parseFloat(e.element.style.opacity||"0"),s=()=>{let o=Date.now()-a,l=Math.min(o/n,1),c=1-Math.pow(1-l,2);e.element.style.opacity=(i+(1-i)*c).toString(),t.element.style.opacity=(i+(1-i)*c).toString(),e.element.style.transform=`translate(-50%, -50%) scale(${1+.1*(1-c)})`,l<1&&requestAnimationFrame(s)};s()}function Ci(e,t){var l;let n=Date.now(),a=parseFloat(e.element.style.opacity||"0"),i=parseFloat(e.element.style.top||"0"),s=i-((l=e.animationStartYOffset)!=null?l:5),o=()=>{let c=Date.now()-n,r=Math.min(c/t,1),p=1-Math.pow(1-r,2);e.element.style.opacity=(a+(1-a)*p).toString(),e.element.style.top=`${i+(s-i)*p}px`,r<1&&requestAnimationFrame(o)};o()}function la(e,t,n,a){var p,f,u,d;let i=n.objects.get("ui_endgame_hand_1"),s=((p=i==null?void 0:i.gameplay)==null?void 0:p.tuning)||{},o=(f=s.click_animation_duration_ms)!=null?f:600,l=(u=s.click_delay_ms)!=null?u:2e3,c=(d=s.click_repeat_delay_ms)!=null?d:3e3,r=()=>{var T,k;e.visible=!0,e.material.opacity=1;let m=e.position.x,y=e.position.y,g=(T=s.hand_offset_x)!=null?T:50,S=(k=s.hand_offset_y)!=null?k:50,x=t.element.getBoundingClientRect(),w=g,_=S,E=Date.now(),H=()=>{var v,I,U;let N=Date.now()-E,C=Math.min(N/o,1),M=C<.5?2*C*C:1-Math.pow(-2*C+2,2)/2;e.position.set(m+(w-m)*M,y+(_-y)*M,0);let W=(I=(v=i==null?void 0:i.transform)==null?void 0:v.scale)!=null?I:.1875,Y=(U=s.hand_scale_multiplier)!=null?U:2.5,se=W*Y*100,Z=se+se*.2*Math.sin(C*Math.PI);e.scale.set(Z,Z,1),C<1?requestAnimationFrame(H):(t.element.style.transform="translate(-50%, -50%) scale(0.95)",setTimeout(()=>{t.element.style.transform="translate(-50%, -50%) scale(1)",a()},100),setTimeout(()=>{e.material.opacity=0,setTimeout(()=>{e.position.set(m,y,0),r()},c)},500))};H()};setTimeout(r,l)}var Ie=be(require("three"));function ca(e,t,n){var f,u,d,m;let a=t.objects.get("hand_tutorial_1"),i=((f=a==null?void 0:a.gameplay)==null?void 0:f.tuning)||{},s=(a==null?void 0:a.render)||{},o=(a==null?void 0:a.transform)||{},l=new Ie.SpriteMaterial({map:e||void 0,transparent:!0,alphaTest:.1}),c=new Ie.Sprite(l);c.position.set(n.x,n.y,0),c.material.opacity=0;let r=(u=i.hand_scale_multiplier)!=null?u:2.5,p=(d=o.scale)!=null?d:.1875;return c.scale.set(p*r*100,p*r*100,1),c.renderOrder=(m=s.z_index)!=null?m:99999,c}function da(e){var m,y,g,S,x,w,_,E,H;let t=e.objects.get("ui_tutorial_1"),n=t==null?void 0:t.ui,a=(t==null?void 0:t.render)||{},i=((m=e.engine.runtime)==null?void 0:m.ui_styles)||{},s=((y=e.engine.runtime)==null?void 0:y.ui)||{},o=(n==null?void 0:n.text)||s.tutorial_label||s.label_text||"CLEAN!",l=(n==null?void 0:n.font)||"brand.warning",c=(n==null?void 0:n.fontSize)||i.label_font_size||52,r=(S=n==null?void 0:n.letterSpacing)!=null?S:(g=i.label_letter_spacing)!=null?g:-1,p=(n==null?void 0:n.align)||"center",f=a.tint,u=typeof f=="string"?f:f?`#${f.toString(16).padStart(6,"0")}`:i.label_fill||"#FFF1C1",d=document.createElement("div");return d.textContent=o,d.style.cssText=`
|
|
95
|
+
font-family: ${O(l)};
|
|
96
|
+
font-size: ${c}px;
|
|
97
|
+
font-weight: ${B(l)};
|
|
98
|
+
color: ${u};
|
|
99
|
+
text-align: ${p};
|
|
100
|
+
letter-spacing: ${r}px;
|
|
101
|
+
text-shadow: ${(x=i.label_shadow_distance)!=null?x:2}px ${(w=i.label_shadow_distance)!=null?w:2}px ${(_=i.label_shadow_blur)!=null?_:4}px rgba(0,0,0,${(E=i.label_shadow_alpha)!=null?E:.8});
|
|
102
|
+
-webkit-text-stroke: ${i.label_stroke||"#8B0000"} 2px;
|
|
103
|
+
opacity: ${(H=a.alpha)!=null?H:0};
|
|
104
|
+
visibility: ${a.visible!==!1?"visible":"hidden"};
|
|
105
|
+
pointer-events: none;
|
|
106
|
+
position: absolute;
|
|
107
|
+
transform: translate(-50%, -50%);
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
`,d}function pa(e,t,n,a,i){var c,r,p,f,u,d,m;let s=i.objects.get("hand_tutorial_1"),o=((c=s==null?void 0:s.gameplay)==null?void 0:c.tuning)||{},l=(s==null?void 0:s.transform)||{};if(!a){let y=(r=o.animation_duration)!=null?r:1.5,g=n%y/y,S=g<.5?2*g*g:-1+(4-2*g)*g,x=(p=o.x_offset)!=null?p:0,w=(f=o.y_offset)!=null?f:0,_=(u=o.animation_range)!=null?u:40,E=_*.7,H=_,T=t.x+x+E,k=t.y+w+H,N=T+E,C=k+H;e.position.set(T+(N-T)*S,k+(C-k)*S,0);let M=(d=l.scale)!=null?d:.1875,W=(m=o.hand_scale_multiplier)!=null?m:2.5,Y=M*W*100;e.scale.set(Y,Y,1)}}var he=be(require("three")),ua=new he.TextureLoader;async function st(e,t,n=16777215,a=!1){try{let s=(globalThis.INLINE_ASSETS||{})[e];return await ua.loadAsync(s||e)}catch{console.warn(`Asset missing: ${e}. Using placeholder.`);let s=document.createElement("canvas");s.width=64,s.height=64;let o=s.getContext("2d");return o&&(o.fillStyle=`#${n.toString(16).padStart(6,"0")}`,a?o.fillRect(0,0,30,60):(o.beginPath(),o.arc(32,32,30,0,Math.PI*2),o.fill(),o.fillRect(27,32,10,40))),new he.CanvasTexture(s)}}async function ma(e,t,n){var m,y,g,S;let i=(globalThis.INLINE_ASSETS||{})[e]||e,s;try{s=await ua.loadAsync(i),console.log("[character] loaded sheet",{path:e,sourceUsed:i})}catch(x){let E=((n.gameplay.character_sheet||{}).fallback_color||"#ff00ff").replace("#","");s=await st(e,t,parseInt(E,16),!0),console.warn("[character] fallback loadAsset used",{path:e,err:x})}if(!s)return[];let o=n.gameplay.character_sheet||{},l=(m=o.cols)!=null?m:3,c=(y=o.rows)!=null?y:2,r=((g=s.image)==null?void 0:g.width)||0,p=((S=s.image)==null?void 0:S.height)||0,f=r/l,u=p/c;if(!Number.isFinite(f)||!Number.isFinite(u)||f<=0||u<=0)return[s];let d=[];for(let x=0;x<c;x++)for(let w=0;w<l;w++){let _=document.createElement("canvas");_.width=f,_.height=u;let E=_.getContext("2d");E&&s.image&&E.drawImage(s.image,w*f,x*u,f,u,0,0,f,u),d.push(new he.CanvasTexture(_))}return d.length>2&&d.push(...d.slice(1,-1).reverse()),console.log("[character] frames prepared",{count:d.length}),d}function fa(e,t){var f,u,d,m;let n=t.gameplay.brush||{},a=t.theme.brush_color||"#ffffff",i=(f=n.radius)!=null?f:20,s=(u=n.inner_radius)!=null?u:15,o=(d=n.alpha)!=null?d:.8,l=(m=n.inner_alpha)!=null?m:.3,c=n.inner_color||"#ffffff",r=document.createElement("canvas");r.width=i*2,r.height=i*2;let p=r.getContext("2d");return p&&(p.clearRect(0,0,r.width,r.height),p.beginPath(),p.arc(i,i,i,0,Math.PI*2),p.fillStyle=a,p.globalAlpha=o,p.fill(),p.beginPath(),p.arc(i,i,s,0,Math.PI*2),p.fillStyle=c,p.globalAlpha=l,p.fill()),new he.CanvasTexture(r)}0&&(module.exports={GameObject,GameObjectManager,Renderer,Transform,animateHandClick,animatePanelEntrance,createBrushTexture,createEndGamePanel,createHandTutorial,createThreeBase,createTutorialLabel,getRegisteredFontIds,loadAsset,loadCharacterFrames,registerFont,resolveFont,resolveFontWeight,updateHandAnimation});
|