@eigong/effekseer-webgpu-runtime 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `@eigong/effekseer-webgpu-runtime` redistributes the Effekseer WebGPU runtime files needed by browser integrations.
4
4
 
5
- The package now separates the bridge into:
5
+ The package separates the bridge into:
6
6
 
7
7
  - client bridge: `effekseer.webgpu.js`
8
8
  - debug/source bridge: `effekseer.webgpu.src.js`
@@ -55,9 +55,42 @@ import { getEffekseerWebGPURuntimeUrls } from '@eigong/effekseer-webgpu-runtime'
55
55
  const urls = getEffekseerWebGPURuntimeUrls()
56
56
  ```
57
57
 
58
+ ## Registered Effects And Warm-Up
59
+
60
+ ```js
61
+ import {
62
+ loadEffekseerWebGPURuntime,
63
+ effekseerWebgpuRuntimeWasmUrl,
64
+ } from '@eigong/effekseer-webgpu-runtime'
65
+
66
+ const effekseer = await loadEffekseerWebGPURuntime()
67
+ effekseer.setWebGPUDevice(device)
68
+ await effekseer.initRuntime(effekseerWebgpuRuntimeWasmUrl)
69
+
70
+ const ctx = effekseer.createContext()
71
+ ctx.initExternal({
72
+ warmupSettings: {
73
+ colorFormat: presentationFormat,
74
+ depthFormat: 'depth24plus',
75
+ sampleCount: 1,
76
+ includeDepthTexture: true,
77
+ },
78
+ })
79
+
80
+ ctx.registerEffects({
81
+ flame: {
82
+ path: '/fx/flame.efkwgpk',
83
+ preload: true,
84
+ warmup: true,
85
+ },
86
+ })
87
+
88
+ await ctx.whenEffectsReady(['flame'])
89
+ ```
90
+
58
91
  ## API Reference
59
92
 
60
- La referencia breve de la API pública está en [API.md](./API.md).
93
+ La referencia breve de la API publica esta en [API.md](./API.md).
61
94
 
62
95
  ## License
63
96
 
package/debug.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { EffekseerApi } from "./index.js"
2
+
1
3
  export declare const effekseerWebgpuDebugBridgeUrl: string
2
4
 
3
5
  export declare function getEffekseerWebGPUDebugRuntimeUrls(): {
@@ -7,4 +9,4 @@ export declare function getEffekseerWebGPUDebugRuntimeUrls(): {
7
9
  effekseerWebgpuBridgeUrl: string
8
10
  }
9
11
 
10
- export declare function loadEffekseerWebGPUDebugRuntime(): Promise<any>
12
+ export declare function loadEffekseerWebGPUDebugRuntime(): Promise<EffekseerApi>
package/index.d.ts CHANGED
@@ -3,6 +3,228 @@ export declare const effekseerWebgpuRuntimeJsUrl: string
3
3
  export declare const effekseerWebgpuRuntimeWasmUrl: string
4
4
  export declare const effekseerWebgpuBridgeUrl: string
5
5
 
6
+ export type ManagedEffectInput =
7
+ | string
8
+ | {
9
+ path: string
10
+ scale?: number
11
+ preload?: boolean
12
+ warmup?: boolean
13
+ enabled?: boolean
14
+ }
15
+
16
+ export type WarmupSettings = {
17
+ colorFormat?: GPUTextureFormat
18
+ depthFormat?: GPUTextureFormat | null
19
+ sampleCount?: number
20
+ width?: number
21
+ height?: number
22
+ frames?: number
23
+ includeDepthTexture?: boolean
24
+ includeBackgroundTexture?: boolean
25
+ }
26
+
27
+ export type ContextInitSettings = {
28
+ instanceMaxCount?: number
29
+ squareMaxCount?: number
30
+ linearColorSpace?: boolean
31
+ compositeWithBackground?: boolean
32
+ externalRenderPass?: boolean
33
+ effects?: Record<string, ManagedEffectInput>
34
+ warmupSettings?: WarmupSettings
35
+ }
36
+
37
+ export type EffekseerRenderPassState = {
38
+ colorFormat: GPUTextureFormat
39
+ depthFormat?: GPUTextureFormat | null
40
+ sampleCount?: number
41
+ backgroundTextureView?: GPUTextureView | null
42
+ depthTextureView?: GPUTextureView | null
43
+ importBackgroundTextureView?: GPUTextureView | null
44
+ importDepthTextureView?: GPUTextureView | null
45
+ }
46
+
47
+ export interface EffekseerEffect {
48
+ nativeptr: number
49
+ readonly isLoaded: boolean
50
+ scale: number
51
+ baseDir?: string
52
+ packageOnly?: boolean
53
+ syncResourceLoad?: boolean
54
+ redirect?: ((path: string) => string) | null
55
+ }
56
+
57
+ export interface EffekseerHandle {
58
+ readonly exists: boolean
59
+ stop(): void
60
+ stopRoot(): void
61
+ setFrame(frame: number): void
62
+ setLocation(x: number, y: number, z: number): void
63
+ setRotation(x: number, y: number, z: number): void
64
+ setScale(x: number, y: number, z: number): void
65
+ setMatrix(matrixArray: ArrayLike<number>): void
66
+ setAllColor(r: number, g: number, b: number, a: number): void
67
+ setTargetLocation(x: number, y: number, z: number): void
68
+ getDynamicInput(index: number): number
69
+ setDynamicInput(index: number, value: number): void
70
+ sendTrigger(index: number): void
71
+ setPaused(paused: boolean): void
72
+ setShown(shown: boolean): void
73
+ setSpeed(speed: number): void
74
+ setRandomSeed(seed: number): void
75
+ }
76
+
77
+ export type ManagedEffectState = {
78
+ id: string
79
+ path: string
80
+ scale: number
81
+ preload: boolean
82
+ warmup: boolean
83
+ enabled: boolean
84
+ status: "unloaded" | "loading" | "loaded" | "failed"
85
+ effect: EffekseerEffect | null
86
+ errorMessage: string
87
+ errorPath: string
88
+ warmupStatus: "idle" | "warming" | "warmed" | "failed"
89
+ warmupErrorMessage: string
90
+ warmupSignature: string
91
+ loadPromise: Promise<EffekseerEffect | null> | null
92
+ activeHandles: Set<EffekseerHandle>
93
+ ownedResourceAliases: string[]
94
+ }
95
+
96
+ export interface EffekseerContext {
97
+ init(target: string | HTMLCanvasElement, settings?: ContextInitSettings): boolean
98
+ initExternal(settings?: ContextInitSettings): boolean
99
+ registerEffects(effects: Record<string, ManagedEffectInput>): void
100
+ preloadEffects(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
101
+ warmupEffects(ids?: string[] | string, options?: Partial<WarmupSettings>): Promise<Map<string, EffekseerEffect | null>>
102
+ whenEffectsReady(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
103
+ reloadEffects(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
104
+ unloadEffects(ids?: string[] | string): void
105
+ unregisterEffects(ids?: string[] | string): void
106
+ getEffect(id: string): EffekseerEffect | null
107
+ getEffectState(id: string): ManagedEffectState | null
108
+ getEffectStates(): ManagedEffectState[]
109
+ loadEffect(
110
+ data: string | ArrayBuffer | ArrayBufferView,
111
+ scale?: number,
112
+ onload?: () => void,
113
+ onerror?: (message: string, path?: string) => void,
114
+ redirect?: (path: string) => string
115
+ ): EffekseerEffect
116
+ loadEffectPackage(
117
+ data: string | ArrayBuffer | ArrayBufferView,
118
+ Unzip: unknown,
119
+ scale?: number,
120
+ onload?: () => void,
121
+ onerror?: (message: string, path?: string) => void
122
+ ): EffekseerEffect
123
+ releaseEffect(effect: EffekseerEffect | null): void
124
+ playEffect(id: string, x?: number, y?: number, z?: number): EffekseerHandle | null
125
+ play(effect: EffekseerEffect | null, x?: number, y?: number, z?: number): EffekseerHandle | null
126
+ update(deltaFrames?: number): void
127
+ beginUpdate(): void
128
+ endUpdate(): void
129
+ updateHandle(handle: EffekseerHandle, deltaFrames?: number): void
130
+ draw(): void
131
+ drawExternal(
132
+ renderPassEncoder: GPURenderPassEncoder,
133
+ renderPassState?: EffekseerRenderPassState | null,
134
+ mode?: "all" | "back" | "front"
135
+ ): void
136
+ beginDraw(): void
137
+ endDraw(): void
138
+ drawHandle(handle: EffekseerHandle): void
139
+ stopAll(): void
140
+ setCompositeMode(enabled: boolean): void
141
+ setProjectionPerspective(fov: number, aspect: number, near: number, far: number): void
142
+ setProjectionOrthographic(width: number, height: number, near: number, far: number): void
143
+ setCameraLookAt(
144
+ positionX: number,
145
+ positionY: number,
146
+ positionZ: number,
147
+ targetX: number,
148
+ targetY: number,
149
+ targetZ: number,
150
+ upvecX: number,
151
+ upvecY: number,
152
+ upvecZ: number
153
+ ): void
154
+ setProjectionMatrix(matrixArray: ArrayLike<number>): void
155
+ setCameraMatrix(matrixArray: ArrayLike<number>): void
156
+ setResourceLoader(loader: (path: string, onload: (data: ArrayBuffer | Uint8Array) => void, onerror: () => void) => void): void
157
+ }
158
+
159
+ export interface EffekseerApi {
160
+ setWebGPUDevice(device: GPUDevice | null): void
161
+ getWebGPUDevice(): GPUDevice | null
162
+ initRuntime(path: string, onload?: () => void, onerror?: (error: unknown) => void): Promise<void>
163
+ createContext(): EffekseerContext | null
164
+ releaseContext(context: EffekseerContext | null): void
165
+ setImageCrossOrigin(crossOrigin: string): void
166
+ setLogEnabled(flag: boolean): void
167
+ init(target: string | HTMLCanvasElement, settings?: ContextInitSettings): boolean
168
+ update(deltaFrames?: number): void
169
+ beginUpdate(): void
170
+ endUpdate(): void
171
+ updateHandle(handle: EffekseerHandle, deltaFrames?: number): void
172
+ draw(): void
173
+ drawExternal(
174
+ renderPassEncoder: GPURenderPassEncoder,
175
+ renderPassState?: EffekseerRenderPassState | null,
176
+ mode?: "all" | "back" | "front"
177
+ ): void
178
+ beginDraw(): void
179
+ endDraw(): void
180
+ drawHandle(handle: EffekseerHandle): void
181
+ setProjectionMatrix(matrixArray: ArrayLike<number>): void
182
+ setProjectionPerspective(fov: number, aspect: number, near: number, far: number): void
183
+ setProjectionOrthographic(width: number, height: number, near: number, far: number): void
184
+ setCameraMatrix(matrixArray: ArrayLike<number>): void
185
+ setCameraLookAt(
186
+ positionX: number,
187
+ positionY: number,
188
+ positionZ: number,
189
+ targetX: number,
190
+ targetY: number,
191
+ targetZ: number,
192
+ upvecX: number,
193
+ upvecY: number,
194
+ upvecZ: number
195
+ ): void
196
+ setCompositeMode(enabled: boolean): void
197
+ loadEffect(
198
+ data: string | ArrayBuffer | ArrayBufferView,
199
+ scale?: number,
200
+ onload?: () => void,
201
+ onerror?: (message: string, path?: string) => void,
202
+ redirect?: (path: string) => string
203
+ ): EffekseerEffect
204
+ loadEffectPackage(
205
+ data: string | ArrayBuffer | ArrayBufferView,
206
+ Unzip: unknown,
207
+ scale?: number,
208
+ onload?: () => void,
209
+ onerror?: (message: string, path?: string) => void
210
+ ): EffekseerEffect
211
+ registerEffects(effects: Record<string, ManagedEffectInput>): void
212
+ preloadEffects(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
213
+ warmupEffects(ids?: string[] | string, options?: Partial<WarmupSettings>): Promise<Map<string, EffekseerEffect | null>>
214
+ reloadEffects(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
215
+ unloadEffects(ids?: string[] | string): void
216
+ unregisterEffects(ids?: string[] | string): void
217
+ getEffect(id: string): EffekseerEffect | null
218
+ getEffectState(id: string): ManagedEffectState | null
219
+ getEffectStates(): ManagedEffectState[]
220
+ whenEffectsReady(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
221
+ playEffect(id: string, x?: number, y?: number, z?: number): EffekseerHandle | null
222
+ releaseEffect(effect: EffekseerEffect | null): void
223
+ play(effect: EffekseerEffect | null, x?: number, y?: number, z?: number): EffekseerHandle | null
224
+ stopAll(): void
225
+ setResourceLoader(loader: (path: string, onload: (data: ArrayBuffer | Uint8Array) => void, onerror: () => void) => void): void
226
+ }
227
+
6
228
  export declare function getEffekseerWebGPURuntimeUrls(): {
7
229
  fflateUrl: string
8
230
  effekseerWebgpuRuntimeJsUrl: string
@@ -10,4 +232,4 @@ export declare function getEffekseerWebGPURuntimeUrls(): {
10
232
  effekseerWebgpuBridgeUrl: string
11
233
  }
12
234
 
13
- export declare function loadEffekseerWebGPURuntime(): Promise<any>
235
+ export declare function loadEffekseerWebGPURuntime(): Promise<EffekseerApi>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eigong/effekseer-webgpu-runtime",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Redistributable Effekseer WebGPU runtime assets with MIT license notice",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -1 +1 @@
1
- const e=(()=>{let e={},t={},r=null,n=!1,a=!1,s=null,i=null,o="",f=0,c=[],l=!0;const u=()=>{n&&"function"==typeof t.SetLogEnabled&&t.SetLogEnabled(l?1:0)},d=e=>e instanceof ArrayBuffer?e:ArrayBuffer.isView(e)?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):null,p=e=>{if("string"!=typeof e||0===e.length)return"";const t=e.replace(/\\/g,"/").split("/"),r=[];for(let e=0;e<t.length;e++){const n=t[e];n&&"."!==n&&(".."!==n?r.push(n):r.length>0&&r.pop())}let n=r.join("/");for(;n.startsWith("/");)n=n.slice(1);return n.replace(/[A-Z]/g,e=>e.toLowerCase())},h="EFWGPKG2",g="__efwgpk__/main_effect_path.txt",m=new Uint8Array([69,102,107,87,103,46,87,101,98,71,80,85,46,67,84,82]);let b=0,w=null;const E=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?3988292384^r>>>1:r>>>1;e[t]=r>>>0}return e})(),y=e=>{if(!(e instanceof Uint8Array))return 0;let t=4294967295;for(let r=0;r<e.length;r++){const n=255&(t^e[r]);t=t>>>8^E[n]}return~t>>>0},S=async(e,t)=>{const r=await(async()=>{if(w)return w;if(!globalThis.crypto||!globalThis.crypto.subtle||"function"!=typeof globalThis.crypto.subtle.importKey)throw new Error("Web Crypto AES-CTR is required for encrypted efkwgpk payloads");return w=globalThis.crypto.subtle.importKey("raw",m,"AES-CTR",!1,["decrypt"]),w})();return globalThis.crypto.subtle.decrypt({name:"AES-CTR",counter:t,length:128},r,e)},v=e=>String(e||"").replace(/\\/g,"/").split("?")[0].split("#")[0],x=e=>{const t=d(e);if(!t||t.byteLength<8)return"";const r=new Uint8Array(t,0,8);return String.fromCharCode(...r)},_=e=>{const t=new Map,r=e?e.byteLength:0,n=(e=>{const t=e?e.byteLength:0;if(!e||t<64)return null;const r=new DataView(e);if(x(e)!==h)return null;const n=r.getUint32(8,!0),a=r.getUint32(12,!0),s=r.getUint32(16,!0),i=r.getUint32(20,!0),o=r.getUint32(24,!0),f=r.getUint32(28,!0),c=r.getUint32(32,!0),l=r.getUint32(36,!0),u=r.getUint32(40,!0),d=r.getUint32(44,!0),p=r.getUint32(48,!0),g=r.getUint32(52,!0),m=2===s?64:3===s?80:0;if(0===m||n!==m||48!==o)return null;let b=null;if(4&a){if(s<3||t<80)return null;if(b=new Uint8Array(e.slice(56,72)),16!==b.byteLength)return null}return{headerSize:n,globalFlags:a,formatRevision:s,entryCount:i,entryStride:o,entriesOffset:f,stringPoolOffset:c,stringPoolSize:l,payloadOffset:u,payloadSize:d,tocCrc:p,payloadCrc:g,payloadNonce:b,payloadEncrypted:!!(4&a)}})(e);if(!n)return t;const a=new DataView(e),{headerSize:s,entryCount:i,entryStride:o,entriesOffset:f,stringPoolOffset:c,stringPoolSize:l,payloadOffset:u,payloadSize:d,tocCrc:g,payloadCrc:m}=n,b=BigInt(i)*BigInt(o);if(b>BigInt(r))return t;const w=Number(b);if(!U(f,w,r))return t;if(!U(c,l,r))return t;if(!U(u,d,r))return t;const E=c+l,S=u+d,v=new Uint8Array(e,0,s).slice();v.fill(0,48,56);const _=new Uint8Array(s+w+l);if(_.set(v,0),_.set(new Uint8Array(e,f,w),s),_.set(new Uint8Array(e,c,l),s+w),y(_)!==g>>>0)return t;const k=new Uint8Array(e,u,d);if(y(k)!==m>>>0)return t;const C=new TextDecoder("utf-8");for(let n=0;n<i;n++){const s=f+n*o,i=a.getUint32(s+8,!0),l=a.getUint32(s+12,!0),d=a.getUint32(s+16,!0),h=a.getUint32(s+20,!0),g=a.getUint32(s+24,!0),m=a.getUint32(s+28,!0),b=a.getUint32(s+32,!0),w=a.getUint32(s+36,!0);if(!U(i,l,r))continue;if(i<c||i+l>E)continue;if(!U(h,g,r))continue;if(h<u||h+g>S)continue;let y="";try{y=C.decode(new Uint8Array(e,i,l))}catch{continue}const v=p(y);if(!v)continue;const x={index:n,path:y,normalizedPath:v,flags:d,payloadOffset:h,packedSize:g,rawSize:m,packedCrc:b,rawCrc:w},_=t.get(v);_?_.push(x):t.set(v,[x])}return t._efwgpkMeta={payloadOffset:u,payloadSize:d,payloadEncrypted:n.payloadEncrypted,payloadNonce:n.payloadNonce,decryptedPayloadPromise:null},t},k=async e=>{const t=globalThis.fflate;if(t&&"function"==typeof t.unzlibSync){const r=t.unzlibSync(new Uint8Array(e));return d(r)}if("function"!=typeof DecompressionStream)throw new Error("No zlib inflate backend available for efkwgpk payload");const r=new DecompressionStream("deflate"),n=r.writable.getWriter();await n.write(e),await n.close();return await new Response(r.readable).arrayBuffer()},C=async(e,t,r)=>{const n=t&&t._efwgpkMeta?t._efwgpkMeta:null;if(!n||!n.payloadEncrypted)return new Uint8Array(e,r.payloadOffset,r.packedSize);if(!n.decryptedPayloadPromise){const t=new Uint8Array(e,n.payloadOffset,n.payloadSize);n.decryptedPayloadPromise=S(t,n.payloadNonce).then(e=>new Uint8Array(e))}const a=await n.decryptedPayloadPromise,s=r.payloadOffset-n.payloadOffset;return s<0||s+r.packedSize>a.byteLength?null:a.subarray(s,s+r.packedSize)},M=async(e,t,r)=>{const n=p(r);if(!n||!e||!t||0===t.size)return null;const a=t.get(n);if(!a||0===a.length)return null;for(let r=0;r<a.length;r++){const n=a[r];if(!U(n.payloadOffset,n.packedSize,e.byteLength))continue;const s=await C(e,t,n);if(s&&y(s)===n.packedCrc>>>0){if(0===n.flags&&n.packedSize===n.rawSize){const e=s.slice();if(y(e)!==n.rawCrc>>>0)continue;return e.buffer}if(1===n.flags){const e=await k(s);if(!e||e.byteLength!==n.rawSize)continue;if(y(new Uint8Array(e))!==n.rawCrc>>>0)continue;return e}}}return null},P=e=>e&&Number.isFinite(e.payloadOffset)&&Number.isFinite(e.packedSize)&&Number.isFinite(e.rawSize)&&Number.isFinite(e.flags)?`${e.flags}:${e.payloadOffset}:${e.packedSize}:${e.rawSize}`:"",R=(e,t,r)=>{const n=p(r);if(!n||!e||!t||0===t.size)return null;const a=t.get(n);if(!a||0===a.length)return null;for(let t=0;t<a.length;t++){const r=a[t];if(U(r.payloadOffset,r.packedSize,e.byteLength)){if(0===r.flags&&r.packedSize===r.rawSize)return r;if(1===r.flags)return r}}return null},U=(e,t,r)=>!!(Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(r))&&(!(e<0||t<0||r<0)&&(!(e>r)&&t<=r-e)),A=(e,t,r)=>{const n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="arraybuffer",n.onload=()=>{const a=0|n.status;a>=200&&a<300||0===a?t(n.response):r&&r("not found",e)},n.onerror=()=>{r&&r("not found",e)},n.send(null)},L=e=>{try{const t=new XMLHttpRequest;t.open("GET",e,!1),t.responseType="arraybuffer",t.send(null);const r=0|t.status;if(r>=200&&r<300||0===r)return t.response}catch{}return null},D=e=>{"function"==typeof e&&("function"==typeof queueMicrotask?queueMicrotask(e):Promise.resolve().then(e))},I=(e,t)=>{const r=String(e||"").replace(/\\/g,"/");const n=Number(t);return`${r}::${Number.isFinite(n)?n:1}`},F=e=>{e&&e.context&&e._cacheKey&&e.context._effectCache&&e.context._effectCache.get(e._cacheKey)===e&&e.context._effectCache.delete(e._cacheKey)},T=e=>e?{id:e.id,path:e.path,scale:e.scale,enabled:e.enabled,status:e.status,effect:"loaded"===e.status?e.effect:null,errorMessage:e.errorMessage,errorPath:e.errorPath,loadPromise:e.loadPromise,activeHandles:new Set(e.activeHandles),ownedResourceAliases:e.ownedResourceAliases.slice()}:null,O=(e,t,r)=>{if(e&&("function"==typeof t&&(e.isLoaded?D(()=>t()):e._loadFailed||e._onloadListeners.push(t)),"function"==typeof r))if(e._loadFailed){const t=e._loadErrorMessage||"failed to load effect",n=e._loadErrorPath||"";D(()=>r(t,n))}else e.isLoaded||e._onerrorListeners.push(r)},z=(e,t,r="")=>{if(!e||e._loadFailed)return;e._loadFailed=!0,e._loadErrorMessage=String(t||"failed to load effect"),e._loadErrorPath=String(r||""),F(e);const n=e._onerrorListeners.slice();e._onloadListeners.length=0,e._onerrorListeners.length=0;for(let t=0;t<n.length;t++){const r=n[t];D(()=>r(e._loadErrorMessage,e._loadErrorPath))}};let B=(e,t,r)=>{A(e,t,r)};const j={ptr:0,capacity:0},W=(t,r)=>{const n=t instanceof Float32Array?t:new Float32Array(t);if(n.length<=0)return void r(0);const a=((s=n.length)<=j.capacity&&0!==j.ptr||(0!==j.ptr&&(e._free(j.ptr),j.ptr=0,j.capacity=0),j.ptr=e._malloc(4*s),j.capacity=s),j.ptr);var s;e.HEAPF32.set(n,a>>2),r(a)},H=Object.freeze({rgba8unorm:22,"rgba8unorm-srgb":23,bgra8unorm:27,"bgra8unorm-srgb":28,rgba16float:40,depth24plus:46,"depth24plus-stencil8":47,depth32float:48}),V=(Object.freeze(Object.fromEntries(Object.entries(H).map(([e,t])=>[t,e]))),e=>{if("number"==typeof e&&Number.isFinite(e))return 0|e;if("string"!=typeof e)return null;const t=e.trim().toLowerCase();return t&&Object.prototype.hasOwnProperty.call(H,t)?H[t]:null}),G=async i=>{if(n)return;if(a)return void await new Promise((e,t)=>{c.push(r=>r?e():t(new Error("Runtime initialization failed.")))});if(a=!0,"undefined"==typeof effekseer_webgpu_native)throw a=!1,new Error("effekseer_webgpu_native is not loaded.");const o={};"string"==typeof i&&i.length>0&&(o.locateFile=e=>e.endsWith(".wasm")?i:e),s&&(o.preinitializedWebGPUDevice=s);const f=effekseer_webgpu_native(o);e=f instanceof Promise?await f:f,!s&&e?.preinitializedWebGPUDevice&&(s=e.preinitializedWebGPUDevice),s&&(e.preinitializedWebGPUDevice=s),(()=>{t={InitInternal:e.cwrap("EffekseerInitInternal","number",["number","number","string","number","number"]),InitExternal:e.cwrap("EffekseerInitExternal","number",["number","number","number","number"]),Init:e.cwrap("EffekseerInit","number",["number","number","string","number","number","number"]),Terminate:e.cwrap("EffekseerTerminate","void",["number"]),Update:e.cwrap("EffekseerUpdate","void",["number","number"]),BeginUpdate:e.cwrap("EffekseerBeginUpdate","void",["number"]),EndUpdate:e.cwrap("EffekseerEndUpdate","void",["number"]),UpdateHandle:e.cwrap("EffekseerUpdateHandle","void",["number","number","number"]),Draw:e.cwrap("EffekseerDraw","void",["number"]),DrawExternal:e.cwrap("EffekseerDrawExternal","void",["number"]),BeginDraw:e.cwrap("EffekseerBeginDraw","void",["number"]),EndDraw:e.cwrap("EffekseerEndDraw","void",["number"]),DrawHandle:e.cwrap("EffekseerDrawHandle","void",["number","number"]),SetProjectionMatrix:e.cwrap("EffekseerSetProjectionMatrix","void",["number","number"]),SetProjectionPerspective:e.cwrap("EffekseerSetProjectionPerspective","void",["number","number","number","number","number"]),SetProjectionOrthographic:e.cwrap("EffekseerSetProjectionOrthographic","void",["number","number","number","number","number"]),SetCameraMatrix:e.cwrap("EffekseerSetCameraMatrix","void",["number","number"]),SetCameraLookAt:e.cwrap("EffekseerSetCameraLookAt","void",["number","number","number","number","number","number","number","number","number","number"]),LoadEffect:e.cwrap("EffekseerLoadEffect","number",["number","number","number","number"]),ReleaseEffect:e.cwrap("EffekseerReleaseEffect","void",["number","number"]),ReloadResources:e.cwrap("EffekseerReloadResources","void",["number","number","number","number"]),StopAllEffects:e.cwrap("EffekseerStopAllEffects","void",["number"]),PlayEffect:e.cwrap("EffekseerPlayEffect","number",["number","number","number","number","number"]),StopEffect:e.cwrap("EffekseerStopEffect","void",["number","number"]),StopRoot:e.cwrap("EffekseerStopRoot","void",["number","number"]),Exists:e.cwrap("EffekseerExists","number",["number","number"]),SetFrame:e.cwrap("EffekseerSetFrame","void",["number","number","number"]),SetLocation:e.cwrap("EffekseerSetLocation","void",["number","number","number","number","number"]),SetRotation:e.cwrap("EffekseerSetRotation","void",["number","number","number","number","number"]),SetScale:e.cwrap("EffekseerSetScale","void",["number","number","number","number","number"]),SetMatrix:e.cwrap("EffekseerSetMatrix","void",["number","number","number"]),SetAllColor:e.cwrap("EffekseerSetAllColor","void",["number","number","number","number","number","number"]),SetTargetLocation:e.cwrap("EffekseerSetTargetLocation","void",["number","number","number","number","number"]),GetDynamicInput:e.cwrap("EffekseerGetDynamicInput","number",["number","number","number"]),SetDynamicInput:e.cwrap("EffekseerSetDynamicInput","void",["number","number","number","number"]),SendTrigger:e.cwrap("EffekseerSendTrigger","void",["number","number","number"]),SetPaused:e.cwrap("EffekseerSetPaused","void",["number","number","number"]),SetShown:e.cwrap("EffekseerSetShown","void",["number","number","number"]),SetSpeed:e.cwrap("EffekseerSetSpeed","void",["number","number","number"]),SetRandomSeed:e.cwrap("EffekseerSetRandomSeed","void",["number","number","number"]),SetCompositeMode:e.cwrap("EffekseerSetCompositeMode","void",["number","number"]),GetRestInstancesCount:e.cwrap("EffekseerGetRestInstancesCount","number",["number"]),DrawExternalBack:e.cwrap("EffekseerDrawExternalBack","void",["number"]),DrawExternalFront:e.cwrap("EffekseerDrawExternalFront","void",["number"]),IsVertexArrayObjectSupported:e.cwrap("EffekseerIsVertexArrayObjectSupported","number",["number"]),SetRestorationOfStatesFlag:e.cwrap("EffekseerSetRestorationOfStatesFlag","void",["number","number"]),CaptureBackground:e.cwrap("EffekseerCaptureBackground","void",["number","number","number","number","number"]),ResetBackground:e.cwrap("EffekseerResetBackground","void",["number"]),SetLogEnabled:e.cwrap("EffekseerSetLogEnabled","void",["number"]),SetDepthTexture:e.cwrap("EffekseerSetDepthTexture","void",["number","number"]),SetBackgroundTexture:e.cwrap("EffekseerSetBackgroundTexture","void",["number","number"])},e.resourcesMap={},e._loadBinary=(t,n)=>{const a=r;if(!a)return null;let s=a.resources.find(e=>e.path===t);if(s)return s.isLoaded?s.buffer:null;s={path:t,isLoaded:!1,buffer:null,isRequired:!!n},a.resources.push(s);const i=e=>String(e||"").replace(/\\/g,"/"),o=e=>{const t=i(e);let r=t.startsWith("/")||/^[a-zA-Z]+:\/\//.test(t)?t:(a.baseDir||"")+t;return a.redirect&&(r=a.redirect(r)),r},f=(e=>{const t=i(e),r=[],n=new Set,a=e=>{e&&!n.has(e)&&(n.add(e),r.push(e))},s=e=>{if(!e||e.includes("/"))return;const t=e.toLowerCase();(t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".dds"))&&a(`Texture/${e}`),(t.endsWith(".efkmodel")||t.endsWith(".mqo"))&&a(`Model/${e}`)},o=t.indexOf("/");if(o>0){const e=t.slice(0,o).toLowerCase();(e.endsWith(".efk")||e.endsWith(".efkefc")||e.endsWith(".efkproj"))&&a(t.slice(o+1))}a(t),s(t);let f=t.indexOf("/");for(;f>=0;){const e=t.slice(f+1);a(e),s(e),f=t.indexOf("/",f+1)}return r})(t);if(a.syncResourceLoad){for(let r=0;r<f.length;r++){const n=f[r],a=o(n),i=e.resourcesMap[a]||e.resourcesMap[n]||e.resourcesMap[t];if(null!=i)return s.buffer=i,s.isLoaded=!0,i;const c=L(a);if(null!=c)return s.buffer=c,s.isLoaded=!0,e.resourcesMap[a]=c,e.resourcesMap[n]=c,c}return s.buffer=null,s.isLoaded=!0,null}for(let r=0;r<f.length;r++){const n=f[r],i=o(n),c=e.resourcesMap[i]||e.resourcesMap[n]||e.resourcesMap[t];if(null!=c)return s.buffer=c,s.isLoaded=!0,Promise.resolve().then(()=>a._update()),null}let c=0;const l=()=>{if(c>=f.length)return s.buffer=null,s.isLoaded=!0,void a._update();const e=f[c++],t=o(e);B(t,e=>{if(null!=e)return s.buffer=e,s.isLoaded=!0,void a._update();l()},()=>{l()})};return l(),null},n=!0,a=!1,u();const s=c;c=[],s.forEach(e=>e(!0))})()};class N{constructor(e){this.context=e,this.nativeptr=0,this.baseDir="",this.syncResourceLoad=!1,this.isLoaded=!1,this.scale=1,this.resources=[],this.mainBuffer=null,this.onload=null,this.onerror=null,this._onloadListeners=[],this._onerrorListeners=[],this._loadFailed=!1,this._loadErrorMessage="",this._loadErrorPath="",this._cacheKey="",this.redirect=null,this.packageOnly=!1,this._ownedResourceAliases=[],this._managedRefIds=new Set,this._didFinalResourceReload=!1}_load(n){const a=d(n);if(!a)return void z(this,"invalid data","");r=this,this.mainBuffer=a,this._didFinalResourceReload=!1;const s=e._malloc(a.byteLength);e.HEAPU8.set(new Uint8Array(a),s),this.nativeptr=t.LoadEffect(this.context.nativeptr,s,a.byteLength,this.scale),e._free(s),r=null,this._update()}_reload(){if(!this.mainBuffer||!this.nativeptr)return;r=this;const n=e._malloc(this.mainBuffer.byteLength);e.HEAPU8.set(new Uint8Array(this.mainBuffer),n),t.ReloadResources(this.context.nativeptr,this.nativeptr,n,this.mainBuffer.byteLength),e._free(n),r=null}_update(){let e=!1;const r=[];for(let t=0;t<this.resources.length;t++){const n=this.resources[t];if(!n.isLoaded){e=!0;break}n.isRequired&&null==n.buffer&&r.push(n.path)}if(e)return;const n=0!==this.nativeptr;if(n&&this.resources.length>0&&!this._didFinalResourceReload&&(this._didFinalResourceReload=!0,this._reload()),r.length>0){const e=`failed to load effect. missing resources: ${r.join(", ")}`;return n&&(t.ReleaseEffect(this.context.nativeptr,this.nativeptr),this.nativeptr=0),console.error(`[EffekseerWebGPU] ${e}`),void z(this,e,this.baseDir||"")}if(!n){return void z(this,"failed to load effect",this.baseDir||"")}!this.isLoaded&&n&&(this.isLoaded=!0,(e=>{if(!e)return;const t=e._onloadListeners.slice();e._onloadListeners.length=0,e._onerrorListeners.length=0;for(let e=0;e<t.length;e++){const r=t[e];D(()=>r())}})(this))}}const $=(t,r,n,a,s,i,o,f=null)=>{const c=f||new N(t);c.scale=a,c._ownedResourceAliases=[],O(c,s,i);const l=_(r);if(0===l.size)return z(c,"invalid data. expected efkwgpk package",n||""),c;const u=(()=>{if("string"!=typeof n||0===n.length)return"";const e=v(n),t=e.lastIndexOf("/");return t>=0?e.slice(0,t+1):""})(),d=u.toLowerCase(),h=`efwgpk://${++b}/`,m=new Map;return c.baseDir=u,c.syncResourceLoad=!0,c.packageOnly=!0,c.redirect=e=>{const t=v(e),r=[];d&&t.toLowerCase().startsWith(d)&&r.push(t.slice(u.length)),r.push(t);for(let e=0;e<r.length;e++){const t=p(r[e]);if(!t)continue;const n=m.get(t);if(n)return n}return e},(async()=>{try{const t=await(async(e,t)=>{const r=await M(e,t,g);if(r)try{const e=new TextDecoder("utf-8").decode(new Uint8Array(r)).replace(/\0+$/,""),t=p(e);if(t)return t}catch{}for(const[e,r]of t.entries())if(e.endsWith(".efkwg")&&r&&r.length>0)return e;return""})(r,l);if(!t)throw new Error("main effect path not found in efkwgpk package");const a=await M(r,l,t),s=String.fromCharCode(...new Uint8Array(a||new ArrayBuffer(0),0,Math.min(4,a?a.byteLength:0)));if(!a||"EFWG"!==s&&"SKFE"!==s)throw new Error("main effect inside efkwgpk is not a valid .efkwg");const i=new Map,o=new Map;for(const[n]of l.entries()){if(n===t||n===p(g))continue;const a=R(r,l,n);if(!a)continue;const s=P(a);if(!s)continue;let f=i.get(s);if(!f){let t=o.get(s);if(void 0===t&&(t=await M(r,l,n),o.set(s,t||null)),!t)continue;f=`${h}__payload/${i.size}`,e.resourcesMap[f]=t,i.set(s,f)}m.set(n,f)}c._ownedResourceAliases=Array.from(i.values()),c._load(a),c.nativeptr||z(c,"failed to load effect from efkwgpk package",n||t)}catch(e){z(c,e&&e.message?e.message:"failed to load effect from efkwgpk package",n||"")}})(),c};class q{constructor(e,t){this.context=e,this.native=t}stop(){t.StopEffect(this.context.nativeptr,this.native)}stopRoot(){t.StopRoot(this.context.nativeptr,this.native)}get exists(){return!!t.Exists(this.context.nativeptr,this.native)}setFrame(e){t.SetFrame(this.context.nativeptr,this.native,e)}setLocation(e,r,n){t.SetLocation(this.context.nativeptr,this.native,e,r,n)}setRotation(e,r,n){t.SetRotation(this.context.nativeptr,this.native,e,r,n)}setScale(e,r,n){t.SetScale(this.context.nativeptr,this.native,e,r,n)}setAllColor(e,r,n,a){t.SetAllColor(this.context.nativeptr,this.native,e,r,n,a)}setTargetLocation(e,r,n){t.SetTargetLocation(this.context.nativeptr,this.native,e,r,n)}getDynamicInput(e){return t.GetDynamicInput(this.context.nativeptr,this.native,e)}setDynamicInput(e,r){t.SetDynamicInput(this.context.nativeptr,this.native,e,r)}sendTrigger(e){t.SendTrigger(this.context.nativeptr,this.native,e)}setPaused(e){t.SetPaused(this.context.nativeptr,this.native,e?1:0)}setShown(e){t.SetShown(this.context.nativeptr,this.native,e?1:0)}setSpeed(e){t.SetSpeed(this.context.nativeptr,this.native,e)}setRandomSeed(e){t.SetRandomSeed(this.context.nativeptr,this.native,e)}setMatrix(e){W(e,e=>t.SetMatrix(this.context.nativeptr,this.native,e))}}class K{constructor(){this.nativeptr=0,this._effectCache=new Map,this._registeredEffects=new Map,this._registeredEffectStates=new Map,this.fixedUpdateStepFrames=1,this.fixedUpdateMaxSubsteps=4,this.fixedUpdateAccumulator=0,this.externalRenderPassEnabled=!1}_normalizeManagedEffectDescriptor(e,t){const r=String(e||"").trim();if(!r)throw new Error("registerEffects() requires non-empty effect ids.");let n=null;if("string"==typeof t)n={path:t};else{if(!t||"object"!=typeof t||Array.isArray(t))throw new Error(`registerEffects() entry "${r}" must be a string path or config object.`);n=t}const a=String(n.path||"").trim();if(!a)throw new Error(`registerEffects() entry "${r}" requires a non-empty path.`);const s=Number(n.scale);return{id:r,path:a,scale:Number.isFinite(s)?s:1,enabled:!1!==n.enabled}}_createManagedEffectState(e){return{id:e.id,path:e.path,scale:e.scale,enabled:e.enabled,status:"unloaded",effect:null,errorMessage:"",errorPath:"",loadPromise:null,activeHandles:new Set,ownedResourceAliases:[],_generation:0,_loadingEffect:null}}_resolveManagedEffectIds(e,t=!1){if(null==e){const e=[];for(const[r,n]of this._registeredEffectStates.entries())t&&!n.enabled||e.push(r);return e}const r=Array.isArray(e)?e:[e],n=[],a=new Set;for(let e=0;e<r.length;e++){const t=String(r[e]||"").trim();t&&!a.has(t)&&(a.add(t),n.push(t))}return n}_registerManagedEffectReference(e,t){e&&(e._managedRefIds instanceof Set||(e._managedRefIds=new Set),e._managedRefIds.add(t))}_releaseManagedEffectReference(e,t){e&&e._managedRefIds instanceof Set&&e._managedRefIds.delete(t)}_releaseManagedEffectIfUnused(r){if(!r)return;const n=r._managedRefIds instanceof Set?r._managedRefIds:null;n&&n.size>0||(F(r),(t=>{if(t&&e.resourcesMap)for(let r=0;r<t.length;r++){const n=t[r];"string"==typeof n&&0!==n.length&&delete e.resourcesMap[n]}})(r._ownedResourceAliases),r._ownedResourceAliases=[],this.nativeptr&&r.nativeptr&&(t.ReleaseEffect(this.nativeptr,r.nativeptr),r.nativeptr=0))}_stopManagedHandles(e){if(e){for(const t of e.activeHandles)try{t?.stopRoot?.()}catch{}e.activeHandles.clear()}}_cleanupManagedHandles(){for(const e of this._registeredEffectStates.values())if(e&&0!==e.activeHandles.size)for(const t of Array.from(e.activeHandles))t&&!1!==t.exists||e.activeHandles.delete(t)}_resetManagedEffectStateToUnloaded(e){e&&(e.effect=null,e.status="unloaded",e.errorMessage="",e.errorPath="",e.loadPromise=null,e.ownedResourceAliases=[],e._loadingEffect=null)}_loadRegisteredEffectState(e){if(!e||!this.nativeptr)return Promise.resolve(null);const t=this._registeredEffects.get(e.id);if(!t)return Promise.resolve(null);const r=e._generation+1;e._generation=r,e.status="loading",e.errorMessage="",e.errorPath="",e.effect=null,e.ownedResourceAliases=[],e._loadingEffect=null;const n=new Promise(n=>{let a=!1,s=null;const i=s=>{if(a)return;a=!0;return this._registeredEffectStates.get(e.id)!==e||e._generation!==r?(this._releaseManagedEffectIfUnused(s),void n(null)):(e._loadingEffect=null,e.loadPromise=null,s&&s.isLoaded?(e.effect=s,e.status="loaded",e.errorMessage="",e.errorPath="",e.ownedResourceAliases=Array.isArray(s._ownedResourceAliases)?s._ownedResourceAliases.slice():[],void n(s)):(e.status="failed",e.errorMessage="failed to load effect",e.errorPath=t.path,void n(null)))},o=(i,o="")=>{if(a)return;a=!0,s&&this._releaseManagedEffectReference(s,e.id);if(this._registeredEffectStates.get(e.id)!==e||e._generation!==r)return s&&this._releaseManagedEffectIfUnused(s),void n(null);e._loadingEffect=null,e.loadPromise=null,e.effect=null,e.status="failed",e.errorMessage=String(i||"failed to load effect"),e.errorPath=String(o||t.path||""),e.ownedResourceAliases=[],s&&this._releaseManagedEffectIfUnused(s),n(null)};try{s=this.loadEffect(t.path,t.scale,()=>i(s),(e,t)=>o(e,t))}catch(e){return void o(e&&e.message?e.message:"failed to load effect",t.path)}e._loadingEffect=s,s?(this._registerManagedEffectReference(s,e.id),s.isLoaded?i(s):s._loadFailed&&o(s._loadErrorMessage,s._loadErrorPath)):o("failed to create effect",t.path)});return e.loadPromise=n,n}_prepareInitSettings(e={},t=!1){const r=e.instanceMaxCount||4e3,n=e.squareMaxCount||1e4,a=!1!==e.linearColorSpace?1:0,s=e.compositeWithBackground?1:0;return this.externalRenderPassEnabled=t,this.fixedUpdateAccumulator=0,{instanceMaxCount:r,squareMaxCount:n,linearColorSpace:a,compositeWithBackground:s}}_finishContextInit(e={}){return this.nativeptr&&e.effects&&(this.registerEffects(e.effects),this.preloadEffects()),!!this.nativeptr}init(e,r={}){if(!0===r.externalRenderPass)return this.initExternal(r);let n="#canvas";"string"==typeof e?n=e.startsWith("#")?e:`#${e}`:"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement&&(e.id||(f+=1,e.id=`effekseer_webgpu_canvas_${f}`),n=`#${e.id}`);const a=this._prepareInitSettings(r,!1);return this.nativeptr=t.InitInternal(a.instanceMaxCount,a.squareMaxCount,n,a.linearColorSpace,a.compositeWithBackground),this._finishContextInit(r)}initExternal(e={}){const r=this._prepareInitSettings(e,!0);return this.nativeptr=t.InitExternal(r.instanceMaxCount,r.squareMaxCount,r.linearColorSpace,r.compositeWithBackground),this._finishContextInit(e)}update(e=1){const r=Number(e);if(!Number.isFinite(r)||r<=0)return void this._cleanupManagedHandles();this.fixedUpdateAccumulator+=r;let n=0;for(;this.fixedUpdateAccumulator>=this.fixedUpdateStepFrames&&n<this.fixedUpdateMaxSubsteps;)t.Update(this.nativeptr,this.fixedUpdateStepFrames),this.fixedUpdateAccumulator-=this.fixedUpdateStepFrames,n++;n>=this.fixedUpdateMaxSubsteps&&this.fixedUpdateAccumulator>=this.fixedUpdateStepFrames&&(this.fixedUpdateAccumulator=0),this._cleanupManagedHandles()}beginUpdate(){t.BeginUpdate(this.nativeptr)}endUpdate(){t.EndUpdate(this.nativeptr)}updateHandle(e,r=1){t.UpdateHandle(this.nativeptr,e.native,r)}draw(){this.externalRenderPassEnabled||t.Draw(this.nativeptr)}drawExternal(r,n=null,a="all"){if(!r)return;const s=V(n&&n.colorFormat),i=(()=>{const e=V(n&&n.depthFormat);return null===e?0:e})(),o=(e=>{const t=Number(e);return!Number.isFinite(t)||t<=0?1:Math.max(1,Math.floor(t))})(n&&n.sampleCount),f=(e,t)=>!!e&&Object.prototype.hasOwnProperty.call(e,t),c=f(n,"depthTextureView")||f(n,"importDepthTextureView"),l=f(n,"backgroundTextureView")||f(n,"importBackgroundTextureView"),u=c?f(n,"depthTextureView")?n.depthTextureView:n.importDepthTextureView:null,d=l?f(n,"backgroundTextureView")?n.backgroundTextureView:n.importBackgroundTextureView:null,p=c?e.__effekseerDepthTextureView:null,h=l?e.__effekseerBackgroundTextureView:null;e.__effekseerExternalRenderPass=r,e.__effekseerExternalPassColorFormat=s,e.__effekseerExternalPassDepthFormat=i,e.__effekseerExternalPassSampleCount=o,c&&(e.__effekseerDepthTextureView=u||null),l&&(e.__effekseerBackgroundTextureView=d||null);const g="back"===a?"back":"front"===a?"front":"all";try{"back"===g?t.DrawExternalBack(this.nativeptr):"front"===g?t.DrawExternalFront(this.nativeptr):t.DrawExternal(this.nativeptr)}finally{c&&(e.__effekseerDepthTextureView=p||null),l&&(e.__effekseerBackgroundTextureView=h||null),e.__effekseerExternalRenderPass=null,e.__effekseerExternalPassColorFormat=null,e.__effekseerExternalPassDepthFormat=null,e.__effekseerExternalPassSampleCount=null}}beginDraw(){t.BeginDraw(this.nativeptr)}endDraw(){t.EndDraw(this.nativeptr)}drawHandle(e){t.DrawHandle(this.nativeptr,e.native)}setProjectionMatrix(e){W(e,e=>t.SetProjectionMatrix(this.nativeptr,e))}setProjectionPerspective(e,r,n,a){t.SetProjectionPerspective(this.nativeptr,e,r,n,a)}setProjectionOrthographic(e,r,n,a){t.SetProjectionOrthographic(this.nativeptr,e,r,n,a)}setCameraMatrix(e){W(e,e=>t.SetCameraMatrix(this.nativeptr,e))}setCameraLookAt(e,r,n,a,s,i,o,f,c){t.SetCameraLookAt(this.nativeptr,e,r,n,a,s,i,o,f,c)}setCameraLookAtFromVector(e,t,r={x:0,y:1,z:0}){this.setCameraLookAt(e.x,e.y,e.z,t.x,t.y,t.z,r.x,r.y,r.z)}setCompositeMode(e){t.SetCompositeMode(this.nativeptr,e?1:0)}loadEffect(e,t=1,r,n,a){const s="function"==typeof t?1:t,i="function"==typeof t?t:r,o="function"==typeof t?r:n,f=a;let c=null;if("string"==typeof e&&null==f){c=I(e,s);const t=this._effectCache.get(c);if(t)return O(t,i,o),t}const l=new N(this);l.scale=s,l.redirect=f,l._cacheKey=c||"",O(l,i,o),c&&this._effectCache.set(c,l);const u=(e,t="")=>(z(l,e,t),l);if("string"==typeof e)return"string"==typeof(p=e)&&0!==p.length&&p.replace(/\\/g,"/").split("?")[0].split("#")[0].toLowerCase().endsWith(".efkwg")?(A(e,t=>{const r=d(t);if(!r)return void u("failed to fetch efkwg effect",e);const n=e.replace(/\\/g,"/").split("?")[0].split("#")[0],a=n.lastIndexOf("/");l.baseDir=a>=0?n.slice(0,a+1):"",l.syncResourceLoad=!1,l._load(r),l.nativeptr||u("failed to load efkwg effect",e)},()=>{u("failed to fetch efkwg effect",e)}),l):(e=>"string"==typeof e&&0!==e.length&&v(e).toLowerCase().endsWith(".efkwgpk"))(e)?(A(e,t=>{const r=d(t);r?$(this,r,e,s,null,null,0,l):u("failed to fetch efkwgpk package",e)},()=>{u("failed to fetch efkwgpk package",e)}),l):u("unsupported effect format. expected .efkwg or .efkwgpk",e);var p;const g=d(e);if(!g)return u("invalid data. expected efkwg or efkwgpk bytes","");if(x(g)===h)return $(this,g,"",s,null,null,0,l);const m=String.fromCharCode(...new Uint8Array(g,0,Math.min(4,g.byteLength)));return"EFWG"===m||"SKFE"===m?(l._load(g),l.nativeptr?l:u("failed to load efkwg effect","")):u("invalid data. expected efkwg or efkwgpk bytes","")}loadEffectPackage(e,t,r=1,n,a){let s=r,i=n,o=a;return"function"==typeof r&&(s=1,i=r,o=n),this.loadEffect(e,s,i,o)}registerEffects(e){if(!e||"object"!=typeof e||Array.isArray(e))throw new Error("registerEffects() expects an object map of effect ids to paths/configs.");const t=[];for(const[r,n]of Object.entries(e)){if(this._registeredEffects.has(r))throw new Error(`registerEffects() duplicate id "${r}".`);t.push(this._normalizeManagedEffectDescriptor(r,n))}for(let e=0;e<t.length;e++){const r=t[e];if(this._registeredEffects.has(r.id))throw new Error(`registerEffects() duplicate id "${r.id}".`)}for(let e=0;e<t.length;e++){const r=t[e];this._registeredEffects.set(r.id,r),this._registeredEffectStates.set(r.id,this._createManagedEffectState(r))}if(this.nativeptr)for(let e=0;e<t.length;e++){const r=t[e];r.enabled&&this.preloadEffects([r.id])}}preloadEffects(e){const t=this._resolveManagedEffectIds(e,null==e);return Promise.all(t.map(async e=>{const t=this._registeredEffectStates.get(e);return t?"loaded"===t.status&&t.effect?.isLoaded?[e,t.effect]:"loading"===t.status&&t.loadPromise?[e,await t.loadPromise]:[e,await this._loadRegisteredEffectState(t)]:[e,null]})).then(e=>new Map(e))}reloadEffects(e){const t=this._resolveManagedEffectIds(e,null==e);return this.unloadEffects(t),this.preloadEffects(t)}unloadEffects(e){const t=this._resolveManagedEffectIds(e);for(let e=0;e<t.length;e++){const r=t[e],n=this._registeredEffectStates.get(r);if(!n)continue;n._generation+=1,this._stopManagedHandles(n);const a=n._loadingEffect;a&&(this._releaseManagedEffectReference(a,r),this._releaseManagedEffectIfUnused(a));const s=n.effect;s&&(this._releaseManagedEffectReference(s,r),this._releaseManagedEffectIfUnused(s)),this._resetManagedEffectStateToUnloaded(n)}}unregisterEffects(e){const t=this._resolveManagedEffectIds(e);this.unloadEffects(t);for(let e=0;e<t.length;e++){const r=t[e];this._registeredEffects.delete(r),this._registeredEffectStates.delete(r)}}getEffect(e){const t=this._registeredEffectStates.get(String(e||""));return"loaded"===t?.status&&t.effect?.isLoaded?t.effect:null}getEffectState(e){return T(this._registeredEffectStates.get(String(e||"")))}getEffectStates(){return Array.from(this._registeredEffectStates.values(),e=>T(e))}whenEffectsReady(e){return this.preloadEffects(e)}playEffect(e,t=0,r=0,n=0){const a=this._registeredEffectStates.get(String(e||""));if(!a||"loaded"!==a.status||!a.effect?.isLoaded)return null;const s=this.play(a.effect,t,r,n);return s&&a.activeHandles.add(s),s}releaseEffect(e){e&&e.nativeptr&&(F(e),t.ReleaseEffect(this.nativeptr,e.nativeptr),e.nativeptr=0)}play(e,r=0,n=0,a=0){if(!e||!e.isLoaded)return null;const s=t.PlayEffect(this.nativeptr,e.nativeptr,r,n,a);return s>=0?new q(this,s):null}stopAll(){t.StopAllEffects(this.nativeptr)}setResourceLoader(e){B=e}getRestInstancesCount(){return t.GetRestInstancesCount(this.nativeptr)}isVertexArrayObjectSupported(){return!!t.IsVertexArrayObjectSupported(this.nativeptr)}setRestorationOfStatesFlag(e){t.SetRestorationOfStatesFlag(this.nativeptr,e?1:0)}captureBackground(e,r,n,a){t.CaptureBackground(this.nativeptr,e,r,n,a)}resetBackground(){t.ResetBackground(this.nativeptr)}}return new class{async initRuntime(e,t,r){try{await G(e),t&&t()}catch(e){a=!1,n=!1,c=[],r?r(e):console.error(e)}}createContext(){return n?new K:null}releaseContext(e){e&&e.nativeptr&&(e.unloadEffects?.(),t.Terminate(e.nativeptr),e.nativeptr=0,e._effectCache?.clear?.(),e._registeredEffects?.clear?.(),e._registeredEffectStates?.clear?.())}setLogEnabled(e){l=!!e,u()}setImageCrossOrigin(e){o=e}setWebGPUDevice(e){if(n||a)throw new Error("setWebGPUDevice() must be called before initRuntime().");if(null==e)return i=null,void(s=null);if("object"!=typeof e||"function"!=typeof e.createCommandEncoder||!e.queue)throw new Error("setWebGPUDevice() expects a valid GPUDevice.");i=e,s=e}setRendererWorkingColorSpace(e){return((e=null)=>{const t=e;return!(!t||!t.ColorManagement)&&"workingColorSpace"in t.ColorManagement&&void 0!==t.LinearSRGBColorSpace&&(t.ColorManagement.workingColorSpace=t.LinearSRGBColorSpace,!0)})(e)}getWebGPUDevice(){return s||(e?e.preinitializedWebGPUDevice:null)||null}init(e,t){return this.defaultContext?.nativeptr&&this.releaseContext(this.defaultContext),this.defaultContext=new K,this.defaultContext.init(e,t)}update(e){this.defaultContext.update(e)}beginUpdate(){this.defaultContext.beginUpdate()}endUpdate(){this.defaultContext.endUpdate()}updateHandle(e,t){this.defaultContext.updateHandle(e,t)}draw(){this.defaultContext.draw()}drawExternal(e,t,r="all"){this.defaultContext.drawExternal(e,t,r)}beginDraw(){this.defaultContext.beginDraw()}endDraw(){this.defaultContext.endDraw()}drawHandle(e){this.defaultContext.drawHandle(e)}setProjectionMatrix(e){this.defaultContext.setProjectionMatrix(e)}setProjectionPerspective(e,t,r,n){this.defaultContext.setProjectionPerspective(e,t,r,n)}setProjectionOrthographic(e,t,r,n){this.defaultContext.setProjectionOrthographic(e,t,r,n)}setCameraMatrix(e){this.defaultContext.setCameraMatrix(e)}setCameraLookAt(e,t,r,n,a,s,i,o,f){this.defaultContext.setCameraLookAt(e,t,r,n,a,s,i,o,f)}setCameraLookAtFromVector(e,t,r){this.defaultContext.setCameraLookAtFromVector(e,t,r)}setCompositeMode(e){this.defaultContext.setCompositeMode(e)}loadEffect(e,t,r,n,a){return this.defaultContext.loadEffect(e,t,r,n,a)}loadEffectPackage(e,t,r,n,a){return this.defaultContext.loadEffectPackage(e,t,r,n,a)}registerEffects(e){this.defaultContext.registerEffects(e)}preloadEffects(e){return this.defaultContext.preloadEffects(e)}reloadEffects(e){return this.defaultContext.reloadEffects(e)}unloadEffects(e){this.defaultContext.unloadEffects(e)}unregisterEffects(e){this.defaultContext.unregisterEffects(e)}getEffect(e){return this.defaultContext.getEffect(e)}getEffectState(e){return this.defaultContext.getEffectState(e)}getEffectStates(){return this.defaultContext.getEffectStates()}whenEffectsReady(e){return this.defaultContext.whenEffectsReady(e)}playEffect(e,t,r,n){return this.defaultContext.playEffect(e,t,r,n)}releaseEffect(e){this.defaultContext.releaseEffect(e)}play(e,t,r,n){return this.defaultContext.play(e,t,r,n)}stopAll(){this.defaultContext.stopAll()}setResourceLoader(e){this.defaultContext.setResourceLoader(e)}getRestInstancesCount(){return this.defaultContext.getRestInstancesCount()}isVertexArrayObjectSupported(){return this.defaultContext.isVertexArrayObjectSupported()}}})();"undefined"!=typeof globalThis&&(globalThis.effekseer=e),"undefined"!=typeof exports&&(exports=e);
1
+ const e=(()=>{let e={},t={},r=null,n=!1,a=!1,s=null,i=null,o="",f=0,u=[],l=!0;const c=()=>{n&&"function"==typeof t.SetLogEnabled&&t.SetLogEnabled(l?1:0)},d=e=>e instanceof ArrayBuffer?e:ArrayBuffer.isView(e)?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):null,p=e=>{if("string"!=typeof e||0===e.length)return"";const t=e.replace(/\\/g,"/").split("/"),r=[];for(let e=0;e<t.length;e++){const n=t[e];n&&"."!==n&&(".."!==n?r.push(n):r.length>0&&r.pop())}let n=r.join("/");for(;n.startsWith("/");)n=n.slice(1);return n.replace(/[A-Z]/g,e=>e.toLowerCase())},h="EFWGPKG2",g="__efwgpk__/main_effect_path.txt",m=new Uint8Array([69,102,107,87,103,46,87,101,98,71,80,85,46,67,84,82]);let w=0,b=null;const E=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?3988292384^r>>>1:r>>>1;e[t]=r>>>0}return e})(),S=e=>{if(!(e instanceof Uint8Array))return 0;let t=4294967295;for(let r=0;r<e.length;r++){const n=255&(t^e[r]);t=t>>>8^E[n]}return~t>>>0},y=async(e,t)=>{const r=await(async()=>{if(b)return b;if(!globalThis.crypto||!globalThis.crypto.subtle||"function"!=typeof globalThis.crypto.subtle.importKey)throw new Error("Web Crypto AES-CTR is required for encrypted efkwgpk payloads");return b=globalThis.crypto.subtle.importKey("raw",m,"AES-CTR",!1,["decrypt"]),b})();return globalThis.crypto.subtle.decrypt({name:"AES-CTR",counter:t,length:128},r,e)},_=e=>String(e||"").replace(/\\/g,"/").split("?")[0].split("#")[0],v=e=>{const t=d(e);if(!t||t.byteLength<8)return"";const r=new Uint8Array(t,0,8);return String.fromCharCode(...r)},x=e=>{const t=new Map,r=e?e.byteLength:0,n=(e=>{const t=e?e.byteLength:0;if(!e||t<64)return null;const r=new DataView(e);if(v(e)!==h)return null;const n=r.getUint32(8,!0),a=r.getUint32(12,!0),s=r.getUint32(16,!0),i=r.getUint32(20,!0),o=r.getUint32(24,!0),f=r.getUint32(28,!0),u=r.getUint32(32,!0),l=r.getUint32(36,!0),c=r.getUint32(40,!0),d=r.getUint32(44,!0),p=r.getUint32(48,!0),g=r.getUint32(52,!0),m=2===s?64:3===s?80:0;if(0===m||n!==m||48!==o)return null;let w=null;if(4&a){if(s<3||t<80)return null;if(w=new Uint8Array(e.slice(56,72)),16!==w.byteLength)return null}return{headerSize:n,globalFlags:a,formatRevision:s,entryCount:i,entryStride:o,entriesOffset:f,stringPoolOffset:u,stringPoolSize:l,payloadOffset:c,payloadSize:d,tocCrc:p,payloadCrc:g,payloadNonce:w,payloadEncrypted:!!(4&a)}})(e);if(!n)return t;const a=new DataView(e),{headerSize:s,entryCount:i,entryStride:o,entriesOffset:f,stringPoolOffset:u,stringPoolSize:l,payloadOffset:c,payloadSize:d,tocCrc:g,payloadCrc:m}=n,w=BigInt(i)*BigInt(o);if(w>BigInt(r))return t;const b=Number(w);if(!T(f,b,r))return t;if(!T(u,l,r))return t;if(!T(c,d,r))return t;const E=u+l,y=c+d,_=new Uint8Array(e,0,s).slice();_.fill(0,48,56);const x=new Uint8Array(s+b+l);if(x.set(_,0),x.set(new Uint8Array(e,f,b),s),x.set(new Uint8Array(e,u,l),s+b),S(x)!==g>>>0)return t;const k=new Uint8Array(e,c,d);if(S(k)!==m>>>0)return t;const C=new TextDecoder("utf-8");for(let n=0;n<i;n++){const s=f+n*o,i=a.getUint32(s+8,!0),l=a.getUint32(s+12,!0),d=a.getUint32(s+16,!0),h=a.getUint32(s+20,!0),g=a.getUint32(s+24,!0),m=a.getUint32(s+28,!0),w=a.getUint32(s+32,!0),b=a.getUint32(s+36,!0);if(!T(i,l,r))continue;if(i<u||i+l>E)continue;if(!T(h,g,r))continue;if(h<c||h+g>y)continue;let S="";try{S=C.decode(new Uint8Array(e,i,l))}catch{continue}const _=p(S);if(!_)continue;const v={index:n,path:S,normalizedPath:_,flags:d,payloadOffset:h,packedSize:g,rawSize:m,packedCrc:w,rawCrc:b},x=t.get(_);x?x.push(v):t.set(_,[v])}return t._efwgpkMeta={payloadOffset:c,payloadSize:d,payloadEncrypted:n.payloadEncrypted,payloadNonce:n.payloadNonce,decryptedPayloadPromise:null},t},k=async e=>{const t=globalThis.fflate;if(t&&"function"==typeof t.unzlibSync){const r=t.unzlibSync(new Uint8Array(e));return d(r)}if("function"!=typeof DecompressionStream)throw new Error("No zlib inflate backend available for efkwgpk payload");const r=new DecompressionStream("deflate"),n=r.writable.getWriter();await n.write(e),await n.close();return await new Response(r.readable).arrayBuffer()},C=async(e,t,r)=>{const n=t&&t._efwgpkMeta?t._efwgpkMeta:null;if(!n||!n.payloadEncrypted)return new Uint8Array(e,r.payloadOffset,r.packedSize);if(!n.decryptedPayloadPromise){const t=new Uint8Array(e,n.payloadOffset,n.payloadSize);n.decryptedPayloadPromise=y(t,n.payloadNonce).then(e=>new Uint8Array(e))}const a=await n.decryptedPayloadPromise,s=r.payloadOffset-n.payloadOffset;return s<0||s+r.packedSize>a.byteLength?null:a.subarray(s,s+r.packedSize)},P=async(e,t,r)=>{const n=p(r);if(!n||!e||!t||0===t.size)return null;const a=t.get(n);if(!a||0===a.length)return null;for(let r=0;r<a.length;r++){const n=a[r];if(!T(n.payloadOffset,n.packedSize,e.byteLength))continue;const s=await C(e,t,n);if(s&&S(s)===n.packedCrc>>>0){if(0===n.flags&&n.packedSize===n.rawSize){const e=s.slice();if(S(e)!==n.rawCrc>>>0)continue;return e.buffer}if(1===n.flags){const e=await k(s);if(!e||e.byteLength!==n.rawSize)continue;if(S(new Uint8Array(e))!==n.rawCrc>>>0)continue;return e}}}return null},M=e=>e&&Number.isFinite(e.payloadOffset)&&Number.isFinite(e.packedSize)&&Number.isFinite(e.rawSize)&&Number.isFinite(e.flags)?`${e.flags}:${e.payloadOffset}:${e.packedSize}:${e.rawSize}`:"",R=(e,t,r)=>{const n=p(r);if(!n||!e||!t||0===t.size)return null;const a=t.get(n);if(!a||0===a.length)return null;for(let t=0;t<a.length;t++){const r=a[t];if(T(r.payloadOffset,r.packedSize,e.byteLength)){if(0===r.flags&&r.packedSize===r.rawSize)return r;if(1===r.flags)return r}}return null},T=(e,t,r)=>!!(Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(r))&&(!(e<0||t<0||r<0)&&(!(e>r)&&t<=r-e)),U=(e,t,r)=>{const n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="arraybuffer",n.onload=()=>{const a=0|n.status;a>=200&&a<300||0===a?t(n.response):r&&r("not found",e)},n.onerror=()=>{r&&r("not found",e)},n.send(null)},A=e=>{try{const t=new XMLHttpRequest;t.open("GET",e,!1),t.responseType="arraybuffer",t.send(null);const r=0|t.status;if(r>=200&&r<300||0===r)return t.response}catch{}return null},L=e=>{"function"==typeof e&&("function"==typeof queueMicrotask?queueMicrotask(e):Promise.resolve().then(e))},D=(e,t)=>{const r=String(e||"").replace(/\\/g,"/");const n=Number(t);return`${r}::${Number.isFinite(n)?n:1}`},F=e=>{e&&e.context&&e._cacheKey&&e.context._effectCache&&e.context._effectCache.get(e._cacheKey)===e&&e.context._effectCache.delete(e._cacheKey)},I=e=>e?{id:e.id,path:e.path,scale:e.scale,preload:e.preload,warmup:e.warmup,enabled:e.enabled,status:e.status,effect:"loaded"===e.status?e.effect:null,errorMessage:e.errorMessage,errorPath:e.errorPath,warmupStatus:e.warmupStatus,warmupErrorMessage:e.warmupErrorMessage,warmupSignature:e.warmupSignature,loadPromise:e.loadPromise,activeHandles:new Set(e.activeHandles),ownedResourceAliases:e.ownedResourceAliases.slice()}:null,O=(e,t,r)=>{if(e&&("function"==typeof t&&(e.isLoaded?L(()=>t()):e._loadFailed||e._onloadListeners.push(t)),"function"==typeof r))if(e._loadFailed){const t=e._loadErrorMessage||"failed to load effect",n=e._loadErrorPath||"";L(()=>r(t,n))}else e.isLoaded||e._onerrorListeners.push(r)},W=(e,t,r="")=>{if(!e||e._loadFailed)return;e._loadFailed=!0,e._loadErrorMessage=String(t||"failed to load effect"),e._loadErrorPath=String(r||""),F(e);const n=e._onerrorListeners.slice();e._onloadListeners.length=0,e._onerrorListeners.length=0;for(let t=0;t<n.length;t++){const r=n[t];L(()=>r(e._loadErrorMessage,e._loadErrorPath))}};let z=(e,t,r)=>{U(e,t,r)};const B={ptr:0,capacity:0},j=(t,r)=>{const n=t instanceof Float32Array?t:new Float32Array(t);if(n.length<=0)return void r(0);const a=((s=n.length)<=B.capacity&&0!==B.ptr||(0!==B.ptr&&(e._free(B.ptr),B.ptr=0,B.capacity=0),B.ptr=e._malloc(4*s),B.capacity=s),B.ptr);var s;e.HEAPF32.set(n,a>>2),r(a)},N=Object.freeze({rgba8unorm:22,"rgba8unorm-srgb":23,bgra8unorm:27,"bgra8unorm-srgb":28,rgba16float:40,depth24plus:46,"depth24plus-stencil8":47,depth32float:48}),G=Object.freeze(Object.fromEntries(Object.entries(N).map(([e,t])=>[t,e]))),V=e=>{if("number"==typeof e&&Number.isFinite(e))return 0|e;if("string"!=typeof e)return null;const t=e.trim().toLowerCase();return t&&Object.prototype.hasOwnProperty.call(N,t)?N[t]:null},H=e=>{if("string"==typeof e){const t=e.trim().toLowerCase();return t&&Object.prototype.hasOwnProperty.call(N,t)?t:null}return"number"==typeof e&&Number.isFinite(e)&&G[0|e]||null},$=e=>{const t=Number(e);return!Number.isFinite(t)||t<=0?1:Math.max(1,Math.floor(t))},q="undefined"!=typeof GPUTextureUsage?GPUTextureUsage:{COPY_SRC:1,COPY_DST:2,TEXTURE_BINDING:4,STORAGE_BINDING:8,RENDER_ATTACHMENT:16},K=async i=>{if(n)return;if(a)return void await new Promise((e,t)=>{u.push(r=>r?e():t(new Error("Runtime initialization failed.")))});if(a=!0,"undefined"==typeof effekseer_webgpu_native)throw a=!1,new Error("effekseer_webgpu_native is not loaded.");const o={};"string"==typeof i&&i.length>0&&(o.locateFile=e=>e.endsWith(".wasm")?i:e),s&&(o.preinitializedWebGPUDevice=s);const f=effekseer_webgpu_native(o);e=f instanceof Promise?await f:f,!s&&e?.preinitializedWebGPUDevice&&(s=e.preinitializedWebGPUDevice),s&&(e.preinitializedWebGPUDevice=s),(()=>{t={InitInternal:e.cwrap("EffekseerInitInternal","number",["number","number","string","number","number"]),InitExternal:e.cwrap("EffekseerInitExternal","number",["number","number","number","number"]),Init:e.cwrap("EffekseerInit","number",["number","number","string","number","number","number"]),Terminate:e.cwrap("EffekseerTerminate","void",["number"]),Update:e.cwrap("EffekseerUpdate","void",["number","number"]),BeginUpdate:e.cwrap("EffekseerBeginUpdate","void",["number"]),EndUpdate:e.cwrap("EffekseerEndUpdate","void",["number"]),UpdateHandle:e.cwrap("EffekseerUpdateHandle","void",["number","number","number"]),Draw:e.cwrap("EffekseerDraw","void",["number"]),DrawExternal:e.cwrap("EffekseerDrawExternal","void",["number"]),BeginDraw:e.cwrap("EffekseerBeginDraw","void",["number"]),EndDraw:e.cwrap("EffekseerEndDraw","void",["number"]),DrawHandle:e.cwrap("EffekseerDrawHandle","void",["number","number"]),SetProjectionMatrix:e.cwrap("EffekseerSetProjectionMatrix","void",["number","number"]),SetProjectionPerspective:e.cwrap("EffekseerSetProjectionPerspective","void",["number","number","number","number","number"]),SetProjectionOrthographic:e.cwrap("EffekseerSetProjectionOrthographic","void",["number","number","number","number","number"]),SetCameraMatrix:e.cwrap("EffekseerSetCameraMatrix","void",["number","number"]),SetCameraLookAt:e.cwrap("EffekseerSetCameraLookAt","void",["number","number","number","number","number","number","number","number","number","number"]),LoadEffect:e.cwrap("EffekseerLoadEffect","number",["number","number","number","number"]),ReleaseEffect:e.cwrap("EffekseerReleaseEffect","void",["number","number"]),ReloadResources:e.cwrap("EffekseerReloadResources","void",["number","number","number","number"]),StopAllEffects:e.cwrap("EffekseerStopAllEffects","void",["number"]),PlayEffect:e.cwrap("EffekseerPlayEffect","number",["number","number","number","number","number"]),StopEffect:e.cwrap("EffekseerStopEffect","void",["number","number"]),StopRoot:e.cwrap("EffekseerStopRoot","void",["number","number"]),Exists:e.cwrap("EffekseerExists","number",["number","number"]),SetFrame:e.cwrap("EffekseerSetFrame","void",["number","number","number"]),SetLocation:e.cwrap("EffekseerSetLocation","void",["number","number","number","number","number"]),SetRotation:e.cwrap("EffekseerSetRotation","void",["number","number","number","number","number"]),SetScale:e.cwrap("EffekseerSetScale","void",["number","number","number","number","number"]),SetMatrix:e.cwrap("EffekseerSetMatrix","void",["number","number","number"]),SetAllColor:e.cwrap("EffekseerSetAllColor","void",["number","number","number","number","number","number"]),SetTargetLocation:e.cwrap("EffekseerSetTargetLocation","void",["number","number","number","number","number"]),GetDynamicInput:e.cwrap("EffekseerGetDynamicInput","number",["number","number","number"]),SetDynamicInput:e.cwrap("EffekseerSetDynamicInput","void",["number","number","number","number"]),SendTrigger:e.cwrap("EffekseerSendTrigger","void",["number","number","number"]),SetPaused:e.cwrap("EffekseerSetPaused","void",["number","number","number"]),SetShown:e.cwrap("EffekseerSetShown","void",["number","number","number"]),SetSpeed:e.cwrap("EffekseerSetSpeed","void",["number","number","number"]),SetRandomSeed:e.cwrap("EffekseerSetRandomSeed","void",["number","number","number"]),SetCompositeMode:e.cwrap("EffekseerSetCompositeMode","void",["number","number"]),GetRestInstancesCount:e.cwrap("EffekseerGetRestInstancesCount","number",["number"]),DrawExternalBack:e.cwrap("EffekseerDrawExternalBack","void",["number"]),DrawExternalFront:e.cwrap("EffekseerDrawExternalFront","void",["number"]),IsVertexArrayObjectSupported:e.cwrap("EffekseerIsVertexArrayObjectSupported","number",["number"]),SetRestorationOfStatesFlag:e.cwrap("EffekseerSetRestorationOfStatesFlag","void",["number","number"]),CaptureBackground:e.cwrap("EffekseerCaptureBackground","void",["number","number","number","number","number"]),ResetBackground:e.cwrap("EffekseerResetBackground","void",["number"]),SetLogEnabled:e.cwrap("EffekseerSetLogEnabled","void",["number"]),SetDepthTexture:e.cwrap("EffekseerSetDepthTexture","void",["number","number"]),SetBackgroundTexture:e.cwrap("EffekseerSetBackgroundTexture","void",["number","number"])},e.resourcesMap={},e._loadBinary=(t,n)=>{const a=r;if(!a)return null;let s=a.resources.find(e=>e.path===t);if(s)return s.isLoaded?s.buffer:null;s={path:t,isLoaded:!1,buffer:null,isRequired:!!n},a.resources.push(s);const i=e=>String(e||"").replace(/\\/g,"/"),o=e=>{const t=i(e);let r=t.startsWith("/")||/^[a-zA-Z]+:\/\//.test(t)?t:(a.baseDir||"")+t;return a.redirect&&(r=a.redirect(r)),r},f=(e=>{const t=i(e),r=[],n=new Set,a=e=>{e&&!n.has(e)&&(n.add(e),r.push(e))},s=e=>{if(!e||e.includes("/"))return;const t=e.toLowerCase();(t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".dds"))&&a(`Texture/${e}`),(t.endsWith(".efkmodel")||t.endsWith(".mqo"))&&a(`Model/${e}`)},o=t.indexOf("/");if(o>0){const e=t.slice(0,o).toLowerCase();(e.endsWith(".efk")||e.endsWith(".efkefc")||e.endsWith(".efkproj"))&&a(t.slice(o+1))}a(t),s(t);let f=t.indexOf("/");for(;f>=0;){const e=t.slice(f+1);a(e),s(e),f=t.indexOf("/",f+1)}return r})(t);if(a.syncResourceLoad){for(let r=0;r<f.length;r++){const n=f[r],a=o(n),i=e.resourcesMap[a]||e.resourcesMap[n]||e.resourcesMap[t];if(null!=i)return s.buffer=i,s.isLoaded=!0,i;const u=A(a);if(null!=u)return s.buffer=u,s.isLoaded=!0,e.resourcesMap[a]=u,e.resourcesMap[n]=u,u}return s.buffer=null,s.isLoaded=!0,null}for(let r=0;r<f.length;r++){const n=f[r],i=o(n),u=e.resourcesMap[i]||e.resourcesMap[n]||e.resourcesMap[t];if(null!=u)return s.buffer=u,s.isLoaded=!0,Promise.resolve().then(()=>a._update()),null}let u=0;const l=()=>{if(u>=f.length)return s.buffer=null,s.isLoaded=!0,void a._update();const e=f[u++],t=o(e);z(t,e=>{if(null!=e)return s.buffer=e,s.isLoaded=!0,void a._update();l()},()=>{l()})};return l(),null},n=!0,a=!1,c();const s=u;u=[],s.forEach(e=>e(!0))})()};class X{constructor(e){this.context=e,this.nativeptr=0,this.baseDir="",this.syncResourceLoad=!1,this.isLoaded=!1,this.scale=1,this.resources=[],this.mainBuffer=null,this.onload=null,this.onerror=null,this._onloadListeners=[],this._onerrorListeners=[],this._loadFailed=!1,this._loadErrorMessage="",this._loadErrorPath="",this._cacheKey="",this.redirect=null,this.packageOnly=!1,this._ownedResourceAliases=[],this._managedRefIds=new Set}_load(n){const a=d(n);if(!a)return void W(this,"invalid data","");r=this,this.mainBuffer=a;const s=e._malloc(a.byteLength);e.HEAPU8.set(new Uint8Array(a),s),this.nativeptr=t.LoadEffect(this.context.nativeptr,s,a.byteLength,this.scale),e._free(s),r=null,this._update()}_reload(){if(!this.mainBuffer||!this.nativeptr)return;r=this;const n=e._malloc(this.mainBuffer.byteLength);e.HEAPU8.set(new Uint8Array(this.mainBuffer),n),t.ReloadResources(this.context.nativeptr,this.nativeptr,n,this.mainBuffer.byteLength),e._free(n),r=null}_update(){let e=!1;const r=[];for(let t=0;t<this.resources.length;t++){const n=this.resources[t];if(!n.isLoaded){e=!0;break}n.isRequired&&null==n.buffer&&r.push(n.path)}if(e)return;const n=0!==this.nativeptr;if(r.length>0){const e=`failed to load effect. missing resources: ${r.join(", ")}`;return n&&(t.ReleaseEffect(this.context.nativeptr,this.nativeptr),this.nativeptr=0),console.error(`[EffekseerWebGPU] ${e}`),void W(this,e,this.baseDir||"")}if(!n){return void W(this,"failed to load effect",this.baseDir||"")}!this.isLoaded&&n&&(this.isLoaded=!0,(e=>{if(!e)return;const t=e._onloadListeners.slice();e._onloadListeners.length=0,e._onerrorListeners.length=0;for(let e=0;e<t.length;e++){const r=t[e];L(()=>r())}})(this))}}const J=(t,r,n,a,s,i,o,f=null)=>{const u=f||new X(t);u.scale=a,u._ownedResourceAliases=[],O(u,s,i);const l=x(r);if(0===l.size)return W(u,"invalid data. expected efkwgpk package",n||""),u;const c=(()=>{if("string"!=typeof n||0===n.length)return"";const e=_(n),t=e.lastIndexOf("/");return t>=0?e.slice(0,t+1):""})(),d=c.toLowerCase(),h=`efwgpk://${++w}/`,m=new Map;return u.baseDir=c,u.syncResourceLoad=!0,u.packageOnly=!0,u.redirect=e=>{const t=_(e),r=[];d&&t.toLowerCase().startsWith(d)&&r.push(t.slice(c.length)),r.push(t);for(let e=0;e<r.length;e++){const t=p(r[e]);if(!t)continue;const n=m.get(t);if(n)return n}return e},(async()=>{try{const t=await(async(e,t)=>{const r=await P(e,t,g);if(r)try{const e=new TextDecoder("utf-8").decode(new Uint8Array(r)).replace(/\0+$/,""),t=p(e);if(t)return t}catch{}for(const[e,r]of t.entries())if(e.endsWith(".efkwg")&&r&&r.length>0)return e;return""})(r,l);if(!t)throw new Error("main effect path not found in efkwgpk package");const a=await P(r,l,t),s=String.fromCharCode(...new Uint8Array(a||new ArrayBuffer(0),0,Math.min(4,a?a.byteLength:0)));if(!a||"EFWG"!==s&&"SKFE"!==s)throw new Error("main effect inside efkwgpk is not a valid .efkwg");const i=new Map,o=new Map;for(const[n]of l.entries()){if(n===t||n===p(g))continue;const a=R(r,l,n);if(!a)continue;const s=M(a);if(!s)continue;let f=i.get(s);if(!f){let t=o.get(s);if(void 0===t&&(t=await P(r,l,n),o.set(s,t||null)),!t)continue;f=`${h}__payload/${i.size}`,e.resourcesMap[f]=t,i.set(s,f)}m.set(n,f)}u._ownedResourceAliases=Array.from(i.values()),u._load(a),u.nativeptr||W(u,"failed to load effect from efkwgpk package",n||t)}catch(e){W(u,e&&e.message?e.message:"failed to load effect from efkwgpk package",n||"")}})(),u};class Y{constructor(e,t){this.context=e,this.native=t}stop(){t.StopEffect(this.context.nativeptr,this.native)}stopRoot(){t.StopRoot(this.context.nativeptr,this.native)}get exists(){return!!t.Exists(this.context.nativeptr,this.native)}setFrame(e){t.SetFrame(this.context.nativeptr,this.native,e)}setLocation(e,r,n){t.SetLocation(this.context.nativeptr,this.native,e,r,n)}setRotation(e,r,n){t.SetRotation(this.context.nativeptr,this.native,e,r,n)}setScale(e,r,n){t.SetScale(this.context.nativeptr,this.native,e,r,n)}setAllColor(e,r,n,a){t.SetAllColor(this.context.nativeptr,this.native,e,r,n,a)}setTargetLocation(e,r,n){t.SetTargetLocation(this.context.nativeptr,this.native,e,r,n)}getDynamicInput(e){return t.GetDynamicInput(this.context.nativeptr,this.native,e)}setDynamicInput(e,r){t.SetDynamicInput(this.context.nativeptr,this.native,e,r)}sendTrigger(e){t.SendTrigger(this.context.nativeptr,this.native,e)}setPaused(e){t.SetPaused(this.context.nativeptr,this.native,e?1:0)}setShown(e){t.SetShown(this.context.nativeptr,this.native,e?1:0)}setSpeed(e){t.SetSpeed(this.context.nativeptr,this.native,e)}setRandomSeed(e){t.SetRandomSeed(this.context.nativeptr,this.native,e)}setMatrix(e){j(e,e=>t.SetMatrix(this.context.nativeptr,this.native,e))}}class Z{constructor(){this.nativeptr=0,this._effectCache=new Map,this._registeredEffects=new Map,this._registeredEffectStates=new Map,this._warmupTargetCache=new Map,this._warmupSettings=this._normalizeWarmupSettings(),this.fixedUpdateStepFrames=1,this.fixedUpdateMaxSubsteps=4,this.fixedUpdateAccumulator=0,this.externalRenderPassEnabled=!1}_normalizeManagedEffectDescriptor(e,t){const r=String(e||"").trim();if(!r)throw new Error("registerEffects() requires non-empty effect ids.");let n=null;if("string"==typeof t)n={path:t};else{if(!t||"object"!=typeof t||Array.isArray(t))throw new Error(`registerEffects() entry "${r}" must be a string path or config object.`);n=t}const a=String(n.path||"").trim();if(!a)throw new Error(`registerEffects() entry "${r}" requires a non-empty path.`);const s=Number(n.scale),i=Object.prototype.hasOwnProperty.call(n,"preload")?!1!==n.preload:!1!==n.enabled;return{id:r,path:a,scale:Number.isFinite(s)?s:1,preload:i,warmup:!0===n.warmup,enabled:i}}_createManagedEffectState(e){return{id:e.id,path:e.path,scale:e.scale,preload:e.preload,warmup:e.warmup,enabled:e.enabled,status:"unloaded",effect:null,errorMessage:"",errorPath:"",warmupStatus:"idle",warmupErrorMessage:"",warmupSignature:"",loadPromise:null,warmupPromise:null,activeHandles:new Set,ownedResourceAliases:[],_generation:0,_loadingEffect:null}}_resolveManagedEffectIds(e,t=null){if(null==e){const e=[];for(const[r,n]of this._registeredEffectStates.entries())("preload"!==t||n.preload)&&("warmup"!==t||n.warmup)&&("preload"!==t&&"warmup"!==t&&null!==t||null!==t&&"preload"!==t&&"warmup"!==t||e.push(r));return e}const r=Array.isArray(e)?e:[e],n=[],a=new Set;for(let e=0;e<r.length;e++){const t=String(r[e]||"").trim();t&&!a.has(t)&&(a.add(t),n.push(t))}return n}_resetManagedEffectWarmupState(e){e&&(e.warmupStatus="idle",e.warmupErrorMessage="",e.warmupSignature="",e.warmupPromise=null)}_toPositiveInteger(e,t){const r=Number(e);return!Number.isFinite(r)||r<=0?t:Math.max(1,Math.floor(r))}_normalizeWarmupSettings(e=null,t=null){const r=e&&"object"==typeof e?e:{},n=t&&"object"==typeof t?t:{},a=H(r.colorFormat??n.colorFormat??(()=>{if("undefined"!=typeof navigator&&navigator.gpu&&"function"==typeof navigator.gpu.getPreferredCanvasFormat){const e=H(navigator.gpu.getPreferredCanvasFormat());if(e)return e}return"bgra8unorm"})());if(!a)throw new Error("warmupSettings.colorFormat must be a supported GPUTextureFormat.");const s=r.depthFormat??n.depthFormat??null,i=null==s?null:H(s);if(null!=s&&!i)throw new Error("warmupSettings.depthFormat must be a supported GPUTextureFormat or null.");return{colorFormat:a,depthFormat:i,sampleCount:$(r.sampleCount??n.sampleCount??1),width:this._toPositiveInteger(r.width??n.width??4,4),height:this._toPositiveInteger(r.height??n.height??4,4),frames:this._toPositiveInteger(r.frames??n.frames??2,2),includeDepthTexture:(r.includeDepthTexture??n.includeDepthTexture??null!=i)&&null!=i,includeBackgroundTexture:!!(r.includeBackgroundTexture??n.includeBackgroundTexture)}}_getWarmupSignature(e){return JSON.stringify({colorFormat:e.colorFormat,depthFormat:e.depthFormat,sampleCount:e.sampleCount,includeDepthTexture:e.includeDepthTexture,includeBackgroundTexture:e.includeBackgroundTexture})}_getWarmupTargetCacheKey(e){return JSON.stringify({colorFormat:e.colorFormat,depthFormat:e.depthFormat,sampleCount:e.sampleCount,width:e.width,height:e.height,includeDepthTexture:e.includeDepthTexture,includeBackgroundTexture:e.includeBackgroundTexture})}_destroyWarmupTarget(e){if(!e)return;const t=e=>{if(e&&"function"==typeof e.destroy)try{e.destroy()}catch{}};t(e.backgroundTexture),t(e.depthTexture),t(e.colorTexture)}_clearWarmupTargetCache(){if(this._warmupTargetCache){for(const e of this._warmupTargetCache.values())this._destroyWarmupTarget(e);this._warmupTargetCache.clear()}}_getRuntimeWebGPUDevice(){return i||s||(e?e.preinitializedWebGPUDevice:null)||null}_getOrCreateWarmupTarget(e){const t=this._getRuntimeWebGPUDevice();if(!t)throw new Error("warmupEffects() requires a GPUDevice. Call setWebGPUDevice() and initRuntime() first.");const r=this._getWarmupTargetCacheKey(e),n=this._warmupTargetCache.get(r);if(n)return n;const a=t.createTexture({size:{width:e.width,height:e.height,depthOrArrayLayers:1},format:e.colorFormat,sampleCount:e.sampleCount,mipLevelCount:1,dimension:"2d",usage:q.RENDER_ATTACHMENT}),s=a.createView();let i=null,o=null;e.depthFormat&&(i=t.createTexture({size:{width:e.width,height:e.height,depthOrArrayLayers:1},format:e.depthFormat,sampleCount:e.sampleCount,mipLevelCount:1,dimension:"2d",usage:q.RENDER_ATTACHMENT|q.TEXTURE_BINDING}),o=i.createView());let f=null,u=null;e.includeBackgroundTexture&&(f=t.createTexture({size:{width:e.width,height:e.height,depthOrArrayLayers:1},format:e.colorFormat,sampleCount:1,mipLevelCount:1,dimension:"2d",usage:q.RENDER_ATTACHMENT|q.TEXTURE_BINDING}),u=f.createView());const l={colorAttachments:[{view:s,clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]};o&&(l.depthStencilAttachment={view:o,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"},"depth24plus-stencil8"===e.depthFormat&&(l.depthStencilAttachment.stencilClearValue=0,l.depthStencilAttachment.stencilLoadOp="clear",l.depthStencilAttachment.stencilStoreOp="discard"));const c={colorFormat:e.colorFormat,depthFormat:e.depthFormat,sampleCount:e.sampleCount};e.includeDepthTexture&&o&&(c.depthTextureView=o),e.includeBackgroundTexture&&u&&(c.backgroundTextureView=u);const d={colorTexture:a,colorView:s,depthTexture:i,depthView:o,backgroundTexture:f,backgroundView:u,renderPassDescriptor:l,renderPassState:c};return this._warmupTargetCache.set(r,d),d}_ensureRegisteredEffectLoaded(e){return e?"loaded"===e.status&&e.effect?.isLoaded?Promise.resolve(e.effect):"loading"===e.status&&e.loadPromise?e.loadPromise:this._loadRegisteredEffectState(e):Promise.resolve(null)}_registerManagedEffectReference(e,t){e&&(e._managedRefIds instanceof Set||(e._managedRefIds=new Set),e._managedRefIds.add(t))}_releaseManagedEffectReference(e,t){e&&e._managedRefIds instanceof Set&&e._managedRefIds.delete(t)}_releaseManagedEffectIfUnused(r){if(!r)return;const n=r._managedRefIds instanceof Set?r._managedRefIds:null;n&&n.size>0||(F(r),(t=>{if(t&&e.resourcesMap)for(let r=0;r<t.length;r++){const n=t[r];"string"==typeof n&&0!==n.length&&delete e.resourcesMap[n]}})(r._ownedResourceAliases),r._ownedResourceAliases=[],this.nativeptr&&r.nativeptr&&(t.ReleaseEffect(this.nativeptr,r.nativeptr),r.nativeptr=0))}_stopManagedHandles(e){if(e){for(const t of e.activeHandles)try{t?.stopRoot?.()}catch{}e.activeHandles.clear()}}_cleanupManagedHandles(){for(const e of this._registeredEffectStates.values())if(e&&0!==e.activeHandles.size)for(const t of Array.from(e.activeHandles))t&&!1!==t.exists||e.activeHandles.delete(t)}_resetManagedEffectStateToUnloaded(e){e&&(e.effect=null,e.status="unloaded",e.errorMessage="",e.errorPath="",e.loadPromise=null,e.ownedResourceAliases=[],e._loadingEffect=null,this._resetManagedEffectWarmupState(e))}_loadRegisteredEffectState(e){if(!e||!this.nativeptr)return Promise.resolve(null);const t=this._registeredEffects.get(e.id);if(!t)return Promise.resolve(null);const r=e._generation+1;e._generation=r,e.status="loading",e.errorMessage="",e.errorPath="",e.effect=null,e.ownedResourceAliases=[],e._loadingEffect=null,this._resetManagedEffectWarmupState(e);const n=new Promise(n=>{let a=!1,s=null;const i=s=>{if(a)return;a=!0;return this._registeredEffectStates.get(e.id)!==e||e._generation!==r?(this._releaseManagedEffectIfUnused(s),void n(null)):(e._loadingEffect=null,e.loadPromise=null,s&&s.isLoaded?(e.effect=s,e.status="loaded",e.errorMessage="",e.errorPath="",e.ownedResourceAliases=Array.isArray(s._ownedResourceAliases)?s._ownedResourceAliases.slice():[],void n(s)):(e.status="failed",e.errorMessage="failed to load effect",e.errorPath=t.path,void n(null)))},o=(i,o="")=>{if(a)return;a=!0,s&&this._releaseManagedEffectReference(s,e.id);if(this._registeredEffectStates.get(e.id)!==e||e._generation!==r)return s&&this._releaseManagedEffectIfUnused(s),void n(null);e._loadingEffect=null,e.loadPromise=null,e.effect=null,e.status="failed",e.errorMessage=String(i||"failed to load effect"),e.errorPath=String(o||t.path||""),e.ownedResourceAliases=[],s&&this._releaseManagedEffectIfUnused(s),n(null)};try{s=this.loadEffect(t.path,t.scale,()=>i(s),(e,t)=>o(e,t))}catch(e){return void o(e&&e.message?e.message:"failed to load effect",t.path)}e._loadingEffect=s,s?(this._registerManagedEffectReference(s,e.id),s.isLoaded?i(s):s._loadFailed&&o(s._loadErrorMessage,s._loadErrorPath)):o("failed to create effect",t.path)});return e.loadPromise=n,n}async _warmupRegisteredEffectStates(e,t=null){const r=this._normalizeWarmupSettings(t,this._warmupSettings),n=this._getWarmupSignature(r),a=new Map,s=[],i=[];for(let t=0;t<e.length;t++){const r=e[t];r&&"loaded"===r.status&&r.effect?.isLoaded?"warmed"!==r.warmupStatus||r.warmupSignature!==n?"warming"===r.warmupStatus&&r.warmupPromise?s.push(r.warmupPromise):i.push(r):a.set(r.id,r.effect):a.set(r?.id??"",null)}if(s.length>0)return await Promise.allSettled(s),this._warmupRegisteredEffectStates(e,r);if(0===i.length){for(let t=0;t<e.length;t++){const r=e[t];r&&!a.has(r.id)&&("warmed"===r.warmupStatus&&r.warmupSignature===n&&r.effect?.isLoaded?a.set(r.id,r.effect):a.set(r.id,null))}return a}const o=(async()=>{const e=new Map,t=[],a=new Map;let s=null;try{const n=this._getRuntimeWebGPUDevice();if(!n)throw new Error("warmupEffects() requires a GPUDevice. Call setWebGPUDevice() and initRuntime() first.");const s=this._getOrCreateWarmupTarget(r);for(let r=0;r<i.length;r++){const n=i[r],s=n._generation;if(a.set(n.id,s),"loaded"!==n.status||!n.effect?.isLoaded){n.warmupStatus="failed",n.warmupErrorMessage="failed to warm up effect because it is not loaded",n.warmupSignature="",e.set(n.id,null);continue}const o=this.play(n.effect,0,0,0);o?t.push({state:n,handle:o,generation:s}):(n.warmupStatus="failed",n.warmupErrorMessage="failed to create a temporary warmup handle",n.warmupSignature="",e.set(n.id,null))}if(t.length>0)for(let e=0;e<r.frames;e++){this.update(1);const e=n.createCommandEncoder(),t=e.beginRenderPass(s.renderPassDescriptor);try{this.drawExternal(t,s.renderPassState,"all")}finally{t.end()}n.queue.submit([e.finish()]),"function"==typeof n.queue.onSubmittedWorkDone&&await n.queue.onSubmittedWorkDone()}}catch(e){s=e}finally{for(let e=0;e<t.length;e++){const r=t[e];try{r.handle.stopRoot?.()}catch{}}t.length>0&&this.update(1)}for(let t=0;t<i.length;t++){const r=i[t];this._registeredEffectStates.get(r.id)===r&&r._generation===a.get(r.id)?s?(r.warmupStatus="failed",r.warmupErrorMessage=s&&s.message?s.message:"failed to warm up effect",r.warmupSignature="",e.set(r.id,null)):e.has(r.id)||(r.warmupStatus="warmed",r.warmupErrorMessage="",r.warmupSignature=n,e.set(r.id,r.effect?.isLoaded?r.effect:null)):e.set(r.id,null)}return e})();for(let e=0;e<i.length;e++){const t=i[e];t.warmupStatus="warming",t.warmupErrorMessage="",t.warmupSignature="",t.warmupPromise=o}const f=await o;for(let e=0;e<i.length;e++){const t=i[e];t.warmupPromise===o&&(t.warmupPromise=null)}for(let t=0;t<e.length;t++){const r=e[t];r&&!a.has(r.id)&&(f.has(r.id)?a.set(r.id,f.get(r.id)):"warmed"===r.warmupStatus&&r.warmupSignature===n&&r.effect?.isLoaded?a.set(r.id,r.effect):a.set(r.id,null))}return a}_prepareInitSettings(e={},t=!1){const r=e.instanceMaxCount||4e3,n=e.squareMaxCount||1e4,a=!1!==e.linearColorSpace?1:0,s=e.compositeWithBackground?1:0;return this.externalRenderPassEnabled=t,this._warmupSettings=this._normalizeWarmupSettings(e.warmupSettings,this._warmupSettings),this.fixedUpdateAccumulator=0,{instanceMaxCount:r,squareMaxCount:n,linearColorSpace:a,compositeWithBackground:s}}_finishContextInit(e={}){return this.nativeptr&&e.effects&&(this.registerEffects(e.effects),this.preloadEffects()),!!this.nativeptr}init(e,r={}){if(!0===r.externalRenderPass)return this.initExternal(r);let n="#canvas";"string"==typeof e?n=e.startsWith("#")?e:`#${e}`:"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement&&(e.id||(f+=1,e.id=`effekseer_webgpu_canvas_${f}`),n=`#${e.id}`);const a=this._prepareInitSettings(r,!1);return this.nativeptr=t.InitInternal(a.instanceMaxCount,a.squareMaxCount,n,a.linearColorSpace,a.compositeWithBackground),this._finishContextInit(r)}initExternal(e={}){const r=this._prepareInitSettings(e,!0);return this.nativeptr=t.InitExternal(r.instanceMaxCount,r.squareMaxCount,r.linearColorSpace,r.compositeWithBackground),this._finishContextInit(e)}update(e=1){const r=Number(e);if(!Number.isFinite(r)||r<=0)return void this._cleanupManagedHandles();this.fixedUpdateAccumulator+=r;let n=0;for(;this.fixedUpdateAccumulator>=this.fixedUpdateStepFrames&&n<this.fixedUpdateMaxSubsteps;)t.Update(this.nativeptr,this.fixedUpdateStepFrames),this.fixedUpdateAccumulator-=this.fixedUpdateStepFrames,n++;n>=this.fixedUpdateMaxSubsteps&&this.fixedUpdateAccumulator>=this.fixedUpdateStepFrames&&(this.fixedUpdateAccumulator=0),this._cleanupManagedHandles()}beginUpdate(){t.BeginUpdate(this.nativeptr)}endUpdate(){t.EndUpdate(this.nativeptr)}updateHandle(e,r=1){t.UpdateHandle(this.nativeptr,e.native,r)}draw(){this.externalRenderPassEnabled||t.Draw(this.nativeptr)}drawExternal(r,n=null,a="all"){if(!r)return;const s=V(n&&n.colorFormat),i=(()=>{const e=V(n&&n.depthFormat);return null===e?0:e})(),o=$(n&&n.sampleCount),f=(e,t)=>!!e&&Object.prototype.hasOwnProperty.call(e,t),u=f(n,"depthTextureView")||f(n,"importDepthTextureView"),l=f(n,"backgroundTextureView")||f(n,"importBackgroundTextureView"),c=u?f(n,"depthTextureView")?n.depthTextureView:n.importDepthTextureView:null,d=l?f(n,"backgroundTextureView")?n.backgroundTextureView:n.importBackgroundTextureView:null,p=u?e.__effekseerDepthTextureView:null,h=l?e.__effekseerBackgroundTextureView:null;e.__effekseerExternalRenderPass=r,e.__effekseerExternalPassColorFormat=s,e.__effekseerExternalPassDepthFormat=i,e.__effekseerExternalPassSampleCount=o,u&&(e.__effekseerDepthTextureView=c||null),l&&(e.__effekseerBackgroundTextureView=d||null);const g="back"===a?"back":"front"===a?"front":"all";try{"back"===g?t.DrawExternalBack(this.nativeptr):"front"===g?t.DrawExternalFront(this.nativeptr):t.DrawExternal(this.nativeptr)}finally{u&&(e.__effekseerDepthTextureView=p||null),l&&(e.__effekseerBackgroundTextureView=h||null),e.__effekseerExternalRenderPass=null,e.__effekseerExternalPassColorFormat=null,e.__effekseerExternalPassDepthFormat=null,e.__effekseerExternalPassSampleCount=null}}beginDraw(){t.BeginDraw(this.nativeptr)}endDraw(){t.EndDraw(this.nativeptr)}drawHandle(e){t.DrawHandle(this.nativeptr,e.native)}setProjectionMatrix(e){j(e,e=>t.SetProjectionMatrix(this.nativeptr,e))}setProjectionPerspective(e,r,n,a){t.SetProjectionPerspective(this.nativeptr,e,r,n,a)}setProjectionOrthographic(e,r,n,a){t.SetProjectionOrthographic(this.nativeptr,e,r,n,a)}setCameraMatrix(e){j(e,e=>t.SetCameraMatrix(this.nativeptr,e))}setCameraLookAt(e,r,n,a,s,i,o,f,u){t.SetCameraLookAt(this.nativeptr,e,r,n,a,s,i,o,f,u)}setCameraLookAtFromVector(e,t,r={x:0,y:1,z:0}){this.setCameraLookAt(e.x,e.y,e.z,t.x,t.y,t.z,r.x,r.y,r.z)}setCompositeMode(e){t.SetCompositeMode(this.nativeptr,e?1:0)}loadEffect(e,t=1,r,n,a){const s="function"==typeof t?1:t,i="function"==typeof t?t:r,o="function"==typeof t?r:n,f=a;let u=null;if("string"==typeof e&&null==f){u=D(e,s);const t=this._effectCache.get(u);if(t)return O(t,i,o),t}const l=new X(this);l.scale=s,l.redirect=f,l._cacheKey=u||"",O(l,i,o),u&&this._effectCache.set(u,l);const c=(e,t="")=>(W(l,e,t),l);if("string"==typeof e)return"string"==typeof(p=e)&&0!==p.length&&p.replace(/\\/g,"/").split("?")[0].split("#")[0].toLowerCase().endsWith(".efkwg")?(U(e,t=>{const r=d(t);if(!r)return void c("failed to fetch efkwg effect",e);const n=e.replace(/\\/g,"/").split("?")[0].split("#")[0],a=n.lastIndexOf("/");l.baseDir=a>=0?n.slice(0,a+1):"",l.syncResourceLoad=!1,l._load(r),l.nativeptr||c("failed to load efkwg effect",e)},()=>{c("failed to fetch efkwg effect",e)}),l):(e=>"string"==typeof e&&0!==e.length&&_(e).toLowerCase().endsWith(".efkwgpk"))(e)?(U(e,t=>{const r=d(t);r?J(this,r,e,s,null,null,0,l):c("failed to fetch efkwgpk package",e)},()=>{c("failed to fetch efkwgpk package",e)}),l):c("unsupported effect format. expected .efkwg or .efkwgpk",e);var p;const g=d(e);if(!g)return c("invalid data. expected efkwg or efkwgpk bytes","");if(v(g)===h)return J(this,g,"",s,null,null,0,l);const m=String.fromCharCode(...new Uint8Array(g,0,Math.min(4,g.byteLength)));return"EFWG"===m||"SKFE"===m?(l._load(g),l.nativeptr?l:c("failed to load efkwg effect","")):c("invalid data. expected efkwg or efkwgpk bytes","")}loadEffectPackage(e,t,r=1,n,a){let s=r,i=n,o=a;return"function"==typeof r&&(s=1,i=r,o=n),this.loadEffect(e,s,i,o)}registerEffects(e){if(!e||"object"!=typeof e||Array.isArray(e))throw new Error("registerEffects() expects an object map of effect ids to paths/configs.");const t=[];for(const[r,n]of Object.entries(e)){if(this._registeredEffects.has(r))throw new Error(`registerEffects() duplicate id "${r}".`);t.push(this._normalizeManagedEffectDescriptor(r,n))}for(let e=0;e<t.length;e++){const r=t[e];if(this._registeredEffects.has(r.id))throw new Error(`registerEffects() duplicate id "${r.id}".`)}for(let e=0;e<t.length;e++){const r=t[e];this._registeredEffects.set(r.id,r),this._registeredEffectStates.set(r.id,this._createManagedEffectState(r))}if(this.nativeptr)for(let e=0;e<t.length;e++){const r=t[e];r.preload&&this.preloadEffects([r.id])}}async preloadEffects(e){const t=this._resolveManagedEffectIds(e,null==e?"preload":null),r=new Map,n=[];for(let e=0;e<t.length;e++){const a=t[e],s=this._registeredEffectStates.get(a);if(!s){r.set(a,null);continue}const i=await this._ensureRegisteredEffectLoaded(s);r.set(a,i),i&&s.warmup&&n.push(s)}if(n.length>0){const e=await this._warmupRegisteredEffectStates(n);for(const[t,n]of e.entries())r.set(t,n)}return r}reloadEffects(e){const t=this._resolveManagedEffectIds(e,null==e?"preload":null);return this.unloadEffects(t),this.preloadEffects(t)}unloadEffects(e){const t=this._resolveManagedEffectIds(e);for(let e=0;e<t.length;e++){const r=t[e],n=this._registeredEffectStates.get(r);if(!n)continue;n._generation+=1,this._stopManagedHandles(n);const a=n._loadingEffect;a&&(this._releaseManagedEffectReference(a,r),this._releaseManagedEffectIfUnused(a));const s=n.effect;s&&(this._releaseManagedEffectReference(s,r),this._releaseManagedEffectIfUnused(s)),this._resetManagedEffectStateToUnloaded(n)}}unregisterEffects(e){const t=this._resolveManagedEffectIds(e);this.unloadEffects(t);for(let e=0;e<t.length;e++){const r=t[e];this._registeredEffects.delete(r),this._registeredEffectStates.delete(r)}}getEffect(e){const t=this._registeredEffectStates.get(String(e||""));return"loaded"===t?.status&&t.effect?.isLoaded?t.effect:null}getEffectState(e){return I(this._registeredEffectStates.get(String(e||"")))}getEffectStates(){return Array.from(this._registeredEffectStates.values(),e=>I(e))}async warmupEffects(e,t){const r=this._resolveManagedEffectIds(e,null==e?"warmup":null),n=new Map,a=[];for(let e=0;e<r.length;e++){const t=r[e],s=this._registeredEffectStates.get(t);if(!s){n.set(t,null);continue}await this._ensureRegisteredEffectLoaded(s)?a.push(s):n.set(t,null)}if(0===a.length)return n;const s=await this._warmupRegisteredEffectStates(a,t);for(const[e,t]of s.entries())n.set(e,t);return n}whenEffectsReady(e){return this.preloadEffects(e)}playEffect(e,t=0,r=0,n=0){const a=this._registeredEffectStates.get(String(e||""));if(!a||"loaded"!==a.status||!a.effect?.isLoaded)return null;const s=this.play(a.effect,t,r,n);return s&&a.activeHandles.add(s),s}releaseEffect(e){e&&e.nativeptr&&(F(e),t.ReleaseEffect(this.nativeptr,e.nativeptr),e.nativeptr=0)}play(e,r=0,n=0,a=0){if(!e||!e.isLoaded)return null;const s=t.PlayEffect(this.nativeptr,e.nativeptr,r,n,a);return s>=0?new Y(this,s):null}stopAll(){t.StopAllEffects(this.nativeptr)}setResourceLoader(e){z=e}getRestInstancesCount(){return t.GetRestInstancesCount(this.nativeptr)}isVertexArrayObjectSupported(){return!!t.IsVertexArrayObjectSupported(this.nativeptr)}setRestorationOfStatesFlag(e){t.SetRestorationOfStatesFlag(this.nativeptr,e?1:0)}captureBackground(e,r,n,a){t.CaptureBackground(this.nativeptr,e,r,n,a)}resetBackground(){t.ResetBackground(this.nativeptr)}}return new class{async initRuntime(e,t,r){try{await K(e),t&&t()}catch(e){a=!1,n=!1,u=[],r?r(e):console.error(e)}}createContext(){return n?new Z:null}releaseContext(e){e&&e.nativeptr&&(e.unloadEffects?.(),e._clearWarmupTargetCache?.(),t.Terminate(e.nativeptr),e.nativeptr=0,e._effectCache?.clear?.(),e._registeredEffects?.clear?.(),e._registeredEffectStates?.clear?.())}setLogEnabled(e){l=!!e,c()}setImageCrossOrigin(e){o=e}setWebGPUDevice(e){if(n||a)throw new Error("setWebGPUDevice() must be called before initRuntime().");if(null==e)return i=null,void(s=null);if("object"!=typeof e||"function"!=typeof e.createCommandEncoder||!e.queue)throw new Error("setWebGPUDevice() expects a valid GPUDevice.");i=e,s=e}setRendererWorkingColorSpace(e){return((e=null)=>{const t=e;return!(!t||!t.ColorManagement)&&"workingColorSpace"in t.ColorManagement&&void 0!==t.LinearSRGBColorSpace&&(t.ColorManagement.workingColorSpace=t.LinearSRGBColorSpace,!0)})(e)}getWebGPUDevice(){return s||(e?e.preinitializedWebGPUDevice:null)||null}init(e,t){return this.defaultContext?.nativeptr&&this.releaseContext(this.defaultContext),this.defaultContext=new Z,this.defaultContext.init(e,t)}update(e){this.defaultContext.update(e)}beginUpdate(){this.defaultContext.beginUpdate()}endUpdate(){this.defaultContext.endUpdate()}updateHandle(e,t){this.defaultContext.updateHandle(e,t)}draw(){this.defaultContext.draw()}drawExternal(e,t,r="all"){this.defaultContext.drawExternal(e,t,r)}beginDraw(){this.defaultContext.beginDraw()}endDraw(){this.defaultContext.endDraw()}drawHandle(e){this.defaultContext.drawHandle(e)}setProjectionMatrix(e){this.defaultContext.setProjectionMatrix(e)}setProjectionPerspective(e,t,r,n){this.defaultContext.setProjectionPerspective(e,t,r,n)}setProjectionOrthographic(e,t,r,n){this.defaultContext.setProjectionOrthographic(e,t,r,n)}setCameraMatrix(e){this.defaultContext.setCameraMatrix(e)}setCameraLookAt(e,t,r,n,a,s,i,o,f){this.defaultContext.setCameraLookAt(e,t,r,n,a,s,i,o,f)}setCameraLookAtFromVector(e,t,r){this.defaultContext.setCameraLookAtFromVector(e,t,r)}setCompositeMode(e){this.defaultContext.setCompositeMode(e)}loadEffect(e,t,r,n,a){return this.defaultContext.loadEffect(e,t,r,n,a)}loadEffectPackage(e,t,r,n,a){return this.defaultContext.loadEffectPackage(e,t,r,n,a)}registerEffects(e){this.defaultContext.registerEffects(e)}preloadEffects(e){return this.defaultContext.preloadEffects(e)}warmupEffects(e,t){return this.defaultContext.warmupEffects(e,t)}reloadEffects(e){return this.defaultContext.reloadEffects(e)}unloadEffects(e){this.defaultContext.unloadEffects(e)}unregisterEffects(e){this.defaultContext.unregisterEffects(e)}getEffect(e){return this.defaultContext.getEffect(e)}getEffectState(e){return this.defaultContext.getEffectState(e)}getEffectStates(){return this.defaultContext.getEffectStates()}whenEffectsReady(e){return this.defaultContext.whenEffectsReady(e)}playEffect(e,t,r,n){return this.defaultContext.playEffect(e,t,r,n)}releaseEffect(e){this.defaultContext.releaseEffect(e)}play(e,t,r,n){return this.defaultContext.play(e,t,r,n)}stopAll(){this.defaultContext.stopAll()}setResourceLoader(e){this.defaultContext.setResourceLoader(e)}getRestInstancesCount(){return this.defaultContext.getRestInstancesCount()}isVertexArrayObjectSupported(){return this.defaultContext.isVertexArrayObjectSupported()}}})();"undefined"!=typeof globalThis&&(globalThis.effekseer=e),"undefined"!=typeof exports&&(exports=e);
@@ -586,11 +586,16 @@ const effekseer = (() => {
586
586
  id: state.id,
587
587
  path: state.path,
588
588
  scale: state.scale,
589
+ preload: state.preload,
590
+ warmup: state.warmup,
589
591
  enabled: state.enabled,
590
592
  status: state.status,
591
593
  effect: state.status === "loaded" ? state.effect : null,
592
594
  errorMessage: state.errorMessage,
593
595
  errorPath: state.errorPath,
596
+ warmupStatus: state.warmupStatus,
597
+ warmupErrorMessage: state.warmupErrorMessage,
598
+ warmupSignature: state.warmupSignature,
594
599
  loadPromise: state.loadPromise,
595
600
  activeHandles: new Set(state.activeHandles),
596
601
  ownedResourceAliases: state.ownedResourceAliases.slice(),
@@ -745,6 +750,29 @@ const effekseer = (() => {
745
750
  return Math.max(1, Math.floor(n));
746
751
  };
747
752
 
753
+ const GPUTextureUsageFlags = (() => {
754
+ if (typeof GPUTextureUsage !== "undefined") {
755
+ return GPUTextureUsage;
756
+ }
757
+ return {
758
+ COPY_SRC: 0x01,
759
+ COPY_DST: 0x02,
760
+ TEXTURE_BINDING: 0x04,
761
+ STORAGE_BINDING: 0x08,
762
+ RENDER_ATTACHMENT: 0x10,
763
+ };
764
+ })();
765
+
766
+ const getDefaultWarmupColorFormat = () => {
767
+ if (typeof navigator !== "undefined" && navigator.gpu && typeof navigator.gpu.getPreferredCanvasFormat === "function") {
768
+ const preferred = toTextureFormatName(navigator.gpu.getPreferredCanvasFormat());
769
+ if (preferred) {
770
+ return preferred;
771
+ }
772
+ }
773
+ return "bgra8unorm";
774
+ };
775
+
748
776
  const setRendererLinearWorkingColorSpace = (colorSpaceApiLike = null) => {
749
777
  const colorSpaceApi = colorSpaceApiLike;
750
778
  if (!colorSpaceApi || !colorSpaceApi.ColorManagement) {
@@ -1093,7 +1121,6 @@ const effekseer = (() => {
1093
1121
  this.packageOnly = false;
1094
1122
  this._ownedResourceAliases = [];
1095
1123
  this._managedRefIds = new Set();
1096
- this._didFinalResourceReload = false;
1097
1124
  }
1098
1125
 
1099
1126
  _load(buffer) {
@@ -1105,7 +1132,6 @@ const effekseer = (() => {
1105
1132
 
1106
1133
  loadingEffect = this;
1107
1134
  this.mainBuffer = ab;
1108
- this._didFinalResourceReload = false;
1109
1135
  const memptr = Module._malloc(ab.byteLength);
1110
1136
  Module.HEAPU8.set(new Uint8Array(ab), memptr);
1111
1137
  this.nativeptr = Core.LoadEffect(this.context.nativeptr, memptr, ab.byteLength, this.scale);
@@ -1147,10 +1173,6 @@ const effekseer = (() => {
1147
1173
  }
1148
1174
 
1149
1175
  const loaded = this.nativeptr !== 0;
1150
- if (loaded && this.resources.length > 0 && !this._didFinalResourceReload) {
1151
- this._didFinalResourceReload = true;
1152
- this._reload();
1153
- }
1154
1176
 
1155
1177
  if (missingRequiredResources.length > 0) {
1156
1178
  const detail = `failed to load effect. missing resources: ${missingRequiredResources.join(", ")}`;
@@ -1320,6 +1342,8 @@ const effekseer = (() => {
1320
1342
  this._effectCache = new Map();
1321
1343
  this._registeredEffects = new Map();
1322
1344
  this._registeredEffectStates = new Map();
1345
+ this._warmupTargetCache = new Map();
1346
+ this._warmupSettings = this._normalizeWarmupSettings();
1323
1347
  this.fixedUpdateStepFrames = 1.0;
1324
1348
  this.fixedUpdateMaxSubsteps = 4;
1325
1349
  this.fixedUpdateAccumulator = 0.0;
@@ -1347,11 +1371,16 @@ const effekseer = (() => {
1347
1371
  }
1348
1372
 
1349
1373
  const numericScale = Number(descriptor.scale);
1374
+ const preload = Object.prototype.hasOwnProperty.call(descriptor, "preload")
1375
+ ? descriptor.preload !== false
1376
+ : descriptor.enabled !== false;
1350
1377
  return {
1351
1378
  id: effectId,
1352
1379
  path,
1353
1380
  scale: Number.isFinite(numericScale) ? numericScale : 1.0,
1354
- enabled: descriptor.enabled !== false,
1381
+ preload,
1382
+ warmup: descriptor.warmup === true,
1383
+ enabled: preload,
1355
1384
  };
1356
1385
  }
1357
1386
 
@@ -1360,12 +1389,18 @@ const effekseer = (() => {
1360
1389
  id: descriptor.id,
1361
1390
  path: descriptor.path,
1362
1391
  scale: descriptor.scale,
1392
+ preload: descriptor.preload,
1393
+ warmup: descriptor.warmup,
1363
1394
  enabled: descriptor.enabled,
1364
1395
  status: "unloaded",
1365
1396
  effect: null,
1366
1397
  errorMessage: "",
1367
1398
  errorPath: "",
1399
+ warmupStatus: "idle",
1400
+ warmupErrorMessage: "",
1401
+ warmupSignature: "",
1368
1402
  loadPromise: null,
1403
+ warmupPromise: null,
1369
1404
  activeHandles: new Set(),
1370
1405
  ownedResourceAliases: [],
1371
1406
  _generation: 0,
@@ -1373,11 +1408,20 @@ const effekseer = (() => {
1373
1408
  };
1374
1409
  }
1375
1410
 
1376
- _resolveManagedEffectIds(ids, enabledOnly = false) {
1411
+ _resolveManagedEffectIds(ids, filter = null) {
1377
1412
  if (ids == null) {
1378
1413
  const resolvedIds = [];
1379
1414
  for (const [id, state] of this._registeredEffectStates.entries()) {
1380
- if (!enabledOnly || state.enabled) {
1415
+ if (filter === "preload" && !state.preload) {
1416
+ continue;
1417
+ }
1418
+ if (filter === "warmup" && !state.warmup) {
1419
+ continue;
1420
+ }
1421
+ if (filter !== "preload" && filter !== "warmup" && filter !== null) {
1422
+ continue;
1423
+ }
1424
+ if (filter === null || filter === "preload" || filter === "warmup") {
1381
1425
  resolvedIds.push(id);
1382
1426
  }
1383
1427
  }
@@ -1398,6 +1442,224 @@ const effekseer = (() => {
1398
1442
  return uniqueIds;
1399
1443
  }
1400
1444
 
1445
+ _resetManagedEffectWarmupState(state) {
1446
+ if (!state) {
1447
+ return;
1448
+ }
1449
+ state.warmupStatus = "idle";
1450
+ state.warmupErrorMessage = "";
1451
+ state.warmupSignature = "";
1452
+ state.warmupPromise = null;
1453
+ }
1454
+
1455
+ _toPositiveInteger(value, defaultValue) {
1456
+ const numericValue = Number(value);
1457
+ if (!Number.isFinite(numericValue) || numericValue <= 0) {
1458
+ return defaultValue;
1459
+ }
1460
+ return Math.max(1, Math.floor(numericValue));
1461
+ }
1462
+
1463
+ _normalizeWarmupSettings(settings = null, baseSettings = null) {
1464
+ const nextSettings = settings && typeof settings === "object" ? settings : {};
1465
+ const base = baseSettings && typeof baseSettings === "object" ? baseSettings : {};
1466
+ const colorFormat = toTextureFormatName(nextSettings.colorFormat ?? base.colorFormat ?? getDefaultWarmupColorFormat());
1467
+ if (!colorFormat) {
1468
+ throw new Error("warmupSettings.colorFormat must be a supported GPUTextureFormat.");
1469
+ }
1470
+
1471
+ const rawDepthFormat = nextSettings.depthFormat ?? base.depthFormat ?? null;
1472
+ const depthFormat = rawDepthFormat == null ? null : toTextureFormatName(rawDepthFormat);
1473
+ if (rawDepthFormat != null && !depthFormat) {
1474
+ throw new Error("warmupSettings.depthFormat must be a supported GPUTextureFormat or null.");
1475
+ }
1476
+
1477
+ const sampleCount = toSampleCountValue(nextSettings.sampleCount ?? base.sampleCount ?? 1);
1478
+ const width = this._toPositiveInteger(nextSettings.width ?? base.width ?? 4, 4);
1479
+ const height = this._toPositiveInteger(nextSettings.height ?? base.height ?? 4, 4);
1480
+ const frames = this._toPositiveInteger(nextSettings.frames ?? base.frames ?? 2, 2);
1481
+ const includeDepthTexture = (nextSettings.includeDepthTexture ?? base.includeDepthTexture ?? (depthFormat != null)) && depthFormat != null;
1482
+ const includeBackgroundTexture = !!(nextSettings.includeBackgroundTexture ?? base.includeBackgroundTexture ?? false);
1483
+
1484
+ return {
1485
+ colorFormat,
1486
+ depthFormat,
1487
+ sampleCount,
1488
+ width,
1489
+ height,
1490
+ frames,
1491
+ includeDepthTexture,
1492
+ includeBackgroundTexture,
1493
+ };
1494
+ }
1495
+
1496
+ _getWarmupSignature(settings) {
1497
+ return JSON.stringify({
1498
+ colorFormat: settings.colorFormat,
1499
+ depthFormat: settings.depthFormat,
1500
+ sampleCount: settings.sampleCount,
1501
+ includeDepthTexture: settings.includeDepthTexture,
1502
+ includeBackgroundTexture: settings.includeBackgroundTexture,
1503
+ });
1504
+ }
1505
+
1506
+ _getWarmupTargetCacheKey(settings) {
1507
+ return JSON.stringify({
1508
+ colorFormat: settings.colorFormat,
1509
+ depthFormat: settings.depthFormat,
1510
+ sampleCount: settings.sampleCount,
1511
+ width: settings.width,
1512
+ height: settings.height,
1513
+ includeDepthTexture: settings.includeDepthTexture,
1514
+ includeBackgroundTexture: settings.includeBackgroundTexture,
1515
+ });
1516
+ }
1517
+
1518
+ _destroyWarmupTarget(target) {
1519
+ if (!target) {
1520
+ return;
1521
+ }
1522
+ const destroyTexture = (texture) => {
1523
+ if (texture && typeof texture.destroy === "function") {
1524
+ try {
1525
+ texture.destroy();
1526
+ } catch {
1527
+ // Ignore texture destruction errors during teardown.
1528
+ }
1529
+ }
1530
+ };
1531
+ destroyTexture(target.backgroundTexture);
1532
+ destroyTexture(target.depthTexture);
1533
+ destroyTexture(target.colorTexture);
1534
+ }
1535
+
1536
+ _clearWarmupTargetCache() {
1537
+ if (!this._warmupTargetCache) {
1538
+ return;
1539
+ }
1540
+ for (const target of this._warmupTargetCache.values()) {
1541
+ this._destroyWarmupTarget(target);
1542
+ }
1543
+ this._warmupTargetCache.clear();
1544
+ }
1545
+
1546
+ _getRuntimeWebGPUDevice() {
1547
+ return externalWebGPUDevice || preinitializedDevice || (Module ? Module.preinitializedWebGPUDevice : null) || null;
1548
+ }
1549
+
1550
+ _getOrCreateWarmupTarget(settings) {
1551
+ const device = this._getRuntimeWebGPUDevice();
1552
+ if (!device) {
1553
+ throw new Error("warmupEffects() requires a GPUDevice. Call setWebGPUDevice() and initRuntime() first.");
1554
+ }
1555
+
1556
+ const cacheKey = this._getWarmupTargetCacheKey(settings);
1557
+ const cachedTarget = this._warmupTargetCache.get(cacheKey);
1558
+ if (cachedTarget) {
1559
+ return cachedTarget;
1560
+ }
1561
+
1562
+ const colorTexture = device.createTexture({
1563
+ size: { width: settings.width, height: settings.height, depthOrArrayLayers: 1 },
1564
+ format: settings.colorFormat,
1565
+ sampleCount: settings.sampleCount,
1566
+ mipLevelCount: 1,
1567
+ dimension: "2d",
1568
+ usage: GPUTextureUsageFlags.RENDER_ATTACHMENT,
1569
+ });
1570
+ const colorView = colorTexture.createView();
1571
+
1572
+ let depthTexture = null;
1573
+ let depthView = null;
1574
+ if (settings.depthFormat) {
1575
+ depthTexture = device.createTexture({
1576
+ size: { width: settings.width, height: settings.height, depthOrArrayLayers: 1 },
1577
+ format: settings.depthFormat,
1578
+ sampleCount: settings.sampleCount,
1579
+ mipLevelCount: 1,
1580
+ dimension: "2d",
1581
+ usage: GPUTextureUsageFlags.RENDER_ATTACHMENT | GPUTextureUsageFlags.TEXTURE_BINDING,
1582
+ });
1583
+ depthView = depthTexture.createView();
1584
+ }
1585
+
1586
+ let backgroundTexture = null;
1587
+ let backgroundView = null;
1588
+ if (settings.includeBackgroundTexture) {
1589
+ backgroundTexture = device.createTexture({
1590
+ size: { width: settings.width, height: settings.height, depthOrArrayLayers: 1 },
1591
+ format: settings.colorFormat,
1592
+ sampleCount: 1,
1593
+ mipLevelCount: 1,
1594
+ dimension: "2d",
1595
+ usage: GPUTextureUsageFlags.RENDER_ATTACHMENT | GPUTextureUsageFlags.TEXTURE_BINDING,
1596
+ });
1597
+ backgroundView = backgroundTexture.createView();
1598
+ }
1599
+
1600
+ const renderPassDescriptor = {
1601
+ colorAttachments: [{
1602
+ view: colorView,
1603
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
1604
+ loadOp: "clear",
1605
+ storeOp: "store",
1606
+ }],
1607
+ };
1608
+
1609
+ if (depthView) {
1610
+ renderPassDescriptor.depthStencilAttachment = {
1611
+ view: depthView,
1612
+ depthClearValue: 1.0,
1613
+ depthLoadOp: "clear",
1614
+ depthStoreOp: "store",
1615
+ };
1616
+ if (settings.depthFormat === "depth24plus-stencil8") {
1617
+ renderPassDescriptor.depthStencilAttachment.stencilClearValue = 0;
1618
+ renderPassDescriptor.depthStencilAttachment.stencilLoadOp = "clear";
1619
+ renderPassDescriptor.depthStencilAttachment.stencilStoreOp = "discard";
1620
+ }
1621
+ }
1622
+
1623
+ const renderPassState = {
1624
+ colorFormat: settings.colorFormat,
1625
+ depthFormat: settings.depthFormat,
1626
+ sampleCount: settings.sampleCount,
1627
+ };
1628
+ if (settings.includeDepthTexture && depthView) {
1629
+ renderPassState.depthTextureView = depthView;
1630
+ }
1631
+ if (settings.includeBackgroundTexture && backgroundView) {
1632
+ renderPassState.backgroundTextureView = backgroundView;
1633
+ }
1634
+
1635
+ const target = {
1636
+ colorTexture,
1637
+ colorView,
1638
+ depthTexture,
1639
+ depthView,
1640
+ backgroundTexture,
1641
+ backgroundView,
1642
+ renderPassDescriptor,
1643
+ renderPassState,
1644
+ };
1645
+
1646
+ this._warmupTargetCache.set(cacheKey, target);
1647
+ return target;
1648
+ }
1649
+
1650
+ _ensureRegisteredEffectLoaded(state) {
1651
+ if (!state) {
1652
+ return Promise.resolve(null);
1653
+ }
1654
+ if (state.status === "loaded" && state.effect?.isLoaded) {
1655
+ return Promise.resolve(state.effect);
1656
+ }
1657
+ if (state.status === "loading" && state.loadPromise) {
1658
+ return state.loadPromise;
1659
+ }
1660
+ return this._loadRegisteredEffectState(state);
1661
+ }
1662
+
1401
1663
  _registerManagedEffectReference(effect, id) {
1402
1664
  if (!effect) {
1403
1665
  return;
@@ -1472,6 +1734,7 @@ const effekseer = (() => {
1472
1734
  state.loadPromise = null;
1473
1735
  state.ownedResourceAliases = [];
1474
1736
  state._loadingEffect = null;
1737
+ this._resetManagedEffectWarmupState(state);
1475
1738
  }
1476
1739
 
1477
1740
  _loadRegisteredEffectState(state) {
@@ -1492,6 +1755,7 @@ const effekseer = (() => {
1492
1755
  state.effect = null;
1493
1756
  state.ownedResourceAliases = [];
1494
1757
  state._loadingEffect = null;
1758
+ this._resetManagedEffectWarmupState(state);
1495
1759
 
1496
1760
  const loadPromise = new Promise((resolve) => {
1497
1761
  let settled = false;
@@ -1597,12 +1861,186 @@ const effekseer = (() => {
1597
1861
  return loadPromise;
1598
1862
  }
1599
1863
 
1864
+ async _warmupRegisteredEffectStates(states, options = null) {
1865
+ const normalizedSettings = this._normalizeWarmupSettings(options, this._warmupSettings);
1866
+ const signature = this._getWarmupSignature(normalizedSettings);
1867
+ const result = new Map();
1868
+ const pendingWarmups = [];
1869
+ const statesToWarm = [];
1870
+
1871
+ for (let i = 0; i < states.length; i++) {
1872
+ const state = states[i];
1873
+ if (!state || state.status !== "loaded" || !state.effect?.isLoaded) {
1874
+ result.set(state?.id ?? "", null);
1875
+ continue;
1876
+ }
1877
+ if (state.warmupStatus === "warmed" && state.warmupSignature === signature) {
1878
+ result.set(state.id, state.effect);
1879
+ continue;
1880
+ }
1881
+ if (state.warmupStatus === "warming" && state.warmupPromise) {
1882
+ pendingWarmups.push(state.warmupPromise);
1883
+ continue;
1884
+ }
1885
+ statesToWarm.push(state);
1886
+ }
1887
+
1888
+ if (pendingWarmups.length > 0) {
1889
+ await Promise.allSettled(pendingWarmups);
1890
+ return this._warmupRegisteredEffectStates(states, normalizedSettings);
1891
+ }
1892
+
1893
+ if (statesToWarm.length === 0) {
1894
+ for (let i = 0; i < states.length; i++) {
1895
+ const state = states[i];
1896
+ if (!state || result.has(state.id)) {
1897
+ continue;
1898
+ }
1899
+ if (state.warmupStatus === "warmed" && state.warmupSignature === signature && state.effect?.isLoaded) {
1900
+ result.set(state.id, state.effect);
1901
+ } else {
1902
+ result.set(state.id, null);
1903
+ }
1904
+ }
1905
+ return result;
1906
+ }
1907
+
1908
+ const batchPromise = (async () => {
1909
+ const batchResult = new Map();
1910
+ const handles = [];
1911
+ const stateGenerationMap = new Map();
1912
+ let batchError = null;
1913
+
1914
+ try {
1915
+ const device = this._getRuntimeWebGPUDevice();
1916
+ if (!device) {
1917
+ throw new Error("warmupEffects() requires a GPUDevice. Call setWebGPUDevice() and initRuntime() first.");
1918
+ }
1919
+
1920
+ const target = this._getOrCreateWarmupTarget(normalizedSettings);
1921
+
1922
+ for (let i = 0; i < statesToWarm.length; i++) {
1923
+ const state = statesToWarm[i];
1924
+ const generation = state._generation;
1925
+ stateGenerationMap.set(state.id, generation);
1926
+ if (state.status !== "loaded" || !state.effect?.isLoaded) {
1927
+ state.warmupStatus = "failed";
1928
+ state.warmupErrorMessage = "failed to warm up effect because it is not loaded";
1929
+ state.warmupSignature = "";
1930
+ batchResult.set(state.id, null);
1931
+ continue;
1932
+ }
1933
+
1934
+ const handle = this.play(state.effect, 0, 0, 0);
1935
+ if (!handle) {
1936
+ state.warmupStatus = "failed";
1937
+ state.warmupErrorMessage = "failed to create a temporary warmup handle";
1938
+ state.warmupSignature = "";
1939
+ batchResult.set(state.id, null);
1940
+ continue;
1941
+ }
1942
+ handles.push({ state, handle, generation });
1943
+ }
1944
+
1945
+ if (handles.length > 0) {
1946
+ for (let frameIndex = 0; frameIndex < normalizedSettings.frames; frameIndex++) {
1947
+ this.update(1.0);
1948
+ const encoder = device.createCommandEncoder();
1949
+ const pass = encoder.beginRenderPass(target.renderPassDescriptor);
1950
+ try {
1951
+ this.drawExternal(pass, target.renderPassState, "all");
1952
+ } finally {
1953
+ pass.end();
1954
+ }
1955
+ device.queue.submit([encoder.finish()]);
1956
+ if (typeof device.queue.onSubmittedWorkDone === "function") {
1957
+ await device.queue.onSubmittedWorkDone();
1958
+ }
1959
+ }
1960
+ }
1961
+ } catch (error) {
1962
+ batchError = error;
1963
+ } finally {
1964
+ for (let i = 0; i < handles.length; i++) {
1965
+ const entry = handles[i];
1966
+ try {
1967
+ entry.handle.stopRoot?.();
1968
+ } catch {
1969
+ // Ignore stale-handle errors during warmup cleanup.
1970
+ }
1971
+ }
1972
+ if (handles.length > 0) {
1973
+ this.update(1.0);
1974
+ }
1975
+ }
1976
+
1977
+ for (let i = 0; i < statesToWarm.length; i++) {
1978
+ const state = statesToWarm[i];
1979
+ const currentState = this._registeredEffectStates.get(state.id);
1980
+ if (currentState !== state || state._generation !== stateGenerationMap.get(state.id)) {
1981
+ batchResult.set(state.id, null);
1982
+ continue;
1983
+ }
1984
+
1985
+ if (batchError) {
1986
+ state.warmupStatus = "failed";
1987
+ state.warmupErrorMessage = batchError && batchError.message ? batchError.message : "failed to warm up effect";
1988
+ state.warmupSignature = "";
1989
+ batchResult.set(state.id, null);
1990
+ continue;
1991
+ }
1992
+
1993
+ if (!batchResult.has(state.id)) {
1994
+ state.warmupStatus = "warmed";
1995
+ state.warmupErrorMessage = "";
1996
+ state.warmupSignature = signature;
1997
+ batchResult.set(state.id, state.effect?.isLoaded ? state.effect : null);
1998
+ }
1999
+ }
2000
+
2001
+ return batchResult;
2002
+ })();
2003
+
2004
+ for (let i = 0; i < statesToWarm.length; i++) {
2005
+ const state = statesToWarm[i];
2006
+ state.warmupStatus = "warming";
2007
+ state.warmupErrorMessage = "";
2008
+ state.warmupSignature = "";
2009
+ state.warmupPromise = batchPromise;
2010
+ }
2011
+
2012
+ const batchResult = await batchPromise;
2013
+ for (let i = 0; i < statesToWarm.length; i++) {
2014
+ const state = statesToWarm[i];
2015
+ if (state.warmupPromise === batchPromise) {
2016
+ state.warmupPromise = null;
2017
+ }
2018
+ }
2019
+
2020
+ for (let i = 0; i < states.length; i++) {
2021
+ const state = states[i];
2022
+ if (!state || result.has(state.id)) {
2023
+ continue;
2024
+ }
2025
+ if (batchResult.has(state.id)) {
2026
+ result.set(state.id, batchResult.get(state.id));
2027
+ } else if (state.warmupStatus === "warmed" && state.warmupSignature === signature && state.effect?.isLoaded) {
2028
+ result.set(state.id, state.effect);
2029
+ } else {
2030
+ result.set(state.id, null);
2031
+ }
2032
+ }
2033
+
2034
+ return result;
2035
+ }
2036
+
1600
2037
  _prepareInitSettings(settings = {}, externalRenderPassEnabled = false) {
1601
2038
  const instanceMaxCount = settings.instanceMaxCount || 4000;
1602
2039
  const squareMaxCount = settings.squareMaxCount || 10000;
1603
2040
  const linearColorSpace = settings.linearColorSpace !== false ? 1 : 0;
1604
2041
  const compositeWithBackground = settings.compositeWithBackground ? 1 : 0;
1605
2042
  this.externalRenderPassEnabled = externalRenderPassEnabled;
2043
+ this._warmupSettings = this._normalizeWarmupSettings(settings.warmupSettings, this._warmupSettings);
1606
2044
 
1607
2045
  // Always use stable fixed-step simulation.
1608
2046
  this.fixedUpdateAccumulator = 0.0;
@@ -1923,31 +2361,43 @@ const effekseer = (() => {
1923
2361
 
1924
2362
  for (let i = 0; i < nextDescriptors.length; i++) {
1925
2363
  const descriptor = nextDescriptors[i];
1926
- if (descriptor.enabled) {
2364
+ if (descriptor.preload) {
1927
2365
  void this.preloadEffects([descriptor.id]);
1928
2366
  }
1929
2367
  }
1930
2368
  }
1931
2369
 
1932
- preloadEffects(ids) {
1933
- const targetIds = this._resolveManagedEffectIds(ids, ids == null);
1934
- return Promise.all(targetIds.map(async (id) => {
2370
+ async preloadEffects(ids) {
2371
+ const targetIds = this._resolveManagedEffectIds(ids, ids == null ? "preload" : null);
2372
+ const result = new Map();
2373
+ const statesToWarm = [];
2374
+
2375
+ for (let i = 0; i < targetIds.length; i++) {
2376
+ const id = targetIds[i];
1935
2377
  const state = this._registeredEffectStates.get(id);
1936
2378
  if (!state) {
1937
- return [id, null];
2379
+ result.set(id, null);
2380
+ continue;
1938
2381
  }
1939
- if (state.status === "loaded" && state.effect?.isLoaded) {
1940
- return [id, state.effect];
2382
+ const effect = await this._ensureRegisteredEffectLoaded(state);
2383
+ result.set(id, effect);
2384
+ if (effect && state.warmup) {
2385
+ statesToWarm.push(state);
1941
2386
  }
1942
- if (state.status === "loading" && state.loadPromise) {
1943
- return [id, await state.loadPromise];
2387
+ }
2388
+
2389
+ if (statesToWarm.length > 0) {
2390
+ const warmupResults = await this._warmupRegisteredEffectStates(statesToWarm);
2391
+ for (const [id, effect] of warmupResults.entries()) {
2392
+ result.set(id, effect);
1944
2393
  }
1945
- return [id, await this._loadRegisteredEffectState(state)];
1946
- })).then((entries) => new Map(entries));
2394
+ }
2395
+
2396
+ return result;
1947
2397
  }
1948
2398
 
1949
2399
  reloadEffects(ids) {
1950
- const targetIds = this._resolveManagedEffectIds(ids, ids == null);
2400
+ const targetIds = this._resolveManagedEffectIds(ids, ids == null ? "preload" : null);
1951
2401
  this.unloadEffects(targetIds);
1952
2402
  return this.preloadEffects(targetIds);
1953
2403
  }
@@ -2003,6 +2453,39 @@ const effekseer = (() => {
2003
2453
  return Array.from(this._registeredEffectStates.values(), (state) => createManagedEffectSnapshot(state));
2004
2454
  }
2005
2455
 
2456
+ async warmupEffects(ids, options) {
2457
+ const targetIds = this._resolveManagedEffectIds(ids, ids == null ? "warmup" : null);
2458
+ const result = new Map();
2459
+ const statesToWarm = [];
2460
+
2461
+ for (let i = 0; i < targetIds.length; i++) {
2462
+ const id = targetIds[i];
2463
+ const state = this._registeredEffectStates.get(id);
2464
+ if (!state) {
2465
+ result.set(id, null);
2466
+ continue;
2467
+ }
2468
+
2469
+ const effect = await this._ensureRegisteredEffectLoaded(state);
2470
+ if (!effect) {
2471
+ result.set(id, null);
2472
+ continue;
2473
+ }
2474
+
2475
+ statesToWarm.push(state);
2476
+ }
2477
+
2478
+ if (statesToWarm.length === 0) {
2479
+ return result;
2480
+ }
2481
+
2482
+ const warmupResults = await this._warmupRegisteredEffectStates(statesToWarm, options);
2483
+ for (const [id, effect] of warmupResults.entries()) {
2484
+ result.set(id, effect);
2485
+ }
2486
+ return result;
2487
+ }
2488
+
2006
2489
  whenEffectsReady(ids) {
2007
2490
  return this.preloadEffects(ids);
2008
2491
  }
@@ -2127,6 +2610,7 @@ const effekseer = (() => {
2127
2610
  return;
2128
2611
  }
2129
2612
  context.unloadEffects?.();
2613
+ context._clearWarmupTargetCache?.();
2130
2614
  Core.Terminate(context.nativeptr);
2131
2615
  context.nativeptr = 0;
2132
2616
  context._effectCache?.clear?.();
@@ -2202,6 +2686,7 @@ const effekseer = (() => {
2202
2686
  loadEffectPackage(pathOrBuffer, Unzip, scale, onload, onerror) { return this.defaultContext.loadEffectPackage(pathOrBuffer, Unzip, scale, onload, onerror); }
2203
2687
  registerEffects(effects) { this.defaultContext.registerEffects(effects); }
2204
2688
  preloadEffects(ids) { return this.defaultContext.preloadEffects(ids); }
2689
+ warmupEffects(ids, options) { return this.defaultContext.warmupEffects(ids, options); }
2205
2690
  reloadEffects(ids) { return this.defaultContext.reloadEffects(ids); }
2206
2691
  unloadEffects(ids) { this.defaultContext.unloadEffects(ids); }
2207
2692
  unregisterEffects(ids) { this.defaultContext.unregisterEffects(ids); }