@hology/core 0.0.211 → 0.0.213

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/dist/effects/sequence/index.d.ts +1 -0
  2. package/dist/effects/sequence/index.js +1 -1
  3. package/dist/effects/sequence/sequence-action.d.ts +5 -0
  4. package/dist/effects/sequence/sequence-actor.d.ts +7 -0
  5. package/dist/effects/sequence/sequence-actor.js +1 -1
  6. package/dist/effects/sequence/sequence-animation-retiming.js +1 -1
  7. package/dist/effects/sequence/sequence-data.d.ts +9 -0
  8. package/dist/effects/sequence/sequence-data.js +1 -1
  9. package/dist/effects/sequence/sequence-player.d.ts +12 -1
  10. package/dist/effects/sequence/sequence-player.js +1 -1
  11. package/dist/effects/sequence/sequence-transform.d.ts +10 -0
  12. package/dist/effects/sequence/sequence-transform.js +4 -0
  13. package/dist/effects/sequence/sequence-value-lane.d.ts +2 -0
  14. package/dist/effects/sequence/sequence-value-lane.js +1 -1
  15. package/dist/effects/vfx/initializsers.d.ts +8 -1
  16. package/dist/effects/vfx/initializsers.js +1 -1
  17. package/dist/effects/vfx/vfx-actor.d.ts +5 -0
  18. package/dist/effects/vfx/vfx-actor.js +1 -1
  19. package/dist/effects/vfx/vfx-asset.d.ts +2 -1
  20. package/dist/effects/vfx/vfx-asset.js +1 -1
  21. package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
  22. package/dist/effects/vfx/vfx-defs.d.ts +10 -1
  23. package/dist/effects/vfx/vfx-defs.js +1 -1
  24. package/dist/effects/vfx/vfx-materializer.js +1 -1
  25. package/dist/effects/vfx/vfx-renderers.d.ts +2 -0
  26. package/dist/effects/vfx/vfx-renderers.js +1 -1
  27. package/dist/gameplay/actors/actor.d.ts +21 -1
  28. package/dist/gameplay/actors/actor.js +1 -1
  29. package/dist/gameplay/actors/builtin/components/character/character-animation.d.ts +3 -0
  30. package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
  31. package/dist/gameplay/actors/builtin/components/character/character-movement-like.d.ts +25 -0
  32. package/dist/gameplay/actors/builtin/components/character/character-movement-like.js +4 -0
  33. package/dist/gameplay/actors/builtin/components/character/character-movement-policy.d.ts +26 -0
  34. package/dist/gameplay/actors/builtin/components/character/character-movement-policy.js +4 -0
  35. package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +158 -55
  36. package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
  37. package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.d.ts +128 -0
  38. package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.js +4 -0
  39. package/dist/gameplay/actors/builtin/components/character/old-character-movement.d.ts +100 -0
  40. package/dist/gameplay/actors/builtin/components/character/old-character-movement.js +4 -0
  41. package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
  42. package/dist/gameplay/actors/builtin/components/index.js +1 -1
  43. package/dist/gameplay/actors/builtin/components/mesh-component.d.ts +1 -0
  44. package/dist/gameplay/actors/builtin/components/mesh-component.js +1 -1
  45. package/dist/gameplay/actors/builtin/components/tween-component.js +1 -1
  46. package/dist/gameplay/actors/builtin/navmesh-actor.d.ts +2 -0
  47. package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
  48. package/dist/gameplay/actors/builtin/trigger-volume.d.ts +3 -3
  49. package/dist/gameplay/actors/builtin/trigger-volume.js +1 -1
  50. package/dist/gameplay/actors/camera/camera-component.d.ts +1 -3
  51. package/dist/gameplay/actors/camera/camera-component.js +1 -1
  52. package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +3 -0
  53. package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
  54. package/dist/gameplay/actors/component.d.ts +3 -0
  55. package/dist/gameplay/actors/component.js +1 -1
  56. package/dist/gameplay/actors/controller/actor-controller.d.ts +16 -0
  57. package/dist/gameplay/actors/controller/actor-controller.js +4 -0
  58. package/dist/gameplay/actors/factory.d.ts +3 -0
  59. package/dist/gameplay/actors/factory.js +1 -1
  60. package/dist/gameplay/actors/index.d.ts +4 -0
  61. package/dist/gameplay/actors/index.js +1 -1
  62. package/dist/gameplay/actors/internal/component-init.js +1 -1
  63. package/dist/gameplay/actors/type-registry.d.ts +10 -0
  64. package/dist/gameplay/actors/type-registry.js +4 -0
  65. package/dist/gameplay/ai/behavior-tree/move.d.ts +2 -2
  66. package/dist/gameplay/animation/retarget.d.ts +50 -0
  67. package/dist/gameplay/animation/retarget.js +4 -0
  68. package/dist/gameplay/animation/root-motion.js +1 -1
  69. package/dist/gameplay/event-graph/actor-transform-properties.d.ts +6 -0
  70. package/dist/gameplay/event-graph/actor-transform-properties.js +4 -0
  71. package/dist/gameplay/event-graph/asset-actor-types.d.ts +3 -0
  72. package/dist/gameplay/event-graph/asset-actor-types.js +4 -0
  73. package/dist/gameplay/event-graph/asset-references.d.ts +12 -0
  74. package/dist/gameplay/event-graph/asset-references.js +4 -0
  75. package/dist/gameplay/event-graph/compiler.d.ts +107 -0
  76. package/dist/gameplay/event-graph/compiler.js +4 -0
  77. package/dist/gameplay/event-graph/decorators.d.ts +74 -0
  78. package/dist/gameplay/event-graph/decorators.js +4 -0
  79. package/dist/gameplay/event-graph/document-compiler.d.ts +107 -0
  80. package/dist/gameplay/event-graph/document-compiler.js +4 -0
  81. package/dist/gameplay/event-graph/event-graph-demo.d.ts +2 -0
  82. package/dist/gameplay/event-graph/event-graph-demo.js +4 -0
  83. package/dist/gameplay/event-graph/graph.d.ts +106 -0
  84. package/dist/gameplay/event-graph/graph.js +4 -0
  85. package/dist/gameplay/event-graph/index.d.ts +13 -0
  86. package/dist/gameplay/event-graph/index.js +4 -0
  87. package/dist/gameplay/event-graph/model.d.ts +71 -0
  88. package/dist/gameplay/event-graph/model.js +4 -0
  89. package/dist/gameplay/event-graph/nodes/execution-nodes.d.ts +115 -0
  90. package/dist/gameplay/event-graph/nodes/execution-nodes.js +4 -0
  91. package/dist/gameplay/event-graph/nodes/gameplay-nodes.d.ts +208 -0
  92. package/dist/gameplay/event-graph/nodes/gameplay-nodes.js +4 -0
  93. package/dist/gameplay/event-graph/nodes/index.d.ts +4 -0
  94. package/dist/gameplay/event-graph/nodes/index.js +4 -0
  95. package/dist/gameplay/event-graph/nodes/value-nodes.d.ts +53 -0
  96. package/dist/gameplay/event-graph/nodes/value-nodes.js +4 -0
  97. package/dist/gameplay/event-graph/registry.d.ts +33 -0
  98. package/dist/gameplay/event-graph/registry.js +4 -0
  99. package/dist/gameplay/event-graph/runtime-assets.d.ts +21 -0
  100. package/dist/gameplay/event-graph/runtime-assets.js +4 -0
  101. package/dist/gameplay/event-graph/runtime.d.ts +160 -0
  102. package/dist/gameplay/event-graph/runtime.js +4 -0
  103. package/dist/gameplay/event-graph/type-inference.d.ts +41 -0
  104. package/dist/gameplay/event-graph/type-inference.js +4 -0
  105. package/dist/gameplay/event-graph/types.d.ts +77 -0
  106. package/dist/gameplay/event-graph/types.js +4 -0
  107. package/dist/gameplay/index.d.ts +17 -2
  108. package/dist/gameplay/index.js +1 -1
  109. package/dist/gameplay/initiate.d.ts +4 -0
  110. package/dist/gameplay/initiate.js +1 -1
  111. package/dist/gameplay/input/input.d.ts +22 -17
  112. package/dist/gameplay/input/input.js +1 -1
  113. package/dist/gameplay/net/browser/index.d.ts +147 -0
  114. package/dist/gameplay/net/browser/index.js +4 -0
  115. package/dist/gameplay/net/index.d.ts +7 -0
  116. package/dist/gameplay/net/index.js +4 -0
  117. package/dist/gameplay/net/net-connection.d.ts +25 -0
  118. package/dist/gameplay/net/net-connection.js +4 -0
  119. package/dist/gameplay/net/net-session.d.ts +70 -0
  120. package/dist/gameplay/net/net-session.js +4 -0
  121. package/dist/gameplay/net/service/net-actor-role.d.ts +12 -0
  122. package/dist/gameplay/net/service/net-actor-role.js +4 -0
  123. package/dist/gameplay/net/service/net-decorator.d.ts +29 -0
  124. package/dist/gameplay/net/service/net-decorator.js +4 -0
  125. package/dist/gameplay/net/service/net-serializer.d.ts +15 -0
  126. package/dist/gameplay/net/service/net-serializer.js +4 -0
  127. package/dist/gameplay/net/service/net-service.d.ts +171 -0
  128. package/dist/gameplay/net/service/net-service.js +4 -0
  129. package/dist/gameplay/net/service/net-utils.d.ts +8 -0
  130. package/dist/gameplay/net/service/net-utils.js +4 -0
  131. package/dist/gameplay/net/service/replication.d.ts +31 -0
  132. package/dist/gameplay/net/service/replication.js +4 -0
  133. package/dist/gameplay/net/service/rpc-decorator.d.ts +21 -0
  134. package/dist/gameplay/net/service/rpc-decorator.js +4 -0
  135. package/dist/gameplay/net/service/rpc.d.ts +35 -0
  136. package/dist/gameplay/net/service/rpc.js +4 -0
  137. package/dist/gameplay/services/asset-loader.d.ts +10 -2
  138. package/dist/gameplay/services/asset-loader.js +1 -1
  139. package/dist/gameplay/services/physics/physics-system.d.ts +16 -1
  140. package/dist/gameplay/services/physics/physics-system.js +1 -1
  141. package/dist/gameplay/services/world.d.ts +25 -2
  142. package/dist/gameplay/services/world.js +1 -1
  143. package/dist/rendering/color-pass.js +1 -1
  144. package/dist/rendering.d.ts +2 -0
  145. package/dist/rendering.js +1 -1
  146. package/dist/scene/asset-resource-loader.d.ts +7 -1
  147. package/dist/scene/asset-resource-loader.js +1 -1
  148. package/dist/scene/batched-mesh-2.d.ts +9 -0
  149. package/dist/scene/batched-mesh-2.js +1 -1
  150. package/dist/scene/bootstrap.d.ts +2 -0
  151. package/dist/scene/bootstrap.js +1 -1
  152. package/dist/scene/custom-param-deserialize.js +1 -1
  153. package/dist/scene/custom-param-runtime-types.js +1 -1
  154. package/dist/scene/materializer.d.ts +29 -0
  155. package/dist/scene/materializer.js +1 -1
  156. package/dist/scene/model.d.ts +114 -2
  157. package/dist/scene/model.js +1 -1
  158. package/dist/scene/objects/prefab.js +1 -1
  159. package/dist/scene/storage/storage.d.ts +1 -1
  160. package/dist/scene/storage/storage.js +1 -1
  161. package/dist/shader/builtin/standard-shader.js +1 -1
  162. package/dist/shader/builtin/toon-shader.js +1 -1
  163. package/dist/shader/builtin/unlit-shader.js +1 -1
  164. package/dist/shader/color-layer.js +1 -1
  165. package/dist/shader/graph/compiler.d.ts +3 -0
  166. package/dist/shader/graph/compiler.js +1 -1
  167. package/dist/shader/graph/model.d.ts +1 -1
  168. package/dist/shader/graph/registry.js +1 -1
  169. package/dist/shader/parameter.d.ts +1 -1
  170. package/dist/shader/parameter.js +1 -1
  171. package/dist/shader-nodes/depth.js +1 -1
  172. package/dist/shader-nodes/scene-sample.js +1 -1
  173. package/dist/test/animation-retarget.test.d.ts +2 -0
  174. package/dist/test/animation-retarget.test.js +4 -0
  175. package/dist/test/batched-mesh-2.test.d.ts +2 -0
  176. package/dist/test/batched-mesh-2.test.js +4 -0
  177. package/dist/test/browser-net-session.test.d.ts +2 -0
  178. package/dist/test/browser-net-session.test.js +4 -0
  179. package/dist/test/event-graph-generated-code.test.d.ts +2 -0
  180. package/dist/test/event-graph-generated-code.test.js +4 -0
  181. package/dist/test/event-graph-types.test.d.ts +2 -0
  182. package/dist/test/event-graph-types.test.js +4 -0
  183. package/dist/test/event-graph.test.d.ts +2 -0
  184. package/dist/test/event-graph.test.js +4 -0
  185. package/dist/test/first-person-camera-component.test.js +1 -1
  186. package/dist/test/input.test.d.ts +2 -0
  187. package/dist/test/input.test.js +4 -0
  188. package/dist/test/net-character-movement.test.d.ts +2 -0
  189. package/dist/test/net-character-movement.test.js +4 -0
  190. package/dist/test/net-property-snapshot.test.d.ts +2 -0
  191. package/dist/test/net-property-snapshot.test.js +4 -0
  192. package/dist/test/prefab-instance-params.test.js +1 -1
  193. package/dist/test/sequence-animation-retiming.test.js +1 -1
  194. package/dist/test/sequence-camera-control.test.js +1 -1
  195. package/dist/test/sequence-scene-binding.test.d.ts +2 -0
  196. package/dist/test/sequence-scene-binding.test.js +4 -0
  197. package/dist/test/sequence-transform.test.d.ts +2 -0
  198. package/dist/test/sequence-transform.test.js +4 -0
  199. package/dist/test/shader-graph.test.js +1 -1
  200. package/dist/test/vfx-random-color-initializer.test.d.ts +2 -0
  201. package/dist/test/vfx-random-color-initializer.test.js +4 -0
  202. package/dist/test/world-prefab-spawn.test.d.ts +2 -0
  203. package/dist/test/world-prefab-spawn.test.js +4 -0
  204. package/dist/utils/three/placeholder-texture.d.ts +3 -0
  205. package/dist/utils/three/placeholder-texture.js +4 -0
  206. package/package.json +18 -2
  207. package/tsconfig.tsbuildinfo +1 -1
@@ -10,4 +10,5 @@ export * from './sequence-action.js';
10
10
  export * from './audio-parameters.js';
11
11
  export * from './sequence-value-lane.js';
12
12
  export * from './sequence-animation-retiming.js';
13
+ export * from './sequence-transform.js';
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,4 @@
1
- export*from"./sequence-data.js";export*from"./sequence-locator.js";export*from"./sequence-definitions.js";export*from"./sequence-event.js";export*from"./sequence-ops.js";export*from"./sequence-player.js";export*from"./sequence-actor.js";export*from"./sequencer.js";export*from"./sequence-action.js";export*from"./audio-parameters.js";export*from"./sequence-value-lane.js";export*from"./sequence-animation-retiming.js";/*
1
+ export*from"./sequence-data.js";export*from"./sequence-locator.js";export*from"./sequence-definitions.js";export*from"./sequence-event.js";export*from"./sequence-ops.js";export*from"./sequence-player.js";export*from"./sequence-actor.js";export*from"./sequencer.js";export*from"./sequence-action.js";export*from"./audio-parameters.js";export*from"./sequence-value-lane.js";export*from"./sequence-animation-retiming.js";export*from"./sequence-transform.js";/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -8,6 +8,11 @@ import { SequenceLocatorReader } from './sequence-locator.js';
8
8
  export interface SequenceAction extends SequenceLocatorReader {
9
9
  /** Bind a role to a runtime target for dynamic actor binding */
10
10
  bindRole(role: SequenceRole, target: BaseActor | Object3D): void;
11
+ /**
12
+ * Resolve and preload resources that depend on runtime role bindings.
13
+ * Call this before latency-sensitive playback after all roles are bound.
14
+ */
15
+ prepare(): Promise<void>;
11
16
  play(options?: SequencePlayOptions): void;
12
17
  pause(): void;
13
18
  cancel(): void;
@@ -97,6 +97,7 @@ export declare class SequenceActor extends BaseActor implements SequenceAction {
97
97
  private actorFactory;
98
98
  private vfxService;
99
99
  private sourceAsset;
100
+ private missingSceneTargets;
100
101
  onInit(): Promise<void>;
101
102
  /**
102
103
  * Load sequence data from an asset
@@ -110,6 +111,7 @@ export declare class SequenceActor extends BaseActor implements SequenceAction {
110
111
  * Update inline sequence data directly
111
112
  */
112
113
  setSequenceData(data: SequenceData): void;
114
+ applySceneParameters(parameters: Record<string, unknown>, changedParameters: ReadonlySet<string>): boolean;
113
115
  /**
114
116
  * Bind a role to a runtime target.
115
117
  * This allows tracks with a role to target a different actor at runtime.
@@ -119,6 +121,10 @@ export declare class SequenceActor extends BaseActor implements SequenceAction {
119
121
  * sequenceActor.bindRole(SequenceRole.Target, enemyActor)
120
122
  */
121
123
  bindRole(role: SequenceRole, target: BaseActor | Object3D): void;
124
+ /**
125
+ * Preload binding-dependent animation variants before latency-sensitive playback.
126
+ */
127
+ prepare(): Promise<void>;
122
128
  /**
123
129
  * Bind a scene object by ID to a target
124
130
  */
@@ -151,6 +157,7 @@ export declare class SequenceActor extends BaseActor implements SequenceAction {
151
157
  * Seek to a specific time
152
158
  */
153
159
  seek(time: number): void;
160
+ private refreshSceneBindings;
154
161
  /**
155
162
  * Refresh a specific asset used in the sequence
156
163
  */
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{Actor as s,BaseActor as r}from"../../gameplay/actors/actor.js";import{inject as a}from"../../gameplay/inject.js";import{ViewController as o}from"../../gameplay/services/render.js";import{AssetLoader as i}from"../../gameplay/services/asset-loader.js";import{World as l}from"../../gameplay/services/world.js";import{ActorFactory as n}from"../../gameplay/actors/factory.js";import{VfxService as p}from"../../effects/vfx/vfx-service.js";import{Parameter as c}from"../../shader/parameter.js";import{createSequenceData as h}from"./sequence-data.js";import{SequencePlayer as d,SequencePlaybackState as m}from"./sequence-player.js";import{Subject as y,takeUntil as u}from"rxjs";let b=class extends r{constructor(){super(...arguments),this.sequenceData=h(),this.sequenceAssetId=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.onComplete=new y,this.onLoop=new y,this.player=new d,this.viewController=a(o),this.assetLoader=a(i),this.world=a(l),this.actorFactory=a(n),this.vfxService=a(p),this.sourceAsset=null}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,this.player.cameraControlEnabled=e}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId=e,this.player.cameraControlTrackId=e}get timescale(){return this.player.timescale}set timescale(e){this.player.timescale=e}get loop(){return this.player.loop}set loop(e){this.player.loop=e}get state(){return this.player.state}get time(){return this.player.time}get duration(){return this.player.duration}get paused(){return this.player.state===m.Paused}get externalTimeControl(){return this.player.externalTimeControl}set externalTimeControl(e){this.player.externalTimeControl=e}get inEditor(){return this.player.inEditor}set inEditor(e){this.player.inEditor=e}async onInit(){this.player.setWorld(this.world),this.player.setViewController(this.viewController),this.player.setAudioListener(this.viewController.audioListener),this.player.setAssetLoader(this.assetLoader),this.player.setActorFactory(this.actorFactory),this.player.setVfxService(this.vfxService),this.viewController.onUpdate(this).pipe(u(this.disposed)).subscribe(e=>this.player.update(e)),this.player.onComplete.pipe(u(this.disposed)).subscribe(()=>this.onComplete.next()),this.player.onLoop.pipe(u(this.disposed)).subscribe(e=>this.onLoop.next(e)),this.sequenceAssetId?await this.loadFromAssetId(this.sequenceAssetId):this.sequenceData&&this.player.load(this.sequenceData)}async loadFromAsset(e){if("sequence"!==e.type)throw new Error(`Asset must be a sequence asset but is ${e.type}`);this.sourceAsset=e,this.sourceAsset.sequence&&(this.sequenceData=this.sourceAsset.sequence,this.player.load(this.sequenceData))}async loadFromAssetId(e){const t=await this.assetLoader.getAsset(e);t&&await this.loadFromAsset(t)}setSequenceData(e){this.sequenceData=e,this.player.load(e)}bindRole(e,t){this.player.bindRole(e,t)}bindObject(e,t){this.player.bindObject(e,t)}getLocator(e){return this.player.getLocator(e)}getLocators(e){return this.player.getLocators(e)}getActiveTrackObjects(e){return this.player.getActiveTrackObjects(e)}play(e){this.player.cameraControlEnabled=e?.cameraControlEnabled??this.cameraControlEnabled,this.player.play()}pause(){this.player.pause()}cancel(){this.player.cancel()}stop(){this.player.stop()}restart(){this.player.restart()}seek(e){this.player.seek(e)}refreshAsset(e){return this.player.refreshAsset(e)}onUpdate(e){}onEndPlay(){this.player.dispose()}dispose(){this.world.removeActor(this)}};e([c({label:"Sequence Data"}),t("design:type",Object)],b.prototype,"sequenceData",void 0),e([c({label:"Camera Control Enabled"}),t("design:type",Boolean),t("design:paramtypes",[Boolean])],b.prototype,"cameraControlEnabled",null),b=e([s()],b);export{b as SequenceActor};/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{Actor as s,BaseActor as r}from"../../gameplay/actors/actor.js";import{inject as a}from"../../gameplay/inject.js";import{ViewController as i}from"../../gameplay/services/render.js";import{AssetLoader as n}from"../../gameplay/services/asset-loader.js";import{World as o}from"../../gameplay/services/world.js";import{ActorFactory as l}from"../../gameplay/actors/factory.js";import{VfxService as p}from"../../effects/vfx/vfx-service.js";import{EventGraphCallable as c}from"../../gameplay/event-graph/decorators.js";import{EVENT_GRAPH_NUMBER_TYPE as h,EVENT_GRAPH_VOID_TYPE as d}from"../../gameplay/event-graph/types.js";import{SEQUENCE_ACTOR_TYPE_ID as m}from"../../gameplay/event-graph/asset-actor-types.js";import{Parameter as y}from"../../shader/parameter.js";import{createSequenceData as u}from"./sequence-data.js";import{SequencePlayer as g,SequencePlaybackState as b}from"./sequence-player.js";import{Subject as f,takeUntil as C}from"rxjs";let v=class extends r{constructor(){super(...arguments),this.sequenceData=u(),this.sequenceAssetId=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.onComplete=new f,this.onLoop=new f,this.player=new g,this.viewController=a(i),this.assetLoader=a(n),this.world=a(o),this.actorFactory=a(l),this.vfxService=a(p),this.sourceAsset=null,this.missingSceneTargets=new Set}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,this.player.cameraControlEnabled=e}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId=e,this.player.cameraControlTrackId=e}get timescale(){return this.player.timescale}set timescale(e){this.player.timescale=e}get loop(){return this.player.loop}set loop(e){this.player.loop=e}get state(){return this.player.state}get time(){return this.player.time}get duration(){return this.player.duration}get paused(){return this.player.state===b.Paused}get externalTimeControl(){return this.player.externalTimeControl}set externalTimeControl(e){this.player.externalTimeControl=e}get inEditor(){return this.player.inEditor}set inEditor(e){this.player.inEditor=e}async onInit(){this.player.setWorld(this.world),this.player.setViewController(this.viewController),this.player.setAudioListener(this.viewController.audioListener),this.player.setAssetLoader(this.assetLoader),this.player.setActorFactory(this.actorFactory),this.player.setVfxService(this.vfxService),this.viewController.onUpdate(this).pipe(C(this.disposed)).subscribe(e=>this.player.update(e)),this.player.onComplete.pipe(C(this.disposed)).subscribe(()=>this.onComplete.next()),this.player.onLoop.pipe(C(this.disposed)).subscribe(e=>this.onLoop.next(e)),this.sequenceAssetId?await this.loadFromAssetId(this.sequenceAssetId):this.sequenceData&&this.player.load(this.sequenceData),this.refreshSceneBindings()}async loadFromAsset(e){if("sequence"!==e.type)throw new Error(`Asset must be a sequence asset but is ${e.type}`);this.sourceAsset=e,this.sourceAsset.sequence&&(this.sequenceData=this.sourceAsset.sequence,this.player.load(this.sequenceData),this.missingSceneTargets.clear(),this.refreshSceneBindings())}async loadFromAssetId(e){const t=await this.assetLoader.getAsset(e);t&&await this.loadFromAsset(t)}setSequenceData(e){this.sequenceData=e,this.player.load(e),this.missingSceneTargets.clear(),this.refreshSceneBindings()}applySceneParameters(e,t){const s=new Set(["sequenceData","cameraControlEnabled"]);return![...t].some(e=>!s.has(e))&&(t.has("sequenceData")&&e.sequenceData&&this.setSequenceData(e.sequenceData),t.has("cameraControlEnabled")&&(this.cameraControlEnabled=Boolean(e.cameraControlEnabled)),!0)}bindRole(e,t){this.player.bindRole(e,t)}async prepare(){this.refreshSceneBindings(),await this.player.prepare()}bindObject(e,t){this.player.bindObject(e,t)}getLocator(e){return this.player.getLocator(e)}getLocators(e){return this.player.getLocators(e)}getActiveTrackObjects(e){return this.refreshSceneBindings(),this.player.getActiveTrackObjects(e)}play(e){this.refreshSceneBindings(),this.player.cameraControlEnabled=e?.cameraControlEnabled??this.cameraControlEnabled,this.player.play()}pause(){this.player.pause()}cancel(){this.player.cancel()}stop(){this.player.stop()}restart(){this.player.restart()}seek(e){this.refreshSceneBindings(),this.player.seek(e)}refreshSceneBindings(){for(const e of S(this.sequenceData?.tracks??[])){if("object"!==e.type||e.role||!e.targetId)continue;const t=this.world.resolveSceneActor(e.targetId);t?(this.player.bindObject(e.targetId,t),this.missingSceneTargets.delete(e.targetId)):(this.player.unbindObject(e.targetId),this.missingSceneTargets.has(e.targetId)||(console.warn(`Sequence "${this.object.name||this.__netSceneId||this.id}" could not resolve scene actor "${e.targetId}"`),this.missingSceneTargets.add(e.targetId)))}}refreshAsset(e){return this.player.refreshAsset(e)}onUpdate(e){}onEndPlay(){this.player.dispose()}dispose(){this.world.removeActor(this)}};e([y({label:"Sequence Data"}),t("design:type",Object)],v.prototype,"sequenceData",void 0),e([y({label:"Camera Control Enabled"}),t("design:type",Boolean),t("design:paramtypes",[Boolean])],v.prototype,"cameraControlEnabled",null),e([c({parameters:[],returns:d}),t("design:type",Function),t("design:paramtypes",[Object]),t("design:returntype",void 0)],v.prototype,"play",null),e([c({parameters:[],returns:d}),t("design:type",Function),t("design:paramtypes",[]),t("design:returntype",void 0)],v.prototype,"pause",null),e([c({parameters:[],returns:d}),t("design:type",Function),t("design:paramtypes",[]),t("design:returntype",void 0)],v.prototype,"cancel",null),e([c({parameters:[],returns:d}),t("design:type",Function),t("design:paramtypes",[]),t("design:returntype",void 0)],v.prototype,"stop",null),e([c({parameters:[],returns:d}),t("design:type",Function),t("design:paramtypes",[]),t("design:returntype",void 0)],v.prototype,"restart",null),e([c({parameters:[{name:"time",type:h}],returns:d}),t("design:type",Function),t("design:paramtypes",[Number]),t("design:returntype",void 0)],v.prototype,"seek",null),v=e([s({typeId:m})],v);export{v as SequenceActor};function S(e){const t=[];for(const s of e)t.push(s),"group"===s.type&&t.push(...S(s.childTracks));return t}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import*as t from"three";const i=1e-4;export const MAX_ANIMATION_CLIP_RETIME_POINTS=3;export function getAnimationClipRetimingMode(t){return t?.mode??"uniform"}export function isAnimationClipUsingRetiming(t){return"uniform"!==getAnimationClipRetimingMode(t.retiming)}export function normalizeAnimationClipRetiming(t){const e=getAnimationClipRetimingMode(t),r="impact"===e?1:3,s=(Array.isArray(t?.points)?t.points:[]).map((t,i)=>({id:"string"==typeof t?.id&&t.id.trim().length>0?t.id:`retime-${i}`,clipProgress:n(t?.clipProgress,.5),sourceProgress:n(t?.sourceProgress,.5)})).sort((t,i)=>t.clipProgress-i.clipProgress||t.sourceProgress-i.sourceProgress).slice(0,r),u=[];let c=0,l=0;for(let t=0;t<s.length;t++){const e=s[t],n=s.length-t-1,r=1-i*(n+1),m=o(e.clipProgress,c+i,r),a=o(e.sourceProgress,l+i,r);u.push({id:e.id,clipProgress:m,sourceProgress:a}),c=m,l=a}return{mode:e,points:u}}export function getAnimationClipRetimingControlPoints(t){return[{id:"retime-start",clipProgress:0,sourceProgress:0,implicit:!0},...normalizeAnimationClipRetiming(t).points.map(t=>({...t,implicit:!1})),{id:"retime-end",clipProgress:1,sourceProgress:1,implicit:!0}]}export function evaluateAnimationClipSourceProgress(t,i){return e(getAnimationClipRetimingControlPoints(t),r(i),"clipProgress","sourceProgress")}export function evaluateAnimationClipOutputProgress(t,i){return e(getAnimationClipRetimingControlPoints(t),r(i),"sourceProgress","clipProgress")}export function getAnimationClipRetimingSignature(t){const i=normalizeAnimationClipRetiming(t.retiming);return JSON.stringify({duration:u(t.duration),clipStartOffset:u(t.clipStartOffset),clipEndOffset:u(t.clipEndOffset),rootMotion:t.rootMotion,retiming:i})}export function buildRetimedAnimationClip(n,u){const l=Math.max(0,n.duration),m=o(u.clipStartOffset,0,l),a=o(l-u.clipEndOffset,m,l),p=Math.max(0,a-m),g=Math.max(i,u.duration),f=getAnimationClipRetimingControlPoints(u.retiming),P=n.tracks.map(t=>{const n=t.clone(),o=t.getValueSize(),u=function(t,n,o,u,c,l,m){const a=function(t,i,e){const n=new Set([s(i),s(e)]);for(const r of t.times)r>=i&&r<=e&&n.add(s(r));return[...n].sort((t,i)=>t-i)}(t,n,o);if(0===a.length)return{times:[],values:[]};const p=t.createInterpolant(),g=[],f=[];for(const t of a){const o=e(l,u<=i?0:r((t-n)/u),"sourceProgress","clipProgress");g.push(s(c*o));const a=p.evaluate(t);if(1===m&&!Array.isArray(a)&&"object"!=typeof a){f.push(a);continue}const P=Array.from(a);for(let t=0;t<m;t++)f.push(P[t]??P[P.length-1]??0)}if(1===g.length&&c>i){g.push(c);for(let t=0;t<m;t++)f.push(f[t])}return{times:g,values:f}}(t,m,a,p,g,f,o);if(0===u.times.length)return null;const l=n;return l.times=c(l.TimeBufferType,u.times),l.values=c(l.ValueBufferType,u.values),l}).filter(Boolean);return new t.AnimationClip(n.name,g,P,n.blendMode)}function e(t,e,n,o){const s=r(e);for(let e=1;e<t.length;e++){const u=t[e-1],c=t[e],l=c[n];if(s>l&&e<t.length-1)continue;const m=u[n],a=u[o],p=c[o],g=l-m;if(g<=i)return r(p);const f=r((s-m)/g);return r(a+(p-a)*f)}return r(t[t.length-1][o])}function n(t,i){return"number"==typeof t&&Number.isFinite(t)?t:i}function r(t){return o(t,0,1)}function o(t,i,e){return Math.min(Math.max(t,i),e)}function s(t){return Math.round(1e6*t)/1e6}function u(t){return Math.round(1e5*t)/1e5}function c(t,i){return t===Array?i.slice():new t(i)}/*
1
+ import*as t from"three";import{getAnimationClipRigId as i,setAnimationClipRigId as e}from"../../gameplay/animation/retarget.js";const n=1e-4;export const MAX_ANIMATION_CLIP_RETIME_POINTS=3;export function getAnimationClipRetimingMode(t){return t?.mode??"uniform"}export function isAnimationClipUsingRetiming(t){return"uniform"!==getAnimationClipRetimingMode(t.retiming)}export function normalizeAnimationClipRetiming(t){const i=getAnimationClipRetimingMode(t),e="impact"===i?1:3,r=(Array.isArray(t?.points)?t.points:[]).map((t,i)=>({id:"string"==typeof t?.id&&t.id.trim().length>0?t.id:`retime-${i}`,clipProgress:o(t?.clipProgress,.5),sourceProgress:o(t?.sourceProgress,.5)})).sort((t,i)=>t.clipProgress-i.clipProgress||t.sourceProgress-i.sourceProgress).slice(0,e),s=[];let c=0,l=0;for(let t=0;t<r.length;t++){const i=r[t],e=r.length-t-1,o=1-n*(e+1),a=u(i.clipProgress,c+n,o),m=u(i.sourceProgress,l+n,o);s.push({id:i.id,clipProgress:a,sourceProgress:m}),c=a,l=m}return{mode:i,points:s}}export function getAnimationClipRetimingControlPoints(t){return[{id:"retime-start",clipProgress:0,sourceProgress:0,implicit:!0},...normalizeAnimationClipRetiming(t).points.map(t=>({...t,implicit:!1})),{id:"retime-end",clipProgress:1,sourceProgress:1,implicit:!0}]}export function evaluateAnimationClipSourceProgress(t,i){return r(getAnimationClipRetimingControlPoints(t),s(i),"clipProgress","sourceProgress")}export function evaluateAnimationClipOutputProgress(t,i){return r(getAnimationClipRetimingControlPoints(t),s(i),"sourceProgress","clipProgress")}export function getAnimationClipRetimingSignature(t){const i=normalizeAnimationClipRetiming(t.retiming);return JSON.stringify({duration:l(t.duration),clipStartOffset:l(t.clipStartOffset),clipEndOffset:l(t.clipEndOffset),rootMotion:t.rootMotion,retiming:i})}export function buildRetimedAnimationClip(o,l){const m=Math.max(0,o.duration),p=u(l.clipStartOffset,0,m),g=u(m-l.clipEndOffset,p,m),f=Math.max(0,g-p),P=Math.max(n,l.duration),d=getAnimationClipRetimingControlPoints(l.retiming),A=o.tracks.map(t=>{const i=t.clone(),e=t.getValueSize(),o=function(t,i,e,o,u,l,a){const m=function(t,i,e){const n=new Set([c(i),c(e)]);for(const r of t.times)r>=i&&r<=e&&n.add(c(r));return[...n].sort((t,i)=>t-i)}(t,i,e);if(0===m.length)return{times:[],values:[]};const p=t.createInterpolant(),g=[],f=[];for(const t of m){const e=r(l,o<=n?0:s((t-i)/o),"sourceProgress","clipProgress");g.push(c(u*e));const m=p.evaluate(t);if(1===a&&!Array.isArray(m)&&"object"!=typeof m){f.push(m);continue}const P=Array.from(m);for(let t=0;t<a;t++)f.push(P[t]??P[P.length-1]??0)}if(1===g.length&&u>n){g.push(u);for(let t=0;t<a;t++)f.push(f[t])}return{times:g,values:f}}(t,p,g,f,P,d,e);if(0===o.times.length)return null;const u=i;return u.times=a(u.TimeBufferType,o.times),u.values=a(u.ValueBufferType,o.values),u}).filter(Boolean),h=new t.AnimationClip(o.name,P,A,o.blendMode);return e(h,i(o)),h}function r(t,i,e,r){const o=s(i);for(let i=1;i<t.length;i++){const u=t[i-1],c=t[i],l=c[e];if(o>l&&i<t.length-1)continue;const a=u[e],m=u[r],p=c[r],g=l-a;if(g<=n)return s(p);const f=s((o-a)/g);return s(m+(p-m)*f)}return s(t[t.length-1][r])}function o(t,i){return"number"==typeof t&&Number.isFinite(t)?t:i}function s(t){return u(t,0,1)}function u(t,i,e){return Math.min(Math.max(t,i),e)}function c(t){return Math.round(1e6*t)/1e6}function l(t){return Math.round(1e5*t)/1e5}function a(t,i){return t===Array?i.slice():new t(i)}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -55,6 +55,7 @@ export declare class Sequence {
55
55
  data: SequenceData;
56
56
  constructor(data: SequenceData);
57
57
  }
58
+ export declare function isSequenceData(value: unknown): value is SequenceData;
58
59
  /**
59
60
  * Predefined roles for binding actors to sequence tracks at runtime.
60
61
  * Used for abilities, combat sequences, and cinematics where actors
@@ -370,6 +371,7 @@ export interface AnimationClipRetiming {
370
371
  * Interpolation mode for keyframes
371
372
  */
372
373
  export type InterpolationMode = 'linear' | 'step' | 'cubic' | 'catmullRom';
374
+ export type TransformPositionTangentMode = 'auto' | 'aligned' | 'broken';
373
375
  /**
374
376
  * Transform keyframe - stores position, rotation, and scale at a specific time
375
377
  */
@@ -380,6 +382,12 @@ export interface TransformKeyframe {
380
382
  time: number;
381
383
  /** Position [x, y, z] */
382
384
  position?: [number, number, number];
385
+ /** How position tangents are resolved for cubic interpolation. */
386
+ positionTangentMode?: TransformPositionTangentMode;
387
+ /** Incoming position velocity in local units per second. */
388
+ positionInTangent?: [number, number, number];
389
+ /** Outgoing position velocity in local units per second. */
390
+ positionOutTangent?: [number, number, number];
383
391
  /** Rotation in euler angles [x, y, z] */
384
392
  rotation?: [number, number, number];
385
393
  /** Scale [x, y, z] */
@@ -571,6 +579,7 @@ export interface SequenceEventData {
571
579
  * Creates a new empty sequence data structure
572
580
  */
573
581
  export declare function createSequenceData(): SequenceData;
582
+ export declare function remapSequenceObjectTrackTargets(data: SequenceData, remappedIds: ReadonlyMap<string, string>): void;
574
583
  /**
575
584
  * Creates a new object track
576
585
  */
@@ -1,4 +1,4 @@
1
- import{SerializedParamType as e}from"../../scene/model.js";import{randomString as t}from"../../utils/math.js";import{getAudioParameterDefinition as r}from"./audio-parameters.js";export class Sequence{constructor(e){this.data=e}}export var SequenceRole;!function(e){e.Self="self",e.Target="target",e.Target2="target2",e.Target3="target3",e.Secondary="secondary"}(SequenceRole||(SequenceRole={}));export function createSequenceData(){return{duration:5,loop:!1,playbackRate:1,tracks:[]}}export function createObjectTrack(e="Object Track"){return{id:t(),name:e,type:"object",muted:!1,locked:!1,targetId:null,role:null,subTracks:[]}}export function createCameraTrack(e="Camera Track"){return{id:t(),name:e,type:"camera",muted:!1,locked:!1,parentRole:null,clips:[],cameraSettings:{fov:60,near:.1,far:1e3},subTracks:[]}}export function createCameraShakeTrack(e="Camera Shake"){return{id:t(),name:e,type:"cameraShake",muted:!1,locked:!1,clips:[],subTracks:[]}}export function createPostProcessTrack(e="Post Process"){return{id:t(),name:e,type:"postProcess",muted:!1,locked:!1,clips:[],stage:"beforeOutput",priority:0,subTracks:[]}}export function createCameraClipInstance(e,r){return{id:t(),startTime:e,duration:r,blendInDuration:.2,blendOutDuration:.2,blendInterpolation:"cubic"}}export function createCameraShakeClipInstance(e,r){return{id:t(),startTime:e,duration:r,attack:0,decay:Math.min(Math.max(.35*r,.05),Math.max(r,.05)),frequency:24,positionAmplitude:[0,0,.12],rotationAmplitude:[.015,.02,.01]}}export function createPostProcessClipInstance(e,r){return{id:t(),shaderGraphAssetId:null,shaderGraphParams:{},startTime:e,duration:r,fadeInDuration:Math.min(.15,Math.max(.25*r,0)),fadeOutDuration:Math.min(.15,Math.max(.25*r,0))}}export function createAudioTrack(e="Audio Track"){return{id:t(),name:e,type:"audio",muted:!1,locked:!1,clips:[],subTracks:[],volume:1,spatial:!1}}export function createVfxTrack(e="VFX Track"){return{id:t(),name:e,type:"vfx",muted:!1,locked:!1,clips:[],position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],subTracks:[]}}export function createSpawnTrack(e="Spawn Track"){return{id:t(),name:e,type:"spawn",muted:!1,locked:!1,spawnType:"mesh",role:null,clips:[],subTracks:[]}}export function createSpawnClipInstance(e,r){return{id:t(),startTime:e,duration:r}}export function createGroupTrack(e="Group"){return{id:t(),name:e,type:"group",muted:!1,locked:!1,collapsed:!1,childTracks:[],subTracks:[]}}export function createTransformSubTrack(){return{id:t(),name:"Transform",type:"transform",muted:!1,components:{position:!0,rotation:!0,scale:!0},keyframes:[]}}export function createAnimationSubTrack(e="Animation"){return{id:t(),name:e,type:"animation",muted:!1,clips:[]}}export function createAudioParameterSubTrack(e="volume"){const a=r(e);return{id:t(),name:a.displayName,type:"audioParameter",muted:!1,parameter:e,keyframes:[]}}export function createPropertySubTrack(r="",a=e.Number){const n="string"==typeof r?{propertyPath:r,propertyType:a}:r;return{id:t(),name:n.name??n.label??n.propertyPath??"Property",type:"property",muted:!1,propertyPath:n.propertyPath,propertyType:n.propertyType,label:n.label,group:n.group,help:n.help,range:n.range,precision:n.precision,stepSize:n.stepSize,options:n.options,editorInput:n.editorInput,defaultValue:n.defaultValue,keyframes:[]}}export function createMaterialSubTrack(e){const r=e.materialMatchMode??(e.materialAssetId?"asset":"parameterName");return{id:t(),name:e.name??e.label??e.parameterName??"Material",type:"material",muted:!1,materialMatchMode:r,materialAssetId:e.materialAssetId??null,parameterName:e.parameterName,uniformName:e.uniformName,uniformType:e.uniformType,valueType:e.valueType,label:e.label,group:e.group,help:e.help,range:e.range,precision:e.precision,stepSize:e.stepSize,defaultValue:e.defaultValue,keyframes:[]}}export function getMaterialSubTrackMatchMode(e){return e.materialMatchMode??(e.materialAssetId?"asset":"parameterName")}export function createVisibilitySubTrack(e="Visibility"){return{id:t(),name:e,type:"visibility",muted:!1,keyframes:[]}}export function createTransformKeyframe(e){return{id:t(),time:e,position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],interpolation:"cubic"}}export function createPropertyKeyframe(r,a={type:e.Number,value:0}){return{id:t(),time:r,value:a,interpolation:"linear"}}export function createAnimationClipInstance(e,r,a){return{id:t(),animationClipAssetId:e,startTime:r,duration:a,clipStartOffset:0,clipEndOffset:0,playbackRate:1,fadeInDuration:.2,retiming:void 0,rootMotion:!1}}export function createAnimationClipRetimingPoint(e=.35,r=.55){return{id:t(),clipProgress:e,sourceProgress:r}}export function createAnimationClipRetiming(e="impact",t=("uniform"===e?[]:[createAnimationClipRetimingPoint()])){return{mode:e,points:t}}export function createAudioClipInstance(e,r,a){return{id:t(),audioAssetId:e,startTime:r,duration:a,clipStartOffset:0,playbackRate:1,volume:1,fadeInDuration:0,fadeOutDuration:0,volumeRandomization:0,pitchRandomization:0}}export function createVfxClipInstance(e,r,a){return{id:t(),vfxAssetId:e,startTime:r,duration:a,endBehavior:"finish",expireWithinSeconds:.25}}export function createEventSubTrack(e="Events"){return{id:t(),name:e,type:"event",muted:!1,events:[]}}export function createSequenceEventData(e,r=""){return{id:t(),time:e,editorOnly:!1,functionName:r,arguments:[]}}export function createLocatorTrack(e="Locator"){return{id:t(),name:e,type:"locator",muted:!1,locked:!1,subTracks:[]}}/*
1
+ import{SerializedParamType as e}from"../../scene/model.js";import{randomString as t}from"../../utils/math.js";import{getAudioParameterDefinition as r}from"./audio-parameters.js";export class Sequence{constructor(e){this.data=e}}export function isSequenceData(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"number"==typeof e.duration&&Array.isArray(e.tracks)}export var SequenceRole;!function(e){e.Self="self",e.Target="target",e.Target2="target2",e.Target3="target3",e.Secondary="secondary"}(SequenceRole||(SequenceRole={}));export function createSequenceData(){return{duration:5,loop:!1,playbackRate:1,tracks:[]}}export function remapSequenceObjectTrackTargets(e,t){a(e.tracks,t)}function a(e,t){for(const r of e)"object"===r.type&&r.targetId&&(r.targetId=t.get(r.targetId)??r.targetId),"group"===r.type&&a(r.childTracks,t)}export function createObjectTrack(e="Object Track"){return{id:t(),name:e,type:"object",muted:!1,locked:!1,targetId:null,role:null,subTracks:[]}}export function createCameraTrack(e="Camera Track"){return{id:t(),name:e,type:"camera",muted:!1,locked:!1,parentRole:null,clips:[],cameraSettings:{fov:60,near:.1,far:1e3},subTracks:[]}}export function createCameraShakeTrack(e="Camera Shake"){return{id:t(),name:e,type:"cameraShake",muted:!1,locked:!1,clips:[],subTracks:[]}}export function createPostProcessTrack(e="Post Process"){return{id:t(),name:e,type:"postProcess",muted:!1,locked:!1,clips:[],stage:"beforeOutput",priority:0,subTracks:[]}}export function createCameraClipInstance(e,r){return{id:t(),startTime:e,duration:r,blendInDuration:.2,blendOutDuration:.2,blendInterpolation:"cubic"}}export function createCameraShakeClipInstance(e,r){return{id:t(),startTime:e,duration:r,attack:0,decay:Math.min(Math.max(.35*r,.05),Math.max(r,.05)),frequency:24,positionAmplitude:[0,0,.12],rotationAmplitude:[.015,.02,.01]}}export function createPostProcessClipInstance(e,r){return{id:t(),shaderGraphAssetId:null,shaderGraphParams:{},startTime:e,duration:r,fadeInDuration:Math.min(.15,Math.max(.25*r,0)),fadeOutDuration:Math.min(.15,Math.max(.25*r,0))}}export function createAudioTrack(e="Audio Track"){return{id:t(),name:e,type:"audio",muted:!1,locked:!1,clips:[],subTracks:[],volume:1,spatial:!1}}export function createVfxTrack(e="VFX Track"){return{id:t(),name:e,type:"vfx",muted:!1,locked:!1,clips:[],position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],subTracks:[]}}export function createSpawnTrack(e="Spawn Track"){return{id:t(),name:e,type:"spawn",muted:!1,locked:!1,spawnType:"mesh",role:null,clips:[],subTracks:[]}}export function createSpawnClipInstance(e,r){return{id:t(),startTime:e,duration:r}}export function createGroupTrack(e="Group"){return{id:t(),name:e,type:"group",muted:!1,locked:!1,collapsed:!1,childTracks:[],subTracks:[]}}export function createTransformSubTrack(){return{id:t(),name:"Transform",type:"transform",muted:!1,components:{position:!0,rotation:!0,scale:!0},keyframes:[]}}export function createAnimationSubTrack(e="Animation"){return{id:t(),name:e,type:"animation",muted:!1,clips:[]}}export function createAudioParameterSubTrack(e="volume"){const a=r(e);return{id:t(),name:a.displayName,type:"audioParameter",muted:!1,parameter:e,keyframes:[]}}export function createPropertySubTrack(r="",a=e.Number){const n="string"==typeof r?{propertyPath:r,propertyType:a}:r;return{id:t(),name:n.name??n.label??n.propertyPath??"Property",type:"property",muted:!1,propertyPath:n.propertyPath,propertyType:n.propertyType,label:n.label,group:n.group,help:n.help,range:n.range,precision:n.precision,stepSize:n.stepSize,options:n.options,editorInput:n.editorInput,defaultValue:n.defaultValue,keyframes:[]}}export function createMaterialSubTrack(e){const r=e.materialMatchMode??(e.materialAssetId?"asset":"parameterName");return{id:t(),name:e.name??e.label??e.parameterName??"Material",type:"material",muted:!1,materialMatchMode:r,materialAssetId:e.materialAssetId??null,parameterName:e.parameterName,uniformName:e.uniformName,uniformType:e.uniformType,valueType:e.valueType,label:e.label,group:e.group,help:e.help,range:e.range,precision:e.precision,stepSize:e.stepSize,defaultValue:e.defaultValue,keyframes:[]}}export function getMaterialSubTrackMatchMode(e){return e.materialMatchMode??(e.materialAssetId?"asset":"parameterName")}export function createVisibilitySubTrack(e="Visibility"){return{id:t(),name:e,type:"visibility",muted:!1,keyframes:[]}}export function createTransformKeyframe(e){return{id:t(),time:e,position:[0,0,0],positionTangentMode:"auto",rotation:[0,0,0],scale:[1,1,1],interpolation:"cubic"}}export function createPropertyKeyframe(r,a={type:e.Number,value:0}){return{id:t(),time:r,value:a,interpolation:"linear"}}export function createAnimationClipInstance(e,r,a){return{id:t(),animationClipAssetId:e,startTime:r,duration:a,clipStartOffset:0,clipEndOffset:0,playbackRate:1,fadeInDuration:.2,retiming:void 0,rootMotion:!1}}export function createAnimationClipRetimingPoint(e=.35,r=.55){return{id:t(),clipProgress:e,sourceProgress:r}}export function createAnimationClipRetiming(e="impact",t=("uniform"===e?[]:[createAnimationClipRetimingPoint()])){return{mode:e,points:t}}export function createAudioClipInstance(e,r,a){return{id:t(),audioAssetId:e,startTime:r,duration:a,clipStartOffset:0,playbackRate:1,volume:1,fadeInDuration:0,fadeOutDuration:0,volumeRandomization:0,pitchRandomization:0}}export function createVfxClipInstance(e,r,a){return{id:t(),vfxAssetId:e,startTime:r,duration:a,endBehavior:"finish",expireWithinSeconds:.25}}export function createEventSubTrack(e="Events"){return{id:t(),name:e,type:"event",muted:!1,events:[]}}export function createSequenceEventData(e,r=""){return{id:t(),time:e,editorOnly:!1,functionName:r,arguments:[]}}export function createLocatorTrack(e="Locator"){return{id:t(),name:e,type:"locator",muted:!1,locked:!1,subTracks:[]}}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -221,8 +221,12 @@ export declare class SequencePlayer implements SequenceLocatorReader {
221
221
  private preloadSequenceResources;
222
222
  private getAudioAssetIdsForSequence;
223
223
  private preloadAudioBuffersForSequence;
224
- private getAnimationClipAssetIdsForSequence;
225
224
  private preloadAnimationClipsForSequence;
225
+ /**
226
+ * Resolve and preload animation variants after role/spawn targets are known.
227
+ */
228
+ prepare(): Promise<void>;
229
+ private prepareAnimationClipsForBindings;
226
230
  /**
227
231
  * Bind a role to a runtime target.
228
232
  * This allows tracks with a role to target a different actor at runtime.
@@ -236,6 +240,10 @@ export declare class SequencePlayer implements SequenceLocatorReader {
236
240
  * Bind a scene object by ID to a target
237
241
  */
238
242
  bindObject(objectId: string, target: Object3D | BaseActor): void;
243
+ /**
244
+ * Remove scene object bindings while retaining role and sequence-owned bindings.
245
+ */
246
+ unbindObject(objectId: string): void;
239
247
  getLocator(bindingId: string): SequenceLocatorSnapshot | null;
240
248
  getLocators(bindingId: string): SequenceLocatorSnapshot[];
241
249
  /**
@@ -248,6 +256,8 @@ export declare class SequencePlayer implements SequenceLocatorReader {
248
256
  private disableLocatorInteraction;
249
257
  private resolveTrackBinding;
250
258
  private createBinding;
259
+ private removeBinding;
260
+ private releaseBinding;
251
261
  /**
252
262
  * Start or resume playback
253
263
  */
@@ -422,6 +432,7 @@ export declare class SequencePlayer implements SequenceLocatorReader {
422
432
  private applyResolvedMaterialValue;
423
433
  private getMaterialSlotResolutions;
424
434
  private ensureSequenceControlledMaterial;
435
+ private animationClipCacheKey;
425
436
  private ensureAnimationClip;
426
437
  private prepareAnimationPlayback;
427
438
  private getPlayableAnimationClip;
@@ -1,4 +1,4 @@
1
- import{BehaviorSubject as e,Subject as t}from"rxjs";import*as a from"three";import{AnimationMixer as s,Color as r,Euler as i,Object3D as n,Quaternion as o,Vector2 as l,Vector3 as c,Vector4 as h}from"three";import{VisualEffect as u}from"../../effects/vfx/vfx-param.js";import{BaseActor as p}from"../../gameplay/actors/actor.js";import d from"../../gameplay/actors/builtin/index.js";import{Prefab as f,PrefabOf as m}from"../../scene/objects/prefab.js";import{SerializedParamType as y}from"../../scene/model.js";import{customParamValueNeedsAsyncResolution as C,deserializeCustomParamValue as v,deserializeCustomParamValueSync as g}from"../../scene/custom-param-deserialize.js";import{getAudioParameterDefinition as A}from"./audio-parameters.js";import{getMaterialSubTrackMatchMode as S,Sequence as w}from"./sequence-data.js";import{getSequenceSubTrackDefinition as P,getSequenceTrackDefinition as b}from"./sequence-definitions.js";import{applyInterpolation as k,evaluateCustomParamValueKeyframes as x,evaluateNumericKeyframes as T,findKeyframeSpan as I}from"./sequence-value-lane.js";import{buildRetimedAnimationClip as M,getAnimationClipRetimingSignature as q,isAnimationClipUsingRetiming as B}from"./sequence-animation-retiming.js";import{SkeletonUtils as O}from"three-stdlib";import{CharacterAnimationComponent as F,CharacterMovementComponent as E}from"../../gameplay/actors/index.js";import{RootMotionClip as j}from"../../gameplay/animation/root-motion.js";import{hashCameraShakeSeed as L}from"../../gameplay/services/camera-shake.js";import{buildShaderGraphPostProcessMaterial as _,shaderGraphPostProcessWeightUniformName as R}from"../../shader/graph/index.js";export var SequencePlaybackState;!function(e){e.Stopped="stopped",e.Playing="playing",e.Paused="paused"}(SequencePlaybackState||(SequencePlaybackState={}));export class SequencePlayer{constructor(){this._state=new e(SequencePlaybackState.Stopped),this._time=new e(0),this._duration=0,this._timescale=1,this._loop=!1,this._externalTimeControl=!1,this._inEditor=!1,this.bindings=new Map,this.roleBindings=new Map,this.sequenceData=null,this.onComplete=new t,this.onLoop=new t,this.onTimeUpdate=this._time.asObservable(),this.onStateChange=this._state.asObservable(),this.loopCount=0,this.viewController=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.sequenceCameras=new Map,this.cameraPlayables=new Map,this.cameraBlendCamera=null,this.cameraBlendSource=null,this.cameraBlendOutSource=null,this.cameraOverrideHandle=null,this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null,this.activeCameraShakeClipKeys=new Set,this.nextCameraShakeClipKeys=new Set,this.activePostProcessClips=new Map,this.nextPostProcessClipKeys=new Set,this.audioListener=null,this.audioBuffers=new Map,this.loadingAudioBuffers=new Map,this.animationClips=new Map,this.loadingAnimationClips=new Map,this.retimedAnimationClips=new Map,this.audioByClip=new Map,this.activeAudioClips=new Set,this.audioGainNodes=new Map,this.audioStartInFlight=new Map,this.lastAudioStartAttemptTime=new Map,this.audioStartRetryIntervalSeconds=.25,this.world=null,this.assetLoader=null,this.actorFactory=null,this.vfxService=null,this.spawnedInstances=new Map,this.activeClips=new Set,this.pendingSpawns=new Set,this.vfxActors=new Map,this.activeVfxClips=new Set,this.locatorMarkers=new Map,this.clearCounter=0,this.propertyPathSegments=new Map,this.propertyResolutionCache=new Map,this.propertySnapshots=new Map,this.materialResolutionCache=new Map,this.materialSnapshots=new Map,this.audioFilters=new Map,this.audioPannerNodes=new Map,this.firedEvents=new Set,this.sequenceEventSyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e)},this.sequenceEventAsyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e),texture:e=>this.assetLoader?.getTextureByAssetId(e)??null,sampler2DNode:e=>this.assetLoader?.getTextureByAssetId(e)??null,object3D:async e=>{const t=await(this.assetLoader?.getModelByAssetId(e));return t?.scene??null},material:e=>this.assetLoader?.getMaterialByAssetId(e)??null,audioBuffer:e=>this.assetLoader?.getAudioByAssetId(e)??null,visualEffect:async e=>{if(!this.assetLoader||!this.actorFactory)return null;const t=await this.assetLoader.getAsset(e);return t?new u(this.actorFactory,t):null},prefab:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new f(t.asset):null},prefabActor:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new m(new f(t.asset)):null},sequence:e=>this.resolveSequenceEventSequence(e),animationClip:e=>this.resolveSequenceEventAnimationClip(e)},this.trackRuntimeEvaluators={object:(e,t,a)=>{t&&this.evaluateObjectTrack(e,t,a)},locator:(e,t,a)=>{t&&this.evaluateLocatorTrack(e,t,a)},camera:(e,t,a)=>this.evaluateCameraTrack(e,a),cameraShake:(e,t,a)=>this.evaluateCameraShakeTrack(e,a),postProcess:(e,t,a)=>this.evaluatePostProcessTrack(e,a),audio:(e,t,a)=>this.evaluateAudioTrack(e,a),vfx:(e,t,a)=>this.evaluateVfxTrack(e,a),spawn:(e,t,a)=>this.evaluateSpawnTrack(e,t,a),group:(e,t,a)=>{if("group"===e.type)for(const t of e.childTracks)this.evaluateTrack(t,a)}},this.subTrackRuntimeEvaluators={transform:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateTransformSubTrack(e,s,a)},animation:(e,t,a)=>this.evaluateAnimationSubTrack(e,t,a),visibility:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateVisibilitySubTrack(e,s,a)},parameter:(e,t,a)=>this.evaluateParameterSubTrack(e,t.target||null,a),event:(e,t,a)=>this.evaluateEventSubTrack(e,t.target||null,a)}}get state(){return this._state.value}get time(){return this._time.value}get duration(){return this._duration}get timescale(){return this._timescale}set timescale(e){this._timescale=Math.max(.01,e)}get loop(){return this._loop}set loop(e){this._loop=e}get externalTimeControl(){return this._externalTimeControl}set externalTimeControl(e){this._externalTimeControl=e}get inEditor(){return this._inEditor}set inEditor(e){this._inEditor=e,this.updateLocatorMarkerVisibility()}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,e||this.releaseCameraOverride()}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId!==e&&(this._cameraControlTrackId=e,this.releaseCameraOverride())}setViewController(e){this.viewController&&this.viewController!==e&&this.viewController.clearCameraShakeContributionsForOwner(this),this.viewController=e}setWorld(e){this.world!==e&&(this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.world=e,this.clearCounter++,this.vfxActors.clear(),this.spawnedInstances.clear(),this.bindings.clear(),this.activeClips.clear(),this.activeVfxClips.clear(),this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear(),this.loadingAudioBuffers.clear(),this.audioFilters.clear(),this.audioPannerNodes.clear(),this.pendingSpawns.clear(),this.propertyResolutionCache.clear(),this.materialResolutionCache.clear(),this.clearRetimedAnimationClipCache(),this._state.next(SequencePlaybackState.Stopped),this.sequenceData&&this.initializeLocatorBindings())}setAudioListener(e){this.audioListener=e}setAssetLoader(e){if(this.assetLoader=e,this.sequenceData){const e=this.clearCounter;this.preloadSequenceResources(this.sequenceData,e)}}setActorFactory(e){this.actorFactory=e}setVfxService(e){this.vfxService=e}load(e){if(this.stop(),this.clearCounter++,this.clearLocatorBindings(),this.clearSequenceCameras(),this.sequenceData=e,this._duration=e.duration,this._loop=e.loop,this._timescale=e.playbackRate,this.clearRetimedAnimationClipCache(),this.bindings.clear(),this.initializeLocatorBindings(),this.loopCount=0,this.assetLoader){const t=this.clearCounter;this.preloadSequenceResources(e,t)}}preloadSequenceResources(e,t){return Promise.all([this.preloadAudioBuffersForSequence(e,t),this.preloadAnimationClipsForSequence(e,t)]).then(()=>{})}getAudioAssetIdsForSequence(e){const t=new Set;for(const a of e.tracks){if("audio"!==a.type)continue;const e=a;for(const a of e.clips??[])a.audioAssetId&&t.add(a.audioAssetId)}return[...t]}async preloadAudioBuffersForSequence(e,t){if(!this.assetLoader)return;const a=this.getAudioAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{if(t!==this.clearCounter)return;if(this.audioBuffers.has(e))return;let a=this.loadingAudioBuffers.get(e);a||(a=this.assetLoader.getAudioByAssetId(e),this.loadingAudioBuffers.set(e,a));try{const s=await a;if(t!==this.clearCounter)return;this.audioBuffers.set(e,s)}catch(e){}finally{this.loadingAudioBuffers.get(e)===a&&this.loadingAudioBuffers.delete(e)}}))}getAnimationClipAssetIdsForSequence(e){const t=new Set;for(const a of H(e.tracks))if("subTracks"in a)for(const e of a.subTracks)if("animation"===e.type)for(const a of e.clips)a.animationClipAssetId&&t.add(a.animationClipAssetId);return[...t]}async preloadAnimationClipsForSequence(e,t){if(!this.assetLoader)return;const a=this.getAnimationClipAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{t===this.clearCounter&&await this.ensureAnimationClip(e)}))}bindRole(e,t){this.roleBindings.set(e,t),this.sequenceData&&this.resolveBindings()}bindObject(e,t){if(this.sequenceData)for(const a of this.sequenceData.tracks)"object"===a.type&&a.targetId===e&&this.createBinding(a,t)}getLocator(e){return this.getLocators(e)[0]??null}getLocators(e){const t=J(e);if(!t||!this.sequenceData)return[];const a=[];for(const e of H(this.sequenceData.tracks)){if("locator"!==e.type)continue;if(J(e.bindingId)!==t)continue;const s=this.bindings.get(e.id),r=s?this.getPlayableObject(s):null;r&&(r.updateWorldMatrix(!0,!1),a.push({trackId:e.id,name:e.name,bindingId:e.bindingId,position:r.getWorldPosition(new c),rotation:r.getWorldQuaternion(new o),scale:r.getWorldScale(new c)}))}return a}resolveBindings(){if(this.sequenceData)for(const e of this.sequenceData.tracks)this.resolveTrackBinding(e)}initializeLocatorBindings(){if(this.sequenceData)for(const e of H(this.sequenceData.tracks)){if("locator"!==e.type||this.bindings.has(e.id))continue;const t=new n;t.name=e.name||"Locator",t.userData.sequenceLocatorTrackId=e.id,this.world?.scene&&null==t.parent&&this.world.scene.add(t);const a=ee(e.name);a.visible=this._inEditor,t.add(a),this.locatorMarkers.set(e.id,a),this.disableLocatorInteraction(t),this.createBinding(e,t)}}clearLocatorBindings(){for(const e of this.locatorMarkers.values())te(e);for(const e of this.bindings.values()){if("locator"!==e.track.type)continue;const t=this.getPlayableObject(e);t?.parent&&t.removeFromParent()}this.locatorMarkers.clear()}updateLocatorMarkerVisibility(){for(const e of this.locatorMarkers.values())e.visible=this._inEditor}disableLocatorInteraction(e){e.traverse(e=>{e.raycast=()=>{}})}resolveTrackBinding(e){if("object"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("spawn"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("group"===e.type)for(const t of e.childTracks)this.resolveTrackBinding(t)}createBinding(e,t){const a=t instanceof p?t.object:t,r=this.bindings.get(e.id),i=null!=r?r.target instanceof p?r.target.object:r.target:null,n=null!=r&&r.target===t&&i===a,o=e.subTracks.some(e=>"animation"===e.type);if(null!=r&&!n){for(const e of r.activeActions.values())e.stop();r.activeActions.clear(),r.mixer?.stopAllAction(),r.charAnimComponent?.stopSequenceAnimation(),r.charAnimComponent=void 0,r.charAnimActionKeys?.clear()}const l=n?r:{track:e,target:t,activeActions:new Map};l.track=e,l.target=t,l.originalTransform={position:a.position.clone(),rotation:a.rotation.clone(),scale:a.scale.clone()},l.originalParent=a.parent,o&&null==l.mixer?l.mixer=new s(a):o||(l.mixer=void 0),this.bindings.set(e.id,l)}play(){this._state.value!==SequencePlaybackState.Playing&&this.sequenceData&&(this._state.value===SequencePlaybackState.Stopped&&(this._time.next(0),this.loopCount=0,this.resolveBindings(),this.captureOriginalTransforms()),this._state.next(SequencePlaybackState.Playing),this.evaluate(this._time.value),this.resumeVfx())}pause(){this._state.value===SequencePlaybackState.Playing&&(this._state.next(SequencePlaybackState.Paused),this.pauseAudio(),this.pauseVfx())}pauseAudio(){for(const e of this.audioByClip.values())e.pause()}pauseVfx(){for(const e of this.vfxActors.values())e.pause()}resumeVfx(){for(const[e,t]of this.vfxActors.entries())(this.activeVfxClips.has(e)||t.getParticleCount()>0)&&t.play()}cancel(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}stop(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreOriginalTransforms(),this.restoreOriginalParents(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}restart(){this.stop(),this.play()}seek(e){const t=Math.max(0,Math.min(e,this._duration));t<this._time.value&&this.resetVfxForTimeReset(t),this._time.next(t),this.evaluate(t)}update(e){if(this._state.value!==SequencePlaybackState.Playing)return;if(!this.sequenceData)return;if(this._externalTimeControl){for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale);return}const t=this._time.value+e*this._timescale;if(t>=this._duration){if(!this._loop)return this._time.next(this._duration),this.evaluate(this._duration),this.releaseCameraOverride(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this._state.next(SequencePlaybackState.Stopped),void this.onComplete.next();{this.loopCount++;const e=t%this._duration;this.resetVfxForTimeReset(e),this._time.next(e),this.firedEvents.clear(),this.onLoop.next(this.loopCount)}}else this._time.next(t);this.evaluate(this._time.value);for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale)}evaluate(e){if(this.sequenceData){this.nextCameraShakeClipKeys.clear(),this.nextPostProcessClipKeys.clear();for(const t of this.sequenceData.tracks){if(!t.muted&&("object"===t.type||"locator"===t.type||"camera"===t.type||"spawn"===t.type||"vfx"===t.type)){const e=this.bindings.get(t.id);this.updateTrackParenting(t,e)}this.evaluateTrack(t,e)}this.updateCameraControl(e),this.syncCameraShakeContributions(),this.syncPostProcessEffects()}}evaluateTrack(e,t){if(e.muted)return;const a=this.bindings.get(e.id);(0,this.trackRuntimeEvaluators[b(e.type).runtimeEvaluator])(e,a,t)}evaluateObjectTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}evaluateLocatorTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}getActiveTrackObjects(e){if(!this.sequenceData)return[];const t=H(this.sequenceData.tracks).find(t=>t.id===e);return t?this.getActiveObjectsForTrack(t):[]}evaluateSubTracks(e,t,a){for(const s of e){if(s.muted)continue;(0,this.subTrackRuntimeEvaluators[P(s.type).runtimeEvaluator])(s,t,a)}}evaluateTransformSubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;const{prev:r,next:i,t:n}=I(s,a);if(r)if(i&&r!==i){const a=k(n,r.interpolation);e.components.position&&r.position&&i.position&&t.position.lerpVectors(ae.fromArray(r.position),se.fromArray(i.position),a),e.components.rotation&&r.rotation&&i.rotation&&(ie.setFromEuler(oe.fromArray([...r.rotation,"XYZ"])),ne.setFromEuler(le.fromArray([...i.rotation,"XYZ"])),t.quaternion.slerpQuaternions(ie,ne,a)),e.components.scale&&r.scale&&i.scale&&t.scale.lerpVectors(ae.fromArray(r.scale),se.fromArray(i.scale),a)}else e.components.position&&r.position&&t.position.fromArray(r.position),e.components.rotation&&r.rotation&&t.rotation.fromArray([...r.rotation,"XYZ"]),e.components.scale&&r.scale&&t.scale.fromArray(r.scale)}evaluateAnimationSubTrack(e,t,s){if(!t.mixer||!t.activeActions)return;if(t.target instanceof p?t.target.object:t.target)for(const r of e.clips){const i=r.startTime+r.duration,n=s>=r.startTime&&s<i,o=`${e.id}-${r.id}`;let l=t.activeActions.get(o),c=!1;if(n){if(!l){c=!0;const e=r.animationClipAssetId;if(null==e)continue;const s=this.animationClips.get(e);if(null==s){this.ensureAnimationClip(e);continue}const i=this.prepareAnimationPlayback(e,s,r),n=t;let h=!1;if(t.target instanceof p){n.charAnimComponent||(n.charAnimComponent=t.target.getComponent(F)??void 0);const a=n.charAnimComponent;if(null!=a){const c=r.rootMotion?B(r)?this.getPlayableAnimationClip(e,s,r,!0):j.fromClip(i.clip,!1):i.clip;if(this._externalTimeControl)l=a.beginExternalAnimationControl(c,{timeScale:i.timeScale});else if(a.play(c,{inPlace:!r.rootMotion,loop:!1,priority:20,timeScale:i.timeScale,fadeTime:r.fadeInDuration??.2,offset:i.startOffset}),l=a.getFullBodyAction(),r.rootMotion){const e=t.target.getComponent(E);e&&e.setRootMotionAction(l,{cancelWithJump:e.allowRootMotionJumpCancel,onJumpCancel:()=>this.cancel()})}t.activeActions.set(o,l),n.charAnimActionKeys||(n.charAnimActionKeys=new Set),n.charAnimActionKeys.add(o),h=!0}}h||(l=t.mixer.clipAction(i.clip),l.setLoop(a.LoopOnce,1),l.clampWhenFinished=!0,l.timeScale=i.timeScale,i.startOffset>0&&(l.time=i.startOffset),t.activeActions.set(o,l),l.play())}if(l){const e=t;if(this._externalTimeControl){e.charAnimComponent?.beginExternalControl();const a=this.getAnimationPlaybackLocalTime(r,s),i=Math.min(a,l.getClip().duration);(c||Math.abs(l.time-i)>.001)&&(l.time=i,l.paused=!1,l.play(),e.charAnimComponent?e.charAnimComponent.getMixer()?.update(0):t.mixer&&t.mixer.update(0))}else e.charAnimComponent?.endExternalControl()}}else if(l){t.activeActions.delete(o);const e=t;e.charAnimActionKeys?.has(o)?(e.charAnimActionKeys.delete(o),l.stop(),0===e.charAnimActionKeys.size&&e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0)):(l.stop(),this._externalTimeControl&&t.mixer&&t.mixer.update(0))}}}evaluateVisibilitySubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;let r=s[0];for(const e of s){if(!(e.time<=a))break;r=e}t.visible=r.visible}evaluatePropertySubTrack(e,t,a){const s=x(e.keyframes,a,{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)});s&&this.applyResolvedPropertyValue(e,t,s)}evaluateParameterSubTrack(e,t,a){if("audioParameter"===e.type)return;const s=x(e.keyframes,a,"property"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)}:"material"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:D(e)}:{});s&&("property"!==e.type?this.applyResolvedMaterialValue(e,t,s):this.applyResolvedPropertyValue(e,t,s))}evaluateEventSubTrack(e,t,a){if(t instanceof p&&this._state.value===SequencePlaybackState.Playing)for(const s of e.events){const r=`${e.id}-${s.id}`;if(a>=s.time&&!this.firedEvents.has(r)){if(this.firedEvents.add(r),s.editorOnly&&!this._inEditor)continue;if(!s.functionName)continue;const e=t[s.functionName];"function"==typeof e?this.invokeSequenceEvent(t,s.functionName,e,s.arguments??[]):console.warn(`Sequence event method '${s.functionName}' not found on actor`)}else s.time>a&&this.firedEvents.delete(r)}}evaluateCameraTrack(e,t){const a=this.ensureSequenceCamera(e);this.applyCameraTrackSettings(e,a),this.evaluateSubTracks(e.subTracks,this.getCameraPlayable(e,a),t),a.updateProjectionMatrix()}evaluateCameraShakeTrack(e,t){if(this.viewController)for(const a of e.clips??[]){if(!this.isCameraShakeClipActive(a,t))continue;const e=t-a.startTime,s=a.id;this.nextCameraShakeClipKeys.add(s),this.viewController.setCameraShakeContribution(this,s,a,e,a.seed??L(a.id))}}evaluatePostProcessTrack(e,t){if(this.viewController&&this.assetLoader){for(const a of e.clips??[]){if(!this.isPostProcessClipActive(a,t))continue;const s=this.getPostProcessClipKey(e,a);this.nextPostProcessClipKeys.add(s),this.ensurePostProcessClipEffect(e,a,s);const r=this.activePostProcessClips.get(s);r?.handle&&(r.handle.stage=e.stage,r.handle.priority=e.priority,r.handle.enabled=!0,this.applyPostProcessClipWeight(r.handle,a,t))}this.evaluatePostProcessMaterialSubTracks(e,t)}}evaluatePostProcessMaterialSubTracks(e,t){for(const a of e.subTracks){if(a.muted||"material"!==a.type)continue;const s=x(a.keyframes,t,{min:a.range?.[0],max:a.range?.[1],stepOnly:D(a)});s&&this.applyPostProcessMaterialValue(e.id,a,s)}}applyPostProcessMaterialValue(e,t,a){if(t.uniformName)for(const s of this.activePostProcessClips.values()){if(s.trackId!==e||!s.handle)continue;const r=s.handle.material,i=r.uniforms?.[t.uniformName];if(!i)continue;const n=G(i.value,a);n.applied&&(i.value=n.value,r.uniformsNeedUpdate=!0)}}isPostProcessClipActive(e,t){return t>=e.startTime&&t<e.startTime+e.duration}getPostProcessClipKey(e,t){return`${e.id}-${t.id}`}ensurePostProcessClipEffect(e,t,a){const s=t.shaderGraphAssetId;if(!s)return void this.releasePostProcessClipEffect(a);const r=JSON.stringify(t.shaderGraphParams??{}),i=this.activePostProcessClips.get(a);if(i?.assetId===s&&i.paramsSignature===r)return;this.releasePostProcessClipEffect(a);const n={key:a,trackId:e.id,clipId:t.id,assetId:s,paramsSignature:r,version:this.clearCounter};this.activePostProcessClips.set(a,n),this.loadPostProcessClipEffect(e,t,n)}async loadPostProcessClipEffect(e,t,a){if(this.assetLoader&&this.viewController)try{const s=await this.assetLoader.getShaderGraphByAssetId(a.assetId);if(!this.isPostProcessClipEntryCurrent(a))return;if("postProcess"!==s.target)return console.warn(`Sequence post-process clip references shader graph "${a.assetId}" with target "${s.target}"`),void this.releasePostProcessClipEffect(a.key);const r=await this.assetLoader.prepareShaderGraphParameters(s,t.shaderGraphParams??{});if(!this.isPostProcessClipEntryCurrent(a))return;const i=_(s,{parameters:r});if(!this.isPostProcessClipEntryCurrent(a))return void i.dispose();a.handle=this.viewController.addPostProcessEffect(i,{stage:e.stage,priority:e.priority,enabled:!0}),this.applyPostProcessClipWeight(a.handle,t,this._time.value)}catch(e){this.isPostProcessClipEntryCurrent(a)&&this.releasePostProcessClipEffect(a.key),console.error(`Failed to create post-process effect for clip ${t.id}:`,e)}}isPostProcessClipEntryCurrent(e){return this.clearCounter===e.version&&this.activePostProcessClips.get(e.key)===e}applyPostProcessClipWeight(e,t,a){const s=e.material.uniforms?.[R];null!=s&&(s.value=this.getPostProcessClipWeight(t,a),e.material.uniformsNeedUpdate=!0)}getPostProcessClipWeight(e,t){const a=Math.max(0,t-e.startTime),s=Math.max(0,e.startTime+e.duration-t);let r=1;const i=Math.max(0,e.fadeInDuration??0);i>0&&(r=Math.min(r,a/i));const n=Math.max(0,e.fadeOutDuration??0);return n>0&&(r=Math.min(r,s/n)),Math.max(0,Math.min(1,r))}syncPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.nextPostProcessClipKeys.has(e)||this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}clearPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}releasePostProcessClipEffect(e){const t=this.activePostProcessClips.get(e);if(t&&(this.activePostProcessClips.delete(e),t.handle)){const e=t.handle.material;t.handle.dispose(),e.dispose()}}getCameraPlayable(e,t){let a=this.cameraPlayables.get(e.id);return a?a.target=t:(a={target:t},this.cameraPlayables.set(e.id,a)),a}ensureSequenceCamera(e){let t=this.sequenceCameras.get(e.id);if(t)null==t.parent&&this.world?.scene.add(t);else{const s=e.cameraSettings??{fov:60,near:.1,far:1e3};t=new a.PerspectiveCamera(s.fov??60,this.getCurrentCameraAspect(),s.near??.1,s.far??1e3),t.name=e.name||"Sequence Camera",t.userData.sequenceCameraTrackId=e.id,t.layers.mask=this.viewController?.getBaseCamera().layers.mask??t.layers.mask,this.sequenceCameras.set(e.id,t),this.world?.scene.add(t)}return t}clearSequenceCameras(){this.releaseCameraOverride();for(const e of this.sequenceCameras.values())e.removeFromParent();this.sequenceCameras.clear(),this.cameraPlayables.clear()}applyCameraTrackSettings(e,t){const a=e.cameraSettings??{fov:60,near:.1,far:1e3};t.fov=a.fov??60,t.near=a.near??.1,t.far=a.far??1e3,t.aspect=this.getCurrentCameraAspect()}getCurrentCameraAspect(){const e=this.viewController?.getBaseCamera();if(e instanceof a.PerspectiveCamera&&Number.isFinite(e.aspect)&&e.aspect>0)return e.aspect;const t=this.viewController?.getSourceCamera();return t instanceof a.PerspectiveCamera&&Number.isFinite(t.aspect)&&t.aspect>0?t.aspect:1}updateCameraControl(e){if(!this._cameraControlEnabled||!this.viewController||!this.sequenceData)return void this.releaseCameraOverride();const t=this.findActiveCameraShot(e);if(t)return void this.updateActiveCameraShot(t,e);const a=this.findBlendOutCameraShot(e);a?this.updateCameraBlendOut(a,e):this.releaseCameraOverride()}findActiveCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of H(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s)this.isCameraClipActive(r,e)&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}return t}findBlendOutCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of H(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s){const s=Math.max(0,r.blendOutDuration??0);if(s<=0)continue;const i=this.getCameraClipEnd(r);e>=i&&e<i+s&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}}return t}isCameraControlTrackEligible(e){return null==this._cameraControlTrackId||e.id===this._cameraControlTrackId}updateActiveCameraShot(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();this.activeCameraClipKey!==e.key&&(this.copyCameraState(this.viewController.getSourceCamera(),this.ensureCameraBlendSource()),this.activeCameraClipKey=e.key,this.cameraBlendOutClipKey=null);const s=Math.max(0,e.clip.blendInDuration??0),r=s<=0?1:this.evaluateCameraBlendAlpha((t-e.clip.startTime)/s,e.clip);r>=1?this.copyCameraState(e.camera,a):this.blendCameraState(this.ensureCameraBlendSource(),e.camera,a,r),a.updateProjectionMatrix(),this.ensureCameraOverride()}updateCameraBlendOut(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();if(this.cameraBlendOutClipKey!==e.key){const t=this.activeCameraClipKey===e.key?this.viewController.getSourceCamera():e.camera;this.copyCameraState(t,this.ensureCameraBlendOutSource()),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=e.key}const s=this.getCameraClipEnd(e.clip),r=Math.max(0,e.clip.blendOutDuration??0),i=r<=0?1:this.evaluateCameraBlendAlpha((t-s)/r,e.clip);this.blendCameraState(this.ensureCameraBlendOutSource(),this.viewController.getBaseCamera(),a,i),a.updateProjectionMatrix(),this.ensureCameraOverride()}ensureCameraBlendCamera(){return this.cameraBlendCamera||(this.cameraBlendCamera=new a.PerspectiveCamera(60,this.getCurrentCameraAspect(),.1,1e3),this.cameraBlendCamera.name="Sequence Camera Blend"),this.cameraBlendCamera}ensureCameraBlendSource(){return this.cameraBlendSource||(this.cameraBlendSource=new a.PerspectiveCamera),this.cameraBlendSource}ensureCameraBlendOutSource(){return this.cameraBlendOutSource||(this.cameraBlendOutSource=new a.PerspectiveCamera),this.cameraBlendOutSource}ensureCameraOverride(){this.viewController&&!this.cameraOverrideHandle&&(this.cameraOverrideHandle=this.viewController.pushCameraOverride(this.ensureCameraBlendCamera(),this))}releaseCameraOverride(){this.cameraOverrideHandle?.release(),this.cameraOverrideHandle=null,this.viewController?.releaseCameraOverridesForOwner(this),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null}isCameraClipActive(e,t){return t>=e.startTime&&t<this.getCameraClipEnd(e)}getCameraClipEnd(e){return e.startTime+Math.max(0,e.duration)}isCameraShakeClipActive(e,t){return t>=e.startTime&&t<this.getCameraShakeClipEnd(e)}getCameraShakeClipEnd(e){return e.startTime+Math.max(0,e.duration)}getCameraClipKey(e,t){return`${e.id}-${t.id}`}evaluateCameraBlendAlpha(e,t){return k(Math.max(0,Math.min(1,e)),t.blendInterpolation??"cubic")}syncCameraShakeContributions(){if(!this.viewController)return this.activeCameraShakeClipKeys.clear(),void this.nextCameraShakeClipKeys.clear();for(const e of this.activeCameraShakeClipKeys)this.nextCameraShakeClipKeys.has(e)||this.viewController.removeCameraShakeContribution(this,e);this.activeCameraShakeClipKeys.clear();for(const e of this.nextCameraShakeClipKeys)this.activeCameraShakeClipKeys.add(e);this.nextCameraShakeClipKeys.clear()}clearCameraShakeContributions(){this.activeCameraShakeClipKeys.clear(),this.nextCameraShakeClipKeys.clear(),this.viewController?.clearCameraShakeContributionsForOwner(this)}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(ae)),t.quaternion.copy(e.getWorldQuaternion(ie)),t.scale.copy(e.getWorldScale(se)),e instanceof a.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect):t.aspect=this.getCurrentCameraAspect(),t.layers.mask=e.layers.mask}blendCameraState(e,t,s,r){e.updateWorldMatrix(!0,!1),t.updateWorldMatrix(!0,!1),s.position.lerpVectors(e.getWorldPosition(ae),t.getWorldPosition(se),r),s.quaternion.slerpQuaternions(e.getWorldQuaternion(ie),t.getWorldQuaternion(ne),r),s.scale.lerpVectors(e.getWorldScale(ae),t.getWorldScale(se),r),e instanceof a.PerspectiveCamera&&t instanceof a.PerspectiveCamera?(s.fov=e.fov+(t.fov-e.fov)*r,s.near=e.near+(t.near-e.near)*r,s.far=e.far+(t.far-e.far)*r,s.aspect=t.aspect):t instanceof a.PerspectiveCamera?(s.fov=t.fov,s.near=t.near,s.far=t.far,s.aspect=t.aspect):s.aspect=this.getCurrentCameraAspect(),s.layers.mask=t.layers.mask}evaluateAudioTrack(e,t){if(!this.assetLoader||!e.clips||0===e.clips.length)return;const a=this._state.value===SequencePlaybackState.Playing,s=this.evaluateAudioSubTracks(e,t);e.volume;for(const r of e.clips){const i=r.startTime+r.duration,n=t>=r.startTime&&t<i,o=`${e.id}-${r.id}`;if(n){if(this.activeAudioClips.has(o)||this.activeAudioClips.add(o),a){const a=this.audioByClip.get(o);a&&a.isPlaying||this.tryStartAudioClip(e,r,o,t,s)}const i=this.audioByClip.get(o);i&&this.applyAudioParameters(i,e,r,o,t,s)}else this.activeAudioClips.has(o)&&(this.activeAudioClips.delete(o),this.lastAudioStartAttemptTime.delete(o),this.audioStartInFlight.delete(o),this.stopAudioClip(o))}}tryStartAudioClip(e,t,a,s,r){if(this.audioStartInFlight.has(a))return;const i=this.lastAudioStartAttemptTime.get(a);if(void 0!==i&&s-i<this.audioStartRetryIntervalSeconds)return;this.lastAudioStartAttemptTime.set(a,s);const n=this.playAudioClip(e,t,a,s,r).catch(()=>{}).finally(()=>{this.audioStartInFlight.get(a)===n&&this.audioStartInFlight.delete(a)});this.audioStartInFlight.set(a,n)}applyAudioParameters(e,t,s,r,i,n){const o=n.volume??1,l=Math.random(),c=s.volumeRandomization?(2*l-1)*s.volumeRandomization:0;let h=1;const u=i-s.startTime;u<s.fadeInDuration&&s.fadeInDuration>0?h=u/s.fadeInDuration:u>s.duration-s.fadeOutDuration&&s.fadeOutDuration>0&&(h=(s.duration-u)/s.fadeOutDuration);const p=Math.max(0,(t.volume??1)*o*(s.volume+c)*h);e.setVolume(p);let d=n.detune??0;if(s.pitchRandomization){d+=(2*Math.random()-1)*s.pitchRandomization}if(e.setDetune(d),e.hasPlaybackControl&&e.setPlaybackRate(s.playbackRate*this.timescale),this.audioListener&&this.audioListener.context){const s=this.audioListener.context,i=[],o=n.lowpass,l=n.highpass;let c=this.audioFilters.get(r);if(void 0!==o||void 0!==l)c||(c=s.createBiquadFilter(),this.audioFilters.set(r,c)),void 0!==o?(c.type="lowpass",c.frequency.value=o):void 0!==l&&(c.type="highpass",c.frequency.value=l),i.push(c);else if(c){try{c.disconnect()}catch{}this.audioFilters.delete(r)}const h=n.pan;if(!t.spatial&&e instanceof a.Audio&&void 0!==h&&"function"==typeof s.createStereoPanner){let e=this.audioPannerNodes.get(r);e||(e=s.createStereoPanner(),this.audioPannerNodes.set(r,e)),e.pan.value=h,i.push(e)}else{const e=this.audioPannerNodes.get(r);if(e){try{e.disconnect()}catch{}this.audioPannerNodes.delete(r)}}e.setFilters(i)}t.spatial&&e instanceof a.PositionalAudio?this.updatePositionalAudioTransform(e,t,s,n.spatialBlend):void 0!==n.pan&&this.audioListener}updatePositionalAudioTransform(e,t,s,r){let i=null,n=null;const o=s.attachedToTrackId||t.parent?.trackId,l=s.attachmentSocketName||t.parent?.socketName;if(o){const e=this.sequenceData?.tracks.find(e=>e.id===o);if(e){const t=this.getActiveObjectsForTrack(e);if(t.length>0){const e=t[0];if(i=ae,n=ie,e.getWorldPosition(i),e.getWorldQuaternion(n),l){const t=this.findSocket(e,l);t&&(t.getWorldPosition(i),t.getWorldQuaternion(n))}}}}if(i&&n){const t="number"==typeof r?a.MathUtils.clamp(r,0,1):1;if(t<1&&this.audioListener){const e=re;this.audioListener.getWorldPosition(e),i=i.clone().lerp(e,1-t)}e.position.copy(i),e.quaternion.copy(n),e.updateMatrixWorld()}}async playAudioClip(e,t,s,r,i){if(!this.assetLoader||!t.audioAssetId||null==this.audioListener)return;if("suspended"===this.audioListener.context.state)try{await this.audioListener.context.resume()}catch(e){return void console.warn("Failed to resume audio context:",e)}this.stopAudioClip(s);const n=this.clearCounter;try{let r=this.audioBuffers.get(t.audioAssetId);if(!r){let e=this.loadingAudioBuffers.get(t.audioAssetId);e||(e=this.assetLoader.getAudioByAssetId(t.audioAssetId),this.loadingAudioBuffers.set(t.audioAssetId,e));try{r=await e,this.audioBuffers.set(t.audioAssetId,r)}finally{this.loadingAudioBuffers.delete(t.audioAssetId)}}if(n!==this.clearCounter)return;const o=this._time.value,l=t.startTime+t.duration;if(!(o>=t.startTime&&o<l))return;const c=Math.max(0,o-t.startTime),h=t.clipStartOffset+c*t.playbackRate;if(h>=r.duration||c>=t.duration)return;let u=this.audioByClip.get(s);const p=!0===e.spatial,d=u&&!0===u.isPositionalAudio;if(u&&p!==d&&(u.isPlaying&&u.stop(),u.disconnect(),this.audioByClip.delete(s),u=void 0),!u){if(p){const e=new a.PositionalAudio(this.audioListener);e.setRefDistance(10),e.setRolloffFactor(1),u=e}else u=new a.Audio(this.audioListener);this.world&&this.world.scene.add(u),this.audioByClip.set(s,u)}Math.min((t.duration-c)/t.playbackRate,(r.duration-h)/t.playbackRate);u.setLoopStart(t.clipStartOffset),u.setLoopEnd(Math.min(t.clipStartOffset+t.duration,r.duration)),u.setLoop(!0),u.setBuffer(r),this.applyAudioParameters(u,e,t,s,o,i),u.isPlaying||u.play()}catch(e){console.error(`Failed to play audio clip ${t.id}:`,e)}}stopAudioClip(e){const t=this.audioByClip.get(e);if(t){try{t.isPlaying&&t.stop()}catch(e){}t.parent&&t.parent.remove(t),this.audioByClip.delete(e)}const a=this.audioGainNodes.get(e);a&&(a.disconnect(),this.audioGainNodes.delete(e));const s=this.audioFilters.get(e);if(s){try{s.disconnect()}catch{}this.audioFilters.delete(e)}const r=this.audioPannerNodes.get(e);if(r){try{r.disconnect()}catch{}this.audioPannerNodes.delete(e)}}stopAllAudio(){for(const e of this.audioByClip.keys())this.stopAudioClip(e);this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear()}evaluateVfxTrack(e,t){if(!this.vfxService||!this.world||!e.clips||0===e.clips.length)return;const a=new Set,s=new Map;for(const r of e.clips){const i=this.getVfxClipKey(e,r);s.set(i,r),this.isVfxClipActiveAtTime(r,t)&&a.add(i)}const r=[];for(const t of this.activeVfxClips)t.startsWith(`${e.id}-`)&&(a.has(t)||r.push(t));for(const e of r)this.activeVfxClips.delete(e);for(const[r,i]of s.entries()){const s=this.vfxActors.get(r);a.has(r)&&!this.activeVfxClips.has(r)?(this.activeVfxClips.add(r),this.ensureVfxActor(e,i,r)):a.has(r)&&s?(this.updateVfxTransform(e,s,t),this._state.value===SequencePlaybackState.Playing&&s.play()):s&&this.applyInactiveVfxClipBehavior(i,s,t)}}getVfxClipKey(e,t){return`${e.id}-${t.id}-${t.vfxAssetId}`}isVfxClipActiveAtTime(e,t){const a=e.startTime+e.duration;return t>=e.startTime&&t<a}resetVfxForTimeReset(e){const t=new Set;if(this.sequenceData)for(const a of H(this.sequenceData.tracks))if("vfx"===a.type)for(const s of a.clips??[])this.isVfxClipActiveAtTime(s,e)&&t.add(this.getVfxClipKey(a,s));this.activeVfxClips.clear();for(const[e,a]of this.vfxActors.entries())t.has(e)||(a.restart(),a.stop(),a.pause())}applyInactiveVfxClipBehavior(e,t,a){const s=e.endBehavior??"finish";if("finish"===s)return void t.stop();if("kill"===s)return void t.applyClipEndBehavior(s);const r=e.startTime+e.duration,i=Math.max(a-r,0),n=Math.max(0,e.expireWithinSeconds??.25),o=Math.max(0,n-i);t.applyClipEndBehavior(s,o)}async ensureVfxActor(e,t,a){if(!this.vfxService||!t.vfxAssetId)return;if(this.vfxActors.has(a)){const e=this.vfxActors.get(a);return e.restart(),void e.play()}const s=this.clearCounter;try{const r=await this.vfxService.createFromAssetId(t.vfxAssetId,this.world.scene);if(s!==this.clearCounter)return void(this.world&&this.world.removeActor(r));const{position:i,rotation:n,scale:o}=this.getVfxTransform(e,t.startTime);r.object.position.copy(i),r.object.rotation.copy(n),r.object.scale.copy(o),this.vfxActors.set(a,r),this._state.value===SequencePlaybackState.Playing&&r.play()}catch(e){console.error(`Failed to create VFX actor for clip ${t.id}:`,e)}}getVfxTransform(e,t){const a=new c,s=new i,r=new c(1,1,1),n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,next:i,t:l}=I(n.keyframes,t);if(e&&(e.position&&a.fromArray(e.position),e.rotation&&s.fromArray([...e.rotation,"XYZ"]),e.scale&&r.fromArray(e.scale)),i&&e!==i&&e.time!==i.time){const t=k(l,e.interpolation);if(e.position&&i.position&&a.lerpVectors(ae.fromArray(e.position),se.fromArray(i.position),t),e.rotation&&i.rotation){ie.setFromEuler(oe.fromArray([...e.rotation,"XYZ"])),ne.setFromEuler(le.fromArray([...i.rotation,"XYZ"]));const a=new o;a.slerpQuaternions(ie,ne,t),s.setFromQuaternion(a)}e.scale&&i.scale&&r.lerpVectors(ae.fromArray(e.scale),se.fromArray(i.scale),t)}}else a.fromArray(e.position),s.fromArray([...e.rotation,"XYZ"]),r.fromArray(e.scale);return{position:a,rotation:s,scale:r}}updateVfxTransform(e,t,a){const{position:s,rotation:r,scale:i}=this.getVfxTransform(e,a);t.object.position.copy(s),t.object.rotation.copy(r),t.object.scale.copy(i)}resolveActorType(e){const t=this.actorFactory.classes[e];if(null!=t)return t;const a=d[e];return a||(console.warn(`Could not resolve actor type: ${e}`),null)}async spawnActorForClip(e,t,a,s){if(!this.world||!e.actorType)return null;const r=this.resolveActorType(e.actorType);if(!r)return null;try{return await this.world.spawnActor(r,a,s)}catch(t){return console.error(`Failed to spawn actor ${e.actorType}:`,t),null}}async spawnPrefabForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.prefabId)return null;try{const t=await this.assetLoader.getPrefabById(e.prefabId);if(!t)return null;return await this.world.spawnPrefab(t,a,s)}catch(t){return console.error(`Failed to spawn prefab ${e.prefabId}:`,t),null}}async spawnMeshForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.meshId)return null;try{const t=await this.assetLoader.getAsset(e.meshId),r=await this.assetLoader.getModelByAssetId(e.meshId),i=O.clone(r.scene);if(i.position.copy(a),i.rotation.copy(s),t){await this.assetLoader.applyMaterials(t,i);const e=t.mesh?.rescale;null!=e&&1!==e&&i.scale.multiplyScalar(e)}return this.world.scene.add(i),i}catch(t){return console.error(`Failed to spawn mesh ${e.meshId}:`,t),null}}despawnInstance(e){if(this.restorePropertySnapshotsForInstance(e),this.restoreMaterialSnapshotsForInstance(e),this.world)switch(e?.type){case"actor":this.world.removeActor(e.instance);break;case"prefab":this.world.removePrefab(e.instance);break;case"mesh":this.world.scene.remove(e.instance)}}despawnAll(){for(const e of this.spawnedInstances.values())this.despawnInstance(e);this.spawnedInstances.clear(),this.activeClips.clear(),this.pendingSpawns.clear()}getInitialTransform(e,t,a){const s=new c,r=new i,n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e}=I(n.keyframes,a);e&&(e.position&&s.fromArray(e.position),e.rotation&&r.fromArray([...e.rotation,"XYZ"]))}else t.initialPosition&&s.fromArray(t.initialPosition),t.initialRotation&&r.fromArray([...t.initialRotation,"XYZ"]);return{position:s,rotation:r}}evaluateSpawnTrack(e,t,a){if(!e.clips||0===e.clips.length)return;const s=t||this.bindings.get(e.id);if(s&&s.target)for(const t of e.clips){const r=t.startTime+t.duration,i=a>=t.startTime&&a<r,n=`${e.id}-${t.id}`;if(i){this.activeClips.has(n)||(this.activeClips.add(n),this.spawnedInstances.set(n,{type:"proxy",target:s.target}));(s.target instanceof p?s.target.object:s.target)&&this.evaluateSubTracks(e.subTracks,s,a)}else this.activeClips.has(n)&&(this.restorePropertySnapshotsForTarget(s.target),this.restoreMaterialSnapshotsForTarget(s.target),this.activeClips.delete(n),this.spawnedInstances.delete(n))}else for(const t of e.clips){const s=t.startTime+t.duration,r=a>=t.startTime&&a<s,i=`${e.id}-${t.id}`,n=this.spawnedInstances.has(i),o=this.pendingSpawns.has(i);if(!r||n||o){if(r&&n){const t=this.spawnedInstances.get(i);t&&"proxy"!==t.type&&this.evaluateSubTracks(e.subTracks,t,a)}else if(!r&&n){const e=this.spawnedInstances.get(i);e&&(this.despawnInstance(e),this.spawnedInstances.delete(i),this.activeClips.delete(i))}}else{const{position:a,rotation:s}=this.getInitialTransform(e,t,t.startTime);this.pendingSpawns.add(i),this.spawnForClip(e,t,a,s,i)}}}getInstanceObject(e){switch(e.type){case"actor":return e.instance.object;case"prefab":return e.instance.mainActor?.object||e.instance.object;case"mesh":return e.instance;case"proxy":return e.target instanceof p?e.target.object:e.target;default:return null}}async spawnForClip(e,t,a,r,i){const n=this.clearCounter;let o=null;try{switch(e.spawnType){case"actor":const s=await this.spawnActorForClip(e,t,a,r);s&&(o={type:"actor",instance:s});break;case"prefab":const i=await this.spawnPrefabForClip(e,t,a,r);i&&(o={type:"prefab",instance:i});break;case"mesh":const n=await this.spawnMeshForClip(e,t,a,r);n&&(o={type:"mesh",instance:n})}if(n!==this.clearCounter)return void(o&&this.despawnInstance(o));const l=this._time.value,c=l>=t.startTime&&l<t.startTime+t.duration;if(o&&c){const t=this.getInstanceObject(o);"proxy"===o.type||("actor"===o.type?o.target=o.instance:"prefab"===o.type?o.target=o.instance.mainActor||o.instance.object:o.target=t);e.subTracks.some(e=>"animation"===e.type)&&t&&(o.mixer=new s(t),o.activeActions=new Map),this.spawnedInstances.set(i,o),this.activeClips.add(i)}else o&&this.despawnInstance(o)}finally{this.pendingSpawns.delete(i)}}getPlayableObject(e){return e.target instanceof p?e.target.object:e.target??null}applyResolvedPropertyValue(e,t,a){if(!t||!e.propertyPath)return;const s=this.getPropertyResolution(t,e);if(!s)return;const r=this.getPropertySnapshotKey(e);this.capturePropertySnapshot(t,r,s);const n=function(e,t){switch(t.type){case y.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.String:return"string"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return N(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return W(e,t.value);case y.Euler:return function(e,t){const a=Q(t,3);if(!a)return{applied:!1};const s=Array.isArray(t)&&"string"==typeof t[3]?t[3]:"XYZ";if(e instanceof i)return e.set(a[0],a[1],a[2],s),{applied:!0,value:e};return{applied:!0,value:new i(a[0],a[1],a[2],s)}}(e,t.value);case y.Color:return X(e,t.value);default:return{applied:!1}}}(s.owner[s.key],a);n.applied&&(s.owner[s.key]=n.value)}getPropertyResolution(e,t){const a=e,s=this.getPropertySnapshotKey(t);let r=this.propertyResolutionCache.get(a);if(r||(r=new Map,this.propertyResolutionCache.set(a,r)),r.has(s))return r.get(s)??null;const i=this.getPropertyPathSegments(t.propertyPath);if(0===i.length)return r.set(s,null),null;let n=e;for(let e=0;e<i.length-1;e++){if(!K(n))return r.set(s,null),null;n=n[i[e]]}if(!K(n))return r.set(s,null),null;const o={owner:n,key:i[i.length-1]};return r.set(s,o),o}getPropertyPathSegments(e){const t=this.propertyPathSegments.get(e);if(t)return t;const a=e.split(".").map(e=>e.trim()).filter(Boolean);return this.propertyPathSegments.set(e,a),a}getPropertySnapshotKey(e){return`${e.id}:${e.propertyPath}`}capturePropertySnapshot(e,t,a){const s=e;let r=this.propertySnapshots.get(s);if(r||(r=new Map,this.propertySnapshots.set(s,r)),r.has(t))return;const i=a.owner[a.key];r.set(t,{resolution:a,hadOwnProperty:Object.prototype.hasOwnProperty.call(a.owner,a.key),value:i,valueSnapshot:Z(i)})}restorePropertySnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restorePropertySnapshotsForTarget(e.instance);break;case"prefab":this.restorePropertySnapshotsForTarget(e.target??null),this.restorePropertySnapshotsForTarget(e.instance.mainActor??null),this.restorePropertySnapshotsForTarget(e.instance.object);break;case"proxy":this.restorePropertySnapshotsForTarget(e.target)}}restorePropertySnapshotsForTarget(e){if(!e)return;const t=e,a=this.propertySnapshots.get(t);if(a){for(const e of a.values())z(e);this.propertySnapshots.delete(t),this.propertyResolutionCache.delete(t)}}restoreAllPropertySnapshots(){for(const e of Array.from(this.propertySnapshots.keys()))this.restorePropertySnapshotsForTarget(e)}restoreMaterialSnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restoreMaterialSnapshotsForTarget(e.instance);break;case"prefab":this.restoreMaterialSnapshotsForTarget(e.target??null),this.restoreMaterialSnapshotsForTarget(e.instance.mainActor??null),this.restoreMaterialSnapshotsForTarget(e.instance.object);break;case"proxy":this.restoreMaterialSnapshotsForTarget(e.target)}}restoreMaterialSnapshotsForTarget(e){if(!e)return;const t=e;this.materialResolutionCache.delete(t);const a=this.materialSnapshots.get(t);if(a){for(const e of a.values())null==e.materialIndex?e.owner.material=e.originalMaterial:Array.isArray(e.owner.material)&&(e.owner.material[e.materialIndex]=e.originalMaterial),e.controlledMaterial!==e.originalMaterial&&e.controlledMaterial.dispose();this.materialSnapshots.delete(t)}}restoreAllMaterialSnapshots(){for(const e of Array.from(this.materialSnapshots.keys()))this.restoreMaterialSnapshotsForTarget(e)}applyResolvedMaterialValue(e,t,a){if(!t||!e.uniformName)return;if("asset"===S(e)&&!e.materialAssetId)return;const s=this.getMaterialSlotResolutions(t,e);for(const r of s){const s=this.ensureSequenceControlledMaterial(t,r),i=s.uniforms?.[e.uniformName];if(!i)continue;const n=G(i.value,a);n.applied&&(i.value=n.value,s.uniformsNeedUpdate=!0)}}getMaterialSlotResolutions(e,t){const a=e,s=S(t),r=`${t.id}:${s}:${t.materialAssetId??""}:${t.uniformName}`;let i=this.materialResolutionCache.get(a);i||(i=new Map,this.materialResolutionCache.set(a,i));const n=i.get(r);if(n)return n;const o=e instanceof p?e.object:e,l=[];return o.traverse(e=>{const a=e.material;if(Array.isArray(a))for(let s=0;s<a.length;s++){const r=a[s];$(r,t)&&l.push({owner:e,materialIndex:s,material:r,key:`${e.uuid}:${s}`})}else $(a,t)&&l.push({owner:e,materialIndex:null,material:a,key:`${e.uuid}:material`})}),i.set(r,l),l}ensureSequenceControlledMaterial(e,t){const a=e;let s=this.materialSnapshots.get(a);s||(s=new Map,this.materialSnapshots.set(a,s));const r=s.get(t.key);if(r)return r.controlledMaterial;const i=t.material.clone();return i.userData={...t.material.userData??{}},null==t.materialIndex?t.owner.material=i:Array.isArray(t.owner.material)&&(t.owner.material[t.materialIndex]=i),s.set(t.key,{owner:t.owner,materialIndex:t.materialIndex,originalMaterial:t.material,controlledMaterial:i}),i}async ensureAnimationClip(e){if(!this.assetLoader)return null;const t=this.animationClips.get(e);if(t)return t;const a=this.loadingAnimationClips.get(e);if(a)return a;const s=(async()=>{try{const t=await this.assetLoader.getAnimationClipByAssetId(e);return t&&this.animationClips.set(e,t),t}catch(t){return console.error(`Failed to load animation clip for asset ${e}:`,t),null}finally{this.loadingAnimationClips.get(e)===s&&this.loadingAnimationClips.delete(e)}})();return this.loadingAnimationClips.set(e,s),s}prepareAnimationPlayback(e,t,a){if(!B(a)){let e=t;return a.clipEndOffset>0&&(e=e.clone(),e.duration=Math.max(0,e.duration-a.clipEndOffset)),{clip:e,timeScale:a.playbackRate,startOffset:a.clipStartOffset}}return{clip:this.getPlayableAnimationClip(e,t,a,!1),timeScale:1,startOffset:0}}getPlayableAnimationClip(e,t,a,s){if(!B(a))return s?j.fromClip(t,!1):t;const r=`${a.id}:${s?"root":"base"}`,i=`${q(a)}|${s?"root":"base"}`,n=this.retimedAnimationClips.get(r);if(n&&n.assetId===e&&n.signature===i)return n.clip;const o=M(t,a),l=s?j.fromClip(o,!1):o;return this.retimedAnimationClips.set(r,{assetId:e,signature:i,clip:l}),l}getAnimationPlaybackLocalTime(e,t){const a=Math.max(0,t-e.startTime);return B(e)?a:a*e.playbackRate+e.clipStartOffset}clearRetimedAnimationClipCache(e){if(null!=e)for(const[t,a]of this.retimedAnimationClips.entries())a.assetId===e&&this.retimedAnimationClips.delete(t);else this.retimedAnimationClips.clear()}captureOriginalTransforms(){for(const e of this.bindings.values()){const t=e.target instanceof p?e.target.object:e.target;t&&(e.originalTransform={position:t.position.clone(),rotation:t.rotation.clone(),scale:t.scale.clone()})}}restoreOriginalTransforms(){for(const e of this.bindings.values())if(e.originalTransform){const t=e.target instanceof p?e.target.object:e.target;t&&(t.position.copy(e.originalTransform.position),t.rotation.copy(e.originalTransform.rotation),t.scale.copy(e.originalTransform.scale))}}stopAllAnimations(){for(const e of this.bindings.values()){for(const t of e.activeActions.values())t.stop();e.activeActions.clear(),e.mixer&&e.mixer.stopAllAction(),e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0),e.charAnimActionKeys?.clear()}}stopAllVfx(){for(const e of this.vfxActors.values())e.paused||e.stop();this.activeVfxClips.clear()}dispose(){if(this.stop(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.bindings.clear(),this.roleBindings.clear(),this.sequenceData=null,this.world)for(const e of this.vfxActors.values())this.world.removeActor(e);this.vfxActors.clear(),this.stopAllAudio(),this.audioBuffers.clear(),this.loadingAudioBuffers.clear(),this.animationClips.clear(),this.loadingAnimationClips.clear(),this.clearRetimedAnimationClipCache(),this.audioByClip.clear()}updateTrackParenting(e,t){const a=this.getActiveObjectsForTrack(e);if(0===a.length)return;let s=null;const r=e.parent?.trackId;if(r){const t=this.sequenceData?H(this.sequenceData.tracks).find(e=>e.id===r):void 0;if(t){const a=this.getActiveObjectsForTrack(t);if(a.length>0&&(s=a[0],e.parent?.socketName)){const t=this.findSocket(s,e.parent.socketName);t&&(s=t)}}}if(!s&&"camera"===e.type&&e.parentRole&&this.roleBindings.has(e.parentRole)){const t=this.roleBindings.get(e.parentRole);if(s=t instanceof p?t.object:t,e.parentRoleSocketName){const t=this.findSocket(s,e.parentRoleSocketName);t&&(s=t)}}for(const r of a)s?r.parent!==s&&(s.add(r),!t||"object"!==e.type&&"locator"!==e.type||(t.currentParent=s)):t?.currentParent&&t.currentParent===r.parent?this.restoreObjectParent(t,r):r.parent&&r.parent!==this.world?.scene&&"object"!==e.type&&"locator"!==e.type&&this.world?.scene.add(r)}findSocket(e,t){if(e.name===t)return e;if(e instanceof a.SkinnedMesh){const a=e.skeleton.bones.find(e=>e.name===t);if(a)return a}return e.getObjectByName(t)||null}getActiveObjectsForTrack(e){if("object"===e.type){const t=this.bindings.get(e.id);if(t&&t.target)return[t.target instanceof p?t.target.object:t.target]}else if("locator"===e.type){const t=this.bindings.get(e.id);if(t&&t.target instanceof n)return[t.target]}else{if("camera"===e.type)return[this.ensureSequenceCamera(e)];if("spawn"===e.type){const t=[];for(const[a,s]of this.spawnedInstances)if(a.startsWith(e.id+"-")&&this.activeClips.has(a)){const e=this.getInstanceObject(s);e&&t.push(e)}return t}if("vfx"===e.type){const t=[];for(const a of this.activeVfxClips)if(a.startsWith(e.id+"-")){const e=this.vfxActors.get(a);e&&t.push(e.object)}return t}}return[]}restoreObjectParent(e,t){e.originalParent?e.originalParent.add(t):this.world&&this.world.scene.add(t),e.currentParent=void 0}restoreOriginalParents(){for(const e of this.bindings.values())if(e.currentParent){const t=e.target instanceof p?e.target.object:e.target;t&&this.restoreObjectParent(e,t)}}evaluateAudioSubTracks(e,t){const a={};for(const s of e.subTracks)if("audioParameter"===s.type){const e=s,r=A(e.parameter),i=T(e.keyframes,t,{min:r.min,max:r.max});void 0!==i&&(a[e.parameter]=i)}return a}stringToRandom(e){let t=0;for(let a=0;a<e.length;a++){t=(t<<5)-t+e.charCodeAt(a),t&=t}const a=1e4*Math.sin(t);return a-Math.floor(a)}async refreshAsset(e){let t=!1;this.assetLoader?.clearCacheById(e),this.animationClips.delete(e),this.loadingAnimationClips.delete(e),this.clearRetimedAnimationClipCache(e),this.vfxService?.clearPool(e),t=this.refreshVfxActorsForAssetIds(new Set([e]))||t;for(const[a,s]of this.activePostProcessClips.entries())s.assetId===e&&(this.releasePostProcessClipEffect(a),t=!0);t=this.refreshSpawnedInstancesForClipKeys(this.getSpawnClipKeysForAsset(e))||t;const a=await this.getAssetOrNull(e);return"shaderGraph"===a?.type&&(t=await this.refreshShaderGraphDependentAssets(e)||t),t}refreshVfxActorsForAssetIds(e){let t=!1;for(const[a,s]of this.vfxActors.entries())this.vfxClipKeyUsesAnyAsset(a,e)&&(this.world&&this.world.removeActor(s),this.vfxActors.delete(a),this.activeVfxClips.delete(a),t=!0);return t}vfxClipKeyUsesAnyAsset(e,t){for(const a of t)if(e.endsWith(`-${a}`))return!0;return!1}refreshSpawnedInstancesForClipKeys(e){let t=!1;for(const[a,s]of this.spawnedInstances.entries())e.has(a)&&(this.despawnInstance(s),this.spawnedInstances.delete(a),this.activeClips.delete(a),t=!0);return t}getSpawnClipKeysForAsset(e){const t=new Set;if(!this.sequenceData)return t;for(const a of H(this.sequenceData.tracks))if("spawn"===a.type&&(a.prefabId===e||a.meshId===e))for(const e of a.clips)t.add(`${a.id}-${e.id}`);return t}async refreshShaderGraphDependentAssets(e){const t=await this.findSequenceVfxAssetIdsUsingShaderGraph(e);for(const e of t)this.vfxService?.clearPool(e);const a=this.refreshVfxActorsForAssetIds(t),s=this.refreshSpawnedInstancesForClipKeys(await this.findSpawnClipKeysUsingShaderGraph(e));return a||s}async findSequenceVfxAssetIdsUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of H(this.sequenceData.tracks))if("vfx"===s.type)for(const r of s.clips)null==r.vfxAssetId||t.has(r.vfxAssetId)||await this.assetUsesShaderGraph(r.vfxAssetId,e,a)&&t.add(r.vfxAssetId);return t}async findSpawnClipKeysUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of H(this.sequenceData.tracks))if("spawn"===s.type&&await this.spawnTrackUsesShaderGraph(s,e,a))for(const e of s.clips)t.add(`${s.id}-${e.id}`);return t}async spawnTrackUsesShaderGraph(e,t,a){if(null!=e.meshId&&await this.assetUsesShaderGraph(e.meshId,t,a))return!0;if(null!=e.prefabId&&await this.assetUsesShaderGraph(e.prefabId,t,a))return!0;for(const s of e.subTracks??[])if("material"===s.type&&null!=s.materialAssetId&&await this.assetUsesShaderGraph(s.materialAssetId,t,a))return!0;return!1}assetUsesShaderGraph(e,t,a,s=new Set){if(e===t)return Promise.resolve(!0);if(s.has(e))return Promise.resolve(!1);if(a.has(e))return a.get(e);const r=this.assetUsesShaderGraphUncached(e,t,a,s);return a.set(e,r),r}async assetUsesShaderGraphUncached(e,t,a,s){if(s.has(e))return!1;const r=await this.getAssetOrNull(e);if(null==r)return!1;const i=new Set(s);return i.add(e),!!this.materialAssetUsesShaderGraph(r,t)||("mesh"===r.type?this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,i):"prefab"===r.type?this.sceneObjectsUseShaderGraph(r.prefab?.objects,t,a,i):"vfx"===r.type&&this.vfxAssetUsesShaderGraph(r,t,a,i))}materialAssetUsesShaderGraph(e,t){return"shaderGraph"===e.type?e.id===t:"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===t}async materialAssignmentsUseShaderGraph(e,t,a,s){for(const r of e??[])if(null!=r.materialId&&"null"!==r.materialId&&await this.assetUsesShaderGraph(r.materialId,t,a,s))return!0;return!1}async sceneObjectsUseShaderGraph(e,t,a,s){for(const r of e??[]){if(await this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,s))return!0;if(null!=r.assetId&&("asset_mesh"===r.type||"prefab"===r.type||"vfx"===r.type)&&await this.assetUsesShaderGraph(r.assetId,t,a,s))return!0;if(await this.sceneObjectsUseShaderGraph(r.children,t,a,s))return!0}return!1}async vfxAssetUsesShaderGraph(e,t,a,s){for(const r of e.vfx?.emitters??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterUsesShaderGraph(e,t,a,s){if(await this.emitterOutputUsesShaderGraph(e.output,t,a,s))return!0;for(const r of e.children??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterOutputUsesShaderGraph(e,t,a,s){const r=e.materialSource??("asset"===e.shaderGraph?.source?"shaderGraph":void 0);return"shaderGraph"===r&&"asset"===e.shaderGraph?.source&&e.shaderGraph.assetId===t||!("material"!==r||!("material"in e)||null==e.material||!await this.assetUsesShaderGraph(e.material,t,a,s))}async getAssetOrNull(e){if(!this.assetLoader)return null;try{return await this.assetLoader.getAsset(e)??null}catch{return null}}async invokeSequenceEvent(e,t,a,s){let r=!1;for(let e=0;e<s.length;e++)if(C(s[e])){r=!0;break}if(r)try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=v(s[e],this.sequenceEventAsyncResolvers);const r=await Promise.all(t);await a.call(e,...r)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}else try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=g(s[e],this.sequenceEventSyncResolvers);a.call(e,...t)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}}resolveSequenceEventActorReference(e){if(!this.world||null==e)return null;const t=e,a="object"==typeof t&&null!=t?.id?t.id:"string"==typeof t?t:null;if(null==a)return null;for(const e of this.world.actors){const t=e.object.userData.src??e.object.userData._src;if(t?.id===a)return e}return null}resolveSequenceEventSequence(e){return function(e){return"object"==typeof e&&null!=e&&"duration"in e&&"tracks"in e}(e)?new w(e):this.assetLoader&&"string"==typeof e?this.assetLoader.getSequenceById(e):null}async resolveSequenceEventAnimationClip(e){const t="string"==typeof e?e:"object"==typeof e&&null!=e?e.assetId??null:null;return null!=t&&this.assetLoader?this.assetLoader.getAnimationClipByAssetId(t):null}}function V(e){return e.options?.length>0||e.propertyType===y.Boolean||e.propertyType===y.String}function D(e){return e.valueType===y.Boolean||e.valueType===y.String}function K(e){return"object"==typeof e&&null!=e||"function"==typeof e}function G(e,t){switch(t.type){case y.Number:return function(e){if("number"==typeof e)return Number.isFinite(e)?{applied:!0,value:e}:{applied:!1};if("string"==typeof e){const t=parseFloat(e);return Number.isFinite(t)?{applied:!0,value:t}:{applied:!1}}return{applied:!1}}(t.value);case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return N(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return W(e,t.value);case y.Color:return function(e,t){if(e instanceof c){const a=ce.set(0);return Y(a,t)?(e.set(a.r,a.g,a.b),{applied:!0,value:e}):{applied:!1}}if(e instanceof h){const a=ce.set(0);return Y(a,t)?(e.set(a.r,a.g,a.b,e.w),{applied:!0,value:e}):{applied:!1}}return X(e,t)}(e,t.value);default:return{applied:!1}}}function $(e,t){const s=S(t);return function(e){return e instanceof a.Material||!0===e?.isMaterial}(e)&&null!=e.uniforms?.[t.uniformName]&&("parameterName"===s||e.userData?.assetId===t.materialAssetId)}function N(e,t){const a=Q(t,2);return a?e instanceof l?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new l(a[0],a[1])}:{applied:!1}}function U(e,t){const a=Q(t,3);return a?e instanceof c?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new c(a[0],a[1],a[2])}:{applied:!1}}function W(e,t){const a=Q(t,4);return a?e instanceof h?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new h(a[0],a[1],a[2],a[3])}:{applied:!1}}function X(e,t){if(e instanceof r)return Y(e,t)?{applied:!0,value:e}:{applied:!1};const a=new r;return Y(a,t)?{applied:!0,value:a}:{applied:!1}}function Q(e,t){if(!Array.isArray(e)||e.length<t)return null;const a=new Array(t);for(let s=0;s<t;s++){if("number"!=typeof e[s])return null;a[s]=e[s]}return a}function Y(e,t){return t instanceof r||"string"==typeof t||"number"==typeof t?(e.set(t),!0):!!(Array.isArray(t)&&t.length>=3)&&(e.setRGB("number"==typeof t[0]?t[0]:0,"number"==typeof t[1]?t[1]:0,"number"==typeof t[2]?t[2]:0),!0)}function Z(e){if(e instanceof l||e instanceof c||e instanceof h||e instanceof r||e instanceof i)return e.clone()}function z(e){const{owner:t,key:a}=e.resolution;e.hadOwnProperty?(!function(e,t){if(e instanceof l&&t instanceof l)return e.copy(t),!0;if(e instanceof c&&t instanceof c)return e.copy(t),!0;if(e instanceof h&&t instanceof h)return e.copy(t),!0;if(e instanceof r&&t instanceof r)return e.copy(t),!0;if(e instanceof i&&t instanceof i)return e.copy(t),!0}(e.value,e.valueSnapshot),t[a]=e.value):delete t[a]}function H(e){const t=[];for(const a of e)t.push(a),"group"===a.type&&t.push(...H(a.childTracks));return t}function J(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function ee(e){const t=new a.Group;t.name=`SequenceLocatorMarker:${e}`,t.renderOrder=1e3;const s=new a.AxesHelper(.35);s.renderOrder=1e3;const r=Array.isArray(s.material)?s.material:[s.material];for(const e of r)e.depthTest=!1,e.transparent=!0,e.opacity=.9,e.toneMapped=!1;t.add(s);const i=function(e){if("undefined"==typeof document)return null;const t=document.createElement("canvas");t.width=256,t.height=64;const s=t.getContext("2d");if(!s)return null;s.clearRect(0,0,t.width,t.height),s.fillStyle="rgba(16, 18, 24, 0.78)",function(e,t,a,s,r,i){const n=t+s,o=a+r;e.beginPath(),e.moveTo(t+i,a),e.lineTo(n-i,a),e.quadraticCurveTo(n,a,n,a+i),e.lineTo(n,o-i),e.quadraticCurveTo(n,o,n-i,o),e.lineTo(t+i,o),e.quadraticCurveTo(t,o,t,o-i),e.lineTo(t,a+i),e.quadraticCurveTo(t,a,t+i,a),e.closePath()}(s,0,8,t.width,48,8),s.fill(),s.font="24px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillStyle="#f8fafc",s.fillText(e||"Locator",t.width/2,t.height/2);const r=new a.CanvasTexture(t);r.needsUpdate=!0;const i=new a.SpriteMaterial({map:r,transparent:!0,depthTest:!1});i.toneMapped=!1;const n=new a.Sprite(i);return n.scale.set(.9,.225,1),n}(e);return i&&(i.position.set(0,.45,0),i.renderOrder=1001,t.add(i)),t.traverse(e=>{e.raycast=()=>{}}),t}function te(e){e.traverse(e=>{const t=e.material;if(Array.isArray(t))for(const e of t)e?.dispose?.(),e?.map?.dispose?.();else t?.dispose?.(),t?.map?.dispose?.()})}const ae=new c,se=new c,re=new c,ie=new o,ne=new o,oe=new i,le=new i,ce=new r;/*
1
+ import{BehaviorSubject as e,Subject as t}from"rxjs";import*as a from"three";import{AnimationMixer as s,Color as i,Euler as r,Object3D as n,Quaternion as o,Vector2 as l,Vector3 as c,Vector4 as h}from"three";import{VisualEffect as u}from"../../effects/vfx/vfx-param.js";import{BaseActor as p}from"../../gameplay/actors/actor.js";import d from"../../gameplay/actors/builtin/index.js";import{Prefab as f,PrefabOf as m}from"../../scene/objects/prefab.js";import{SerializedParamType as y}from"../../scene/model.js";import{customParamValueNeedsAsyncResolution as C,deserializeCustomParamValue as g,deserializeCustomParamValueSync as v}from"../../scene/custom-param-deserialize.js";import{getAudioParameterDefinition as A}from"./audio-parameters.js";import{getMaterialSubTrackMatchMode as S,Sequence as w,isSequenceData as P}from"./sequence-data.js";import{getSequenceSubTrackDefinition as b,getSequenceTrackDefinition as k}from"./sequence-definitions.js";import{applyInterpolation as x,evaluateCustomParamValueKeyframes as T,evaluateNumericKeyframes as I,findKeyframeSpan as B}from"./sequence-value-lane.js";import{evaluateTransformPositionSpan as M}from"./sequence-transform.js";import{buildRetimedAnimationClip as q,getAnimationClipRetimingSignature as O,isAnimationClipUsingRetiming as F}from"./sequence-animation-retiming.js";import*as E from"three/addons/utils/SkeletonUtils.js";import{CharacterAnimationComponent as j,getCharacterMovementLike as L}from"../../gameplay/actors/index.js";import{RootMotionClip as _}from"../../gameplay/animation/root-motion.js";import{getAnimationClipRigId as R,getAnimationRigIdFromObject as V,setAnimationClipRigId as D}from"../../gameplay/animation/retarget.js";import{hashCameraShakeSeed as K}from"../../gameplay/services/camera-shake.js";import{buildShaderGraphPostProcessMaterial as $,shaderGraphPostProcessWeightUniformName as G}from"../../shader/graph/index.js";export var SequencePlaybackState;!function(e){e.Stopped="stopped",e.Playing="playing",e.Paused="paused"}(SequencePlaybackState||(SequencePlaybackState={}));export class SequencePlayer{constructor(){this._state=new e(SequencePlaybackState.Stopped),this._time=new e(0),this._duration=0,this._timescale=1,this._loop=!1,this._externalTimeControl=!1,this._inEditor=!1,this.bindings=new Map,this.roleBindings=new Map,this.sequenceData=null,this.onComplete=new t,this.onLoop=new t,this.onTimeUpdate=this._time.asObservable(),this.onStateChange=this._state.asObservable(),this.loopCount=0,this.viewController=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.sequenceCameras=new Map,this.cameraPlayables=new Map,this.cameraBlendCamera=null,this.cameraBlendSource=null,this.cameraBlendOutSource=null,this.cameraOverrideHandle=null,this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null,this.activeCameraShakeClipKeys=new Set,this.nextCameraShakeClipKeys=new Set,this.activePostProcessClips=new Map,this.nextPostProcessClipKeys=new Set,this.audioListener=null,this.audioBuffers=new Map,this.loadingAudioBuffers=new Map,this.animationClips=new Map,this.loadingAnimationClips=new Map,this.retimedAnimationClips=new Map,this.audioByClip=new Map,this.activeAudioClips=new Set,this.audioGainNodes=new Map,this.audioStartInFlight=new Map,this.lastAudioStartAttemptTime=new Map,this.audioStartRetryIntervalSeconds=.25,this.world=null,this.assetLoader=null,this.actorFactory=null,this.vfxService=null,this.spawnedInstances=new Map,this.activeClips=new Set,this.pendingSpawns=new Set,this.vfxActors=new Map,this.activeVfxClips=new Set,this.locatorMarkers=new Map,this.clearCounter=0,this.propertyPathSegments=new Map,this.propertyResolutionCache=new Map,this.propertySnapshots=new Map,this.materialResolutionCache=new Map,this.materialSnapshots=new Map,this.audioFilters=new Map,this.audioPannerNodes=new Map,this.firedEvents=new Set,this.sequenceEventSyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e)},this.sequenceEventAsyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e),texture:e=>this.assetLoader?.getTextureByAssetId(e)??null,sampler2DNode:e=>this.assetLoader?.getTextureByAssetId(e)??null,object3D:async e=>{const t=await(this.assetLoader?.getModelByAssetId(e));return t?.scene??null},material:e=>this.assetLoader?.getMaterialByAssetId(e)??null,audioBuffer:e=>this.assetLoader?.getAudioByAssetId(e)??null,visualEffect:async e=>{if(!this.assetLoader||!this.actorFactory)return null;const t=await this.assetLoader.getAsset(e);return t?new u(this.actorFactory,t):null},prefab:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new f(t.asset):null},prefabActor:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new m(new f(t.asset)):null},sequence:e=>this.resolveSequenceEventSequence(e),animationClip:e=>this.resolveSequenceEventAnimationClip(e)},this.trackRuntimeEvaluators={object:(e,t,a)=>{t&&this.evaluateObjectTrack(e,t,a)},locator:(e,t,a)=>{t&&this.evaluateLocatorTrack(e,t,a)},camera:(e,t,a)=>this.evaluateCameraTrack(e,a),cameraShake:(e,t,a)=>this.evaluateCameraShakeTrack(e,a),postProcess:(e,t,a)=>this.evaluatePostProcessTrack(e,a),audio:(e,t,a)=>this.evaluateAudioTrack(e,a),vfx:(e,t,a)=>this.evaluateVfxTrack(e,a),spawn:(e,t,a)=>this.evaluateSpawnTrack(e,t,a),group:(e,t,a)=>{if("group"===e.type)for(const t of e.childTracks)this.evaluateTrack(t,a)}},this.subTrackRuntimeEvaluators={transform:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateTransformSubTrack(e,s,a)},animation:(e,t,a)=>this.evaluateAnimationSubTrack(e,t,a),visibility:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateVisibilitySubTrack(e,s,a)},parameter:(e,t,a)=>this.evaluateParameterSubTrack(e,t.target||null,a),event:(e,t,a)=>this.evaluateEventSubTrack(e,t.target||null,a)}}get state(){return this._state.value}get time(){return this._time.value}get duration(){return this._duration}get timescale(){return this._timescale}set timescale(e){this._timescale=Math.max(.01,e)}get loop(){return this._loop}set loop(e){this._loop=e}get externalTimeControl(){return this._externalTimeControl}set externalTimeControl(e){this._externalTimeControl=e}get inEditor(){return this._inEditor}set inEditor(e){this._inEditor=e,this.updateLocatorMarkerVisibility()}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,e||this.releaseCameraOverride()}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId!==e&&(this._cameraControlTrackId=e,this.releaseCameraOverride())}setViewController(e){this.viewController&&this.viewController!==e&&this.viewController.clearCameraShakeContributionsForOwner(this),this.viewController=e}setWorld(e){this.world!==e&&(this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.world=e,this.clearCounter++,this.vfxActors.clear(),this.spawnedInstances.clear(),this.bindings.clear(),this.activeClips.clear(),this.activeVfxClips.clear(),this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear(),this.loadingAudioBuffers.clear(),this.audioFilters.clear(),this.audioPannerNodes.clear(),this.pendingSpawns.clear(),this.propertyResolutionCache.clear(),this.materialResolutionCache.clear(),this.clearRetimedAnimationClipCache(),this._state.next(SequencePlaybackState.Stopped),this.sequenceData&&this.initializeLocatorBindings())}setAudioListener(e){this.audioListener=e}setAssetLoader(e){if(this.assetLoader=e,this.sequenceData){const e=this.clearCounter;this.preloadSequenceResources(this.sequenceData,e)}}setActorFactory(e){this.actorFactory=e}setVfxService(e){this.vfxService=e}load(e){if(this.stop(),this.clearCounter++,this.clearLocatorBindings(),this.clearSequenceCameras(),this.sequenceData=e,this._duration=e.duration,this._loop=e.loop,this._timescale=e.playbackRate,this.clearRetimedAnimationClipCache(),this.bindings.clear(),this.initializeLocatorBindings(),this.loopCount=0,this.assetLoader){const t=this.clearCounter;this.preloadSequenceResources(e,t)}}preloadSequenceResources(e,t){return Promise.all([this.preloadAudioBuffersForSequence(e,t),this.preloadAnimationClipsForSequence(e,t)]).then(()=>{})}getAudioAssetIdsForSequence(e){const t=new Set;for(const a of e.tracks){if("audio"!==a.type)continue;const e=a;for(const a of e.clips??[])a.audioAssetId&&t.add(a.audioAssetId)}return[...t]}async preloadAudioBuffersForSequence(e,t){if(!this.assetLoader)return;const a=this.getAudioAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{if(t!==this.clearCounter)return;if(this.audioBuffers.has(e))return;let a=this.loadingAudioBuffers.get(e);a||(a=this.assetLoader.getAudioByAssetId(e),this.loadingAudioBuffers.set(e,a));try{const s=await a;if(t!==this.clearCounter)return;this.audioBuffers.set(e,s)}catch(e){}finally{this.loadingAudioBuffers.get(e)===a&&this.loadingAudioBuffers.delete(e)}}))}async preloadAnimationClipsForSequence(e,t){this.assetLoader&&t===this.clearCounter&&await this.prepareAnimationClipsForBindings(e,t)}async prepare(){if(!this.sequenceData||!this.assetLoader)return;this.resolveBindings();const e=this.clearCounter;await this.prepareAnimationClipsForBindings(this.sequenceData,e)}async prepareAnimationClipsForBindings(e,t){const a=[];for(const s of se(e.tracks)){if(!("subTracks"in s))continue;const e=this.bindings.get(s.id),i=null==e?null:this.getPlayableObject(e);if(null==i)continue;const r=V(i);for(const e of s.subTracks)if("animation"===e.type)for(const s of e.clips){if(t!==this.clearCounter)return;null!=s.animationClipAssetId&&a.push(this.ensureAnimationClip(s.animationClipAssetId,r))}}await Promise.all(a)}bindRole(e,t){this.roleBindings.set(e,t),this.sequenceData&&this.resolveBindings()}bindObject(e,t){if(this.sequenceData)for(const a of se(this.sequenceData.tracks))"object"!==a.type||a.targetId!==e||a.role||this.createBinding(a,t)}unbindObject(e){if(this.sequenceData)for(const t of se(this.sequenceData.tracks))"object"!==t.type||t.targetId!==e||t.role||this.removeBinding(t.id)}getLocator(e){return this.getLocators(e)[0]??null}getLocators(e){const t=ie(e);if(!t||!this.sequenceData)return[];const a=[];for(const e of se(this.sequenceData.tracks)){if("locator"!==e.type)continue;if(ie(e.bindingId)!==t)continue;const s=this.bindings.get(e.id),i=s?this.getPlayableObject(s):null;i&&(i.updateWorldMatrix(!0,!1),a.push({trackId:e.id,name:e.name,bindingId:e.bindingId,position:i.getWorldPosition(new c),rotation:i.getWorldQuaternion(new o),scale:i.getWorldScale(new c)}))}return a}resolveBindings(){if(this.sequenceData)for(const e of this.sequenceData.tracks)this.resolveTrackBinding(e)}initializeLocatorBindings(){if(this.sequenceData)for(const e of se(this.sequenceData.tracks)){if("locator"!==e.type||this.bindings.has(e.id))continue;const t=new n;t.name=e.name||"Locator",t.userData.sequenceLocatorTrackId=e.id,this.world?.scene&&null==t.parent&&this.world.scene.add(t);const a=re(e.name);a.visible=this._inEditor,t.add(a),this.locatorMarkers.set(e.id,a),this.disableLocatorInteraction(t),this.createBinding(e,t)}}clearLocatorBindings(){for(const e of this.locatorMarkers.values())ne(e);for(const e of this.bindings.values()){if("locator"!==e.track.type)continue;const t=this.getPlayableObject(e);t?.parent&&t.removeFromParent()}this.locatorMarkers.clear()}updateLocatorMarkerVisibility(){for(const e of this.locatorMarkers.values())e.visible=this._inEditor}disableLocatorInteraction(e){e.traverse(e=>{e.raycast=()=>{}})}resolveTrackBinding(e){if("object"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("spawn"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("group"===e.type)for(const t of e.childTracks)this.resolveTrackBinding(t)}createBinding(e,t){const a=t instanceof p?t.object:t,i=this.bindings.get(e.id),r=null!=i?i.target instanceof p?i.target.object:i.target:null,n=null!=i&&i.target===t&&r===a,o=e.subTracks.some(e=>"animation"===e.type);null==i||n||this.releaseBinding(i);const l=n?i:{track:e,target:t,activeActions:new Map};l.track=e,l.target=t,n||(l.originalTransform={position:a.position.clone(),rotation:a.rotation.clone(),scale:a.scale.clone()},l.originalParent=a.parent),o&&null==l.mixer?l.mixer=new s(a):o||(l.mixer=void 0),this.bindings.set(e.id,l)}removeBinding(e){const t=this.bindings.get(e);t&&(this.releaseBinding(t),this.bindings.delete(e))}releaseBinding(e){for(const t of e.activeActions.values())t.stop();e.activeActions.clear(),e.mixer?.stopAllAction(),e.charAnimComponent?.stopSequenceAnimation(),e.charAnimComponent=void 0,e.charAnimActionKeys?.clear()}play(){this._state.value!==SequencePlaybackState.Playing&&this.sequenceData&&(this._state.value===SequencePlaybackState.Stopped&&(this._time.next(0),this.loopCount=0,this.resolveBindings(),this.captureOriginalTransforms()),this._state.next(SequencePlaybackState.Playing),this.evaluate(this._time.value),this.resumeVfx())}pause(){this._state.value===SequencePlaybackState.Playing&&(this._state.next(SequencePlaybackState.Paused),this.pauseAudio(),this.pauseVfx())}pauseAudio(){for(const e of this.audioByClip.values())e.pause()}pauseVfx(){for(const e of this.vfxActors.values())e.pause()}resumeVfx(){for(const[e,t]of this.vfxActors.entries())(this.activeVfxClips.has(e)||t.getParticleCount()>0)&&t.play()}cancel(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}stop(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreOriginalTransforms(),this.restoreOriginalParents(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}restart(){this.stop(),this.play()}seek(e){const t=Math.max(0,Math.min(e,this._duration));t<this._time.value&&this.resetVfxForTimeReset(t),this._time.next(t),this.evaluate(t)}update(e){if(this._state.value!==SequencePlaybackState.Playing)return;if(!this.sequenceData)return;if(this._externalTimeControl){for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale);return}const t=this._time.value+e*this._timescale;if(t>=this._duration){if(!this._loop)return this._time.next(this._duration),this.evaluate(this._duration),this.releaseCameraOverride(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this._state.next(SequencePlaybackState.Stopped),void this.onComplete.next();{this.loopCount++;const e=t%this._duration;this.resetVfxForTimeReset(e),this._time.next(e),this.firedEvents.clear(),this.onLoop.next(this.loopCount)}}else this._time.next(t);this.evaluate(this._time.value);for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale)}evaluate(e){if(this.sequenceData){this.nextCameraShakeClipKeys.clear(),this.nextPostProcessClipKeys.clear();for(const t of this.sequenceData.tracks){if(!t.muted&&("object"===t.type||"locator"===t.type||"camera"===t.type||"spawn"===t.type||"vfx"===t.type)){const e=this.bindings.get(t.id);this.updateTrackParenting(t,e)}this.evaluateTrack(t,e)}this.updateCameraControl(e),this.syncCameraShakeContributions(),this.syncPostProcessEffects()}}evaluateTrack(e,t){if(e.muted)return;const a=this.bindings.get(e.id);(0,this.trackRuntimeEvaluators[k(e.type).runtimeEvaluator])(e,a,t)}evaluateObjectTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}evaluateLocatorTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}getActiveTrackObjects(e){if(!this.sequenceData)return[];const t=se(this.sequenceData.tracks).find(t=>t.id===e);return t?this.getActiveObjectsForTrack(t):[]}evaluateSubTracks(e,t,a){for(const s of e){if(s.muted)continue;(0,this.subTrackRuntimeEvaluators[b(s.type).runtimeEvaluator])(s,t,a)}}evaluateTransformSubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;const{prev:i,next:r,prevIndex:n,nextIndex:o,t:l}=B(s,a);if(i)if(e.components.position&&M(s,n,o,l,t.position),r&&i!==r){const a=x(l,i.interpolation);e.components.rotation&&i.rotation&&r.rotation&&(he.setFromEuler(pe.fromArray([...i.rotation,"XYZ"])),ue.setFromEuler(de.fromArray([...r.rotation,"XYZ"])),t.quaternion.slerpQuaternions(he,ue,a)),e.components.scale&&i.scale&&r.scale&&t.scale.lerpVectors(oe.fromArray(i.scale),le.fromArray(r.scale),a)}else e.components.rotation&&i.rotation&&t.rotation.fromArray([...i.rotation,"XYZ"]),e.components.scale&&i.scale&&t.scale.fromArray(i.scale)}evaluateAnimationSubTrack(e,t,s){if(!t.mixer||!t.activeActions)return;const i=t.target instanceof p?t.target.object:t.target;if(i)for(const r of e.clips){const n=r.startTime+r.duration,o=s>=r.startTime&&s<n,l=`${e.id}-${r.id}`;let c=t.activeActions.get(l),h=!1;if(o){if(!c){h=!0;const e=r.animationClipAssetId;if(null==e)continue;const s=V(i),n=this.animationClipCacheKey(e,s),o=this.animationClips.get(n);if(null==o){this.ensureAnimationClip(e,s);continue}const u=this.prepareAnimationPlayback(n,o,r),d=t;let f=!1;if(t.target instanceof p){d.charAnimComponent||(d.charAnimComponent=t.target.getComponent(j)??void 0);const e=d.charAnimComponent;if(null!=e){const a=r.rootMotion&&!this.inEditor?F(r)?this.getPlayableAnimationClip(n,o,r,!0):_.fromClip(u.clip,!1):u.clip;if(this._externalTimeControl)c=e.beginExternalAnimationControl(a,{timeScale:u.timeScale});else if(e.play(a,{inPlace:!r.rootMotion,loop:!1,priority:20,timeScale:u.timeScale,fadeTime:r.fadeInDuration??.2,offset:u.startOffset}),c=e.getFullBodyAction(),r.rootMotion){const e=L(t.target);e&&e.setRootMotionAction(c,{cancelWithJump:e.allowRootMotionJumpCancel,onJumpCancel:()=>this.cancel()})}t.activeActions.set(l,c),d.charAnimActionKeys||(d.charAnimActionKeys=new Set),d.charAnimActionKeys.add(l),f=!0}}f||(c=t.mixer.clipAction(u.clip),c.setLoop(a.LoopOnce,1),c.clampWhenFinished=!0,c.timeScale=u.timeScale,u.startOffset>0&&(c.time=u.startOffset),t.activeActions.set(l,c),c.play())}if(c){const e=t;if(this._externalTimeControl){e.charAnimComponent?.beginExternalControl();const a=this.getAnimationPlaybackLocalTime(r,s),i=Math.min(a,c.getClip().duration);(h||Math.abs(c.time-i)>.001)&&(c.time=i,c.paused=!1,c.play(),e.charAnimComponent?e.charAnimComponent.getMixer()?.update(0):t.mixer&&t.mixer.update(0))}else e.charAnimComponent?.endExternalControl()}}else if(c){t.activeActions.delete(l);const e=t;e.charAnimActionKeys?.has(l)?(e.charAnimActionKeys.delete(l),c.stop(),0===e.charAnimActionKeys.size&&e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0)):(c.stop(),this._externalTimeControl&&t.mixer&&t.mixer.update(0))}}}evaluateVisibilitySubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;let i=s[0];for(const e of s){if(!(e.time<=a))break;i=e}t.visible=i.visible}evaluatePropertySubTrack(e,t,a){const s=T(e.keyframes,a,{min:e.range?.[0],max:e.range?.[1],stepOnly:N(e)});s&&this.applyResolvedPropertyValue(e,t,s)}evaluateParameterSubTrack(e,t,a){if("audioParameter"===e.type)return;const s=T(e.keyframes,a,"property"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:N(e)}:"material"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:U(e)}:{});s&&("property"!==e.type?this.applyResolvedMaterialValue(e,t,s):this.applyResolvedPropertyValue(e,t,s))}evaluateEventSubTrack(e,t,a){if(t instanceof p&&this._state.value===SequencePlaybackState.Playing)for(const s of e.events){const i=`${e.id}-${s.id}`;if(a>=s.time&&!this.firedEvents.has(i)){if(this.firedEvents.add(i),s.editorOnly&&!this._inEditor)continue;if(!s.functionName)continue;const e=t[s.functionName];"function"==typeof e?this.invokeSequenceEvent(t,s.functionName,e,s.arguments??[]):console.warn(`Sequence event method '${s.functionName}' not found on actor`)}else s.time>a&&this.firedEvents.delete(i)}}evaluateCameraTrack(e,t){const a=this.ensureSequenceCamera(e);this.applyCameraTrackSettings(e,a),this.evaluateSubTracks(e.subTracks,this.getCameraPlayable(e,a),t),a.updateProjectionMatrix()}evaluateCameraShakeTrack(e,t){if(this.viewController)for(const a of e.clips??[]){if(!this.isCameraShakeClipActive(a,t))continue;const e=t-a.startTime,s=a.id;this.nextCameraShakeClipKeys.add(s),this.viewController.setCameraShakeContribution(this,s,a,e,a.seed??K(a.id))}}evaluatePostProcessTrack(e,t){if(this.viewController&&this.assetLoader){for(const a of e.clips??[]){if(!this.isPostProcessClipActive(a,t))continue;const s=this.getPostProcessClipKey(e,a);this.nextPostProcessClipKeys.add(s),this.ensurePostProcessClipEffect(e,a,s);const i=this.activePostProcessClips.get(s);i?.handle&&(i.handle.stage=e.stage,i.handle.priority=e.priority,i.handle.enabled=!0,this.applyPostProcessClipWeight(i.handle,a,t))}this.evaluatePostProcessMaterialSubTracks(e,t)}}evaluatePostProcessMaterialSubTracks(e,t){for(const a of e.subTracks){if(a.muted||"material"!==a.type)continue;const s=T(a.keyframes,t,{min:a.range?.[0],max:a.range?.[1],stepOnly:U(a)});s&&this.applyPostProcessMaterialValue(e.id,a,s)}}applyPostProcessMaterialValue(e,t,a){if(t.uniformName)for(const s of this.activePostProcessClips.values()){if(s.trackId!==e||!s.handle)continue;const i=s.handle.material,r=i.uniforms?.[t.uniformName];if(!r)continue;const n=X(r.value,a);n.applied&&(r.value=n.value,i.uniformsNeedUpdate=!0)}}isPostProcessClipActive(e,t){return t>=e.startTime&&t<e.startTime+e.duration}getPostProcessClipKey(e,t){return`${e.id}-${t.id}`}ensurePostProcessClipEffect(e,t,a){const s=t.shaderGraphAssetId;if(!s)return void this.releasePostProcessClipEffect(a);const i=JSON.stringify(t.shaderGraphParams??{}),r=this.activePostProcessClips.get(a);if(r?.assetId===s&&r.paramsSignature===i)return;this.releasePostProcessClipEffect(a);const n={key:a,trackId:e.id,clipId:t.id,assetId:s,paramsSignature:i,version:this.clearCounter};this.activePostProcessClips.set(a,n),this.loadPostProcessClipEffect(e,t,n)}async loadPostProcessClipEffect(e,t,a){if(this.assetLoader&&this.viewController)try{const s=await this.assetLoader.getShaderGraphByAssetId(a.assetId);if(!this.isPostProcessClipEntryCurrent(a))return;if("postProcess"!==s.target)return console.warn(`Sequence post-process clip references shader graph "${a.assetId}" with target "${s.target}"`),void this.releasePostProcessClipEffect(a.key);const i=await this.assetLoader.prepareShaderGraphParameters(s,t.shaderGraphParams??{});if(!this.isPostProcessClipEntryCurrent(a))return;const r=$(s,{parameters:i});if(!this.isPostProcessClipEntryCurrent(a))return void r.dispose();a.handle=this.viewController.addPostProcessEffect(r,{stage:e.stage,priority:e.priority,enabled:!0}),this.applyPostProcessClipWeight(a.handle,t,this._time.value)}catch(e){this.isPostProcessClipEntryCurrent(a)&&this.releasePostProcessClipEffect(a.key),console.error(`Failed to create post-process effect for clip ${t.id}:`,e)}}isPostProcessClipEntryCurrent(e){return this.clearCounter===e.version&&this.activePostProcessClips.get(e.key)===e}applyPostProcessClipWeight(e,t,a){const s=e.material.uniforms?.[G];null!=s&&(s.value=this.getPostProcessClipWeight(t,a),e.material.uniformsNeedUpdate=!0)}getPostProcessClipWeight(e,t){const a=Math.max(0,t-e.startTime),s=Math.max(0,e.startTime+e.duration-t);let i=1;const r=Math.max(0,e.fadeInDuration??0);r>0&&(i=Math.min(i,a/r));const n=Math.max(0,e.fadeOutDuration??0);return n>0&&(i=Math.min(i,s/n)),Math.max(0,Math.min(1,i))}syncPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.nextPostProcessClipKeys.has(e)||this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}clearPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}releasePostProcessClipEffect(e){const t=this.activePostProcessClips.get(e);if(t&&(this.activePostProcessClips.delete(e),t.handle)){const e=t.handle.material;t.handle.dispose(),e.dispose()}}getCameraPlayable(e,t){let a=this.cameraPlayables.get(e.id);return a?a.target=t:(a={target:t},this.cameraPlayables.set(e.id,a)),a}ensureSequenceCamera(e){let t=this.sequenceCameras.get(e.id);if(t)null==t.parent&&this.world?.scene.add(t);else{const s=e.cameraSettings??{fov:60,near:.1,far:1e3};t=new a.PerspectiveCamera(s.fov??60,this.getCurrentCameraAspect(),s.near??.1,s.far??1e3),t.name=e.name||"Sequence Camera",t.userData.sequenceCameraTrackId=e.id,t.layers.mask=this.viewController?.getBaseCamera().layers.mask??t.layers.mask,this.sequenceCameras.set(e.id,t),this.world?.scene.add(t)}return t}clearSequenceCameras(){this.releaseCameraOverride();for(const e of this.sequenceCameras.values())e.removeFromParent();this.sequenceCameras.clear(),this.cameraPlayables.clear()}applyCameraTrackSettings(e,t){const a=e.cameraSettings??{fov:60,near:.1,far:1e3};t.fov=a.fov??60,t.near=a.near??.1,t.far=a.far??1e3,t.aspect=this.getCurrentCameraAspect()}getCurrentCameraAspect(){const e=this.viewController?.getBaseCamera();if(e instanceof a.PerspectiveCamera&&Number.isFinite(e.aspect)&&e.aspect>0)return e.aspect;const t=this.viewController?.getSourceCamera();return t instanceof a.PerspectiveCamera&&Number.isFinite(t.aspect)&&t.aspect>0?t.aspect:1}updateCameraControl(e){if(!this._cameraControlEnabled||!this.viewController||!this.sequenceData)return void this.releaseCameraOverride();const t=this.findActiveCameraShot(e);if(t)return void this.updateActiveCameraShot(t,e);const a=this.findBlendOutCameraShot(e);a?this.updateCameraBlendOut(a,e):this.releaseCameraOverride()}findActiveCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of se(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const i of s)this.isCameraClipActive(i,e)&&(t={track:a,clip:i,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,i)})}return t}findBlendOutCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of se(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const i of s){const s=Math.max(0,i.blendOutDuration??0);if(s<=0)continue;const r=this.getCameraClipEnd(i);e>=r&&e<r+s&&(t={track:a,clip:i,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,i)})}}return t}isCameraControlTrackEligible(e){return null==this._cameraControlTrackId||e.id===this._cameraControlTrackId}updateActiveCameraShot(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();this.activeCameraClipKey!==e.key&&(this.copyCameraState(this.viewController.getSourceCamera(),this.ensureCameraBlendSource()),this.activeCameraClipKey=e.key,this.cameraBlendOutClipKey=null);const s=Math.max(0,e.clip.blendInDuration??0),i=s<=0?1:this.evaluateCameraBlendAlpha((t-e.clip.startTime)/s,e.clip);i>=1?this.copyCameraState(e.camera,a):this.blendCameraState(this.ensureCameraBlendSource(),e.camera,a,i),a.updateProjectionMatrix(),this.ensureCameraOverride()}updateCameraBlendOut(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();if(this.cameraBlendOutClipKey!==e.key){const t=this.activeCameraClipKey===e.key?this.viewController.getSourceCamera():e.camera;this.copyCameraState(t,this.ensureCameraBlendOutSource()),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=e.key}const s=this.getCameraClipEnd(e.clip),i=Math.max(0,e.clip.blendOutDuration??0),r=i<=0?1:this.evaluateCameraBlendAlpha((t-s)/i,e.clip);this.blendCameraState(this.ensureCameraBlendOutSource(),this.viewController.getBaseCamera(),a,r),a.updateProjectionMatrix(),this.ensureCameraOverride()}ensureCameraBlendCamera(){return this.cameraBlendCamera||(this.cameraBlendCamera=new a.PerspectiveCamera(60,this.getCurrentCameraAspect(),.1,1e3),this.cameraBlendCamera.name="Sequence Camera Blend"),this.cameraBlendCamera}ensureCameraBlendSource(){return this.cameraBlendSource||(this.cameraBlendSource=new a.PerspectiveCamera),this.cameraBlendSource}ensureCameraBlendOutSource(){return this.cameraBlendOutSource||(this.cameraBlendOutSource=new a.PerspectiveCamera),this.cameraBlendOutSource}ensureCameraOverride(){this.viewController&&!this.cameraOverrideHandle&&(this.cameraOverrideHandle=this.viewController.pushCameraOverride(this.ensureCameraBlendCamera(),this))}releaseCameraOverride(){this.cameraOverrideHandle?.release(),this.cameraOverrideHandle=null,this.viewController?.releaseCameraOverridesForOwner(this),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null}isCameraClipActive(e,t){return t>=e.startTime&&t<this.getCameraClipEnd(e)}getCameraClipEnd(e){return e.startTime+Math.max(0,e.duration)}isCameraShakeClipActive(e,t){return t>=e.startTime&&t<this.getCameraShakeClipEnd(e)}getCameraShakeClipEnd(e){return e.startTime+Math.max(0,e.duration)}getCameraClipKey(e,t){return`${e.id}-${t.id}`}evaluateCameraBlendAlpha(e,t){return x(Math.max(0,Math.min(1,e)),t.blendInterpolation??"cubic")}syncCameraShakeContributions(){if(!this.viewController)return this.activeCameraShakeClipKeys.clear(),void this.nextCameraShakeClipKeys.clear();for(const e of this.activeCameraShakeClipKeys)this.nextCameraShakeClipKeys.has(e)||this.viewController.removeCameraShakeContribution(this,e);this.activeCameraShakeClipKeys.clear();for(const e of this.nextCameraShakeClipKeys)this.activeCameraShakeClipKeys.add(e);this.nextCameraShakeClipKeys.clear()}clearCameraShakeContributions(){this.activeCameraShakeClipKeys.clear(),this.nextCameraShakeClipKeys.clear(),this.viewController?.clearCameraShakeContributionsForOwner(this)}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(oe)),t.quaternion.copy(e.getWorldQuaternion(he)),t.scale.copy(e.getWorldScale(le)),e instanceof a.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect):t.aspect=this.getCurrentCameraAspect(),t.layers.mask=e.layers.mask}blendCameraState(e,t,s,i){e.updateWorldMatrix(!0,!1),t.updateWorldMatrix(!0,!1),s.position.lerpVectors(e.getWorldPosition(oe),t.getWorldPosition(le),i),s.quaternion.slerpQuaternions(e.getWorldQuaternion(he),t.getWorldQuaternion(ue),i),s.scale.lerpVectors(e.getWorldScale(oe),t.getWorldScale(le),i),e instanceof a.PerspectiveCamera&&t instanceof a.PerspectiveCamera?(s.fov=e.fov+(t.fov-e.fov)*i,s.near=e.near+(t.near-e.near)*i,s.far=e.far+(t.far-e.far)*i,s.aspect=t.aspect):t instanceof a.PerspectiveCamera?(s.fov=t.fov,s.near=t.near,s.far=t.far,s.aspect=t.aspect):s.aspect=this.getCurrentCameraAspect(),s.layers.mask=t.layers.mask}evaluateAudioTrack(e,t){if(!this.assetLoader||!e.clips||0===e.clips.length)return;const a=this._state.value===SequencePlaybackState.Playing,s=this.evaluateAudioSubTracks(e,t);e.volume;for(const i of e.clips){const r=i.startTime+i.duration,n=t>=i.startTime&&t<r,o=`${e.id}-${i.id}`;if(n){if(this.activeAudioClips.has(o)||this.activeAudioClips.add(o),a){const a=this.audioByClip.get(o);a&&a.isPlaying||this.tryStartAudioClip(e,i,o,t,s)}const r=this.audioByClip.get(o);r&&this.applyAudioParameters(r,e,i,o,t,s)}else this.activeAudioClips.has(o)&&(this.activeAudioClips.delete(o),this.lastAudioStartAttemptTime.delete(o),this.audioStartInFlight.delete(o),this.stopAudioClip(o))}}tryStartAudioClip(e,t,a,s,i){if(this.audioStartInFlight.has(a))return;const r=this.lastAudioStartAttemptTime.get(a);if(void 0!==r&&s-r<this.audioStartRetryIntervalSeconds)return;this.lastAudioStartAttemptTime.set(a,s);const n=this.playAudioClip(e,t,a,s,i).catch(()=>{}).finally(()=>{this.audioStartInFlight.get(a)===n&&this.audioStartInFlight.delete(a)});this.audioStartInFlight.set(a,n)}applyAudioParameters(e,t,s,i,r,n){const o=n.volume??1,l=Math.random(),c=s.volumeRandomization?(2*l-1)*s.volumeRandomization:0;let h=1;const u=r-s.startTime;u<s.fadeInDuration&&s.fadeInDuration>0?h=u/s.fadeInDuration:u>s.duration-s.fadeOutDuration&&s.fadeOutDuration>0&&(h=(s.duration-u)/s.fadeOutDuration);const p=Math.max(0,(t.volume??1)*o*(s.volume+c)*h);e.setVolume(p);let d=n.detune??0;if(s.pitchRandomization){d+=(2*Math.random()-1)*s.pitchRandomization}if(e.setDetune(d),e.hasPlaybackControl&&e.setPlaybackRate(s.playbackRate*this.timescale),this.audioListener&&this.audioListener.context){const s=this.audioListener.context,r=[],o=n.lowpass,l=n.highpass;let c=this.audioFilters.get(i);if(void 0!==o||void 0!==l)c||(c=s.createBiquadFilter(),this.audioFilters.set(i,c)),void 0!==o?(c.type="lowpass",c.frequency.value=o):void 0!==l&&(c.type="highpass",c.frequency.value=l),r.push(c);else if(c){try{c.disconnect()}catch{}this.audioFilters.delete(i)}const h=n.pan;if(!t.spatial&&e instanceof a.Audio&&void 0!==h&&"function"==typeof s.createStereoPanner){let e=this.audioPannerNodes.get(i);e||(e=s.createStereoPanner(),this.audioPannerNodes.set(i,e)),e.pan.value=h,r.push(e)}else{const e=this.audioPannerNodes.get(i);if(e){try{e.disconnect()}catch{}this.audioPannerNodes.delete(i)}}e.setFilters(r)}t.spatial&&e instanceof a.PositionalAudio?this.updatePositionalAudioTransform(e,t,s,n.spatialBlend):void 0!==n.pan&&this.audioListener}updatePositionalAudioTransform(e,t,s,i){let r=null,n=null;const o=s.attachedToTrackId||t.parent?.trackId,l=s.attachmentSocketName||t.parent?.socketName;if(o){const e=this.sequenceData?.tracks.find(e=>e.id===o);if(e){const t=this.getActiveObjectsForTrack(e);if(t.length>0){const e=t[0];if(r=oe,n=he,e.getWorldPosition(r),e.getWorldQuaternion(n),l){const t=this.findSocket(e,l);t&&(t.getWorldPosition(r),t.getWorldQuaternion(n))}}}}if(r&&n){const t="number"==typeof i?a.MathUtils.clamp(i,0,1):1;if(t<1&&this.audioListener){const e=ce;this.audioListener.getWorldPosition(e),r=r.clone().lerp(e,1-t)}e.position.copy(r),e.quaternion.copy(n),e.updateMatrixWorld()}}async playAudioClip(e,t,s,i,r){if(!this.assetLoader||!t.audioAssetId||null==this.audioListener)return;if("suspended"===this.audioListener.context.state)try{await this.audioListener.context.resume()}catch(e){return void console.warn("Failed to resume audio context:",e)}this.stopAudioClip(s);const n=this.clearCounter;try{let i=this.audioBuffers.get(t.audioAssetId);if(!i){let e=this.loadingAudioBuffers.get(t.audioAssetId);e||(e=this.assetLoader.getAudioByAssetId(t.audioAssetId),this.loadingAudioBuffers.set(t.audioAssetId,e));try{i=await e,this.audioBuffers.set(t.audioAssetId,i)}finally{this.loadingAudioBuffers.delete(t.audioAssetId)}}if(n!==this.clearCounter)return;const o=this._time.value,l=t.startTime+t.duration;if(!(o>=t.startTime&&o<l))return;const c=Math.max(0,o-t.startTime),h=t.clipStartOffset+c*t.playbackRate;if(h>=i.duration||c>=t.duration)return;let u=this.audioByClip.get(s);const p=!0===e.spatial,d=u&&!0===u.isPositionalAudio;if(u&&p!==d&&(u.isPlaying&&u.stop(),u.disconnect(),this.audioByClip.delete(s),u=void 0),!u){if(p){const e=new a.PositionalAudio(this.audioListener);e.setRefDistance(10),e.setRolloffFactor(1),u=e}else u=new a.Audio(this.audioListener);this.world&&this.world.scene.add(u),this.audioByClip.set(s,u)}Math.min((t.duration-c)/t.playbackRate,(i.duration-h)/t.playbackRate);u.setLoopStart(t.clipStartOffset),u.setLoopEnd(Math.min(t.clipStartOffset+t.duration,i.duration)),u.setLoop(!0),u.setBuffer(i),this.applyAudioParameters(u,e,t,s,o,r),u.isPlaying||u.play()}catch(e){console.error(`Failed to play audio clip ${t.id}:`,e)}}stopAudioClip(e){const t=this.audioByClip.get(e);if(t){try{t.isPlaying&&t.stop()}catch(e){}t.parent&&t.parent.remove(t),this.audioByClip.delete(e)}const a=this.audioGainNodes.get(e);a&&(a.disconnect(),this.audioGainNodes.delete(e));const s=this.audioFilters.get(e);if(s){try{s.disconnect()}catch{}this.audioFilters.delete(e)}const i=this.audioPannerNodes.get(e);if(i){try{i.disconnect()}catch{}this.audioPannerNodes.delete(e)}}stopAllAudio(){for(const e of this.audioByClip.keys())this.stopAudioClip(e);this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear()}evaluateVfxTrack(e,t){if(!this.vfxService||!this.world||!e.clips||0===e.clips.length)return;const a=new Set,s=new Map;for(const i of e.clips){const r=this.getVfxClipKey(e,i);s.set(r,i),this.isVfxClipActiveAtTime(i,t)&&a.add(r)}const i=[];for(const t of this.activeVfxClips)t.startsWith(`${e.id}-`)&&(a.has(t)||i.push(t));for(const e of i)this.activeVfxClips.delete(e);for(const[i,r]of s.entries()){const s=this.vfxActors.get(i);a.has(i)&&!this.activeVfxClips.has(i)?(this.activeVfxClips.add(i),this.ensureVfxActor(e,r,i)):a.has(i)&&s?(this.updateVfxTransform(e,s,t),this._state.value===SequencePlaybackState.Playing&&s.play()):s&&this.applyInactiveVfxClipBehavior(r,s,t)}}getVfxClipKey(e,t){return`${e.id}-${t.id}-${t.vfxAssetId}`}isVfxClipActiveAtTime(e,t){const a=e.startTime+e.duration;return t>=e.startTime&&t<a}resetVfxForTimeReset(e){const t=new Set;if(this.sequenceData)for(const a of se(this.sequenceData.tracks))if("vfx"===a.type)for(const s of a.clips??[])this.isVfxClipActiveAtTime(s,e)&&t.add(this.getVfxClipKey(a,s));this.activeVfxClips.clear();for(const[e,a]of this.vfxActors.entries())t.has(e)||(a.restart(),a.stop(),a.pause())}applyInactiveVfxClipBehavior(e,t,a){const s=e.endBehavior??"finish";if("finish"===s)return void t.stop();if("kill"===s)return void t.applyClipEndBehavior(s);const i=e.startTime+e.duration,r=Math.max(a-i,0),n=Math.max(0,e.expireWithinSeconds??.25),o=Math.max(0,n-r);t.applyClipEndBehavior(s,o)}async ensureVfxActor(e,t,a){if(!this.vfxService||!t.vfxAssetId)return;if(this.vfxActors.has(a)){const e=this.vfxActors.get(a);return e.restart(),void e.play()}const s=this.clearCounter;try{const i=await this.vfxService.createFromAssetId(t.vfxAssetId,this.world.scene);if(s!==this.clearCounter)return void(this.world&&this.world.removeActor(i));const{position:r,rotation:n,scale:o}=this.getVfxTransform(e,t.startTime);i.object.position.copy(r),i.object.rotation.copy(n),i.object.scale.copy(o),this.vfxActors.set(a,i),this._state.value===SequencePlaybackState.Playing&&i.play()}catch(e){console.error(`Failed to create VFX actor for clip ${t.id}:`,e)}}getVfxTransform(e,t){const a=new c,s=new r,i=new c(1,1,1),n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,next:r,prevIndex:l,nextIndex:c,t:h}=B(n.keyframes,t);if(n.components.position&&M(n.keyframes,l,c,h,a),e&&(e.rotation&&s.fromArray([...e.rotation,"XYZ"]),e.scale&&i.fromArray(e.scale)),r&&e!==r&&e.time!==r.time){const t=x(h,e.interpolation);if(e.rotation&&r.rotation){he.setFromEuler(pe.fromArray([...e.rotation,"XYZ"])),ue.setFromEuler(de.fromArray([...r.rotation,"XYZ"]));const a=new o;a.slerpQuaternions(he,ue,t),s.setFromQuaternion(a)}e.scale&&r.scale&&i.lerpVectors(oe.fromArray(e.scale),le.fromArray(r.scale),t)}}else a.fromArray(e.position),s.fromArray([...e.rotation,"XYZ"]),i.fromArray(e.scale);return{position:a,rotation:s,scale:i}}updateVfxTransform(e,t,a){const{position:s,rotation:i,scale:r}=this.getVfxTransform(e,a);t.object.position.copy(s),t.object.rotation.copy(i),t.object.scale.copy(r)}resolveActorType(e){const t=this.actorFactory.classes[e];if(null!=t)return t;const a=d[e];return a||(console.warn(`Could not resolve actor type: ${e}`),null)}async spawnActorForClip(e,t,a,s){if(!this.world||!e.actorType)return null;const i=this.resolveActorType(e.actorType);if(!i)return null;try{return await this.world.spawnActor(i,a,s)}catch(t){return console.error(`Failed to spawn actor ${e.actorType}:`,t),null}}async spawnPrefabForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.prefabId)return null;try{const t=await this.assetLoader.getPrefabById(e.prefabId);if(!t)return null;return await this.world.spawnPrefab(t,a,s)}catch(t){return console.error(`Failed to spawn prefab ${e.prefabId}:`,t),null}}async spawnMeshForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.meshId)return null;try{const t=await this.assetLoader.getAsset(e.meshId),i=await this.assetLoader.getModelByAssetId(e.meshId),r=E.clone(i.scene);if(r.position.copy(a),r.rotation.copy(s),t){await this.assetLoader.applyMaterials(t,r);const e=t.mesh?.rescale;null!=e&&1!==e&&r.scale.multiplyScalar(e)}return this.world.scene.add(r),r}catch(t){return console.error(`Failed to spawn mesh ${e.meshId}:`,t),null}}despawnInstance(e){if(this.restorePropertySnapshotsForInstance(e),this.restoreMaterialSnapshotsForInstance(e),this.world)switch(e?.type){case"actor":this.world.removeActor(e.instance);break;case"prefab":this.world.removePrefab(e.instance);break;case"mesh":this.world.scene.remove(e.instance)}}despawnAll(){for(const e of this.spawnedInstances.values())this.despawnInstance(e);this.spawnedInstances.clear(),this.activeClips.clear(),this.pendingSpawns.clear()}getInitialTransform(e,t,a){const s=new c,i=new r,n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,prevIndex:t,nextIndex:r,t:o}=B(n.keyframes,a);n.components.position&&M(n.keyframes,t,r,o,s),e&&e.rotation&&i.fromArray([...e.rotation,"XYZ"])}else t.initialPosition&&s.fromArray(t.initialPosition),t.initialRotation&&i.fromArray([...t.initialRotation,"XYZ"]);return{position:s,rotation:i}}evaluateSpawnTrack(e,t,a){if(!e.clips||0===e.clips.length)return;const s=t||this.bindings.get(e.id);if(s&&s.target)for(const t of e.clips){const i=t.startTime+t.duration,r=a>=t.startTime&&a<i,n=`${e.id}-${t.id}`;if(r){this.activeClips.has(n)||(this.activeClips.add(n),this.spawnedInstances.set(n,{type:"proxy",target:s.target}));(s.target instanceof p?s.target.object:s.target)&&this.evaluateSubTracks(e.subTracks,s,a)}else this.activeClips.has(n)&&(this.restorePropertySnapshotsForTarget(s.target),this.restoreMaterialSnapshotsForTarget(s.target),this.activeClips.delete(n),this.spawnedInstances.delete(n))}else for(const t of e.clips){const s=t.startTime+t.duration,i=a>=t.startTime&&a<s,r=`${e.id}-${t.id}`,n=this.spawnedInstances.has(r),o=this.pendingSpawns.has(r);if(!i||n||o){if(i&&n){const t=this.spawnedInstances.get(r);t&&"proxy"!==t.type&&this.evaluateSubTracks(e.subTracks,t,a)}else if(!i&&n){const e=this.spawnedInstances.get(r);e&&(this.despawnInstance(e),this.spawnedInstances.delete(r),this.activeClips.delete(r))}}else{const{position:a,rotation:s}=this.getInitialTransform(e,t,t.startTime);this.pendingSpawns.add(r),this.spawnForClip(e,t,a,s,r)}}}getInstanceObject(e){switch(e.type){case"actor":return e.instance.object;case"prefab":return e.instance.mainActor?.object||e.instance.object;case"mesh":return e.instance;case"proxy":return e.target instanceof p?e.target.object:e.target;default:return null}}async spawnForClip(e,t,a,i,r){const n=this.clearCounter;let o=null;try{switch(e.spawnType){case"actor":const s=await this.spawnActorForClip(e,t,a,i);s&&(o={type:"actor",instance:s});break;case"prefab":const r=await this.spawnPrefabForClip(e,t,a,i);r&&(o={type:"prefab",instance:r});break;case"mesh":const n=await this.spawnMeshForClip(e,t,a,i);n&&(o={type:"mesh",instance:n})}if(n!==this.clearCounter)return void(o&&this.despawnInstance(o));const l=this._time.value,c=l>=t.startTime&&l<t.startTime+t.duration;if(o&&c){const t=this.getInstanceObject(o);"proxy"===o.type||("actor"===o.type?o.target=o.instance:"prefab"===o.type?o.target=o.instance.mainActor||o.instance.object:o.target=t);e.subTracks.some(e=>"animation"===e.type)&&t&&(o.mixer=new s(t),o.activeActions=new Map),this.spawnedInstances.set(r,o),this.activeClips.add(r)}else o&&this.despawnInstance(o)}finally{this.pendingSpawns.delete(r)}}getPlayableObject(e){return e.target instanceof p?e.target.object:e.target??null}applyResolvedPropertyValue(e,t,a){if(!t||!e.propertyPath)return;const s=this.getPropertyResolution(t,e);if(!s)return;const i=this.getPropertySnapshotKey(e);this.capturePropertySnapshot(t,i,s);const n=function(e,t){switch(t.type){case y.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.String:return"string"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return Y(e,t.value);case y.Vector3:return Z(e,t.value);case y.Vector4:return z(e,t.value);case y.Euler:return function(e,t){const a=J(t,3);if(!a)return{applied:!1};const s=Array.isArray(t)&&"string"==typeof t[3]?t[3]:"XYZ";if(e instanceof r)return e.set(a[0],a[1],a[2],s),{applied:!0,value:e};return{applied:!0,value:new r(a[0],a[1],a[2],s)}}(e,t.value);case y.Color:return H(e,t.value);default:return{applied:!1}}}(s.owner[s.key],a);n.applied&&(s.owner[s.key]=n.value)}getPropertyResolution(e,t){const a=e,s=this.getPropertySnapshotKey(t);let i=this.propertyResolutionCache.get(a);if(i||(i=new Map,this.propertyResolutionCache.set(a,i)),i.has(s))return i.get(s)??null;const r=this.getPropertyPathSegments(t.propertyPath);if(0===r.length)return i.set(s,null),null;let n=e;for(let e=0;e<r.length-1;e++){if(!W(n))return i.set(s,null),null;n=n[r[e]]}if(!W(n))return i.set(s,null),null;const o={owner:n,key:r[r.length-1]};return i.set(s,o),o}getPropertyPathSegments(e){const t=this.propertyPathSegments.get(e);if(t)return t;const a=e.split(".").map(e=>e.trim()).filter(Boolean);return this.propertyPathSegments.set(e,a),a}getPropertySnapshotKey(e){return`${e.id}:${e.propertyPath}`}capturePropertySnapshot(e,t,a){const s=e;let i=this.propertySnapshots.get(s);if(i||(i=new Map,this.propertySnapshots.set(s,i)),i.has(t))return;const r=a.owner[a.key];i.set(t,{resolution:a,hadOwnProperty:Object.prototype.hasOwnProperty.call(a.owner,a.key),value:r,valueSnapshot:te(r)})}restorePropertySnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restorePropertySnapshotsForTarget(e.instance);break;case"prefab":this.restorePropertySnapshotsForTarget(e.target??null),this.restorePropertySnapshotsForTarget(e.instance.mainActor??null),this.restorePropertySnapshotsForTarget(e.instance.object);break;case"proxy":this.restorePropertySnapshotsForTarget(e.target)}}restorePropertySnapshotsForTarget(e){if(!e)return;const t=e,a=this.propertySnapshots.get(t);if(a){for(const e of a.values())ae(e);this.propertySnapshots.delete(t),this.propertyResolutionCache.delete(t)}}restoreAllPropertySnapshots(){for(const e of Array.from(this.propertySnapshots.keys()))this.restorePropertySnapshotsForTarget(e)}restoreMaterialSnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restoreMaterialSnapshotsForTarget(e.instance);break;case"prefab":this.restoreMaterialSnapshotsForTarget(e.target??null),this.restoreMaterialSnapshotsForTarget(e.instance.mainActor??null),this.restoreMaterialSnapshotsForTarget(e.instance.object);break;case"proxy":this.restoreMaterialSnapshotsForTarget(e.target)}}restoreMaterialSnapshotsForTarget(e){if(!e)return;const t=e;this.materialResolutionCache.delete(t);const a=this.materialSnapshots.get(t);if(a){for(const e of a.values())null==e.materialIndex?e.owner.material=e.originalMaterial:Array.isArray(e.owner.material)&&(e.owner.material[e.materialIndex]=e.originalMaterial),e.controlledMaterial!==e.originalMaterial&&e.controlledMaterial.dispose();this.materialSnapshots.delete(t)}}restoreAllMaterialSnapshots(){for(const e of Array.from(this.materialSnapshots.keys()))this.restoreMaterialSnapshotsForTarget(e)}applyResolvedMaterialValue(e,t,a){if(!t||!e.uniformName)return;if("asset"===S(e)&&!e.materialAssetId)return;const s=this.getMaterialSlotResolutions(t,e);for(const i of s){const s=this.ensureSequenceControlledMaterial(t,i),r=s.uniforms?.[e.uniformName];if(!r)continue;const n=X(r.value,a);n.applied&&(r.value=n.value,s.uniformsNeedUpdate=!0)}}getMaterialSlotResolutions(e,t){const a=e,s=S(t),i=`${t.id}:${s}:${t.materialAssetId??""}:${t.uniformName}`;let r=this.materialResolutionCache.get(a);r||(r=new Map,this.materialResolutionCache.set(a,r));const n=r.get(i);if(n)return n;const o=e instanceof p?e.object:e,l=[];return o.traverse(e=>{const a=e.material;if(Array.isArray(a))for(let s=0;s<a.length;s++){const i=a[s];Q(i,t)&&l.push({owner:e,materialIndex:s,material:i,key:`${e.uuid}:${s}`})}else Q(a,t)&&l.push({owner:e,materialIndex:null,material:a,key:`${e.uuid}:material`})}),r.set(i,l),l}ensureSequenceControlledMaterial(e,t){const a=e;let s=this.materialSnapshots.get(a);s||(s=new Map,this.materialSnapshots.set(a,s));const i=s.get(t.key);if(i)return i.controlledMaterial;const r=t.material.clone();return r.userData={...t.material.userData??{}},null==t.materialIndex?t.owner.material=r:Array.isArray(t.owner.material)&&(t.owner.material[t.materialIndex]=r),s.set(t.key,{owner:t.owner,materialIndex:t.materialIndex,originalMaterial:t.material,controlledMaterial:r}),r}animationClipCacheKey(e,t){return`${e}|${t??""}`}async ensureAnimationClip(e,t){if(!this.assetLoader)return null;const a=this.animationClipCacheKey(e,t),s=this.animationClips.get(a);if(s)return s;const i=this.loadingAnimationClips.get(a);if(i)return i;const r=(async()=>{try{const s=await this.assetLoader.getAnimationClipForTargetByAssetId(e,t);return s&&this.animationClips.set(a,s),s}catch(a){return console.error(`Failed to load animation clip for asset ${e}`+(null==t?"":` and target rig ${t}`)+":",a),null}finally{this.loadingAnimationClips.get(a)===r&&this.loadingAnimationClips.delete(a)}})();return this.loadingAnimationClips.set(a,r),r}prepareAnimationPlayback(e,t,a){if(!F(a)){let e=t;return a.clipEndOffset>0&&(e=e.clone(),D(e,R(t)),e.duration=Math.max(0,e.duration-a.clipEndOffset)),{clip:e,timeScale:a.playbackRate,startOffset:a.clipStartOffset}}return{clip:this.getPlayableAnimationClip(e,t,a,!1),timeScale:1,startOffset:0}}getPlayableAnimationClip(e,t,a,s){if(!F(a))return s?_.fromClip(t,!1):t;const i=`${a.id}:${s?"root":"base"}`,r=`${O(a)}|${s?"root":"base"}`,n=this.retimedAnimationClips.get(i);if(n&&n.assetId===e&&n.signature===r)return n.clip;const o=q(t,a),l=s?_.fromClip(o,!1):o;return this.retimedAnimationClips.set(i,{assetId:e,signature:r,clip:l}),l}getAnimationPlaybackLocalTime(e,t){const a=Math.max(0,t-e.startTime);return F(e)?a:a*e.playbackRate+e.clipStartOffset}clearRetimedAnimationClipCache(e){if(null!=e)for(const[t,a]of this.retimedAnimationClips.entries())a.assetId===e&&this.retimedAnimationClips.delete(t);else this.retimedAnimationClips.clear()}captureOriginalTransforms(){for(const e of this.bindings.values()){const t=e.target instanceof p?e.target.object:e.target;t&&(e.originalTransform={position:t.position.clone(),rotation:t.rotation.clone(),scale:t.scale.clone()})}}restoreOriginalTransforms(){for(const e of this.bindings.values())if(e.originalTransform){const t=e.target instanceof p?e.target.object:e.target;t&&(t.position.copy(e.originalTransform.position),t.rotation.copy(e.originalTransform.rotation),t.scale.copy(e.originalTransform.scale))}}stopAllAnimations(){for(const e of this.bindings.values()){for(const t of e.activeActions.values())t.stop();e.activeActions.clear(),e.mixer&&e.mixer.stopAllAction(),e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0),e.charAnimActionKeys?.clear()}}stopAllVfx(){for(const e of this.vfxActors.values())e.paused||e.stop();this.activeVfxClips.clear()}dispose(){if(this.stop(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.bindings.clear(),this.roleBindings.clear(),this.sequenceData=null,this.world)for(const e of this.vfxActors.values())this.world.removeActor(e);this.vfxActors.clear(),this.stopAllAudio(),this.audioBuffers.clear(),this.loadingAudioBuffers.clear(),this.animationClips.clear(),this.loadingAnimationClips.clear(),this.clearRetimedAnimationClipCache(),this.audioByClip.clear()}updateTrackParenting(e,t){const a=this.getActiveObjectsForTrack(e);if(0===a.length)return;let s=null;const i=e.parent?.trackId;if(i){const t=this.sequenceData?se(this.sequenceData.tracks).find(e=>e.id===i):void 0;if(t){const a=this.getActiveObjectsForTrack(t);if(a.length>0&&(s=a[0],e.parent?.socketName)){const t=this.findSocket(s,e.parent.socketName);t&&(s=t)}}}if(!s&&"camera"===e.type&&e.parentRole&&this.roleBindings.has(e.parentRole)){const t=this.roleBindings.get(e.parentRole);if(s=t instanceof p?t.object:t,e.parentRoleSocketName){const t=this.findSocket(s,e.parentRoleSocketName);t&&(s=t)}}for(const i of a)s?i.parent!==s&&(s.add(i),!t||"object"!==e.type&&"locator"!==e.type||(t.currentParent=s)):t?.currentParent&&t.currentParent===i.parent?this.restoreObjectParent(t,i):i.parent&&i.parent!==this.world?.scene&&"object"!==e.type&&"locator"!==e.type&&this.world?.scene.add(i)}findSocket(e,t){if(e.name===t)return e;if(e instanceof a.SkinnedMesh){const a=e.skeleton.bones.find(e=>e.name===t);if(a)return a}return e.getObjectByName(t)||null}getActiveObjectsForTrack(e){if("object"===e.type){const t=this.bindings.get(e.id);if(t&&t.target)return[t.target instanceof p?t.target.object:t.target]}else if("locator"===e.type){const t=this.bindings.get(e.id);if(t&&t.target instanceof n)return[t.target]}else{if("camera"===e.type)return[this.ensureSequenceCamera(e)];if("spawn"===e.type){const t=[];for(const[a,s]of this.spawnedInstances)if(a.startsWith(e.id+"-")&&this.activeClips.has(a)){const e=this.getInstanceObject(s);e&&t.push(e)}return t}if("vfx"===e.type){const t=[];for(const a of this.activeVfxClips)if(a.startsWith(e.id+"-")){const e=this.vfxActors.get(a);e&&t.push(e.object)}return t}}return[]}restoreObjectParent(e,t){e.originalParent?e.originalParent.add(t):this.world&&this.world.scene.add(t),e.currentParent=void 0}restoreOriginalParents(){for(const e of this.bindings.values())if(e.currentParent){const t=e.target instanceof p?e.target.object:e.target;t&&this.restoreObjectParent(e,t)}}evaluateAudioSubTracks(e,t){const a={};for(const s of e.subTracks)if("audioParameter"===s.type){const e=s,i=A(e.parameter),r=I(e.keyframes,t,{min:i.min,max:i.max});void 0!==r&&(a[e.parameter]=r)}return a}stringToRandom(e){let t=0;for(let a=0;a<e.length;a++){t=(t<<5)-t+e.charCodeAt(a),t&=t}const a=1e4*Math.sin(t);return a-Math.floor(a)}async refreshAsset(e){let t=!1;this.assetLoader?.clearCacheById(e),this.animationClips.delete(e),this.loadingAnimationClips.delete(e),this.clearRetimedAnimationClipCache(e),this.vfxService?.clearPool(e),t=this.refreshVfxActorsForAssetIds(new Set([e]))||t;for(const[a,s]of this.activePostProcessClips.entries())s.assetId===e&&(this.releasePostProcessClipEffect(a),t=!0);t=this.refreshSpawnedInstancesForClipKeys(this.getSpawnClipKeysForAsset(e))||t;const a=await this.getAssetOrNull(e);return"shaderGraph"===a?.type&&(t=await this.refreshShaderGraphDependentAssets(e)||t),t}refreshVfxActorsForAssetIds(e){let t=!1;for(const[a,s]of this.vfxActors.entries())this.vfxClipKeyUsesAnyAsset(a,e)&&(this.world&&this.world.removeActor(s),this.vfxActors.delete(a),this.activeVfxClips.delete(a),t=!0);return t}vfxClipKeyUsesAnyAsset(e,t){for(const a of t)if(e.endsWith(`-${a}`))return!0;return!1}refreshSpawnedInstancesForClipKeys(e){let t=!1;for(const[a,s]of this.spawnedInstances.entries())e.has(a)&&(this.despawnInstance(s),this.spawnedInstances.delete(a),this.activeClips.delete(a),t=!0);return t}getSpawnClipKeysForAsset(e){const t=new Set;if(!this.sequenceData)return t;for(const a of se(this.sequenceData.tracks))if("spawn"===a.type&&(a.prefabId===e||a.meshId===e))for(const e of a.clips)t.add(`${a.id}-${e.id}`);return t}async refreshShaderGraphDependentAssets(e){const t=await this.findSequenceVfxAssetIdsUsingShaderGraph(e);for(const e of t)this.vfxService?.clearPool(e);const a=this.refreshVfxActorsForAssetIds(t),s=this.refreshSpawnedInstancesForClipKeys(await this.findSpawnClipKeysUsingShaderGraph(e));return a||s}async findSequenceVfxAssetIdsUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of se(this.sequenceData.tracks))if("vfx"===s.type)for(const i of s.clips)null==i.vfxAssetId||t.has(i.vfxAssetId)||await this.assetUsesShaderGraph(i.vfxAssetId,e,a)&&t.add(i.vfxAssetId);return t}async findSpawnClipKeysUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of se(this.sequenceData.tracks))if("spawn"===s.type&&await this.spawnTrackUsesShaderGraph(s,e,a))for(const e of s.clips)t.add(`${s.id}-${e.id}`);return t}async spawnTrackUsesShaderGraph(e,t,a){if(null!=e.meshId&&await this.assetUsesShaderGraph(e.meshId,t,a))return!0;if(null!=e.prefabId&&await this.assetUsesShaderGraph(e.prefabId,t,a))return!0;for(const s of e.subTracks??[])if("material"===s.type&&null!=s.materialAssetId&&await this.assetUsesShaderGraph(s.materialAssetId,t,a))return!0;return!1}assetUsesShaderGraph(e,t,a,s=new Set){if(e===t)return Promise.resolve(!0);if(s.has(e))return Promise.resolve(!1);if(a.has(e))return a.get(e);const i=this.assetUsesShaderGraphUncached(e,t,a,s);return a.set(e,i),i}async assetUsesShaderGraphUncached(e,t,a,s){if(s.has(e))return!1;const i=await this.getAssetOrNull(e);if(null==i)return!1;const r=new Set(s);return r.add(e),!!this.materialAssetUsesShaderGraph(i,t)||("mesh"===i.type?this.materialAssignmentsUseShaderGraph(i.materialAssignments,t,a,r):"prefab"===i.type?this.sceneObjectsUseShaderGraph(i.prefab?.objects,t,a,r):"vfx"===i.type&&this.vfxAssetUsesShaderGraph(i,t,a,r))}materialAssetUsesShaderGraph(e,t){return"shaderGraph"===e.type?e.id===t:"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===t}async materialAssignmentsUseShaderGraph(e,t,a,s){for(const i of e??[])if(null!=i.materialId&&"null"!==i.materialId&&await this.assetUsesShaderGraph(i.materialId,t,a,s))return!0;return!1}async sceneObjectsUseShaderGraph(e,t,a,s){for(const i of e??[]){if(await this.materialAssignmentsUseShaderGraph(i.materialAssignments,t,a,s))return!0;if(null!=i.assetId&&("asset_mesh"===i.type||"prefab"===i.type||"vfx"===i.type)&&await this.assetUsesShaderGraph(i.assetId,t,a,s))return!0;if(await this.sceneObjectsUseShaderGraph(i.children,t,a,s))return!0}return!1}async vfxAssetUsesShaderGraph(e,t,a,s){for(const i of e.vfx?.emitters??[])if(await this.emitterUsesShaderGraph(i,t,a,s))return!0;return!1}async emitterUsesShaderGraph(e,t,a,s){if(await this.emitterOutputUsesShaderGraph(e.output,t,a,s))return!0;for(const i of e.children??[])if(await this.emitterUsesShaderGraph(i,t,a,s))return!0;return!1}async emitterOutputUsesShaderGraph(e,t,a,s){const i=e.materialSource??("asset"===e.shaderGraph?.source?"shaderGraph":void 0);return"shaderGraph"===i&&"asset"===e.shaderGraph?.source&&e.shaderGraph.assetId===t||!("material"!==i||!("material"in e)||null==e.material||!await this.assetUsesShaderGraph(e.material,t,a,s))}async getAssetOrNull(e){if(!this.assetLoader)return null;try{return await this.assetLoader.getAsset(e)??null}catch{return null}}async invokeSequenceEvent(e,t,a,s){let i=!1;for(let e=0;e<s.length;e++)if(C(s[e])){i=!0;break}if(i)try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=g(s[e],this.sequenceEventAsyncResolvers);const i=await Promise.all(t);await a.call(e,...i)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}else try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=v(s[e],this.sequenceEventSyncResolvers);a.call(e,...t)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}}resolveSequenceEventActorReference(e){if(!this.world||null==e)return null;const t=e,a="object"==typeof t&&null!=t?.id?t.id:"string"==typeof t?t:null;if(null==a)return null;for(const e of this.world.actors){const t=e.object.userData.src??e.object.userData._src;if(t?.id===a)return e}return null}resolveSequenceEventSequence(e){return P(e)?new w(e):this.assetLoader&&"string"==typeof e?this.assetLoader.getSequenceById(e):null}async resolveSequenceEventAnimationClip(e){const t="string"==typeof e?e:"object"==typeof e&&null!=e?e.assetId??null:null;return null!=t&&this.assetLoader?this.assetLoader.getAnimationClipByAssetId(t):null}}function N(e){return e.options?.length>0||e.propertyType===y.Boolean||e.propertyType===y.String}function U(e){return e.valueType===y.Boolean||e.valueType===y.String}function W(e){return"object"==typeof e&&null!=e||"function"==typeof e}function X(e,t){switch(t.type){case y.Number:return function(e){if("number"==typeof e)return Number.isFinite(e)?{applied:!0,value:e}:{applied:!1};if("string"==typeof e){const t=parseFloat(e);return Number.isFinite(t)?{applied:!0,value:t}:{applied:!1}}return{applied:!1}}(t.value);case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return Y(e,t.value);case y.Vector3:return Z(e,t.value);case y.Vector4:return z(e,t.value);case y.Color:return function(e,t){if(e instanceof c){const a=fe.set(0);return ee(a,t)?(e.set(a.r,a.g,a.b),{applied:!0,value:e}):{applied:!1}}if(e instanceof h){const a=fe.set(0);return ee(a,t)?(e.set(a.r,a.g,a.b,e.w),{applied:!0,value:e}):{applied:!1}}return H(e,t)}(e,t.value);default:return{applied:!1}}}function Q(e,t){const s=S(t);return function(e){return e instanceof a.Material||!0===e?.isMaterial}(e)&&null!=e.uniforms?.[t.uniformName]&&("parameterName"===s||e.userData?.assetId===t.materialAssetId)}function Y(e,t){const a=J(t,2);return a?e instanceof l?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new l(a[0],a[1])}:{applied:!1}}function Z(e,t){const a=J(t,3);return a?e instanceof c?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new c(a[0],a[1],a[2])}:{applied:!1}}function z(e,t){const a=J(t,4);return a?e instanceof h?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new h(a[0],a[1],a[2],a[3])}:{applied:!1}}function H(e,t){if(e instanceof i)return ee(e,t)?{applied:!0,value:e}:{applied:!1};const a=new i;return ee(a,t)?{applied:!0,value:a}:{applied:!1}}function J(e,t){if(!Array.isArray(e)||e.length<t)return null;const a=new Array(t);for(let s=0;s<t;s++){if("number"!=typeof e[s])return null;a[s]=e[s]}return a}function ee(e,t){return t instanceof i||"string"==typeof t||"number"==typeof t?(e.set(t),!0):!!(Array.isArray(t)&&t.length>=3)&&(e.setRGB("number"==typeof t[0]?t[0]:0,"number"==typeof t[1]?t[1]:0,"number"==typeof t[2]?t[2]:0),!0)}function te(e){if(e instanceof l||e instanceof c||e instanceof h||e instanceof i||e instanceof r)return e.clone()}function ae(e){const{owner:t,key:a}=e.resolution;e.hadOwnProperty?(!function(e,t){if(e instanceof l&&t instanceof l)return e.copy(t),!0;if(e instanceof c&&t instanceof c)return e.copy(t),!0;if(e instanceof h&&t instanceof h)return e.copy(t),!0;if(e instanceof i&&t instanceof i)return e.copy(t),!0;if(e instanceof r&&t instanceof r)return e.copy(t),!0}(e.value,e.valueSnapshot),t[a]=e.value):delete t[a]}function se(e){const t=[];for(const a of e)t.push(a),"group"===a.type&&t.push(...se(a.childTracks));return t}function ie(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function re(e){const t=new a.Group;t.name=`SequenceLocatorMarker:${e}`,t.renderOrder=1e3;const s=new a.AxesHelper(.35);s.renderOrder=1e3;const i=Array.isArray(s.material)?s.material:[s.material];for(const e of i)e.depthTest=!1,e.transparent=!0,e.opacity=.9,e.toneMapped=!1;t.add(s);const r=function(e){if("undefined"==typeof document)return null;const t=document.createElement("canvas");t.width=256,t.height=64;const s=t.getContext("2d");if(!s)return null;s.clearRect(0,0,t.width,t.height),s.fillStyle="rgba(16, 18, 24, 0.78)",function(e,t,a,s,i,r){const n=t+s,o=a+i;e.beginPath(),e.moveTo(t+r,a),e.lineTo(n-r,a),e.quadraticCurveTo(n,a,n,a+r),e.lineTo(n,o-r),e.quadraticCurveTo(n,o,n-r,o),e.lineTo(t+r,o),e.quadraticCurveTo(t,o,t,o-r),e.lineTo(t,a+r),e.quadraticCurveTo(t,a,t+r,a),e.closePath()}(s,0,8,t.width,48,8),s.fill(),s.font="24px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillStyle="#f8fafc",s.fillText(e||"Locator",t.width/2,t.height/2);const i=new a.CanvasTexture(t);i.needsUpdate=!0;const r=new a.SpriteMaterial({map:i,transparent:!0,depthTest:!1});r.toneMapped=!1;const n=new a.Sprite(r);return n.scale.set(.9,.225,1),n}(e);return r&&(r.position.set(0,.45,0),r.renderOrder=1001,t.add(r)),t.traverse(e=>{e.raycast=()=>{}}),t}function ne(e){e.traverse(e=>{const t=e.material;if(Array.isArray(t))for(const e of t)e?.dispose?.(),e?.map?.dispose?.();else t?.dispose?.(),t?.map?.dispose?.()})}const oe=new c,le=new c,ce=new c,he=new o,ue=new o,pe=new r,de=new r,fe=new i;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -0,0 +1,10 @@
1
+ import { Vector3 } from 'three';
2
+ import { TransformKeyframe } from './sequence-data.js';
3
+ export type TransformPositionTangentDirection = 'in' | 'out';
4
+ /** Evaluates transform position keys without allocating in the playback path. */
5
+ export declare function evaluateTransformPosition(keyframes: readonly TransformKeyframe[], time: number, target: Vector3): boolean;
6
+ /** Evaluates a position from an already-resolved key span. */
7
+ export declare function evaluateTransformPositionSpan(keyframes: readonly TransformKeyframe[], previousIndex: number, nextIndex: number, t: number, target: Vector3): boolean;
8
+ /** Resolves an authored or automatic position tangent in local units per second. */
9
+ export declare function resolveTransformPositionTangent(keyframes: readonly TransformKeyframe[], keyframeIndex: number, direction: TransformPositionTangentDirection, target: Vector3): boolean;
10
+ //# sourceMappingURL=sequence-transform.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{Vector3 as n}from"three";export function evaluateTransformPosition(n,o,t){const i=function(n,o){let t=-1,i=-1,e=-1;for(let r=0;r<n.length;r++){const s=n[r];if(s.position){if(-1===t&&(t=r),!(s.time<=o)){e=r;break}i=r}}if(-1===t)return null;-1===i&&(i=t);if(-1===e){e=i;for(let o=i+1;o<n.length;o++)if(n[o].position){e=o;break}}const r=n[i],s=n[e],p=s.time-r.time;return{previousIndex:i,nextIndex:e,t:i===e||p<=0?0:Math.max(0,Math.min(1,(o-r.time)/p))}}(n,o);return!!i&&evaluateTransformPositionSpan(n,i.previousIndex,i.nextIndex,i.t,t)}export function evaluateTransformPositionSpan(n,o,t,r,s){const p=n[o],u=n[t];if(!p?.position)return!1;if(o===t||!u?.position)return s.fromArray(p.position),!0;switch(p.interpolation){case"step":return s.fromArray(p.position),!0;case"linear":return function(n,o,t,i){i.set(n[0]+(o[0]-n[0])*t,n[1]+(o[1]-n[1])*t,n[2]+(o[2]-n[2])*t)}(p.position,u.position,r,s),!0;case"cubic":case"catmullRom":return function(n,o,t,r,s){const p=n[o],u=n[t],a=Math.max(0,u.time-p.time);if(!p.position||!u.position||0===a)return void s.fromArray(p.position??u.position??[0,0,0]);resolveTransformPositionTangent(n,o,"out",i),resolveTransformPositionTangent(n,t,"in",e);const f=r*r,c=f*r,l=2*c-3*f+1,m=c-2*f+r,T=-2*c+3*f,g=c-f;s.set(l*p.position[0]+m*a*i.x+T*u.position[0]+g*a*e.x,l*p.position[1]+m*a*i.y+T*u.position[1]+g*a*e.y,l*p.position[2]+m*a*i.z+T*u.position[2]+g*a*e.z)}(n,o,t,r,s),!0}}export function resolveTransformPositionTangent(n,i,e,r){const s=n[i];if(!s?.position)return!1;const p=s.positionTangentMode??"auto";if("auto"!==p){const n="in"===e?s.positionInTangent??("aligned"===p?s.positionOutTangent:void 0):s.positionOutTangent??("aligned"===p?s.positionInTangent:void 0);if(n)return r.fromArray(n),!0}return function(n,i,e){const r=n[i];if(!r?.position)return!1;const s=o(n,i,-1),p=o(n,i,1),u=s>=0?n[s]:null,a=p>=0?n[p]:null;if(u?.position&&a?.position)return t(u,a,e);if(a?.position)return t(r,a,e);if(u?.position)return t(u,r,e);return e.set(0,0,0),!0}(n,i,r)}function o(n,o,t){for(let i=o+t;i>=0&&i<n.length;i+=t)if(n[i].position)return i;return-1}function t(n,o,t){if(!n.position||!o.position)return!1;const i=o.time-n.time;return i<=0?(t.set(0,0,0),!0):(t.set((o.position[0]-n.position[0])/i,(o.position[1]-n.position[1])/i,(o.position[2]-n.position[2])/i),!0)}const i=new n,e=new n;/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -6,6 +6,8 @@ export interface TimedSequenceItem {
6
6
  export interface SequenceKeyframeSpan<T extends TimedSequenceItem> {
7
7
  prev: T | null;
8
8
  next: T | null;
9
+ prevIndex: number;
10
+ nextIndex: number;
9
11
  t: number;
10
12
  }
11
13
  export interface NumericValueLaneOptions {