reze-engine 0.42.0 → 0.42.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/animation.d.ts +19 -13
- package/dist/animation.d.ts.map +1 -1
- package/dist/animation.js +26 -17
- package/dist/engine.d.ts +3 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +14 -3
- package/dist/physics/physics.d.ts +22 -2
- package/dist/physics/physics.d.ts.map +1 -1
- package/dist/physics/physics.js +24 -3
- package/dist/physics-debug.d.ts +30 -0
- package/dist/physics-debug.d.ts.map +1 -0
- package/dist/physics-debug.js +526 -0
- package/dist/shaders/materials/body.d.ts +2 -0
- package/dist/shaders/materials/body.d.ts.map +1 -0
- package/dist/shaders/materials/body.js +95 -0
- package/dist/shaders/materials/cloth_rough.d.ts +2 -0
- package/dist/shaders/materials/cloth_rough.d.ts.map +1 -0
- package/dist/shaders/materials/cloth_rough.js +69 -0
- package/dist/shaders/materials/cloth_smooth.d.ts +2 -0
- package/dist/shaders/materials/cloth_smooth.d.ts.map +1 -0
- package/dist/shaders/materials/cloth_smooth.js +61 -0
- package/dist/shaders/materials/default.d.ts +2 -0
- package/dist/shaders/materials/default.d.ts.map +1 -0
- package/dist/shaders/materials/default.js +43 -0
- package/dist/shaders/materials/eye.d.ts +2 -0
- package/dist/shaders/materials/eye.d.ts.map +1 -0
- package/dist/shaders/materials/eye.js +60 -0
- package/dist/shaders/materials/face.d.ts +2 -0
- package/dist/shaders/materials/face.d.ts.map +1 -0
- package/dist/shaders/materials/face.js +95 -0
- package/dist/shaders/materials/hair.d.ts +2 -0
- package/dist/shaders/materials/hair.d.ts.map +1 -0
- package/dist/shaders/materials/hair.js +90 -0
- package/dist/shaders/materials/metal.d.ts +2 -0
- package/dist/shaders/materials/metal.d.ts.map +1 -0
- package/dist/shaders/materials/metal.js +77 -0
- package/dist/shaders/materials/mmd_classic.d.ts +2 -0
- package/dist/shaders/materials/mmd_classic.d.ts.map +1 -0
- package/dist/shaders/materials/mmd_classic.js +66 -0
- package/dist/shaders/materials/stockings.d.ts +2 -0
- package/dist/shaders/materials/stockings.d.ts.map +1 -0
- package/dist/shaders/materials/stockings.js +122 -0
- package/dist/shaders/passes/physics-debug.d.ts +2 -0
- package/dist/shaders/passes/physics-debug.d.ts.map +1 -0
- package/dist/shaders/passes/physics-debug.js +69 -0
- package/dist/vmd-writer.d.ts.map +1 -1
- package/dist/vmd-writer.js +25 -21
- package/package.json +2 -2
- package/src/animation.ts +26 -17
- package/src/engine.ts +14 -3
- package/src/physics/physics.ts +27 -3
- package/src/vmd-writer.ts +26 -26
- package/dist/physics/autofit.d.ts +0 -147
- package/dist/physics/autofit.d.ts.map +0 -1
- package/dist/physics/autofit.js +0 -501
- package/dist/shaders/passes/ground-noise.d.ts +0 -7
- package/dist/shaders/passes/ground-noise.d.ts.map +0 -1
- package/dist/shaders/passes/ground-noise.js +0 -88
package/src/engine.ts
CHANGED
|
@@ -905,7 +905,9 @@ export class Engine {
|
|
|
905
905
|
private bgParamsDummyBuffer!: GPUBuffer
|
|
906
906
|
private compositePipelineLayout!: GPUPipelineLayout
|
|
907
907
|
/** time=0 origin for the active effect — reset each setEffect. */
|
|
908
|
-
|
|
908
|
+
/** Scene-clock reading when the current effect was installed. The effect's
|
|
909
|
+
* `time` is measured from here — see where it is written. */
|
|
910
|
+
private effectEpochScene = 0
|
|
909
911
|
private compositeBloomView: GPUTextureView | null = null
|
|
910
912
|
|
|
911
913
|
// EEVEE-style bloom pyramid (mirrors Blender 3.6 effect_bloom_frag.glsl):
|
|
@@ -1495,7 +1497,7 @@ export class Engine {
|
|
|
1495
1497
|
this.anchorTrail.clear()
|
|
1496
1498
|
this.compositePipelineIdentity = identity
|
|
1497
1499
|
this.compositePipelineGamma = gamma
|
|
1498
|
-
this.
|
|
1500
|
+
this.effectEpochScene = this.sceneClock
|
|
1499
1501
|
this.rebuildCompositeBindGroup()
|
|
1500
1502
|
this.writeCompositeViewUniforms()
|
|
1501
1503
|
return { ok: true, diagnostics: [], mounts }
|
|
@@ -6271,7 +6273,16 @@ export class Engine {
|
|
|
6271
6273
|
u[22] = v[10]
|
|
6272
6274
|
u[23] = 0
|
|
6273
6275
|
// Effect clock + canvas size (viewU[6]) — written on the same refresh.
|
|
6274
|
-
|
|
6276
|
+
// The effect clock, on the SCENE's time rather than the wall's.
|
|
6277
|
+
//
|
|
6278
|
+
// renderFrame() drives offline export as fast as the encoder will take
|
|
6279
|
+
// frames, so wall time races ahead of the video's own time — a rain effect
|
|
6280
|
+
// fell at the wrong rate in the export, a twinkle blinked at the wrong
|
|
6281
|
+
// speed, and none of it matched what the editor had shown. Measured
|
|
6282
|
+
// against the accumulated frame delta, an effect animates identically in
|
|
6283
|
+
// the editor, in an export, and in a re-export, which is the same rule the
|
|
6284
|
+
// trails already followed.
|
|
6285
|
+
u[24] = this.sceneClock - this.effectEpochScene
|
|
6275
6286
|
u[26] = this.canvas.width
|
|
6276
6287
|
u[27] = this.canvas.height
|
|
6277
6288
|
// Camera world position (viewU[10]) — the other half of bgWorldPos. It
|
package/src/physics/physics.ts
CHANGED
|
@@ -28,8 +28,28 @@ export class RezePhysics {
|
|
|
28
28
|
private readonly maxSubSteps = 6
|
|
29
29
|
/** EMA of one world.step's CPU cost; drives catch-up load shedding. */
|
|
30
30
|
private stepCostEmaMs = 0.5
|
|
31
|
-
/**
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Share of the frame a single frame may spend catching physics up before it
|
|
33
|
+
* sheds the backlog instead.
|
|
34
|
+
*
|
|
35
|
+
* A FRACTION, not a fixed millisecond count, and that distinction is the whole
|
|
36
|
+
* point. It used to be a flat 8ms — about half a frame at 60Hz, which is what
|
|
37
|
+
* it was tuned against. The moment anything else made frames longer (a heavy
|
|
38
|
+
* effect, a weak GPU) the frame grew and the budget did not, so at 30Hz
|
|
39
|
+
* physics was allowed a QUARTER of the frame while needing twice the
|
|
40
|
+
* substeps. It shed work it could easily afford, and shedding discards time —
|
|
41
|
+
* so physics ran fractionally slow-motion against a character moving at full
|
|
42
|
+
* speed, which is exactly what hair and skirts lagging behind the body looks
|
|
43
|
+
* like.
|
|
44
|
+
*
|
|
45
|
+
* At 60Hz this reproduces the old 8ms almost exactly, so nothing that was
|
|
46
|
+
* tuned against it moves.
|
|
47
|
+
*/
|
|
48
|
+
private readonly stepBudgetFraction = 0.5
|
|
49
|
+
/** Floor and ceiling on that share: a very short frame still gets enough to
|
|
50
|
+
* make progress, and a very long one must not spend all of itself here. */
|
|
51
|
+
private readonly stepBudgetMinMs = 8
|
|
52
|
+
private readonly stepBudgetMaxMs = 24
|
|
33
53
|
|
|
34
54
|
// Fixed-timestep render interpolation ("Fix Your Timestep"): the dynamic body pose is
|
|
35
55
|
// rendered as lerp(prev, curr, alpha) between the last two completed substeps, where
|
|
@@ -260,7 +280,11 @@ export class RezePhysics {
|
|
|
260
280
|
// state (6× step cost every frame; iOS "starts smooth, then stays slow").
|
|
261
281
|
// Catching up must never cost more than a frame-budget slice: shed the backlog
|
|
262
282
|
// instead (physics runs fractionally slow-motion for a beat; framerate holds).
|
|
263
|
-
const
|
|
283
|
+
const budgetMs = Math.min(
|
|
284
|
+
this.stepBudgetMaxMs,
|
|
285
|
+
Math.max(this.stepBudgetMinMs, dt * 1000 * this.stepBudgetFraction),
|
|
286
|
+
)
|
|
287
|
+
const affordable = Math.max(1, Math.floor(budgetMs / Math.max(0.05, this.stepCostEmaMs)))
|
|
264
288
|
if (nSub > affordable) nSub = affordable
|
|
265
289
|
for (let k = 0; k < nSub; k++) {
|
|
266
290
|
this.savePrevState()
|
package/src/vmd-writer.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnimationClip, BoneInterpolation } from "./animation"
|
|
1
|
+
import { AnimationClip, BoneInterpolation, ControlPoint } from "./animation"
|
|
2
2
|
|
|
3
3
|
const VMD_HEADER = "Vocaloid Motion Data 0002"
|
|
4
4
|
const HEADER_SIZE = 30
|
|
@@ -189,34 +189,34 @@ function writeFixedShiftJIS(buffer: ArrayBuffer, offset: number, str: string, ma
|
|
|
189
189
|
|
|
190
190
|
/**
|
|
191
191
|
* Convert BoneInterpolation back to the 64-byte raw VMD interpolation table.
|
|
192
|
-
* Exact inverse of rawInterpolationToBoneInterpolation in animation.ts
|
|
192
|
+
* Exact inverse of rawInterpolationToBoneInterpolation in animation.ts — see the
|
|
193
|
+
* layout note there for why the record is written four times.
|
|
193
194
|
*/
|
|
194
195
|
function boneInterpolationToRaw(interp: BoneInterpolation): Uint8Array {
|
|
195
|
-
|
|
196
|
+
// The one 16-byte record: each channel's x1 / y1 / x2 / y2, interleaved.
|
|
197
|
+
const record = new Uint8Array(16)
|
|
198
|
+
const put = (c: number, cp: ControlPoint[]): void => {
|
|
199
|
+
record[c] = cp[0].x
|
|
200
|
+
record[c + 4] = cp[0].y
|
|
201
|
+
record[c + 8] = cp[1].x
|
|
202
|
+
record[c + 12] = cp[1].y
|
|
203
|
+
}
|
|
204
|
+
put(0, interp.translationX)
|
|
205
|
+
put(1, interp.translationY)
|
|
206
|
+
put(2, interp.translationZ)
|
|
207
|
+
put(3, interp.rotation)
|
|
196
208
|
|
|
197
|
-
//
|
|
198
|
-
|
|
199
|
-
raw
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
raw[
|
|
207
|
-
raw[
|
|
208
|
-
|
|
209
|
-
// TranslationY: [{x: raw[16], y: raw[20]}, {x: raw[24], y: raw[28]}]
|
|
210
|
-
raw[16] = interp.translationY[0].x
|
|
211
|
-
raw[20] = interp.translationY[0].y
|
|
212
|
-
raw[24] = interp.translationY[1].x
|
|
213
|
-
raw[28] = interp.translationY[1].y
|
|
214
|
-
|
|
215
|
-
// TranslationZ: [{x: raw[32], y: raw[36]}, {x: raw[40], y: raw[44]}]
|
|
216
|
-
raw[32] = interp.translationZ[0].x
|
|
217
|
-
raw[36] = interp.translationZ[0].y
|
|
218
|
-
raw[40] = interp.translationZ[1].x
|
|
219
|
-
raw[44] = interp.translationZ[1].y
|
|
209
|
+
// Copy `r` starts at byte r * 16 and holds record[r..15], so channel r's own
|
|
210
|
+
// bytes land where the reader (and MMD, and babylon-mmd) look for them.
|
|
211
|
+
const raw = new Uint8Array(64)
|
|
212
|
+
for (let r = 0; r < 4; r++) {
|
|
213
|
+
for (let i = r; i < 16; i++) raw[r * 16 + (i - r)] = record[i]
|
|
214
|
+
}
|
|
215
|
+
// Bytes 2 and 3 of the first copy are not interpolation — they are the physics
|
|
216
|
+
// toggle. 0x0000 is "physics on", which is what both reference motions carry and
|
|
217
|
+
// the only state a clip can round-trip: BoneInterpolation does not model the flag.
|
|
218
|
+
raw[2] = 0
|
|
219
|
+
raw[3] = 0
|
|
220
220
|
|
|
221
221
|
return raw
|
|
222
222
|
}
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { type Rigidbody } from "./types";
|
|
2
|
-
import type { Skinning } from "../model";
|
|
3
|
-
/**
|
|
4
|
-
* Supplementary colliders fitted to the mesh a PMX rigid body fails to cover.
|
|
5
|
-
*
|
|
6
|
-
* PMX body proxies are bodies of revolution — 下半身 is a capsule lying
|
|
7
|
-
* transversely across the hips, so its cross-section is a circle. A pelvis seen
|
|
8
|
-
* from the side is not a circle, and across every rig measured the butt sits
|
|
9
|
-
* 0.18–0.71 units OUTSIDE that capsule while the front is flush or inside. That
|
|
10
|
-
* gap is where a skirt goes through a character: the cloth is resting correctly
|
|
11
|
-
* on the collider it was given, and the collider stops half a unit short of the
|
|
12
|
-
* skin.
|
|
13
|
-
*
|
|
14
|
-
* A rest offset cannot close it (see RigidBodyStore.restOffset) — it is one
|
|
15
|
-
* scalar on a radially symmetric shape, and the error is asymmetric. Measured
|
|
16
|
-
* on 托特's run cycle, the offset that clears the butt is 0.5, which is simply
|
|
17
|
-
* the size of the missing geometry, and at that value the skirt stands off the
|
|
18
|
-
* front and hips by the same 0.5.
|
|
19
|
-
*
|
|
20
|
-
* So fit the missing piece instead: take each bone-following body's own skinned
|
|
21
|
-
* vertices, find the ones that escape its shape in a concentrated lobe, and fit
|
|
22
|
-
* a capsule to that lobe. That is the fix riggers apply by hand, derived from
|
|
23
|
-
* the mesh rather than guessed.
|
|
24
|
-
*
|
|
25
|
-
* Measured on 托特's run cycle, counting butt vertices swallowed by a cloth
|
|
26
|
-
* body: 32.4 per frame with nothing, 30.9 with a 0.02 rest offset, 12.4 with
|
|
27
|
-
* this pass, 10.4 with both.
|
|
28
|
-
*/
|
|
29
|
-
export interface AutoFitOptions {
|
|
30
|
-
/** A vertex counts as protruding past this much (model units). Below it the
|
|
31
|
-
* mesh is within authoring tolerance of the proxy and needs no help. */
|
|
32
|
-
minProtrusion?: number;
|
|
33
|
-
/**
|
|
34
|
-
* Ignore vertices further out than this multiple of the source shape's
|
|
35
|
-
* RADIUS (its smallest characteristic dimension).
|
|
36
|
-
*
|
|
37
|
-
* A coarse first cut at keeping hair and loose clothing out — anything
|
|
38
|
-
* standing further off the proxy than the proxy is wide is not skin. The
|
|
39
|
-
* discriminator that actually does the work is minConcentration.
|
|
40
|
-
*/
|
|
41
|
-
maxProtrusionRatio?: number;
|
|
42
|
-
/** Fewer protruding vertices than this and it is a spike, not a region. */
|
|
43
|
-
minVertices?: number;
|
|
44
|
-
/**
|
|
45
|
-
* Per-axis quantile the fitted lobe's extent is clipped to, each end. A
|
|
46
|
-
* handful of stray vertices (a weight-painting slip, a seam) would otherwise
|
|
47
|
-
* stretch the capsule far past the surface everyone can see.
|
|
48
|
-
*/
|
|
49
|
-
quantile?: number;
|
|
50
|
-
/** Skip the fit unless the capsule actually reaches this far past what is
|
|
51
|
-
* already covered — otherwise it adds solver rows for nothing. */
|
|
52
|
-
minGain?: number;
|
|
53
|
-
/** How tightly the kept lobe's outward directions must agree, 0–1. A loose
|
|
54
|
-
* sanity check; the real discriminator is minConcentration. */
|
|
55
|
-
minDirectionality?: number;
|
|
56
|
-
/** Vertices outside the dominant lobe, by this cosine, are not part of the
|
|
57
|
-
* feature being fitted. */
|
|
58
|
-
lobeCos?: number;
|
|
59
|
-
/**
|
|
60
|
-
* How much deeper the fitted lobe must be than protrusion typically is on
|
|
61
|
-
* this body, averaged over the vertices that protrude at all.
|
|
62
|
-
*
|
|
63
|
-
* This is the guard that separates "the proxy is missing a lobe" from "the
|
|
64
|
-
* proxy is not a proxy for this mesh at all". A pelvis escapes its capsule by
|
|
65
|
-
* 0.53 at the back and 0.14 at the front, so the back lobe stands well clear
|
|
66
|
-
* of the average. Hair escapes the skull by a similar depth in every
|
|
67
|
-
* direction, so its deepest lobe is no deeper than typical and the ratio sits
|
|
68
|
-
* near 1. See the note at the meanProtrusion computation for what this
|
|
69
|
-
* deliberately refuses to fit.
|
|
70
|
-
*
|
|
71
|
-
* Without it the pass fits the hairstyle — measured on 托特, 頭 reports
|
|
72
|
-
* 3653 of 4669 vertices outside its capsule, and the fitted shape was a crate
|
|
73
|
-
* around the whole head. No threshold on depth or vertex count tells those
|
|
74
|
-
* two cases apart; concentration does.
|
|
75
|
-
*/
|
|
76
|
-
minConcentration?: number;
|
|
77
|
-
/**
|
|
78
|
-
* How many capsules may be fitted to one body, each against what the previous
|
|
79
|
-
* ones already cover.
|
|
80
|
-
*
|
|
81
|
-
* One capsule inscribed in a lobe does not fill it — on 托特's butt a single
|
|
82
|
-
* fit removed 58% of the clipping and left the rest at the edges the capsule
|
|
83
|
-
* could not reach. Each further pass re-measures protrusion against the
|
|
84
|
-
* original shape UNION everything fitted so far, so it lands on whatever is
|
|
85
|
-
* still exposed instead of re-fitting the same bulge.
|
|
86
|
-
*/
|
|
87
|
-
maxShapesPerBody?: number;
|
|
88
|
-
/**
|
|
89
|
-
* Quantile of the lobe's perpendicular spread used as the capsule radius.
|
|
90
|
-
*
|
|
91
|
-
* The clip-versus-float dial, and the one to reach for if a result looks
|
|
92
|
-
* wrong. Lower hugs the body: less standoff in idle, more clipping left. 1.0
|
|
93
|
-
* encloses the lobe entirely, which is what produced a visibly hovering
|
|
94
|
-
* skirt on 托特.
|
|
95
|
-
*/
|
|
96
|
-
radiusQuantile?: number;
|
|
97
|
-
/**
|
|
98
|
-
* Fit only the deepest part of each lobe: points at least this fraction of
|
|
99
|
-
* the lobe's own maximum protrusion.
|
|
100
|
-
*
|
|
101
|
-
* A lobe tapers to nothing at its edges, and a capsule sized to span the
|
|
102
|
-
* whole thing has to be fat enough to reach the edges too. Fitting the deep
|
|
103
|
-
* core keeps each capsule small and lets a later pass handle the shallows
|
|
104
|
-
* with its own, which is both tighter and closer to what the surface is
|
|
105
|
-
* actually doing.
|
|
106
|
-
*/
|
|
107
|
-
lobeDepthFraction?: number;
|
|
108
|
-
}
|
|
109
|
-
/** What the pass decided for one source body — surfaced so a rig can be
|
|
110
|
-
* inspected rather than silently rebuilt underneath its author. */
|
|
111
|
-
export interface AutoFitResult {
|
|
112
|
-
/** Index of the body in the input array that this supplements. */
|
|
113
|
-
sourceIndex: number;
|
|
114
|
-
sourceName: string;
|
|
115
|
-
/** Vertices dominated by that body's bone, and how many were outside it. */
|
|
116
|
-
vertexCount: number;
|
|
117
|
-
protrudingCount: number;
|
|
118
|
-
/** Furthest any kept vertex sat outside the source shape. */
|
|
119
|
-
maxProtrusion: number;
|
|
120
|
-
/** How far the fitted capsule reaches past what was already covered. */
|
|
121
|
-
gain: number;
|
|
122
|
-
/** Length of the kept lobe's mean outward direction, 0–1. */
|
|
123
|
-
directionality: number;
|
|
124
|
-
/** Lobe depth over the body's average protrusion. See minConcentration. */
|
|
125
|
-
concentration: number;
|
|
126
|
-
/**
|
|
127
|
-
* Furthest the capsule's newly exposed surface sits from the skin it was
|
|
128
|
-
* fitted to — the amount cloth resting on it will stand off the body at the
|
|
129
|
-
* worst point, and the number to watch if a result looks puffy. Only the part
|
|
130
|
-
* reaching outside the source shape is measured; the rest is buried.
|
|
131
|
-
*/
|
|
132
|
-
overshoot: number;
|
|
133
|
-
body: Rigidbody;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Fit supplementary colliders for every bone-following body whose own mesh
|
|
137
|
-
* escapes it.
|
|
138
|
-
*
|
|
139
|
-
* `vertices` is the model's interleaved vertex buffer (stride 8, position
|
|
140
|
-
* first) and `skinning` its joints/weights — both in PMX bind pose, the same
|
|
141
|
-
* space as `shapePosition` / `shapeRotation`, so nothing has to be skinned.
|
|
142
|
-
*
|
|
143
|
-
* Returns one entry per body it chose to supplement; the caller appends
|
|
144
|
-
* `.body` to the rigid body list before constructing RezePhysics.
|
|
145
|
-
*/
|
|
146
|
-
export declare function fitSupplementaryColliders(rigidbodies: Rigidbody[], vertices: Float32Array, skinning: Skinning, options?: AutoFitOptions): AutoFitResult[];
|
|
147
|
-
//# sourceMappingURL=autofit.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"autofit.d.ts","sourceRoot":"","sources":["../../src/physics/autofit.ts"],"names":[],"mappings":"AACA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,SAAS,CAAA;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,cAAc;IAC7B;6EACyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;uEACmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;oEACgE;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;gCAC4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AA2BD;oEACoE;AACpE,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAA;IACrB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,cAAc,EAAE,MAAM,CAAA;IACtB,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAA;IACrB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,SAAS,CAAA;CAChB;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,SAAS,EAAE,EACxB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,cAAmB,GAC3B,aAAa,EAAE,CA4CjB"}
|