reze-engine 0.2.19 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -66
- package/dist/bezier-interpolate.d.ts +15 -0
- package/dist/bezier-interpolate.d.ts.map +1 -0
- package/dist/bezier-interpolate.js +40 -0
- package/dist/engine.d.ts +12 -13
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +107 -175
- package/dist/ik-solver.d.ts +26 -0
- package/dist/ik-solver.d.ts.map +1 -0
- package/dist/ik-solver.js +372 -0
- package/dist/math.d.ts +1 -0
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +8 -0
- package/dist/model.d.ts +46 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +201 -3
- package/dist/player.d.ts +100 -0
- package/dist/player.d.ts.map +1 -0
- package/dist/player.js +409 -0
- package/dist/pmx-loader.d.ts.map +1 -1
- package/dist/pmx-loader.js +57 -36
- package/dist/vmd-loader.d.ts +11 -1
- package/dist/vmd-loader.d.ts.map +1 -1
- package/dist/vmd-loader.js +91 -15
- package/package.json +1 -1
- package/src/bezier-interpolate.ts +47 -0
- package/src/camera.ts +358 -358
- package/src/engine.ts +123 -194
- package/src/ik-solver.ts +488 -0
- package/src/math.ts +555 -546
- package/src/model.ts +284 -3
- package/src/physics.ts +752 -752
- package/src/player.ts +490 -0
- package/src/pmx-loader.ts +1173 -1145
- package/src/vmd-loader.ts +276 -179
package/dist/model.js
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
import { Mat4, Quat, easeInOut } from "./math";
|
|
1
|
+
import { Mat4, Quat, Vec3, easeInOut } from "./math";
|
|
2
|
+
import { IKSolverSystem } from "./ik-solver";
|
|
2
3
|
const VERTEX_STRIDE = 8;
|
|
4
|
+
// Euler rotation order for angle constraints
|
|
5
|
+
export var EulerRotationOrder;
|
|
6
|
+
(function (EulerRotationOrder) {
|
|
7
|
+
EulerRotationOrder[EulerRotationOrder["YXZ"] = 0] = "YXZ";
|
|
8
|
+
EulerRotationOrder[EulerRotationOrder["ZYX"] = 1] = "ZYX";
|
|
9
|
+
EulerRotationOrder[EulerRotationOrder["XZY"] = 2] = "XZY";
|
|
10
|
+
})(EulerRotationOrder || (EulerRotationOrder = {}));
|
|
11
|
+
// Solve axis optimization
|
|
12
|
+
export var SolveAxis;
|
|
13
|
+
(function (SolveAxis) {
|
|
14
|
+
SolveAxis[SolveAxis["None"] = 0] = "None";
|
|
15
|
+
SolveAxis[SolveAxis["Fixed"] = 1] = "Fixed";
|
|
16
|
+
SolveAxis[SolveAxis["X"] = 2] = "X";
|
|
17
|
+
SolveAxis[SolveAxis["Y"] = 3] = "Y";
|
|
18
|
+
SolveAxis[SolveAxis["Z"] = 4] = "Z";
|
|
19
|
+
})(SolveAxis || (SolveAxis = {}));
|
|
3
20
|
export class Model {
|
|
4
21
|
constructor(vertexData, indexData, textures, materials, skeleton, skinning, morphing, rigidbodies = [], joints = []) {
|
|
5
22
|
this.textures = [];
|
|
@@ -27,6 +44,7 @@ export class Model {
|
|
|
27
44
|
}
|
|
28
45
|
this.initializeRuntimeSkeleton();
|
|
29
46
|
this.initializeRotTweenBuffers();
|
|
47
|
+
this.initializeTransTweenBuffers();
|
|
30
48
|
this.initializeRuntimeMorph();
|
|
31
49
|
this.initializeMorphTweenBuffers();
|
|
32
50
|
this.applyMorphs(); // Apply initial morphs (all weights are 0, so no change)
|
|
@@ -53,6 +71,51 @@ export class Model {
|
|
|
53
71
|
rotations[qi + 3] = 1;
|
|
54
72
|
}
|
|
55
73
|
}
|
|
74
|
+
// Initialize IK runtime state
|
|
75
|
+
this.initializeIKRuntime();
|
|
76
|
+
}
|
|
77
|
+
initializeIKRuntime() {
|
|
78
|
+
const boneCount = this.skeleton.bones.length;
|
|
79
|
+
const bones = this.skeleton.bones;
|
|
80
|
+
// Initialize IK chain info for all bones (will be populated for IK chain bones)
|
|
81
|
+
const ikChainInfo = new Array(boneCount);
|
|
82
|
+
for (let i = 0; i < boneCount; i++) {
|
|
83
|
+
ikChainInfo[i] = {
|
|
84
|
+
ikRotation: new Quat(0, 0, 0, 1),
|
|
85
|
+
localRotation: new Quat(0, 0, 0, 1),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Build IK solvers from bone data
|
|
89
|
+
const ikSolvers = [];
|
|
90
|
+
let solverIndex = 0;
|
|
91
|
+
for (let i = 0; i < boneCount; i++) {
|
|
92
|
+
const bone = bones[i];
|
|
93
|
+
if (bone.ikTargetIndex !== undefined && bone.ikLinks && bone.ikLinks.length > 0) {
|
|
94
|
+
// Check if all links are affected by physics (for optimization)
|
|
95
|
+
let canSkipWhenPhysicsEnabled = true;
|
|
96
|
+
for (const link of bone.ikLinks) {
|
|
97
|
+
// For now, assume no bones are physics-controlled (can be enhanced later)
|
|
98
|
+
// If a bone has a rigidbody attached, it's physics-controlled
|
|
99
|
+
const hasPhysics = this.rigidbodies.some((rb) => rb.boneIndex === link.boneIndex);
|
|
100
|
+
if (!hasPhysics) {
|
|
101
|
+
canSkipWhenPhysicsEnabled = false;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const solver = {
|
|
106
|
+
index: solverIndex++,
|
|
107
|
+
ikBoneIndex: i,
|
|
108
|
+
targetBoneIndex: bone.ikTargetIndex,
|
|
109
|
+
iterationCount: bone.ikIteration ?? 1,
|
|
110
|
+
limitAngle: bone.ikLimitAngle ?? Math.PI,
|
|
111
|
+
links: bone.ikLinks,
|
|
112
|
+
canSkipWhenPhysicsEnabled,
|
|
113
|
+
};
|
|
114
|
+
ikSolvers.push(solver);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
this.runtimeSkeleton.ikChainInfo = ikChainInfo;
|
|
118
|
+
this.runtimeSkeleton.ikSolvers = ikSolvers;
|
|
56
119
|
}
|
|
57
120
|
initializeRotTweenBuffers() {
|
|
58
121
|
const n = this.skeleton.bones.length;
|
|
@@ -64,6 +127,16 @@ export class Model {
|
|
|
64
127
|
durationMs: new Float32Array(n),
|
|
65
128
|
};
|
|
66
129
|
}
|
|
130
|
+
initializeTransTweenBuffers() {
|
|
131
|
+
const n = this.skeleton.bones.length;
|
|
132
|
+
this.transTweenState = {
|
|
133
|
+
active: new Uint8Array(n),
|
|
134
|
+
startVec: new Float32Array(n * 3),
|
|
135
|
+
targetVec: new Float32Array(n * 3),
|
|
136
|
+
startTimeMs: new Float32Array(n),
|
|
137
|
+
durationMs: new Float32Array(n),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
67
140
|
initializeMorphTweenBuffers() {
|
|
68
141
|
const n = this.morphing.morphs.length;
|
|
69
142
|
this.morphTweenState = {
|
|
@@ -108,6 +181,26 @@ export class Model {
|
|
|
108
181
|
state.active[i] = 0;
|
|
109
182
|
}
|
|
110
183
|
}
|
|
184
|
+
updateTranslationTweens() {
|
|
185
|
+
const state = this.transTweenState;
|
|
186
|
+
const now = performance.now();
|
|
187
|
+
const translations = this.runtimeSkeleton.localTranslations;
|
|
188
|
+
const boneCount = this.skeleton.bones.length;
|
|
189
|
+
for (let i = 0; i < boneCount; i++) {
|
|
190
|
+
if (state.active[i] !== 1)
|
|
191
|
+
continue;
|
|
192
|
+
const startMs = state.startTimeMs[i];
|
|
193
|
+
const durMs = Math.max(1, state.durationMs[i]);
|
|
194
|
+
const t = Math.max(0, Math.min(1, (now - startMs) / durMs));
|
|
195
|
+
const e = easeInOut(t);
|
|
196
|
+
const ti = i * 3;
|
|
197
|
+
translations[ti] = state.startVec[ti] + (state.targetVec[ti] - state.startVec[ti]) * e;
|
|
198
|
+
translations[ti + 1] = state.startVec[ti + 1] + (state.targetVec[ti + 1] - state.startVec[ti + 1]) * e;
|
|
199
|
+
translations[ti + 2] = state.startVec[ti + 2] + (state.targetVec[ti + 2] - state.startVec[ti + 2]) * e;
|
|
200
|
+
if (t >= 1)
|
|
201
|
+
state.active[i] = 0;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
111
204
|
updateMorphWeightTweens() {
|
|
112
205
|
const state = this.morphTweenState;
|
|
113
206
|
const now = performance.now();
|
|
@@ -231,6 +324,91 @@ export class Model {
|
|
|
231
324
|
state.active[idx] = 1;
|
|
232
325
|
}
|
|
233
326
|
}
|
|
327
|
+
// Move bones using VMD-style relative translations (relative to bind pose world position)
|
|
328
|
+
// This is the default behavior for VMD animations
|
|
329
|
+
moveBones(names, relativeTranslations, durationMs) {
|
|
330
|
+
const state = this.transTweenState;
|
|
331
|
+
const now = performance.now();
|
|
332
|
+
const dur = durationMs && durationMs > 0 ? durationMs : 0;
|
|
333
|
+
const localRot = this.runtimeSkeleton.localRotations;
|
|
334
|
+
// Compute bind pose world positions for all bones
|
|
335
|
+
const skeleton = this.skeleton;
|
|
336
|
+
const computeBindPoseWorldPosition = (idx) => {
|
|
337
|
+
const bone = skeleton.bones[idx];
|
|
338
|
+
const bindPos = new Vec3(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2]);
|
|
339
|
+
if (bone.parentIndex >= 0 && bone.parentIndex < skeleton.bones.length) {
|
|
340
|
+
const parentWorldPos = computeBindPoseWorldPosition(bone.parentIndex);
|
|
341
|
+
return parentWorldPos.add(bindPos);
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
return bindPos;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
for (let i = 0; i < names.length; i++) {
|
|
348
|
+
const name = names[i];
|
|
349
|
+
const idx = this.runtimeSkeleton.nameIndex[name] ?? -1;
|
|
350
|
+
if (idx < 0 || idx >= this.skeleton.bones.length)
|
|
351
|
+
continue;
|
|
352
|
+
const bone = this.skeleton.bones[idx];
|
|
353
|
+
const ti = idx * 3;
|
|
354
|
+
const qi = idx * 4;
|
|
355
|
+
const translations = this.runtimeSkeleton.localTranslations;
|
|
356
|
+
const vmdRelativeTranslation = relativeTranslations[i];
|
|
357
|
+
// VMD translation is relative to bind pose world position
|
|
358
|
+
// targetWorldPos = bindPoseWorldPos + vmdRelativeTranslation
|
|
359
|
+
const bindPoseWorldPos = computeBindPoseWorldPosition(idx);
|
|
360
|
+
const targetWorldPos = bindPoseWorldPos.add(vmdRelativeTranslation);
|
|
361
|
+
// Convert target world position to local translation
|
|
362
|
+
// We need parent's bind pose world position to transform to parent space
|
|
363
|
+
let parentBindPoseWorldPos;
|
|
364
|
+
if (bone.parentIndex >= 0) {
|
|
365
|
+
parentBindPoseWorldPos = computeBindPoseWorldPosition(bone.parentIndex);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
parentBindPoseWorldPos = new Vec3(0, 0, 0);
|
|
369
|
+
}
|
|
370
|
+
// Transform target world position to parent's local space
|
|
371
|
+
// In bind pose, parent's world matrix is just a translation
|
|
372
|
+
const parentSpacePos = targetWorldPos.subtract(parentBindPoseWorldPos);
|
|
373
|
+
// Subtract bindTranslation to get position after bind translation
|
|
374
|
+
const afterBindTranslation = parentSpacePos.subtract(new Vec3(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2]));
|
|
375
|
+
// Apply inverse rotation to get local translation
|
|
376
|
+
const localRotation = new Quat(localRot[qi], localRot[qi + 1], localRot[qi + 2], localRot[qi + 3]);
|
|
377
|
+
const invRotation = localRotation.conjugate().normalize();
|
|
378
|
+
const rotationMat = Mat4.fromQuat(invRotation.x, invRotation.y, invRotation.z, invRotation.w);
|
|
379
|
+
const rm = rotationMat.values;
|
|
380
|
+
const localTranslation = new Vec3(rm[0] * afterBindTranslation.x + rm[4] * afterBindTranslation.y + rm[8] * afterBindTranslation.z, rm[1] * afterBindTranslation.x + rm[5] * afterBindTranslation.y + rm[9] * afterBindTranslation.z, rm[2] * afterBindTranslation.x + rm[6] * afterBindTranslation.y + rm[10] * afterBindTranslation.z);
|
|
381
|
+
const [tx, ty, tz] = [localTranslation.x, localTranslation.y, localTranslation.z];
|
|
382
|
+
if (dur === 0) {
|
|
383
|
+
translations[ti] = tx;
|
|
384
|
+
translations[ti + 1] = ty;
|
|
385
|
+
translations[ti + 2] = tz;
|
|
386
|
+
state.active[idx] = 0;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
let sx = translations[ti];
|
|
390
|
+
let sy = translations[ti + 1];
|
|
391
|
+
let sz = translations[ti + 2];
|
|
392
|
+
if (state.active[idx] === 1) {
|
|
393
|
+
const startMs = state.startTimeMs[idx];
|
|
394
|
+
const prevDur = Math.max(1, state.durationMs[idx]);
|
|
395
|
+
const t = Math.max(0, Math.min(1, (now - startMs) / prevDur));
|
|
396
|
+
const e = easeInOut(t);
|
|
397
|
+
sx = state.startVec[ti] + (state.targetVec[ti] - state.startVec[ti]) * e;
|
|
398
|
+
sy = state.startVec[ti + 1] + (state.targetVec[ti + 1] - state.startVec[ti + 1]) * e;
|
|
399
|
+
sz = state.startVec[ti + 2] + (state.targetVec[ti + 2] - state.startVec[ti + 2]) * e;
|
|
400
|
+
}
|
|
401
|
+
state.startVec[ti] = sx;
|
|
402
|
+
state.startVec[ti + 1] = sy;
|
|
403
|
+
state.startVec[ti + 2] = sz;
|
|
404
|
+
state.targetVec[ti] = tx;
|
|
405
|
+
state.targetVec[ti + 1] = ty;
|
|
406
|
+
state.targetVec[ti + 2] = tz;
|
|
407
|
+
state.startTimeMs[idx] = now;
|
|
408
|
+
state.durationMs[idx] = dur;
|
|
409
|
+
state.active[idx] = 1;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
234
412
|
getBoneWorldMatrices() {
|
|
235
413
|
return this.runtimeSkeleton.worldMatrices;
|
|
236
414
|
}
|
|
@@ -334,13 +512,29 @@ export class Model {
|
|
|
334
512
|
}
|
|
335
513
|
evaluatePose() {
|
|
336
514
|
this.updateRotationTweens();
|
|
515
|
+
this.updateTranslationTweens();
|
|
337
516
|
const hasActiveMorphTweens = this.updateMorphWeightTweens();
|
|
338
517
|
if (hasActiveMorphTweens) {
|
|
339
518
|
this.applyMorphs();
|
|
340
519
|
}
|
|
520
|
+
// Compute initial world matrices (needed for IK solving)
|
|
521
|
+
this.computeWorldMatrices();
|
|
522
|
+
// Solve IK chains (modifies localRotations)
|
|
523
|
+
this.solveIKChains();
|
|
524
|
+
// Recompute world matrices with IK rotations applied
|
|
341
525
|
this.computeWorldMatrices();
|
|
342
526
|
return hasActiveMorphTweens;
|
|
343
527
|
}
|
|
528
|
+
solveIKChains() {
|
|
529
|
+
const ikSolvers = this.runtimeSkeleton.ikSolvers;
|
|
530
|
+
if (!ikSolvers || ikSolvers.length === 0)
|
|
531
|
+
return;
|
|
532
|
+
const ikChainInfo = this.runtimeSkeleton.ikChainInfo;
|
|
533
|
+
if (!ikChainInfo)
|
|
534
|
+
return;
|
|
535
|
+
IKSolverSystem.solve(ikSolvers, this.skeleton.bones, this.runtimeSkeleton.localRotations, this.runtimeSkeleton.localTranslations, this.runtimeSkeleton.worldMatrices, ikChainInfo, false // usePhysics - can be enhanced later
|
|
536
|
+
);
|
|
537
|
+
}
|
|
344
538
|
computeWorldMatrices() {
|
|
345
539
|
const bones = this.skeleton.bones;
|
|
346
540
|
const localRot = this.runtimeSkeleton.localRotations;
|
|
@@ -397,11 +591,15 @@ export class Model {
|
|
|
397
591
|
}
|
|
398
592
|
}
|
|
399
593
|
}
|
|
400
|
-
// Build local matrix: identity + bind translation, then rotation, then append translation
|
|
594
|
+
// Build local matrix: identity + bind translation, then rotation, then local translation, then append translation
|
|
595
|
+
const ti = i * 3;
|
|
596
|
+
const localTx = localTrans[ti] + addLocalTx;
|
|
597
|
+
const localTy = localTrans[ti + 1] + addLocalTy;
|
|
598
|
+
const localTz = localTrans[ti + 2] + addLocalTz;
|
|
401
599
|
this.cachedIdentityMat1
|
|
402
600
|
.setIdentity()
|
|
403
601
|
.translateInPlace(b.bindTranslation[0], b.bindTranslation[1], b.bindTranslation[2]);
|
|
404
|
-
this.cachedIdentityMat2.setIdentity().translateInPlace(
|
|
602
|
+
this.cachedIdentityMat2.setIdentity().translateInPlace(localTx, localTy, localTz);
|
|
405
603
|
const localM = this.cachedIdentityMat1.multiply(rotateM).multiply(this.cachedIdentityMat2);
|
|
406
604
|
const worldOffset = i * 16;
|
|
407
605
|
if (b.parentIndex >= 0) {
|
package/dist/player.d.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Quat, Vec3 } from "./math";
|
|
2
|
+
export interface AnimationPose {
|
|
3
|
+
boneRotations: Map<string, Quat>;
|
|
4
|
+
boneTranslations: Map<string, Vec3>;
|
|
5
|
+
morphWeights: Map<string, number>;
|
|
6
|
+
}
|
|
7
|
+
export interface AnimationProgress {
|
|
8
|
+
current: number;
|
|
9
|
+
duration: number;
|
|
10
|
+
percentage: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class Player {
|
|
13
|
+
private frames;
|
|
14
|
+
private boneTracks;
|
|
15
|
+
private morphTracks;
|
|
16
|
+
private duration;
|
|
17
|
+
private isPlaying;
|
|
18
|
+
private isPaused;
|
|
19
|
+
private currentTime;
|
|
20
|
+
private startTime;
|
|
21
|
+
private pausedTime;
|
|
22
|
+
private pauseStartTime;
|
|
23
|
+
private audioElement?;
|
|
24
|
+
private audioUrl?;
|
|
25
|
+
private audioLoaded;
|
|
26
|
+
/**
|
|
27
|
+
* Load VMD animation file and optionally audio
|
|
28
|
+
*/
|
|
29
|
+
loadVmd(vmdUrl: string, audioUrl?: string): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Load audio file
|
|
32
|
+
*/
|
|
33
|
+
loadAudio(url: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Process frames into tracks
|
|
36
|
+
*/
|
|
37
|
+
private processFrames;
|
|
38
|
+
/**
|
|
39
|
+
* Start or resume playback
|
|
40
|
+
*/
|
|
41
|
+
play(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Pause playback
|
|
44
|
+
*/
|
|
45
|
+
pause(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Stop playback and reset to beginning
|
|
48
|
+
*/
|
|
49
|
+
stop(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Seek to specific time
|
|
52
|
+
*/
|
|
53
|
+
seek(time: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* Update playback and return current pose
|
|
56
|
+
* Returns null if not playing, but returns current pose if paused
|
|
57
|
+
*/
|
|
58
|
+
update(currentRealTime: number): AnimationPose | null;
|
|
59
|
+
/**
|
|
60
|
+
* Get pose at specific time (pure function)
|
|
61
|
+
*/
|
|
62
|
+
getPoseAtTime(time: number): AnimationPose;
|
|
63
|
+
/**
|
|
64
|
+
* Get current playback progress
|
|
65
|
+
*/
|
|
66
|
+
getProgress(): AnimationProgress;
|
|
67
|
+
/**
|
|
68
|
+
* Get current time
|
|
69
|
+
*/
|
|
70
|
+
getCurrentTime(): number;
|
|
71
|
+
/**
|
|
72
|
+
* Get animation duration
|
|
73
|
+
*/
|
|
74
|
+
getDuration(): number;
|
|
75
|
+
/**
|
|
76
|
+
* Check if playing
|
|
77
|
+
*/
|
|
78
|
+
isPlayingState(): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Check if paused
|
|
81
|
+
*/
|
|
82
|
+
isPausedState(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Check if has audio
|
|
85
|
+
*/
|
|
86
|
+
hasAudio(): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Set audio volume (0.0 to 1.0)
|
|
89
|
+
*/
|
|
90
|
+
setVolume(volume: number): void;
|
|
91
|
+
/**
|
|
92
|
+
* Mute audio
|
|
93
|
+
*/
|
|
94
|
+
mute(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Unmute audio
|
|
97
|
+
*/
|
|
98
|
+
unmute(): void;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=player.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAGnC,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAChC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,MAAM;IAEjB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAwE;IAC1F,OAAO,CAAC,WAAW,CAA0E;IAC7F,OAAO,CAAC,QAAQ,CAAY;IAG5B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAY;IAG/B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,cAAc,CAAY;IAGlC,OAAO,CAAC,YAAY,CAAC,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,CAAQ;IACzB,OAAO,CAAC,WAAW,CAAiB;IAEpC;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/D;;OAEG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB3C;;OAEG;IACH,OAAO,CAAC,aAAa;IAwErB;;OAEG;IACH,IAAI,IAAI,IAAI;IAyBZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAYb;;OAEG;IACH,IAAI,IAAI,IAAI;IAcZ;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAgBxB;;;OAGG;IACH,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAiCrD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IA+I1C;;OAEG;IACH,WAAW,IAAI,iBAAiB;IAQhC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM/B;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,MAAM,IAAI,IAAI;CAKf"}
|