@react-three/fiber 10.0.0-canary.e881a4a → 10.0.0-canary.ea31ccd

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.
@@ -1,20 +1,19 @@
1
1
  'use strict';
2
2
 
3
3
  const webgpu = require('three/webgpu');
4
- const Inspector_js = require('three/addons/inspector/Inspector.js');
5
4
  const jsxRuntime = require('react/jsx-runtime');
6
5
  const React = require('react');
7
6
  const useMeasure = require('react-use-measure');
8
7
  const itsFine = require('its-fine');
9
- const fiber = require('@react-three/fiber');
8
+ const traditional = require('zustand/traditional');
9
+ const scheduler = require('@pmndrs/scheduler');
10
+ const Tb = require('scheduler');
10
11
  const GroundedSkybox_js = require('three/examples/jsm/objects/GroundedSkybox.js');
11
12
  const HDRLoader_js = require('three/examples/jsm/loaders/HDRLoader.js');
13
+ const HDRCubeTextureLoader_js = require('three/examples/jsm/loaders/HDRCubeTextureLoader.js');
12
14
  const EXRLoader_js = require('three/examples/jsm/loaders/EXRLoader.js');
13
15
  const UltraHDRLoader_js = require('three/examples/jsm/loaders/UltraHDRLoader.js');
14
16
  const gainmapJs = require('@monogrid/gainmap-js');
15
- const Tb = require('scheduler');
16
- const traditional = require('zustand/traditional');
17
- const scheduler = require('@pmndrs/scheduler');
18
17
  const suspendReact = require('suspend-react');
19
18
  const lite = require('dequal/lite');
20
19
  require('zustand/shallow');
@@ -55,6 +54,10 @@ const Tb__default = /*#__PURE__*/_interopDefaultCompat(Tb);
55
54
 
56
55
  const R3F_BUILD_LEGACY = false;
57
56
  const R3F_BUILD_WEBGPU = true;
57
+ async function loadInspector() {
58
+ const { Inspector } = await import('three/addons/inspector/Inspector.js');
59
+ return Inspector;
60
+ }
58
61
  const WebGLRenderer = class WebGLRenderer2 {
59
62
  constructor() {
60
63
  throw new Error(
@@ -68,13 +71,13 @@ const WebGLCubeRenderTarget = null;
68
71
  const THREE = /*#__PURE__*/_mergeNamespaces({
69
72
  __proto__: null,
70
73
  CubeRenderTargetCompat: webgpu.CubeRenderTarget,
71
- Inspector: Inspector_js.Inspector,
72
74
  R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
73
75
  R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
74
76
  RenderTargetCompat: webgpu.RenderTarget,
75
77
  WebGLCubeRenderTarget: WebGLCubeRenderTarget,
76
78
  WebGLRenderTarget: WebGLRenderTarget,
77
- WebGLRenderer: WebGLRenderer
79
+ WebGLRenderer: WebGLRenderer,
80
+ loadInspector: loadInspector
78
81
  }, [webgpu__namespace]);
79
82
 
80
83
  const primaryRegistry = /* @__PURE__ */ new Map();
@@ -135,823 +138,553 @@ function getPrimaryIds() {
135
138
  return Array.from(primaryRegistry.keys());
136
139
  }
137
140
 
138
- const presetsObj = {
139
- apartment: "lebombo_1k.hdr",
140
- city: "potsdamer_platz_1k.hdr",
141
- dawn: "kiara_1_dawn_1k.hdr",
142
- forest: "forest_slope_1k.hdr",
143
- lobby: "st_fagans_interior_1k.hdr",
144
- night: "dikhololo_night_1k.hdr",
145
- park: "rooitou_park_1k.hdr",
146
- studio: "studio_small_03_1k.hdr",
147
- sunset: "venice_sunset_1k.hdr",
148
- warehouse: "empty_warehouse_01_1k.hdr"
149
- };
141
+ var __defProp$1 = Object.defineProperty;
142
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
143
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
144
+ const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React__namespace.useLayoutEffect : React__namespace.useEffect;
145
+ function useMutableCallback(fn) {
146
+ const ref = React__namespace.useRef(fn);
147
+ useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
148
+ return ref;
149
+ }
150
+ function useBridge() {
151
+ const fiber = itsFine.useFiber();
152
+ const ContextBridge = itsFine.useContextBridge();
153
+ return React__namespace.useMemo(
154
+ () => ({ children }) => {
155
+ const strict = !!itsFine.traverseFiber(fiber, true, (node) => node.type === React__namespace.StrictMode);
156
+ const Root = strict ? React__namespace.StrictMode : React__namespace.Fragment;
157
+ return /* @__PURE__ */ jsxRuntime.jsx(Root, { children: /* @__PURE__ */ jsxRuntime.jsx(ContextBridge, { children }) });
158
+ },
159
+ [fiber, ContextBridge]
160
+ );
161
+ }
162
+ function Block({ set }) {
163
+ useIsomorphicLayoutEffect(() => {
164
+ set(new Promise(() => null));
165
+ return () => set(false);
166
+ }, [set]);
167
+ return null;
168
+ }
169
+ const ErrorBoundary = /* @__PURE__ */ (() => {
170
+ var _a;
171
+ return _a = class extends React__namespace.Component {
172
+ constructor() {
173
+ super(...arguments);
174
+ __publicField$1(this, "state", { error: false });
175
+ }
176
+ componentDidCatch(err) {
177
+ this.props.set(err);
178
+ }
179
+ render() {
180
+ return this.state.error ? null : this.props.children;
181
+ }
182
+ }, __publicField$1(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
183
+ })();
150
184
 
151
- const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
152
- const isArray = (arr) => Array.isArray(arr);
153
- const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
154
- function useEnvironment({
155
- files = defaultFiles,
156
- path = "",
157
- preset = void 0,
158
- colorSpace = void 0,
159
- extensions
160
- } = {}) {
161
- if (preset) {
162
- validatePreset(preset);
163
- files = presetsObj[preset];
164
- path = CUBEMAP_ROOT;
165
- }
166
- const multiFile = isArray(files);
167
- const { extension, isCubemap } = getExtension(files);
168
- const loader = getLoader$1(extension);
169
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
170
- const renderer = fiber.useThree((state) => state.renderer);
171
- React.useLayoutEffect(() => {
172
- if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
173
- function clearGainmapTexture() {
174
- fiber.useLoader.clear(loader, multiFile ? [files] : files);
185
+ const is = {
186
+ obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== "function",
187
+ fun: (a) => typeof a === "function",
188
+ str: (a) => typeof a === "string",
189
+ num: (a) => typeof a === "number",
190
+ boo: (a) => typeof a === "boolean",
191
+ und: (a) => a === void 0,
192
+ nul: (a) => a === null,
193
+ arr: (a) => Array.isArray(a),
194
+ equ(a, b, { arrays = "shallow", objects = "reference", strict = true } = {}) {
195
+ if (typeof a !== typeof b || !!a !== !!b) return false;
196
+ if (is.str(a) || is.num(a) || is.boo(a)) return a === b;
197
+ const isObj = is.obj(a);
198
+ if (isObj && objects === "reference") return a === b;
199
+ const isArr = is.arr(a);
200
+ if (isArr && arrays === "reference") return a === b;
201
+ if ((isArr || isObj) && a === b) return true;
202
+ let i;
203
+ for (i in a) if (!(i in b)) return false;
204
+ if (isObj && arrays === "shallow" && objects === "shallow") {
205
+ for (i in strict ? b : a) if (!is.equ(a[i], b[i], { strict, objects: "reference" })) return false;
206
+ } else {
207
+ for (i in strict ? b : a) if (a[i] !== b[i]) return false;
175
208
  }
176
- renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
177
- }, [extension, files, loader, multiFile, renderer.domElement]);
178
- const loaderResult = fiber.useLoader(
179
- loader,
180
- multiFile ? [files] : files,
181
- (loader2) => {
182
- if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
183
- loader2.setRenderer?.(renderer);
184
- }
185
- loader2.setPath?.(path);
186
- if (extensions) extensions(loader2);
209
+ if (is.und(i)) {
210
+ if (isArr && a.length === 0 && b.length === 0) return true;
211
+ if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
212
+ if (a !== b) return false;
187
213
  }
188
- );
189
- let texture = multiFile ? (
190
- // @ts-ignore
191
- loaderResult[0]
192
- ) : loaderResult;
193
- if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
194
- texture = texture.renderTarget?.texture;
214
+ return true;
195
215
  }
196
- texture.mapping = isCubemap ? webgpu.CubeReflectionMapping : webgpu.EquirectangularReflectionMapping;
197
- texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
198
- return texture;
199
- }
200
- const preloadDefaultOptions = {
201
- files: defaultFiles,
202
- path: "",
203
- preset: void 0,
204
- extensions: void 0
205
216
  };
206
- useEnvironment.preload = (preloadOptions) => {
207
- const options = { ...preloadDefaultOptions, ...preloadOptions };
208
- let { files, path = "" } = options;
209
- const { preset, extensions } = options;
210
- if (preset) {
211
- validatePreset(preset);
212
- files = presetsObj[preset];
213
- path = CUBEMAP_ROOT;
217
+ const isOrthographicCamera = (def) => def && def.isOrthographicCamera;
218
+ const isRef$1 = (obj) => obj !== null && typeof obj === "object" && obj.hasOwnProperty("current");
219
+ const isColorRepresentation = (value) => value != null && (typeof value === "string" || typeof value === "number" || value.isColor);
220
+ const isObject3D = (object) => object?.isObject3D;
221
+ const isTexture = (value) => !!value?.isTexture;
222
+ const isVectorLike = (object) => object !== null && typeof object === "object" && "set" in object && typeof object.set === "function";
223
+ const isCopyable = (object) => isVectorLike(object) && "copy" in object && typeof object.copy === "function";
224
+ const hasConstructor = (object) => !!object?.constructor;
225
+
226
+ function calculateDpr(dpr) {
227
+ const target = typeof window !== "undefined" ? window.devicePixelRatio ?? 2 : 1;
228
+ return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
229
+ }
230
+ function getUuidPrefix(uuid) {
231
+ return uuid.split("-")[0];
232
+ }
233
+ function updateCamera(camera, size) {
234
+ if (camera.manual) return;
235
+ if (isOrthographicCamera(camera)) {
236
+ camera.left = size.width / -2;
237
+ camera.right = size.width / 2;
238
+ camera.top = size.height / 2;
239
+ camera.bottom = size.height / -2;
240
+ } else {
241
+ camera.aspect = size.width / size.height;
214
242
  }
215
- const { extension } = getExtension(files);
216
- if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
217
- throw new Error("useEnvironment: Preloading gainmaps is not supported");
243
+ camera.updateProjectionMatrix();
244
+ }
245
+ const frustumMatrix = new webgpu.Matrix4();
246
+ function updateFrustum(camera, frustum) {
247
+ const target = frustum ?? new webgpu.Frustum();
248
+ frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
249
+ target.setFromProjectionMatrix(frustumMatrix);
250
+ return target;
251
+ }
252
+
253
+ const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
254
+ function findInitialRoot(instance) {
255
+ let root = instance.root;
256
+ while (root.getState().previousRoot) root = root.getState().previousRoot;
257
+ return root;
258
+ }
259
+ function getRootState(obj) {
260
+ let state = obj.__r3f?.root.getState();
261
+ if (!state) {
262
+ obj.traverseAncestors((ancestor) => {
263
+ const parentState = ancestor.__r3f?.root.getState();
264
+ if (parentState) {
265
+ state = parentState;
266
+ return false;
267
+ }
268
+ });
218
269
  }
219
- const loader = getLoader$1(extension);
220
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
221
- fiber.useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
222
- loader2.setPath?.(path);
223
- if (extensions) extensions(loader2);
224
- });
225
- };
226
- const clearDefaultOptins = {
227
- files: defaultFiles,
228
- preset: void 0
229
- };
230
- useEnvironment.clear = (clearOptions) => {
231
- const options = { ...clearDefaultOptins, ...clearOptions };
232
- let { files } = options;
233
- const { preset } = options;
234
- if (preset) {
235
- validatePreset(preset);
236
- files = presetsObj[preset];
270
+ return state;
271
+ }
272
+ function buildGraph(object) {
273
+ const data = { nodes: {}, materials: {}, meshes: {} };
274
+ if (object) {
275
+ object.traverse((obj) => {
276
+ if (obj.name) data.nodes[obj.name] = obj;
277
+ if (obj.material) {
278
+ const material = Array.isArray(obj.material) ? obj.material[0] : obj.material;
279
+ const nameAlreadyUsed = data.materials[material.name];
280
+ let materialName = material.name;
281
+ if (nameAlreadyUsed) {
282
+ materialName = materialName + `-${getUuidPrefix(material.uuid)}`;
283
+ material.userData.materialCacheName = materialName;
284
+ }
285
+ data.materials[materialName] = material;
286
+ }
287
+ if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
288
+ });
237
289
  }
238
- const { extension } = getExtension(files);
239
- const loader = getLoader$1(extension);
240
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
241
- fiber.useLoader.clear(loader, isArray(files) ? [files] : files);
242
- };
243
- function validatePreset(preset) {
244
- if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
290
+ return data;
245
291
  }
246
- function getExtension(files) {
247
- const isCubemap = isArray(files) && files.length === 6;
248
- const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
249
- const firstEntry = isArray(files) ? files[0] : files;
250
- const extension = isCubemap ? "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
251
- return { extension, isCubemap, isGainmap };
292
+ function dispose(obj) {
293
+ if (obj.type !== "Scene") obj.dispose?.();
294
+ for (const p in obj) {
295
+ const prop = obj[p];
296
+ if (prop?.type !== "Scene") prop?.dispose?.();
297
+ }
252
298
  }
253
- function getLoader$1(extension) {
254
- const loader = extension === "cube" ? webgpu.CubeTextureLoader : extension === "hdr" ? HDRLoader_js.HDRLoader : extension === "exr" ? EXRLoader_js.EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader_js.UltraHDRLoader : extension === "webp" ? gainmapJs.GainMapLoader : null;
255
- return loader;
299
+ function getInstanceProps(pendingProps) {
300
+ const props = {};
301
+ for (const key in pendingProps) {
302
+ if (!REACT_INTERNAL_PROPS.includes(key)) props[key] = pendingProps[key];
303
+ }
304
+ return props;
305
+ }
306
+ function prepare(target, root, type, props) {
307
+ const object = target;
308
+ let instance = object?.__r3f;
309
+ if (!instance) {
310
+ instance = {
311
+ root,
312
+ type,
313
+ parent: null,
314
+ children: [],
315
+ props: getInstanceProps(props),
316
+ object,
317
+ eventCount: 0,
318
+ handlers: {},
319
+ isHidden: false
320
+ };
321
+ if (object) object.__r3f = instance;
322
+ }
323
+ return instance;
324
+ }
325
+ function invalidateInstance(instance) {
326
+ if (!instance.parent) return;
327
+ const state = instance.root?.getState?.();
328
+ if (state && state.internal.frames === 0) state.invalidate();
256
329
  }
257
330
 
258
- const isRef$1 = (obj) => obj.current && obj.current.isScene;
259
- const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
260
- function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
261
- sceneProps = {
262
- backgroundBlurriness: 0,
263
- backgroundIntensity: 1,
264
- backgroundRotation: [0, 0, 0],
265
- environmentIntensity: 1,
266
- environmentRotation: [0, 0, 0],
267
- ...sceneProps
268
- };
269
- const target = resolveScene(scene || defaultScene);
270
- const oldbg = target.background;
271
- const oldenv = target.environment;
272
- const oldSceneProps = {
273
- // @ts-ignore
274
- backgroundBlurriness: target.backgroundBlurriness,
275
- // @ts-ignore
276
- backgroundIntensity: target.backgroundIntensity,
277
- // @ts-ignore
278
- backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
279
- // @ts-ignore
280
- environmentIntensity: target.environmentIntensity,
281
- // @ts-ignore
282
- environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
331
+ const tempFrustum = new webgpu.Frustum();
332
+ let hasWarnedWebGL = false;
333
+ let tslModule = null;
334
+ async function loadTSL() {
335
+ if (tslModule) return tslModule;
336
+ try {
337
+ const tsl = await import('three/tsl');
338
+ tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
339
+ return tslModule;
340
+ } catch {
341
+ return null;
342
+ }
343
+ }
344
+ function createOcclusionObserverNode(store, uniform) {
345
+ const node = new webgpu.Node("float");
346
+ node.updateType = webgpu.NodeUpdateType.OBJECT;
347
+ node.update = function(frame) {
348
+ const { internal } = store.getState();
349
+ const registry = internal.visibilityRegistry;
350
+ const cache = internal.occlusionCache;
351
+ for (const entry of registry.values()) {
352
+ const { object, handlers } = entry;
353
+ if (handlers.onOccluded || handlers.onVisible) {
354
+ const isOccluded = frame.renderer.isOccluded(object);
355
+ cache.set(object, isOccluded);
356
+ }
357
+ }
283
358
  };
284
- if (background !== "only") target.environment = texture;
285
- if (background) target.background = texture;
286
- fiber.applyProps(target, sceneProps);
287
- return () => {
288
- if (background !== "only") target.environment = oldenv;
289
- if (background) target.background = oldbg;
290
- fiber.applyProps(target, oldSceneProps);
359
+ node.setup = function() {
360
+ return uniform(0);
291
361
  };
362
+ return node;
292
363
  }
293
- function EnvironmentMap({ scene, background = false, map, ...config }) {
294
- const defaultScene = fiber.useThree((state) => state.scene);
295
- React__namespace.useLayoutEffect(() => {
296
- if (map) return setEnvProps(background, scene, defaultScene, map, config);
297
- });
298
- return null;
364
+ let occlusionSetupPromise = null;
365
+ function enableOcclusion(store) {
366
+ const state = store.getState();
367
+ const { internal, renderer } = state;
368
+ if (internal.occlusionEnabled || occlusionSetupPromise) return;
369
+ const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
370
+ if (!hasOcclusionSupport) {
371
+ if (!hasWarnedWebGL) {
372
+ console.warn(
373
+ "[R3F] Warning: onOccluded/onVisible occlusion queries require WebGPU renderer. Occlusion events will not fire on WebGL."
374
+ );
375
+ hasWarnedWebGL = true;
376
+ }
377
+ return;
378
+ }
379
+ occlusionSetupPromise = setupOcclusion(store);
299
380
  }
300
- function EnvironmentCube({
301
- background = false,
302
- scene,
303
- blur,
304
- backgroundBlurriness,
305
- backgroundIntensity,
306
- backgroundRotation,
307
- environmentIntensity,
308
- environmentRotation,
309
- ...rest
310
- }) {
311
- const texture = useEnvironment(rest);
312
- const defaultScene = fiber.useThree((state) => state.scene);
313
- React__namespace.useLayoutEffect(() => {
314
- return setEnvProps(background, scene, defaultScene, texture, {
315
- backgroundBlurriness: blur ?? backgroundBlurriness,
316
- backgroundIntensity,
317
- backgroundRotation,
318
- environmentIntensity,
319
- environmentRotation
320
- });
381
+ async function setupOcclusion(store) {
382
+ const state = store.getState();
383
+ const { internal, rootScene, set } = state;
384
+ const tsl = await loadTSL();
385
+ if (!tsl) {
386
+ console.warn("[R3F] Warning: TSL module not available. Occlusion queries disabled.");
387
+ occlusionSetupPromise = null;
388
+ return;
389
+ }
390
+ const { uniform, nodeObject } = tsl;
391
+ let helperGroup = internal.helperGroup;
392
+ if (!helperGroup) {
393
+ helperGroup = new webgpu.Group();
394
+ helperGroup.name = "__r3fInternal";
395
+ helperGroup.__r3fInternal = true;
396
+ rootScene.add(helperGroup);
397
+ }
398
+ const geometry = new webgpu.BoxGeometry(1, 1, 1);
399
+ const material = new webgpu.MeshBasicNodeMaterial({
400
+ transparent: true,
401
+ opacity: 0
321
402
  });
322
- React__namespace.useEffect(() => {
323
- return () => {
324
- texture.dispose();
325
- };
326
- }, [texture]);
327
- return null;
328
- }
329
- function EnvironmentPortal({
330
- children,
331
- near = 0.1,
332
- far = 1e3,
333
- resolution = 256,
334
- frames = 1,
335
- map,
336
- background = false,
337
- blur,
338
- backgroundBlurriness,
339
- backgroundIntensity,
340
- backgroundRotation,
341
- environmentIntensity,
342
- environmentRotation,
343
- scene,
344
- files,
345
- path,
346
- preset = void 0,
347
- extensions
348
- }) {
349
- const renderer = fiber.useThree((state) => state.renderer);
350
- const isLegacy = fiber.useThree((state) => state.isLegacy);
351
- const defaultScene = fiber.useThree((state) => state.scene);
352
- const camera = React__namespace.useRef(null);
353
- const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
354
- const fbo = React__namespace.useMemo(() => {
355
- const fbo2 = isLegacy ? new WebGLCubeRenderTarget(resolution) : new webgpu.CubeRenderTarget(resolution);
356
- fbo2.texture.type = webgpu.HalfFloatType;
357
- return fbo2;
358
- }, [resolution, isLegacy]);
359
- React__namespace.useEffect(() => {
360
- return () => {
361
- fbo.dispose();
362
- };
363
- }, [fbo]);
364
- React__namespace.useLayoutEffect(() => {
365
- if (frames === 1) {
366
- const autoClear = renderer.autoClear;
367
- renderer.autoClear = true;
368
- camera.current.update(renderer, virtualScene);
369
- renderer.autoClear = autoClear;
370
- }
371
- return setEnvProps(background, scene, defaultScene, fbo.texture, {
372
- backgroundBlurriness: blur ?? backgroundBlurriness,
373
- backgroundIntensity,
374
- backgroundRotation,
375
- environmentIntensity,
376
- environmentRotation
377
- });
378
- }, [
379
- children,
380
- virtualScene,
381
- fbo.texture,
382
- scene,
383
- defaultScene,
384
- background,
385
- frames,
386
- renderer,
387
- blur,
388
- backgroundBlurriness,
389
- backgroundIntensity,
390
- backgroundRotation,
391
- environmentIntensity,
392
- environmentRotation
393
- ]);
394
- let count = 1;
395
- fiber.useFrame(() => {
396
- if (frames === Infinity || count < frames) {
397
- const autoClear = renderer.autoClear;
398
- renderer.autoClear = true;
399
- camera.current.update(renderer, virtualScene);
400
- renderer.autoClear = autoClear;
401
- count++;
403
+ const observerNode = nodeObject(createOcclusionObserverNode(store, uniform));
404
+ material.colorNode = observerNode;
405
+ material.needsUpdate = true;
406
+ const mesh = new webgpu.Mesh(geometry, material);
407
+ mesh.name = "__r3fOcclusionObserver";
408
+ mesh.scale.setScalar(1e-4);
409
+ mesh.frustumCulled = false;
410
+ mesh.__r3fInternal = true;
411
+ helperGroup.add(mesh);
412
+ set((state2) => ({
413
+ internal: {
414
+ ...state2.internal,
415
+ helperGroup,
416
+ occlusionObserver: mesh,
417
+ occlusionEnabled: true
402
418
  }
403
- });
404
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fiber.createPortal(
405
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
406
- children,
407
- /* @__PURE__ */ jsxRuntime.jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
408
- files || preset ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { background: true, map, extensions }) : null
409
- ] }),
410
- virtualScene
411
- ) });
419
+ }));
420
+ occlusionSetupPromise = null;
412
421
  }
413
- function EnvironmentGround(props) {
414
- const textureDefault = useEnvironment(props);
415
- const texture = props.map || textureDefault;
416
- React__namespace.useMemo(() => fiber.extend({ GroundProjectedEnvImpl: GroundedSkybox_js.GroundedSkybox }), []);
417
- React__namespace.useEffect(() => {
418
- return () => {
419
- textureDefault.dispose();
420
- };
421
- }, [textureDefault]);
422
- const height = props.ground?.height ?? 15;
423
- const radius = props.ground?.radius ?? 60;
424
- const scale = props.ground?.scale ?? 1e3;
425
- const args = React__namespace.useMemo(
426
- () => [texture, height, radius],
427
- [texture, height, radius]
428
- );
429
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
430
- /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props, map: texture }),
431
- /* @__PURE__ */ jsxRuntime.jsx("groundProjectedEnvImpl", { args, scale })
432
- ] });
433
- }
434
- function EnvironmentColor({ color, scene }) {
435
- const defaultScene = fiber.useThree((state) => state.scene);
436
- React__namespace.useLayoutEffect(() => {
437
- if (color === void 0) return;
438
- const target = resolveScene(scene || defaultScene);
439
- const oldBg = target.background;
440
- target.background = new webgpu.Color(color);
441
- return () => {
442
- target.background = oldBg;
443
- };
444
- });
445
- return null;
446
- }
447
- function EnvironmentDualSource(props) {
448
- const { backgroundFiles, ...envProps } = props;
449
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
450
- /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...envProps, background: false }),
451
- /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
452
- ] });
453
- }
454
- function Environment(props) {
455
- if (props.color && !props.files && !props.preset && !props.map) {
456
- return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentColor, { ...props });
422
+ function disableOcclusion(store) {
423
+ const { internal, set } = store.getState();
424
+ if (!internal.occlusionEnabled) return;
425
+ if (internal.occlusionObserver) {
426
+ internal.occlusionObserver.removeFromParent();
427
+ internal.occlusionObserver.geometry.dispose();
428
+ internal.occlusionObserver.material.dispose();
457
429
  }
458
- if (props.backgroundFiles && props.backgroundFiles !== props.files) {
459
- return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentDualSource, { ...props });
430
+ internal.occlusionCache.clear();
431
+ set((state) => ({
432
+ internal: {
433
+ ...state.internal,
434
+ occlusionObserver: null,
435
+ occlusionEnabled: false
436
+ }
437
+ }));
438
+ }
439
+ function cleanupHelperGroup(store) {
440
+ const { internal, set } = store.getState();
441
+ disableOcclusion(store);
442
+ if (internal.helperGroup) {
443
+ internal.helperGroup.removeFromParent();
444
+ set((state) => ({
445
+ internal: {
446
+ ...state.internal,
447
+ helperGroup: null
448
+ }
449
+ }));
460
450
  }
461
- return props.ground ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props });
462
451
  }
463
-
464
- var __defProp$1 = Object.defineProperty;
465
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
466
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
467
- const act = React__namespace["act"];
468
- const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React__namespace.useLayoutEffect : React__namespace.useEffect;
469
- function useMutableCallback(fn) {
470
- const ref = React__namespace.useRef(fn);
471
- useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
472
- return ref;
452
+ function registerVisibility(store, object, handlers) {
453
+ const { internal } = store.getState();
454
+ const registry = internal.visibilityRegistry;
455
+ const entry = {
456
+ object,
457
+ handlers,
458
+ lastFramedState: null,
459
+ lastOccludedState: null,
460
+ lastVisibleState: null
461
+ };
462
+ registry.set(object.uuid, entry);
463
+ if (handlers.onOccluded || handlers.onVisible) {
464
+ object.occlusionTest = true;
465
+ if (!internal.occlusionEnabled) {
466
+ enableOcclusion(store);
467
+ }
468
+ }
473
469
  }
474
- function useBridge() {
475
- const fiber = itsFine.useFiber();
476
- const ContextBridge = itsFine.useContextBridge();
477
- return React__namespace.useMemo(
478
- () => ({ children }) => {
479
- const strict = !!itsFine.traverseFiber(fiber, true, (node) => node.type === React__namespace.StrictMode);
480
- const Root = strict ? React__namespace.StrictMode : React__namespace.Fragment;
481
- return /* @__PURE__ */ jsxRuntime.jsx(Root, { children: /* @__PURE__ */ jsxRuntime.jsx(ContextBridge, { children }) });
482
- },
483
- [fiber, ContextBridge]
484
- );
470
+ function unregisterVisibility(store, object) {
471
+ const { internal } = store.getState();
472
+ internal.visibilityRegistry.delete(object.uuid);
473
+ internal.occlusionCache.delete(object);
485
474
  }
486
- function Block({ set }) {
487
- useIsomorphicLayoutEffect(() => {
488
- set(new Promise(() => null));
489
- return () => set(false);
490
- }, [set]);
491
- return null;
475
+ function updateVisibilityHandlers(store, object, handlers) {
476
+ const { internal } = store.getState();
477
+ const entry = internal.visibilityRegistry.get(object.uuid);
478
+ if (!entry) return false;
479
+ entry.handlers = handlers;
480
+ if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
481
+ object.occlusionTest = true;
482
+ enableOcclusion(store);
483
+ }
484
+ return true;
492
485
  }
493
- const ErrorBoundary = /* @__PURE__ */ (() => {
494
- var _a;
495
- return _a = class extends React__namespace.Component {
496
- constructor() {
497
- super(...arguments);
498
- __publicField$1(this, "state", { error: false });
499
- }
500
- componentDidCatch(err) {
501
- this.props.set(err);
502
- }
503
- render() {
504
- return this.state.error ? null : this.props.children;
486
+ function checkVisibility(state) {
487
+ const { internal, camera } = state;
488
+ const registry = internal.visibilityRegistry;
489
+ if (registry.size === 0) return;
490
+ updateFrustum(camera, tempFrustum);
491
+ for (const entry of registry.values()) {
492
+ const { object, handlers, lastFramedState, lastOccludedState, lastVisibleState } = entry;
493
+ let inFrustum = null;
494
+ const computeFrustum = () => {
495
+ if (inFrustum === null) {
496
+ if (object.geometry?.boundingSphere === null) {
497
+ object.geometry?.computeBoundingSphere();
498
+ }
499
+ inFrustum = tempFrustum.intersectsObject(object);
500
+ }
501
+ return inFrustum;
502
+ };
503
+ if (handlers.onFramed) {
504
+ const currentInFrustum = computeFrustum();
505
+ if (currentInFrustum !== lastFramedState) {
506
+ entry.lastFramedState = currentInFrustum;
507
+ handlers.onFramed(currentInFrustum);
508
+ }
505
509
  }
506
- }, __publicField$1(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
507
- })();
508
-
509
- const is = {
510
- obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== "function",
511
- fun: (a) => typeof a === "function",
512
- str: (a) => typeof a === "string",
513
- num: (a) => typeof a === "number",
514
- boo: (a) => typeof a === "boolean",
515
- und: (a) => a === void 0,
516
- nul: (a) => a === null,
517
- arr: (a) => Array.isArray(a),
518
- equ(a, b, { arrays = "shallow", objects = "reference", strict = true } = {}) {
519
- if (typeof a !== typeof b || !!a !== !!b) return false;
520
- if (is.str(a) || is.num(a) || is.boo(a)) return a === b;
521
- const isObj = is.obj(a);
522
- if (isObj && objects === "reference") return a === b;
523
- const isArr = is.arr(a);
524
- if (isArr && arrays === "reference") return a === b;
525
- if ((isArr || isObj) && a === b) return true;
526
- let i;
527
- for (i in a) if (!(i in b)) return false;
528
- if (isObj && arrays === "shallow" && objects === "shallow") {
529
- for (i in strict ? b : a) if (!is.equ(a[i], b[i], { strict, objects: "reference" })) return false;
530
- } else {
531
- for (i in strict ? b : a) if (a[i] !== b[i]) return false;
510
+ let currentOcclusion = null;
511
+ if (handlers.onOccluded && internal.occlusionEnabled) {
512
+ currentOcclusion = internal.occlusionCache.get(object) ?? null;
513
+ if (currentOcclusion !== null && currentOcclusion !== lastOccludedState) {
514
+ entry.lastOccludedState = currentOcclusion;
515
+ handlers.onOccluded(currentOcclusion);
516
+ }
532
517
  }
533
- if (is.und(i)) {
534
- if (isArr && a.length === 0 && b.length === 0) return true;
535
- if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
536
- if (a !== b) return false;
518
+ if (handlers.onVisible) {
519
+ const currentInFrustum = computeFrustum();
520
+ if (!handlers.onFramed && currentInFrustum !== lastFramedState) {
521
+ entry.lastFramedState = currentInFrustum;
522
+ }
523
+ let isOccluded = currentOcclusion;
524
+ if (isOccluded === null && internal.occlusionEnabled) {
525
+ isOccluded = internal.occlusionCache.get(object) ?? null;
526
+ }
527
+ if (isOccluded === null) isOccluded = false;
528
+ const isVisible = currentInFrustum && !isOccluded && object.visible;
529
+ if (isVisible !== lastVisibleState) {
530
+ entry.lastVisibleState = isVisible;
531
+ handlers.onVisible(isVisible);
532
+ }
537
533
  }
538
- return true;
539
534
  }
540
- };
541
- const isOrthographicCamera = (def) => def && def.isOrthographicCamera;
542
- const isRef = (obj) => obj !== null && typeof obj === "object" && obj.hasOwnProperty("current");
543
- const isColorRepresentation = (value) => value != null && (typeof value === "string" || typeof value === "number" || value.isColor);
544
- const isObject3D = (object) => object?.isObject3D;
545
- const isTexture = (value) => !!value?.isTexture;
546
- const isVectorLike = (object) => object !== null && typeof object === "object" && "set" in object && typeof object.set === "function";
547
- const isCopyable = (object) => isVectorLike(object) && "copy" in object && typeof object.copy === "function";
548
- const hasConstructor = (object) => !!object?.constructor;
549
-
550
- function calculateDpr(dpr) {
551
- const target = typeof window !== "undefined" ? window.devicePixelRatio ?? 2 : 1;
552
- return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
553
535
  }
554
- function getUuidPrefix(uuid) {
555
- return uuid.split("-")[0];
536
+ function hasVisibilityHandlers(handlers) {
537
+ if (!handlers) return false;
538
+ return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
556
539
  }
557
- function updateCamera(camera, size) {
558
- if (camera.manual) return;
559
- if (isOrthographicCamera(camera)) {
560
- camera.left = size.width / -2;
561
- camera.right = size.width / 2;
562
- camera.top = size.height / 2;
563
- camera.bottom = size.height / -2;
564
- } else {
565
- camera.aspect = size.width / size.height;
566
- }
567
- camera.updateProjectionMatrix();
540
+
541
+ const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
542
+ function fromRef(ref, transform) {
543
+ const marker = { [FROM_REF]: ref };
544
+ if (transform) marker.transform = transform;
545
+ return marker;
568
546
  }
569
- const frustumMatrix = new webgpu.Matrix4();
570
- function updateFrustum(camera, frustum) {
571
- const target = frustum ?? new webgpu.Frustum();
572
- frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
573
- target.setFromProjectionMatrix(frustumMatrix);
574
- return target;
547
+ function isFromRef(value) {
548
+ return value !== null && typeof value === "object" && FROM_REF in value;
575
549
  }
576
550
 
577
- const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
578
- function findInitialRoot(instance) {
579
- let root = instance.root;
580
- while (root.getState().previousRoot) root = root.getState().previousRoot;
581
- return root;
551
+ const ONCE = Symbol.for("@react-three/fiber.once");
552
+ function once(...args) {
553
+ return { [ONCE]: args.length ? args : true };
582
554
  }
583
- function getRootState(obj) {
584
- let state = obj.__r3f?.root.getState();
585
- if (!state) {
586
- obj.traverseAncestors((ancestor) => {
587
- const parentState = ancestor.__r3f?.root.getState();
588
- if (parentState) {
589
- state = parentState;
590
- return false;
591
- }
592
- });
593
- }
594
- return state;
555
+ function isOnce(value) {
556
+ return value !== null && typeof value === "object" && ONCE in value;
595
557
  }
596
- function buildGraph(object) {
597
- const data = { nodes: {}, materials: {}, meshes: {} };
598
- if (object) {
599
- object.traverse((obj) => {
600
- if (obj.name) data.nodes[obj.name] = obj;
601
- if (obj.material) {
602
- const material = Array.isArray(obj.material) ? obj.material[0] : obj.material;
603
- const nameAlreadyUsed = data.materials[material.name];
604
- let materialName = material.name;
605
- if (nameAlreadyUsed) {
606
- materialName = materialName + `-${getUuidPrefix(material.uuid)}`;
607
- material.userData.materialCacheName = materialName;
608
- }
609
- data.materials[materialName] = material;
610
- }
611
- if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
612
- });
558
+
559
+ const shownNotices = /* @__PURE__ */ new Set();
560
+ function notifyDepreciated({ heading, body, link }) {
561
+ if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
562
+ return;
613
563
  }
614
- return data;
615
- }
616
- function dispose(obj) {
617
- if (obj.type !== "Scene") obj.dispose?.();
618
- for (const p in obj) {
619
- const prop = obj[p];
620
- if (prop?.type !== "Scene") prop?.dispose?.();
564
+ if (shownNotices.has(heading)) return;
565
+ shownNotices.add(heading);
566
+ const caller = getCallerFrame();
567
+ if (caller) {
568
+ console.log();
621
569
  }
622
- }
623
- function getInstanceProps(pendingProps) {
624
- const props = {};
625
- for (const key in pendingProps) {
626
- if (!REACT_INTERNAL_PROPS.includes(key)) props[key] = pendingProps[key];
570
+ const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
571
+ if (caller) {
572
+ console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
573
+ }
574
+ if (body || link) {
575
+ let message = "";
576
+ if (body) message += body;
577
+ if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
578
+ console.warn(`%c${message}`, "font-weight: bold;");
627
579
  }
628
- return props;
629
580
  }
630
- function prepare(target, root, type, props) {
631
- const object = target;
632
- let instance = object?.__r3f;
633
- if (!instance) {
634
- instance = {
635
- root,
636
- type,
637
- parent: null,
638
- children: [],
639
- props: getInstanceProps(props),
640
- object,
641
- eventCount: 0,
642
- handlers: {},
643
- isHidden: false
644
- };
645
- if (object) object.__r3f = instance;
581
+ function getCallerFrame(depth = 3) {
582
+ const stack = new Error().stack;
583
+ if (!stack) return null;
584
+ const lines = stack.split("\n");
585
+ const frame = lines[depth];
586
+ if (!frame) return null;
587
+ let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
588
+ if (!match) {
589
+ match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
646
590
  }
647
- return instance;
591
+ if (!match) return null;
592
+ const [, fn, url, line] = match;
593
+ return {
594
+ functionName: fn ?? "<anonymous>",
595
+ location: formatLocation(url, Number(line))
596
+ };
648
597
  }
649
- function invalidateInstance(instance) {
650
- if (!instance.parent) return;
651
- instance.props.onUpdate?.(instance.object);
652
- const state = instance.root?.getState?.();
653
- if (state && state.internal.frames === 0) state.invalidate();
598
+ function formatLocation(url, line) {
599
+ const clean = url.split("?")[0];
600
+ const file = clean.split("/").pop() ?? clean;
601
+ return `${file}:${line}`;
654
602
  }
655
-
656
- const tempFrustum = new webgpu.Frustum();
657
- let hasWarnedWebGL = false;
658
- let tslModule = null;
659
- async function loadTSL() {
660
- if (tslModule) return tslModule;
661
- try {
662
- const tsl = await import('three/tsl');
663
- tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
664
- return tslModule;
665
- } catch {
666
- return null;
603
+ function notifyAlpha({ message, link }) {
604
+ if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
605
+ return;
606
+ }
607
+ if (shownNotices.has(message)) return;
608
+ shownNotices.add(message);
609
+ const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
610
+ console.log(`%c\u{1F52C} ${message}`, boxStyle);
611
+ {
612
+ console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
667
613
  }
668
614
  }
669
- function createOcclusionObserverNode(store, uniform) {
670
- const node = new webgpu.Node("float");
671
- node.updateType = webgpu.NodeUpdateType.OBJECT;
672
- node.update = function(frame) {
673
- const { internal } = store.getState();
674
- const registry = internal.visibilityRegistry;
675
- const cache = internal.occlusionCache;
676
- for (const entry of registry.values()) {
677
- const { object, handlers } = entry;
678
- if (handlers.onOccluded || handlers.onVisible) {
679
- const isOccluded = frame.renderer.isOccluded(object);
680
- cache.set(object, isOccluded);
615
+
616
+ const RESERVED_PROPS = [
617
+ "children",
618
+ "key",
619
+ "ref",
620
+ // Instance props
621
+ "args",
622
+ "dispose",
623
+ "attach",
624
+ "object",
625
+ // Behavior flags
626
+ "dispose"
627
+ ];
628
+ const EVENT_REGEX = /^on(Pointer|Drag|Drop|Click|DoubleClick|ContextMenu|Wheel)/;
629
+ const VISIBILITY_EVENT_REGEX = /^on(Framed|Occluded|Visible)$/;
630
+ const INDEX_REGEX = /-\d+$/;
631
+ const MEMOIZED_PROTOTYPES = /* @__PURE__ */ new Map();
632
+ const colorMaps = ["map", "emissiveMap", "sheenColorMap", "specularColorMap", "envMap"];
633
+ function resolve(root, key) {
634
+ if (!key.includes("-")) return { root, key, target: root[key] };
635
+ if (key in root) return { root, key, target: root[key] };
636
+ const originalKey = key;
637
+ let target = root;
638
+ const parts = key.split("-");
639
+ for (const part of parts) {
640
+ if (typeof target !== "object" || target === null) {
641
+ if (target !== void 0) {
642
+ const remaining = parts.slice(parts.indexOf(part)).join("-");
643
+ return { root: target, key: remaining, target: void 0 };
681
644
  }
645
+ return { root, key: originalKey, target: void 0 };
682
646
  }
683
- };
684
- node.setup = function() {
685
- return uniform(0);
686
- };
687
- return node;
647
+ key = part;
648
+ root = target;
649
+ target = target[key];
650
+ }
651
+ return { root, key, target };
688
652
  }
689
- let occlusionSetupPromise = null;
690
- function enableOcclusion(store) {
691
- const state = store.getState();
692
- const { internal, renderer } = state;
693
- if (internal.occlusionEnabled || occlusionSetupPromise) return;
694
- const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
695
- if (!hasOcclusionSupport) {
696
- if (!hasWarnedWebGL) {
697
- console.warn(
698
- "[R3F] Warning: onOccluded/onVisible occlusion queries require WebGPU renderer. Occlusion events will not fire on WebGL."
699
- );
700
- hasWarnedWebGL = true;
653
+ function attach(parent, child) {
654
+ if (is.str(child.props.attach)) {
655
+ if (INDEX_REGEX.test(child.props.attach)) {
656
+ const index = child.props.attach.replace(INDEX_REGEX, "");
657
+ const { root: root2, key: key2 } = resolve(parent.object, index);
658
+ if (!Array.isArray(root2[key2])) root2[key2] = [];
701
659
  }
702
- return;
660
+ const { root, key } = resolve(parent.object, child.props.attach);
661
+ child.previousAttach = root[key];
662
+ root[key] = child.object;
663
+ } else if (is.fun(child.props.attach)) {
664
+ child.previousAttach = child.props.attach(parent.object, child.object);
703
665
  }
704
- occlusionSetupPromise = setupOcclusion(store);
705
666
  }
706
- async function setupOcclusion(store) {
707
- const state = store.getState();
708
- const { internal, rootScene, set } = state;
709
- const tsl = await loadTSL();
710
- if (!tsl) {
711
- console.warn("[R3F] Warning: TSL module not available. Occlusion queries disabled.");
712
- occlusionSetupPromise = null;
713
- return;
714
- }
715
- const { uniform, nodeObject } = tsl;
716
- let helperGroup = internal.helperGroup;
717
- if (!helperGroup) {
718
- helperGroup = new webgpu.Group();
719
- helperGroup.name = "__r3fInternal";
720
- helperGroup.__r3fInternal = true;
721
- rootScene.add(helperGroup);
667
+ function detach(parent, child) {
668
+ if (is.str(child.props.attach)) {
669
+ const { root, key } = resolve(parent.object, child.props.attach);
670
+ const previous = child.previousAttach;
671
+ if (previous === void 0) delete root[key];
672
+ else root[key] = previous;
673
+ } else {
674
+ child.previousAttach?.(parent.object, child.object);
722
675
  }
723
- const geometry = new webgpu.BoxGeometry(1, 1, 1);
724
- const material = new webgpu.MeshBasicNodeMaterial({
725
- transparent: true,
726
- opacity: 0
727
- });
728
- const observerNode = nodeObject(createOcclusionObserverNode(store, uniform));
729
- material.colorNode = observerNode;
730
- material.needsUpdate = true;
731
- const mesh = new webgpu.Mesh(geometry, material);
732
- mesh.name = "__r3fOcclusionObserver";
733
- mesh.scale.setScalar(1e-4);
734
- mesh.frustumCulled = false;
735
- mesh.__r3fInternal = true;
736
- helperGroup.add(mesh);
737
- set((state2) => ({
738
- internal: {
739
- ...state2.internal,
740
- helperGroup,
741
- occlusionObserver: mesh,
742
- occlusionEnabled: true
676
+ delete child.previousAttach;
677
+ }
678
+ function getMemoizedPrototype(root) {
679
+ let ctor = MEMOIZED_PROTOTYPES.get(root.constructor);
680
+ try {
681
+ if (!ctor) {
682
+ ctor = new root.constructor();
683
+ MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
743
684
  }
744
- }));
745
- occlusionSetupPromise = null;
746
- }
747
- function disableOcclusion(store) {
748
- const { internal, set } = store.getState();
749
- if (!internal.occlusionEnabled) return;
750
- if (internal.occlusionObserver) {
751
- internal.occlusionObserver.removeFromParent();
752
- internal.occlusionObserver.geometry.dispose();
753
- internal.occlusionObserver.material.dispose();
754
- }
755
- internal.occlusionCache.clear();
756
- set((state) => ({
757
- internal: {
758
- ...state.internal,
759
- occlusionObserver: null,
760
- occlusionEnabled: false
761
- }
762
- }));
763
- }
764
- function cleanupHelperGroup(store) {
765
- const { internal, set } = store.getState();
766
- disableOcclusion(store);
767
- if (internal.helperGroup) {
768
- internal.helperGroup.removeFromParent();
769
- set((state) => ({
770
- internal: {
771
- ...state.internal,
772
- helperGroup: null
773
- }
774
- }));
775
- }
776
- }
777
- function registerVisibility(store, object, handlers) {
778
- const { internal } = store.getState();
779
- const registry = internal.visibilityRegistry;
780
- const entry = {
781
- object,
782
- handlers,
783
- lastFramedState: null,
784
- lastOccludedState: null,
785
- lastVisibleState: null
786
- };
787
- registry.set(object.uuid, entry);
788
- if (handlers.onOccluded || handlers.onVisible) {
789
- object.occlusionTest = true;
790
- if (!internal.occlusionEnabled) {
791
- enableOcclusion(store);
792
- }
793
- }
794
- }
795
- function unregisterVisibility(store, object) {
796
- const { internal } = store.getState();
797
- internal.visibilityRegistry.delete(object.uuid);
798
- internal.occlusionCache.delete(object);
799
- }
800
- function updateVisibilityHandlers(store, object, handlers) {
801
- const { internal } = store.getState();
802
- const entry = internal.visibilityRegistry.get(object.uuid);
803
- if (!entry) return false;
804
- entry.handlers = handlers;
805
- if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
806
- object.occlusionTest = true;
807
- enableOcclusion(store);
808
- }
809
- return true;
810
- }
811
- function checkVisibility(state) {
812
- const { internal, camera } = state;
813
- const registry = internal.visibilityRegistry;
814
- if (registry.size === 0) return;
815
- updateFrustum(camera, tempFrustum);
816
- for (const entry of registry.values()) {
817
- const { object, handlers, lastFramedState, lastOccludedState, lastVisibleState } = entry;
818
- let inFrustum = null;
819
- const computeFrustum = () => {
820
- if (inFrustum === null) {
821
- if (object.geometry?.boundingSphere === null) {
822
- object.geometry?.computeBoundingSphere();
823
- }
824
- inFrustum = tempFrustum.intersectsObject(object);
825
- }
826
- return inFrustum;
827
- };
828
- if (handlers.onFramed) {
829
- const currentInFrustum = computeFrustum();
830
- if (currentInFrustum !== lastFramedState) {
831
- entry.lastFramedState = currentInFrustum;
832
- handlers.onFramed(currentInFrustum);
833
- }
834
- }
835
- let currentOcclusion = null;
836
- if (handlers.onOccluded && internal.occlusionEnabled) {
837
- currentOcclusion = internal.occlusionCache.get(object) ?? null;
838
- if (currentOcclusion !== null && currentOcclusion !== lastOccludedState) {
839
- entry.lastOccludedState = currentOcclusion;
840
- handlers.onOccluded(currentOcclusion);
841
- }
842
- }
843
- if (handlers.onVisible) {
844
- const currentInFrustum = computeFrustum();
845
- if (!handlers.onFramed && currentInFrustum !== lastFramedState) {
846
- entry.lastFramedState = currentInFrustum;
847
- }
848
- let isOccluded = currentOcclusion;
849
- if (isOccluded === null && internal.occlusionEnabled) {
850
- isOccluded = internal.occlusionCache.get(object) ?? null;
851
- }
852
- if (isOccluded === null) isOccluded = false;
853
- const isVisible = currentInFrustum && !isOccluded && object.visible;
854
- if (isVisible !== lastVisibleState) {
855
- entry.lastVisibleState = isVisible;
856
- handlers.onVisible(isVisible);
857
- }
858
- }
859
- }
860
- }
861
- function hasVisibilityHandlers(handlers) {
862
- if (!handlers) return false;
863
- return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
864
- }
865
-
866
- const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
867
- function fromRef(ref) {
868
- return { [FROM_REF]: ref };
869
- }
870
- function isFromRef(value) {
871
- return value !== null && typeof value === "object" && FROM_REF in value;
872
- }
873
-
874
- const ONCE = Symbol.for("@react-three/fiber.once");
875
- function once(...args) {
876
- return { [ONCE]: args.length ? args : true };
877
- }
878
- function isOnce(value) {
879
- return value !== null && typeof value === "object" && ONCE in value;
880
- }
881
-
882
- const RESERVED_PROPS = [
883
- "children",
884
- "key",
885
- "ref",
886
- // Instance props
887
- "args",
888
- "dispose",
889
- "attach",
890
- "object",
891
- "onUpdate",
892
- // Behavior flags
893
- "dispose"
894
- ];
895
- const EVENT_REGEX = /^on(Pointer|Drag|Drop|Click|DoubleClick|ContextMenu|Wheel)/;
896
- const VISIBILITY_EVENT_REGEX = /^on(Framed|Occluded|Visible)$/;
897
- const INDEX_REGEX = /-\d+$/;
898
- const MEMOIZED_PROTOTYPES = /* @__PURE__ */ new Map();
899
- const colorMaps = ["map", "emissiveMap", "sheenColorMap", "specularColorMap", "envMap"];
900
- function resolve(root, key) {
901
- if (!key.includes("-")) return { root, key, target: root[key] };
902
- if (key in root) return { root, key, target: root[key] };
903
- const originalKey = key;
904
- let target = root;
905
- const parts = key.split("-");
906
- for (const part of parts) {
907
- if (typeof target !== "object" || target === null) {
908
- if (target !== void 0) {
909
- const remaining = parts.slice(parts.indexOf(part)).join("-");
910
- return { root: target, key: remaining, target: void 0 };
911
- }
912
- return { root, key: originalKey, target: void 0 };
913
- }
914
- key = part;
915
- root = target;
916
- target = target[key];
917
- }
918
- return { root, key, target };
919
- }
920
- function attach(parent, child) {
921
- if (is.str(child.props.attach)) {
922
- if (INDEX_REGEX.test(child.props.attach)) {
923
- const index = child.props.attach.replace(INDEX_REGEX, "");
924
- const { root: root2, key: key2 } = resolve(parent.object, index);
925
- if (!Array.isArray(root2[key2])) root2[key2] = [];
926
- }
927
- const { root, key } = resolve(parent.object, child.props.attach);
928
- child.previousAttach = root[key];
929
- root[key] = child.object;
930
- } else if (is.fun(child.props.attach)) {
931
- child.previousAttach = child.props.attach(parent.object, child.object);
932
- }
933
- }
934
- function detach(parent, child) {
935
- if (is.str(child.props.attach)) {
936
- const { root, key } = resolve(parent.object, child.props.attach);
937
- const previous = child.previousAttach;
938
- if (previous === void 0) delete root[key];
939
- else root[key] = previous;
940
- } else {
941
- child.previousAttach?.(parent.object, child.object);
942
- }
943
- delete child.previousAttach;
944
- }
945
- function getMemoizedPrototype(root) {
946
- let ctor = MEMOIZED_PROTOTYPES.get(root.constructor);
947
- try {
948
- if (!ctor) {
949
- ctor = new root.constructor();
950
- MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
951
- }
952
- } catch {
953
- }
954
- return ctor;
685
+ } catch {
686
+ }
687
+ return ctor;
955
688
  }
956
689
  function diffProps(instance, newProps) {
957
690
  const changedProps = {};
@@ -966,11 +699,9 @@ function diffProps(instance, newProps) {
966
699
  for (const prop in instance.props) {
967
700
  if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
968
701
  const { root, key } = resolve(instance.object, prop);
969
- if (root.constructor && root.constructor.length === 0) {
702
+ if (typeof root?.constructor === "function") {
970
703
  const ctor = getMemoizedPrototype(root);
971
- if (!is.und(ctor)) changedProps[key] = ctor[key];
972
- } else {
973
- changedProps[key] = 0;
704
+ if (!is.und(ctor)) changedProps[prop] = ctor[key];
974
705
  }
975
706
  }
976
707
  return changedProps;
@@ -982,6 +713,13 @@ function applyProps(object, props) {
982
713
  for (const prop in props) {
983
714
  const value = props[prop];
984
715
  if (RESERVED_PROPS.includes(prop)) continue;
716
+ if (prop === "onUpdate") {
717
+ notifyDepreciated({
718
+ heading: "onUpdate is no longer an R3F prop",
719
+ body: "v10 removed the onUpdate hook: R3F no longer calls it after prop updates. The value is assigned to the object by name. On a Texture that sets three's Texture.onUpdate, which the renderer calls after a GPU upload, not after prop changes. On a node it replaces the Node.onUpdate() method. On other objects it is never called.\n\nUse an effect keyed on the props that change, read the object in useFrame, or use a ref callback.",
720
+ link: "https://docs.pmnd.rs/react-three-fiber/migration/v10#onupdate-removed"
721
+ });
722
+ }
985
723
  if (instance && EVENT_REGEX.test(prop)) {
986
724
  if (typeof value === "function") instance.handlers[prop] = value;
987
725
  else delete instance.handlers[prop];
@@ -1087,613 +825,11 @@ function applyProps(object, props) {
1087
825
  return object;
1088
826
  }
1089
827
 
1090
- const DEFAULT_POINTER_ID = 0;
1091
- const XR_POINTER_ID_START = 1e3;
1092
- function getPointerState(internal, pointerId) {
1093
- let state = internal.pointerMap.get(pointerId);
1094
- if (!state) {
1095
- state = {
1096
- hovered: /* @__PURE__ */ new Map(),
1097
- captured: /* @__PURE__ */ new Map(),
1098
- initialClick: [0, 0],
1099
- initialHits: []
1100
- };
1101
- internal.pointerMap.set(pointerId, state);
1102
- }
1103
- return state;
1104
- }
1105
- function getPointerId(event) {
1106
- return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
1107
- }
1108
- function makeId(event) {
1109
- return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
1110
- }
1111
- function releaseInternalPointerCapture(internal, obj, pointerId) {
1112
- const pointerState = internal.pointerMap.get(pointerId);
1113
- if (!pointerState) return;
1114
- const captureData = pointerState.captured.get(obj);
1115
- if (captureData) {
1116
- pointerState.captured.delete(obj);
1117
- captureData.target.releasePointerCapture(pointerId);
1118
- }
1119
- }
1120
- function removeInteractivity(store, object) {
1121
- const { internal } = store.getState();
1122
- internal.interaction = internal.interaction.filter((o) => o !== object);
1123
- for (const [pointerId, pointerState] of internal.pointerMap) {
1124
- pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
1125
- pointerState.hovered.forEach((value, key) => {
1126
- if (value.eventObject === object || value.object === object) {
1127
- pointerState.hovered.delete(key);
1128
- }
1129
- });
1130
- if (pointerState.captured.has(object)) {
1131
- releaseInternalPointerCapture(internal, object, pointerId);
1132
- }
1133
- }
1134
- unregisterVisibility(store, object);
1135
- }
1136
- function createEvents(store) {
1137
- function calculateDistance(event, pointerId) {
1138
- const { internal } = store.getState();
1139
- const pointerState = internal.pointerMap.get(pointerId);
1140
- if (!pointerState) return 0;
1141
- const [initialX, initialY] = pointerState.initialClick;
1142
- const dx = event.offsetX - initialX;
1143
- const dy = event.offsetY - initialY;
1144
- return Math.round(Math.sqrt(dx * dx + dy * dy));
1145
- }
1146
- function filterPointerEvents(objects) {
1147
- return objects.filter(
1148
- (obj) => ["Move", "Over", "Enter", "Out", "Leave"].some(
1149
- (name) => obj.__r3f?.handlers["onPointer" + name]
1150
- ) || ["OverEnter", "OverLeave", "Over"].some(
1151
- (name) => obj.__r3f?.handlers["onDrag" + name]
1152
- ) || obj.__r3f?.handlers.onDrop
1153
- );
1154
- }
1155
- function intersect(event, filter) {
1156
- const state = store.getState();
1157
- const duplicates = /* @__PURE__ */ new Set();
1158
- const intersections = [];
1159
- const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction;
1160
- for (let i = 0; i < eventsObjects.length; i++) {
1161
- const state2 = getRootState(eventsObjects[i]);
1162
- if (state2) {
1163
- state2.raycaster.camera = void 0;
1164
- }
1165
- }
1166
- if (!state.previousRoot) {
1167
- state.events.compute?.(event, state);
1168
- }
1169
- function handleRaycast(obj) {
1170
- const state2 = getRootState(obj);
1171
- if (!state2 || !state2.events.enabled || state2.raycaster.camera === null) return [];
1172
- if (state2.raycaster.camera === void 0) {
1173
- state2.events.compute?.(event, state2, state2.previousRoot?.getState());
1174
- if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
1175
- }
1176
- return state2.raycaster.camera ? state2.raycaster.intersectObject(obj, true) : [];
1177
- }
1178
- let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
1179
- const aInteractivePriority = a.object.userData?.interactivePriority;
1180
- const bInteractivePriority = b.object.userData?.interactivePriority;
1181
- if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
1182
- if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
1183
- if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
1184
- if (aInteractivePriority !== bInteractivePriority) {
1185
- return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
1186
- }
1187
- }
1188
- const aState = getRootState(a.object);
1189
- const bState = getRootState(b.object);
1190
- const aPriority = aState?.events?.priority ?? 1;
1191
- const bPriority = bState?.events?.priority ?? 1;
1192
- return bPriority - aPriority || a.distance - b.distance;
1193
- }).filter((item) => {
1194
- const id = makeId(item);
1195
- if (duplicates.has(id)) return false;
1196
- duplicates.add(id);
1197
- return true;
1198
- });
1199
- if (state.events.filter) hits = state.events.filter(hits, state);
1200
- for (const hit of hits) {
1201
- let eventObject = hit.object;
1202
- while (eventObject) {
1203
- if (eventObject.__r3f?.eventCount) {
1204
- intersections.push({ ...hit, eventObject });
1205
- }
1206
- eventObject = eventObject.parent;
1207
- }
1208
- }
1209
- if ("pointerId" in event) {
1210
- const pointerId = event.pointerId;
1211
- const pointerState = state.internal.pointerMap.get(pointerId);
1212
- if (pointerState?.captured.size) {
1213
- for (const captureData of pointerState.captured.values()) {
1214
- if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
1215
- }
1216
- }
1217
- }
1218
- return intersections;
1219
- }
1220
- function handleIntersects(intersections, event, delta, callback) {
1221
- if (intersections.length) {
1222
- const localState = { stopped: false };
1223
- for (const hit of intersections) {
1224
- const state = getRootState(hit.object);
1225
- if (state) {
1226
- const { raycaster, pointer, camera, internal } = state;
1227
- const unprojectedPoint = new webgpu.Vector3(pointer.x, pointer.y, 0).unproject(camera);
1228
- const hasPointerCapture = (id) => {
1229
- const pointerState = internal.pointerMap.get(id);
1230
- return pointerState?.captured.has(hit.eventObject) ?? false;
1231
- };
1232
- const setPointerCapture = (id) => {
1233
- const captureData = { intersection: hit, target: event.target };
1234
- const pointerState = getPointerState(internal, id);
1235
- pointerState.captured.set(hit.eventObject, captureData);
1236
- event.target.setPointerCapture(id);
1237
- };
1238
- const releasePointerCapture = (id) => {
1239
- releaseInternalPointerCapture(internal, hit.eventObject, id);
1240
- };
1241
- const extractEventProps = {};
1242
- for (const prop in event) {
1243
- const property = event[prop];
1244
- if (typeof property !== "function") extractEventProps[prop] = property;
1245
- }
1246
- const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
1247
- const raycastEvent = {
1248
- ...hit,
1249
- ...extractEventProps,
1250
- pointer,
1251
- intersections,
1252
- stopped: localState.stopped,
1253
- delta,
1254
- unprojectedPoint,
1255
- ray: raycaster.ray,
1256
- camera,
1257
- pointerId: eventPointerId,
1258
- // Hijack stopPropagation, which just sets a flag
1259
- stopPropagation() {
1260
- const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
1261
- if (
1262
- // ...if this pointer hasn't been captured
1263
- !pointerState?.captured.size || // ... or if the hit object is capturing the pointer
1264
- pointerState.captured.has(hit.eventObject)
1265
- ) {
1266
- raycastEvent.stopped = localState.stopped = true;
1267
- if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
1268
- const higher = intersections.slice(0, intersections.indexOf(hit));
1269
- cancelPointer([...higher, hit], eventPointerId);
1270
- }
1271
- }
1272
- },
1273
- // there should be a distinction between target and currentTarget
1274
- target: { hasPointerCapture, setPointerCapture, releasePointerCapture },
1275
- currentTarget: { hasPointerCapture, setPointerCapture, releasePointerCapture },
1276
- nativeEvent: event
1277
- };
1278
- callback(raycastEvent);
1279
- if (localState.stopped === true) break;
1280
- }
1281
- }
1282
- }
1283
- return intersections;
1284
- }
1285
- function cancelPointer(intersections, pointerId) {
1286
- const { internal } = store.getState();
1287
- const pid = pointerId ?? DEFAULT_POINTER_ID;
1288
- const pointerState = internal.pointerMap.get(pid);
1289
- if (!pointerState) return;
1290
- for (const [hoveredId, hoveredObj] of pointerState.hovered) {
1291
- if (!intersections.length || !intersections.find(
1292
- (hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
1293
- )) {
1294
- const eventObject = hoveredObj.eventObject;
1295
- const instance = eventObject.__r3f;
1296
- pointerState.hovered.delete(hoveredId);
1297
- if (instance?.eventCount) {
1298
- const handlers = instance.handlers;
1299
- const data = { ...hoveredObj, intersections };
1300
- handlers.onPointerOut?.(data);
1301
- handlers.onPointerLeave?.(data);
1302
- handlers.onDragOverLeave?.(data);
1303
- }
1304
- }
1305
- }
1306
- }
1307
- function pointerMissed(event, objects) {
1308
- for (let i = 0; i < objects.length; i++) {
1309
- const instance = objects[i].__r3f;
1310
- instance?.handlers.onPointerMissed?.(event);
1311
- }
1312
- }
1313
- function dragOverMissed(event, objects) {
1314
- for (let i = 0; i < objects.length; i++) {
1315
- const instance = objects[i].__r3f;
1316
- instance?.handlers.onDragOverMissed?.(event);
1317
- }
1318
- }
1319
- function dropMissed(event, objects) {
1320
- for (let i = 0; i < objects.length; i++) {
1321
- const instance = objects[i].__r3f;
1322
- instance?.handlers.onDropMissed?.(event);
1323
- }
1324
- }
1325
- function cleanupPointer(pointerId) {
1326
- const { internal } = store.getState();
1327
- const pointerState = internal.pointerMap.get(pointerId);
1328
- if (pointerState) {
1329
- for (const [, hoveredObj] of pointerState.hovered) {
1330
- const eventObject = hoveredObj.eventObject;
1331
- const instance = eventObject.__r3f;
1332
- if (instance?.eventCount) {
1333
- const handlers = instance.handlers;
1334
- const data = { ...hoveredObj, intersections: [] };
1335
- handlers.onPointerOut?.(data);
1336
- handlers.onPointerLeave?.(data);
1337
- }
1338
- }
1339
- internal.pointerMap.delete(pointerId);
1340
- }
1341
- internal.pointerDirty.delete(pointerId);
1342
- }
1343
- function processDeferredPointer(event, pointerId) {
1344
- const state = store.getState();
1345
- const { internal } = state;
1346
- if (!state.events.enabled) return;
1347
- const filter = filterPointerEvents;
1348
- const hits = intersect(event, filter);
1349
- cancelPointer(hits, pointerId);
1350
- function onIntersect(data) {
1351
- const eventObject = data.eventObject;
1352
- const instance = eventObject.__r3f;
1353
- if (!instance?.eventCount) return;
1354
- const handlers = instance.handlers;
1355
- if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
1356
- const id = makeId(data);
1357
- const pointerState = getPointerState(internal, pointerId);
1358
- const hoveredItem = pointerState.hovered.get(id);
1359
- if (!hoveredItem) {
1360
- pointerState.hovered.set(id, data);
1361
- handlers.onPointerOver?.(data);
1362
- handlers.onPointerEnter?.(data);
1363
- } else if (hoveredItem.stopped) {
1364
- data.stopPropagation();
1365
- }
1366
- }
1367
- handlers.onPointerMove?.(data);
1368
- }
1369
- handleIntersects(hits, event, 0, onIntersect);
1370
- }
1371
- function handlePointer(name) {
1372
- switch (name) {
1373
- case "onPointerLeave":
1374
- case "onDragLeave":
1375
- return () => cancelPointer([]);
1376
- // Global cancel of these events
1377
- case "onPointerCancel":
1378
- return (event) => {
1379
- const pointerId = getPointerId(event);
1380
- cleanupPointer(pointerId);
1381
- };
1382
- case "onLostPointerCapture":
1383
- return (event) => {
1384
- const { internal } = store.getState();
1385
- const pointerId = getPointerId(event);
1386
- const pointerState = internal.pointerMap.get(pointerId);
1387
- if (pointerState?.captured.size) {
1388
- requestAnimationFrame(() => {
1389
- const pointerState2 = internal.pointerMap.get(pointerId);
1390
- if (pointerState2?.captured.size) {
1391
- pointerState2.captured.clear();
1392
- }
1393
- cancelPointer([], pointerId);
1394
- });
1395
- }
1396
- };
1397
- }
1398
- return function handleEvent(event) {
1399
- const state = store.getState();
1400
- const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
1401
- const pointerId = getPointerId(event);
1402
- internal.lastEvent.current = event;
1403
- if (!events.enabled) return;
1404
- const isPointerMove = name === "onPointerMove";
1405
- const isDragOver = name === "onDragOver";
1406
- const isDrop = name === "onDrop";
1407
- const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
1408
- const isPointerDown = name === "onPointerDown";
1409
- const isPointerUp = name === "onPointerUp";
1410
- const isWheel = name === "onWheel";
1411
- const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
1412
- if (isPointerMove && canDeferRaycasts) {
1413
- events.compute?.(event, state);
1414
- internal.pointerDirty.set(pointerId, event);
1415
- return;
1416
- }
1417
- if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
1418
- events.compute?.(event, state);
1419
- internal.pointerDirty.set(pointerId, event);
1420
- return;
1421
- }
1422
- if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
1423
- const deferredEvent = internal.pointerDirty.get(pointerId);
1424
- internal.pointerDirty.delete(pointerId);
1425
- processDeferredPointer(deferredEvent, pointerId);
1426
- }
1427
- const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
1428
- const hits = intersect(event, filter);
1429
- const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
1430
- if (isPointerDown) {
1431
- const pointerState2 = getPointerState(internal, pointerId);
1432
- pointerState2.initialClick = [event.offsetX, event.offsetY];
1433
- pointerState2.initialHits = hits.map((hit) => hit.eventObject);
1434
- }
1435
- const pointerState = internal.pointerMap.get(pointerId);
1436
- const initialHits = pointerState?.initialHits ?? [];
1437
- if (isClickEvent && !hits.length) {
1438
- if (delta <= 2) {
1439
- pointerMissed(event, internal.interaction);
1440
- if (onPointerMissed) onPointerMissed(event);
1441
- }
1442
- }
1443
- if (isDragOver && !hits.length) {
1444
- dragOverMissed(event, internal.interaction);
1445
- if (onDragOverMissed) onDragOverMissed(event);
1446
- }
1447
- if (isDrop && !hits.length) {
1448
- dropMissed(event, internal.interaction);
1449
- if (onDropMissed) onDropMissed(event);
1450
- }
1451
- if (isPointerMove || isDragOver) {
1452
- cancelPointer(hits, pointerId);
1453
- }
1454
- function onIntersect(data) {
1455
- const eventObject = data.eventObject;
1456
- const instance = eventObject.__r3f;
1457
- if (!instance?.eventCount) return;
1458
- const handlers = instance.handlers;
1459
- if (isPointerMove) {
1460
- if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
1461
- const id = makeId(data);
1462
- const pointerState2 = getPointerState(internal, pointerId);
1463
- const hoveredItem = pointerState2.hovered.get(id);
1464
- if (!hoveredItem) {
1465
- pointerState2.hovered.set(id, data);
1466
- handlers.onPointerOver?.(data);
1467
- handlers.onPointerEnter?.(data);
1468
- } else if (hoveredItem.stopped) {
1469
- data.stopPropagation();
1470
- }
1471
- }
1472
- handlers.onPointerMove?.(data);
1473
- } else if (isDragOver) {
1474
- const id = makeId(data);
1475
- const pointerState2 = getPointerState(internal, pointerId);
1476
- const hoveredItem = pointerState2.hovered.get(id);
1477
- if (!hoveredItem) {
1478
- pointerState2.hovered.set(id, data);
1479
- handlers.onDragOverEnter?.(data);
1480
- } else if (hoveredItem.stopped) {
1481
- data.stopPropagation();
1482
- }
1483
- handlers.onDragOver?.(data);
1484
- } else if (isDrop) {
1485
- handlers.onDrop?.(data);
1486
- } else {
1487
- const handler = handlers[name];
1488
- if (handler) {
1489
- if (!isClickEvent || initialHits.includes(eventObject)) {
1490
- pointerMissed(
1491
- event,
1492
- internal.interaction.filter((object) => !initialHits.includes(object))
1493
- );
1494
- handler(data);
1495
- }
1496
- } else {
1497
- if (isClickEvent && initialHits.includes(eventObject)) {
1498
- pointerMissed(
1499
- event,
1500
- internal.interaction.filter((object) => !initialHits.includes(object))
1501
- );
1502
- }
1503
- }
1504
- }
1505
- }
1506
- handleIntersects(hits, event, delta, onIntersect);
1507
- };
1508
- }
1509
- function flushDeferredPointers() {
1510
- const { internal, events } = store.getState();
1511
- if (!events.frameTimedRaycasts) return;
1512
- for (const [pointerId, event] of internal.pointerDirty) {
1513
- processDeferredPointer(event, pointerId);
1514
- }
1515
- internal.pointerDirty.clear();
1516
- }
1517
- return { handlePointer, flushDeferredPointers, processDeferredPointer };
1518
- }
1519
- const DOM_EVENTS = {
1520
- onClick: ["click", false],
1521
- onContextMenu: ["contextmenu", false],
1522
- onDoubleClick: ["dblclick", false],
1523
- onDragEnter: ["dragenter", false],
1524
- onDragLeave: ["dragleave", false],
1525
- onDragOver: ["dragover", false],
1526
- onDrop: ["drop", false],
1527
- onWheel: ["wheel", true],
1528
- onPointerDown: ["pointerdown", true],
1529
- onPointerUp: ["pointerup", true],
1530
- onPointerLeave: ["pointerleave", true],
1531
- onPointerMove: ["pointermove", true],
1532
- onPointerCancel: ["pointercancel", true],
1533
- onLostPointerCapture: ["lostpointercapture", true]
1534
- };
1535
- function createPointerEvents(store) {
1536
- const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
1537
- let nextXRPointerId = XR_POINTER_ID_START;
1538
- const xrPointers = /* @__PURE__ */ new Map();
1539
- return {
1540
- priority: 1,
1541
- enabled: true,
1542
- frameTimedRaycasts: true,
1543
- alwaysFireOnScroll: true,
1544
- updateOnFrame: false,
1545
- compute(event, state) {
1546
- state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
1547
- state.raycaster.setFromCamera(state.pointer, state.camera);
1548
- },
1549
- connected: void 0,
1550
- handlers: Object.keys(DOM_EVENTS).reduce(
1551
- (acc, key) => ({ ...acc, [key]: handlePointer(key) }),
1552
- {}
1553
- ),
1554
- update: (pointerId) => {
1555
- const { events, internal } = store.getState();
1556
- if (!events.handlers) return;
1557
- if (pointerId !== void 0) {
1558
- const event = internal.pointerDirty.get(pointerId);
1559
- if (event) {
1560
- internal.pointerDirty.delete(pointerId);
1561
- processDeferredPointer(event, pointerId);
1562
- } else if (internal.lastEvent?.current) {
1563
- processDeferredPointer(internal.lastEvent.current, pointerId);
1564
- }
1565
- } else {
1566
- flushDeferredPointers();
1567
- if (internal.lastEvent?.current) {
1568
- events.handlers.onPointerMove(internal.lastEvent.current);
1569
- }
1570
- }
1571
- },
1572
- flush: () => {
1573
- const { events, internal } = store.getState();
1574
- flushDeferredPointers();
1575
- if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
1576
- events.handlers.onPointerMove(internal.lastEvent.current);
1577
- }
1578
- },
1579
- connect: (target) => {
1580
- if (!target) return;
1581
- const { set, events } = store.getState();
1582
- events.disconnect?.();
1583
- set((state) => ({ events: { ...state.events, connected: target } }));
1584
- if (events.handlers) {
1585
- for (const name in events.handlers) {
1586
- const event = events.handlers[name];
1587
- const [eventName, passive] = DOM_EVENTS[name];
1588
- target.addEventListener(eventName, event, { passive });
1589
- }
1590
- }
1591
- },
1592
- disconnect: () => {
1593
- const { set, events } = store.getState();
1594
- if (events.connected) {
1595
- if (events.handlers) {
1596
- for (const name in events.handlers) {
1597
- const event = events.handlers[name];
1598
- const [eventName] = DOM_EVENTS[name];
1599
- events.connected.removeEventListener(eventName, event);
1600
- }
1601
- }
1602
- set((state) => ({ events: { ...state.events, connected: void 0 } }));
1603
- }
1604
- },
1605
- // PREVIEW (A8): the XR pointer registration API may change before stable.
1606
- registerPointer: (config) => {
1607
- const pointerId = nextXRPointerId++;
1608
- xrPointers.set(pointerId, config);
1609
- const { internal } = store.getState();
1610
- getPointerState(internal, pointerId);
1611
- return pointerId;
1612
- },
1613
- unregisterPointer: (pointerId) => {
1614
- xrPointers.delete(pointerId);
1615
- const { internal } = store.getState();
1616
- const pointerState = internal.pointerMap.get(pointerId);
1617
- if (pointerState) {
1618
- for (const [, hoveredObj] of pointerState.hovered) {
1619
- const eventObject = hoveredObj.eventObject;
1620
- const instance = eventObject.__r3f;
1621
- if (instance?.eventCount) {
1622
- const handlers = instance.handlers;
1623
- const data = { ...hoveredObj, intersections: [] };
1624
- handlers.onPointerOut?.(data);
1625
- handlers.onPointerLeave?.(data);
1626
- }
1627
- }
1628
- internal.pointerMap.delete(pointerId);
1629
- }
1630
- internal.pointerDirty.delete(pointerId);
1631
- }
1632
- };
1633
- }
1634
-
1635
- const shownNotices = /* @__PURE__ */ new Set();
1636
- function notifyDepreciated({ heading, body, link }) {
1637
- if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
1638
- return;
1639
- }
1640
- if (shownNotices.has(heading)) return;
1641
- shownNotices.add(heading);
1642
- const caller = getCallerFrame();
1643
- if (caller) {
1644
- console.log();
1645
- }
1646
- const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
1647
- if (caller) {
1648
- console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
1649
- }
1650
- if (body || link) {
1651
- let message = "";
1652
- if (body) message += body;
1653
- if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
1654
- console.warn(`%c${message}`, "font-weight: bold;");
1655
- }
1656
- }
1657
- function getCallerFrame(depth = 3) {
1658
- const stack = new Error().stack;
1659
- if (!stack) return null;
1660
- const lines = stack.split("\n");
1661
- const frame = lines[depth];
1662
- if (!frame) return null;
1663
- let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
1664
- if (!match) {
1665
- match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
1666
- }
1667
- if (!match) return null;
1668
- const [, fn, url, line] = match;
1669
- return {
1670
- functionName: fn ?? "<anonymous>",
1671
- location: formatLocation(url, Number(line))
1672
- };
1673
- }
1674
- function formatLocation(url, line) {
1675
- const clean = url.split("?")[0];
1676
- const file = clean.split("/").pop() ?? clean;
1677
- return `${file}:${line}`;
1678
- }
1679
- function notifyAlpha({ message, link }) {
1680
- if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
1681
- return;
1682
- }
1683
- if (shownNotices.has(message)) return;
1684
- shownNotices.add(message);
1685
- const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
1686
- console.log(`%c\u{1F52C} ${message}`, boxStyle);
1687
- {
1688
- console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
1689
- }
1690
- }
1691
-
1692
- const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
1693
- function isInternalRendererAccess(stack, callerDepth = 2) {
1694
- if (!stack) return false;
1695
- const caller = stack.split("\n")[callerDepth] ?? "";
1696
- return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
828
+ const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
829
+ function isInternalRendererAccess(stack, callerDepth = 2) {
830
+ if (!stack) return false;
831
+ const caller = stack.split("\n")[callerDepth] ?? "";
832
+ return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
1697
833
  }
1698
834
 
1699
835
  const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
@@ -1805,7 +941,7 @@ const createStore = (invalidate, advance) => {
1805
941
  size: newSize,
1806
942
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
1807
943
  }));
1808
- scheduler.getScheduler().invalidate();
944
+ get().invalidate();
1809
945
  }
1810
946
  }
1811
947
  return;
@@ -1820,15 +956,16 @@ const createStore = (invalidate, advance) => {
1820
956
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
1821
957
  _sizeImperative: true
1822
958
  }));
1823
- scheduler.getScheduler().invalidate();
959
+ get().invalidate();
1824
960
  },
1825
961
  setDpr: (dpr) => set((state2) => {
1826
962
  const resolved = calculateDpr(dpr);
1827
963
  return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
1828
964
  }),
1829
965
  setFrameloop: (frameloop = "always") => {
966
+ const rootId = get().internal.rootId;
967
+ if (rootId) scheduler.getScheduler().setRootFrameloop(rootId, frameloop);
1830
968
  set(() => ({ frameloop }));
1831
- scheduler.getScheduler().frameloop = frameloop;
1832
969
  },
1833
970
  setError: (error) => set(() => ({ error })),
1834
971
  error: null,
@@ -1944,17 +1081,11 @@ const createStore = (invalidate, advance) => {
1944
1081
  oldSize = size;
1945
1082
  oldDpr = viewport.dpr;
1946
1083
  updateCamera(camera, size);
1947
- if (internal.isSecondary && canvasTarget) {
1948
- if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
1949
- canvasTarget.setSize(size.width, size.height, false);
1950
- } else {
1951
- if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
1952
- actualRenderer.setSize(size.width, size.height, false);
1953
- if (canvasTarget) {
1954
- if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
1955
- canvasTarget.setSize(size.width, size.height, false);
1956
- }
1957
- }
1084
+ const resizeTarget = canvasTarget ?? actualRenderer;
1085
+ if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
1086
+ resizeTarget.setSize(size.width, size.height, false);
1087
+ const activeTarget = actualRenderer.getCanvasTarget?.();
1088
+ if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
1958
1089
  }
1959
1090
  if (camera !== oldCamera) {
1960
1091
  oldCamera = camera;
@@ -1975,7 +1106,7 @@ const createStore = (invalidate, advance) => {
1975
1106
 
1976
1107
  const memoizedLoaders = /* @__PURE__ */ new WeakMap();
1977
1108
  const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
1978
- function getLoader(Proto) {
1109
+ function getLoader$1(Proto) {
1979
1110
  if (isConstructor$1(Proto)) {
1980
1111
  let loader = memoizedLoaders.get(Proto);
1981
1112
  if (!loader) {
@@ -1988,7 +1119,7 @@ function getLoader(Proto) {
1988
1119
  }
1989
1120
  function loadingFn(extensions, onProgress) {
1990
1121
  return function(Proto, input) {
1991
- const loader = getLoader(Proto);
1122
+ const loader = getLoader$1(Proto);
1992
1123
  if (extensions) extensions(loader);
1993
1124
  if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
1994
1125
  return loader.loadAsync(input, onProgress).then((data) => {
@@ -2016,7 +1147,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
2016
1147
  const results = cacheKeys.map(
2017
1148
  (key, index) => suspendReact.suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
2018
1149
  );
2019
- return Array.isArray(input) ? results : results[0];
1150
+ const stableRef = React.useRef(null);
1151
+ const previous = stableRef.current;
1152
+ const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
1153
+ stableRef.current = stable;
1154
+ return Array.isArray(input) ? stable : stable[0];
2020
1155
  }
2021
1156
  useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
2022
1157
  const inputs = Array.isArray(input) ? input : [input];
@@ -2029,9 +1164,9 @@ useLoader.clear = function(loader, input, cacheKey) {
2029
1164
  const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
2030
1165
  cacheKeys.forEach((key) => suspendReact.clear([loader, key]));
2031
1166
  };
2032
- useLoader.loader = getLoader;
1167
+ useLoader.loader = getLoader$1;
2033
1168
 
2034
- function useFrame(callback, priorityOrOptions) {
1169
+ function useFrame$1(callback, priorityOrOptions) {
2035
1170
  const store = React__namespace.useContext(context);
2036
1171
  const isInsideCanvas = store !== null;
2037
1172
  const scheduler$1 = scheduler.getScheduler();
@@ -2136,6 +1271,13 @@ function useFrame(callback, priorityOrOptions) {
2136
1271
  * Use for controlling the entire frame loop, adding phases, etc.
2137
1272
  */
2138
1273
  scheduler: scheduler2,
1274
+ /**
1275
+ * The root that currently owns this job. Resolve on access because ambient
1276
+ * jobs can be adopted by a Canvas after the controls object is created.
1277
+ */
1278
+ get rootId() {
1279
+ return scheduler.getScheduler().getJobRootId(id);
1280
+ },
2139
1281
  /**
2140
1282
  * Manually step this job only.
2141
1283
  * Bypasses FPS limiting - always runs.
@@ -2152,6 +1294,14 @@ function useFrame(callback, priorityOrOptions) {
2152
1294
  stepAll: (timestamp) => {
2153
1295
  scheduler.getScheduler().step(timestamp);
2154
1296
  },
1297
+ /**
1298
+ * Request frames for this job's owning root without waking sibling roots.
1299
+ */
1300
+ invalidate: (frames, stackFrames) => {
1301
+ const scheduler3 = scheduler.getScheduler();
1302
+ const rootId = scheduler3.getJobRootId(id);
1303
+ if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
1304
+ },
2155
1305
  /**
2156
1306
  * Pause this job (set enabled=false).
2157
1307
  * Job remains registered but won't run.
@@ -2181,6 +1331,11 @@ function getUrls(input) {
2181
1331
  if (Array.isArray(input)) return input;
2182
1332
  return Object.values(input);
2183
1333
  }
1334
+ function inputSignature(input) {
1335
+ if (typeof input === "string") return input;
1336
+ if (Array.isArray(input)) return input.join("\0");
1337
+ return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
1338
+ }
2184
1339
  function allUrlsCached(urls, textureCache) {
2185
1340
  return urls.every((url) => textureCache.has(url));
2186
1341
  }
@@ -2199,31 +1354,44 @@ function buildFromCache(input, textureCache) {
2199
1354
  }
2200
1355
  }
2201
1356
  function useTexture(input, optionsOrOnLoad) {
2202
- const renderer = useThree((state) => state.internal.actualRenderer);
1357
+ const renderer = useThree$1((state) => state.internal.actualRenderer);
2203
1358
  const store = useStore();
2204
1359
  const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
2205
1360
  const { onLoad, cache = true } = options;
2206
1361
  const onLoadRef = React.useRef(onLoad);
2207
1362
  onLoadRef.current = onLoad;
2208
1363
  const onLoadCalledForRef = React.useRef(null);
2209
- const urls = React.useMemo(() => getUrls(input), [input]);
1364
+ const inputKey = React.useMemo(() => inputSignature(input), [input]);
1365
+ const stableInput = React.useMemo(() => input, [inputKey]);
1366
+ const urls = React.useMemo(() => getUrls(stableInput), [stableInput]);
2210
1367
  const cachedResult = React.useMemo(() => {
2211
1368
  if (!cache) return null;
2212
1369
  const textures = store.getState().textures;
2213
1370
  if (!allUrlsCached(urls, textures)) return null;
2214
- return buildFromCache(input, textures);
2215
- }, [cache, urls, input, store]);
1371
+ return buildFromCache(stableInput, textures);
1372
+ }, [cache, urls, stableInput, store]);
2216
1373
  const loadedTextures = useLoader(
2217
1374
  webgpu.TextureLoader,
2218
- IsObject(input) ? Object.values(input) : input
1375
+ IsObject(stableInput) ? Object.values(stableInput) : stableInput
2219
1376
  );
2220
- const inputKey = urls.join("\0");
1377
+ const mappedTextures = React.useMemo(() => {
1378
+ if (cachedResult) return cachedResult;
1379
+ if (IsObject(stableInput)) {
1380
+ const keyed = {};
1381
+ const textureArray = loadedTextures;
1382
+ let i = 0;
1383
+ for (const key in stableInput) keyed[key] = textureArray[i++];
1384
+ return keyed;
1385
+ } else {
1386
+ return loadedTextures;
1387
+ }
1388
+ }, [stableInput, loadedTextures, cachedResult]);
2221
1389
  React.useLayoutEffect(() => {
2222
1390
  if (cachedResult) return;
2223
1391
  if (onLoadCalledForRef.current === inputKey) return;
2224
1392
  onLoadCalledForRef.current = inputKey;
2225
- onLoadRef.current?.(loadedTextures);
2226
- }, [cachedResult, loadedTextures, inputKey]);
1393
+ onLoadRef.current?.(mappedTextures);
1394
+ }, [cachedResult, mappedTextures, inputKey]);
2227
1395
  React.useEffect(() => {
2228
1396
  if (cachedResult) return;
2229
1397
  if ("initTexture" in renderer) {
@@ -2242,30 +1410,18 @@ function useTexture(input, optionsOrOnLoad) {
2242
1410
  });
2243
1411
  }
2244
1412
  }, [renderer, loadedTextures, cachedResult]);
2245
- const mappedTextures = React.useMemo(() => {
2246
- if (cachedResult) return cachedResult;
2247
- if (IsObject(input)) {
2248
- const keyed = {};
2249
- const textureArray = loadedTextures;
2250
- let i = 0;
2251
- for (const key in input) keyed[key] = textureArray[i++];
2252
- return keyed;
2253
- } else {
2254
- return loadedTextures;
2255
- }
2256
- }, [input, loadedTextures, cachedResult]);
2257
1413
  React.useEffect(() => {
2258
1414
  if (!cache) return;
2259
1415
  const urlTextureMap = [];
2260
- if (typeof input === "string") {
2261
- urlTextureMap.push([input, mappedTextures]);
2262
- } else if (Array.isArray(input)) {
1416
+ if (typeof stableInput === "string") {
1417
+ urlTextureMap.push([stableInput, mappedTextures]);
1418
+ } else if (Array.isArray(stableInput)) {
2263
1419
  const textureArray = mappedTextures;
2264
- input.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
2265
- } else if (IsObject(input)) {
1420
+ stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
1421
+ } else if (IsObject(stableInput)) {
2266
1422
  const textureRecord = mappedTextures;
2267
- for (const key in input) {
2268
- const url = input[key];
1423
+ for (const key in stableInput) {
1424
+ const url = stableInput[key];
2269
1425
  urlTextureMap.push([url, textureRecord[key]]);
2270
1426
  }
2271
1427
  }
@@ -2294,7 +1450,7 @@ function useTexture(input, optionsOrOnLoad) {
2294
1450
  }
2295
1451
  return { _textureRefs: refs };
2296
1452
  });
2297
- }, [cache, input, mappedTextures, store]);
1453
+ }, [cache, stableInput, mappedTextures, store]);
2298
1454
  return mappedTextures;
2299
1455
  }
2300
1456
  useTexture.preload = (url) => useLoader.preload(webgpu.TextureLoader, url);
@@ -2365,13 +1521,13 @@ function useTextures(selector) {
2365
1521
  };
2366
1522
  }, [store]);
2367
1523
  const subscribe = selector ? () => selector(registry) : (state) => state.textures;
2368
- const selected = useThree(subscribe);
1524
+ const selected = useThree$1(subscribe);
2369
1525
  return selector ? selected : registry;
2370
1526
  }
2371
1527
 
2372
1528
  function useRenderTarget(widthOrOptions, heightOrOptions, options) {
2373
- const isLegacy = useThree((s) => s.isLegacy);
2374
- const size = useThree((s) => s.size);
1529
+ const isLegacy = useThree$1((s) => s.isLegacy);
1530
+ const size = useThree$1((s) => s.size);
2375
1531
  let width;
2376
1532
  let height;
2377
1533
  let opts;
@@ -2396,12 +1552,133 @@ function useRenderTarget(widthOrOptions, heightOrOptions, options) {
2396
1552
  }, [width, height, size.width, size.height, opts, isLegacy]);
2397
1553
  }
2398
1554
 
1555
+ const presetsObj = {
1556
+ apartment: "lebombo_1k.hdr",
1557
+ city: "potsdamer_platz_1k.hdr",
1558
+ dawn: "kiara_1_dawn_1k.hdr",
1559
+ forest: "forest_slope_1k.hdr",
1560
+ lobby: "st_fagans_interior_1k.hdr",
1561
+ night: "dikhololo_night_1k.hdr",
1562
+ park: "rooitou_park_1k.hdr",
1563
+ studio: "studio_small_03_1k.hdr",
1564
+ sunset: "venice_sunset_1k.hdr",
1565
+ warehouse: "empty_warehouse_01_1k.hdr"
1566
+ };
1567
+
1568
+ const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
1569
+ const isArray = (arr) => Array.isArray(arr);
1570
+ const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
1571
+ function useEnvironment({
1572
+ files = defaultFiles,
1573
+ path = "",
1574
+ preset = void 0,
1575
+ colorSpace = void 0,
1576
+ extensions
1577
+ } = {}) {
1578
+ if (preset) {
1579
+ validatePreset(preset);
1580
+ files = presetsObj[preset];
1581
+ path = CUBEMAP_ROOT;
1582
+ }
1583
+ const multiFile = isArray(files);
1584
+ const { extension, isCubemap } = getExtension(files);
1585
+ const loader = getLoader(extension);
1586
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1587
+ const renderer = useThree$1((state) => state.renderer);
1588
+ React.useLayoutEffect(() => {
1589
+ if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
1590
+ function clearGainmapTexture() {
1591
+ useLoader.clear(loader, multiFile ? [files] : files);
1592
+ }
1593
+ renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
1594
+ }, [extension, files, loader, multiFile, renderer.domElement]);
1595
+ const loaderResult = useLoader(
1596
+ loader,
1597
+ multiFile ? [files] : files,
1598
+ (loader2) => {
1599
+ if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
1600
+ loader2.setRenderer?.(renderer);
1601
+ }
1602
+ loader2.setPath?.(path);
1603
+ if (extensions) extensions(loader2);
1604
+ }
1605
+ );
1606
+ let texture = multiFile ? (
1607
+ // @ts-ignore
1608
+ loaderResult[0]
1609
+ ) : loaderResult;
1610
+ if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
1611
+ texture = texture.renderTarget?.texture;
1612
+ }
1613
+ texture.mapping = isCubemap ? webgpu.CubeReflectionMapping : webgpu.EquirectangularReflectionMapping;
1614
+ texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
1615
+ return texture;
1616
+ }
1617
+ const preloadDefaultOptions = {
1618
+ files: defaultFiles,
1619
+ path: "",
1620
+ preset: void 0,
1621
+ extensions: void 0
1622
+ };
1623
+ useEnvironment.preload = (preloadOptions) => {
1624
+ const options = { ...preloadDefaultOptions, ...preloadOptions };
1625
+ let { files, path = "" } = options;
1626
+ const { preset, extensions } = options;
1627
+ if (preset) {
1628
+ validatePreset(preset);
1629
+ files = presetsObj[preset];
1630
+ path = CUBEMAP_ROOT;
1631
+ }
1632
+ const { extension } = getExtension(files);
1633
+ if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
1634
+ throw new Error("useEnvironment: Preloading gainmaps is not supported");
1635
+ }
1636
+ const loader = getLoader(extension);
1637
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1638
+ useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
1639
+ loader2.setPath?.(path);
1640
+ if (extensions) extensions(loader2);
1641
+ });
1642
+ };
1643
+ const clearDefaultOptins = {
1644
+ files: defaultFiles,
1645
+ preset: void 0
1646
+ };
1647
+ useEnvironment.clear = (clearOptions) => {
1648
+ const options = { ...clearDefaultOptins, ...clearOptions };
1649
+ let { files } = options;
1650
+ const { preset } = options;
1651
+ if (preset) {
1652
+ validatePreset(preset);
1653
+ files = presetsObj[preset];
1654
+ }
1655
+ const { extension } = getExtension(files);
1656
+ const loader = getLoader(extension);
1657
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1658
+ useLoader.clear(loader, isArray(files) ? [files] : files);
1659
+ };
1660
+ function validatePreset(preset) {
1661
+ if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
1662
+ }
1663
+ function getExtension(files) {
1664
+ const isCubemap = isArray(files) && files.length === 6;
1665
+ const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
1666
+ const firstEntry = isArray(files) ? files[0] : files;
1667
+ const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
1668
+ const extension = isCubemap ? firstExtension === "hdr" ? "hdr-cube" : "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstExtension;
1669
+ return { extension, isCubemap, isGainmap };
1670
+ }
1671
+ function getLoader(extension) {
1672
+ const loader = extension === "cube" ? webgpu.CubeTextureLoader : extension === "hdr-cube" ? HDRCubeTextureLoader_js.HDRCubeTextureLoader : extension === "hdr" ? HDRLoader_js.HDRLoader : extension === "exr" ? EXRLoader_js.EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader_js.UltraHDRLoader : extension === "webp" ? gainmapJs.GainMapLoader : null;
1673
+ return loader;
1674
+ }
1675
+
2399
1676
  function useStore() {
2400
1677
  const store = React.useContext(context);
2401
1678
  if (!store) throw new Error("R3F: Hooks can only be used within the Canvas component!");
2402
1679
  return store;
2403
1680
  }
2404
- function useThree(selector = (state) => state, equalityFn) {
1681
+ function useThree$1(selector = (state) => state, equalityFn) {
2405
1682
  return useStore()(selector, equalityFn);
2406
1683
  }
2407
1684
  function useInstanceHandle(ref) {
@@ -2413,6 +1690,8 @@ function useGraph(object) {
2413
1690
  return React.useMemo(() => buildGraph(object), [object]);
2414
1691
  }
2415
1692
 
1693
+ const t = 1, o = 8, r = 32, e = 2, i$1 = 268435456;
1694
+
2416
1695
  let effectId = 0;
2417
1696
  function addEffect(callback) {
2418
1697
  notifyDepreciated({
@@ -2441,22 +1720,28 @@ function addTail(callback) {
2441
1720
  return scheduler.getScheduler().onIdle(callback);
2442
1721
  }
2443
1722
  function invalidate(state, frames = 1, stackFrames = false) {
2444
- scheduler.getScheduler().invalidate(frames, stackFrames);
1723
+ const rootId = state?.internal?.rootId;
1724
+ const scheduler$1 = scheduler.getScheduler();
1725
+ if (rootId) scheduler$1.invalidateRoot(rootId, frames, stackFrames);
1726
+ else scheduler$1.invalidate(frames, stackFrames);
2445
1727
  }
2446
- function advance(timestamp) {
2447
- scheduler.getScheduler().step(timestamp);
1728
+ function advance(timestamp, runGlobalEffects, state) {
1729
+ const rootId = state?.internal?.rootId;
1730
+ const scheduler$1 = scheduler.getScheduler();
1731
+ if (rootId) scheduler$1.stepRoot(rootId, timestamp);
1732
+ else scheduler$1.step(timestamp);
2448
1733
  }
2449
1734
 
2450
- const version = "10.0.0-alpha.3";
1735
+ const version = "10.0.0-alpha.5";
2451
1736
  const packageData = {
2452
1737
  version: version};
2453
1738
 
2454
1739
  function Xb(Tt) {
2455
1740
  return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
2456
1741
  }
2457
- var Rm = { exports: {} }, Og = { exports: {} }, _b;
1742
+ var Rm = { exports: {} }, Og = { exports: {} }, _b$1;
2458
1743
  function Kb() {
2459
- return _b || (_b = 1, (function(Tt) {
1744
+ return _b$1 || (_b$1 = 1, (function(Tt) {
2460
1745
  Tt.exports = function(m) {
2461
1746
  function Yn(t, r, a, l) {
2462
1747
  return new uc(t, r, a, l);
@@ -13311,399 +12596,982 @@ Check the top-level render call using <` + i + ">.");
13311
12596
  var o = x.H;
13312
12597
  x.H = $o;
13313
12598
  try {
13314
- return Vi(e, n);
12599
+ return Vi(e, n);
12600
+ } finally {
12601
+ x.H = o;
12602
+ }
12603
+ }, useReducer: function(e, n, o) {
12604
+ z = "useReducer", D(), N();
12605
+ var i = x.H;
12606
+ x.H = $o;
12607
+ try {
12608
+ return Br(e, n, o);
12609
+ } finally {
12610
+ x.H = i;
12611
+ }
12612
+ }, useRef: function() {
12613
+ return z = "useRef", D(), N(), xe().memoizedState;
12614
+ }, useState: function() {
12615
+ z = "useState", D(), N();
12616
+ var e = x.H;
12617
+ x.H = $o;
12618
+ try {
12619
+ return Br(gr);
12620
+ } finally {
12621
+ x.H = e;
12622
+ }
12623
+ }, useDebugValue: function() {
12624
+ z = "useDebugValue", D(), N();
12625
+ }, useDeferredValue: function(e, n) {
12626
+ return z = "useDeferredValue", D(), N(), nc(e, n);
12627
+ }, useTransition: function() {
12628
+ return z = "useTransition", D(), N(), Qp();
12629
+ }, useSyncExternalStore: function(e, n, o) {
12630
+ return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
12631
+ }, useId: function() {
12632
+ return z = "useId", D(), N(), xe().memoizedState;
12633
+ }, useFormState: function(e) {
12634
+ return z = "useFormState", D(), N(), hs(e);
12635
+ }, useActionState: function(e) {
12636
+ return z = "useActionState", D(), N(), hs(e);
12637
+ }, useOptimistic: function(e, n) {
12638
+ return z = "useOptimistic", D(), N(), rf(e, n);
12639
+ }, useMemoCache: function(e) {
12640
+ return D(), Oa(e);
12641
+ }, useHostTransitionStatus: ia, useCacheRefresh: function() {
12642
+ return z = "useCacheRefresh", N(), xe().memoizedState;
12643
+ }, useEffectEvent: function(e) {
12644
+ return z = "useEffectEvent", D(), N(), oa(e);
12645
+ } }, dm = { readContext: function(e) {
12646
+ return Ce(), Ee(e);
12647
+ }, use: function(e) {
12648
+ return D(), we(e);
12649
+ }, useCallback: function(e, n) {
12650
+ return z = "useCallback", D(), N(), Ma(e, n);
12651
+ }, useContext: function(e) {
12652
+ return z = "useContext", D(), N(), Ee(e);
12653
+ }, useEffect: function(e, n) {
12654
+ z = "useEffect", D(), N(), Qn(2048, Ut, e, n);
12655
+ }, useImperativeHandle: function(e, n, o) {
12656
+ return z = "useImperativeHandle", D(), N(), aa(e, n, o);
12657
+ }, useInsertionEffect: function(e, n) {
12658
+ return z = "useInsertionEffect", D(), N(), Qn(4, Wt, e, n);
12659
+ }, useLayoutEffect: function(e, n) {
12660
+ return z = "useLayoutEffect", D(), N(), Qn(4, Rr, e, n);
12661
+ }, useMemo: function(e, n) {
12662
+ z = "useMemo", D(), N();
12663
+ var o = x.H;
12664
+ x.H = $o;
12665
+ try {
12666
+ return Vi(e, n);
12667
+ } finally {
12668
+ x.H = o;
12669
+ }
12670
+ }, useReducer: function(e, n, o) {
12671
+ z = "useReducer", D(), N();
12672
+ var i = x.H;
12673
+ x.H = $o;
12674
+ try {
12675
+ return Qi(e, n, o);
12676
+ } finally {
12677
+ x.H = i;
12678
+ }
12679
+ }, useRef: function() {
12680
+ return z = "useRef", D(), N(), xe().memoizedState;
12681
+ }, useState: function() {
12682
+ z = "useState", D(), N();
12683
+ var e = x.H;
12684
+ x.H = $o;
12685
+ try {
12686
+ return Qi(gr);
12687
+ } finally {
12688
+ x.H = e;
12689
+ }
12690
+ }, useDebugValue: function() {
12691
+ z = "useDebugValue", D(), N();
12692
+ }, useDeferredValue: function(e, n) {
12693
+ return z = "useDeferredValue", D(), N(), sf(e, n);
12694
+ }, useTransition: function() {
12695
+ return z = "useTransition", D(), N(), Ro();
12696
+ }, useSyncExternalStore: function(e, n, o) {
12697
+ return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
12698
+ }, useId: function() {
12699
+ return z = "useId", D(), N(), xe().memoizedState;
12700
+ }, useFormState: function(e) {
12701
+ return z = "useFormState", D(), N(), $t(e);
12702
+ }, useActionState: function(e) {
12703
+ return z = "useActionState", D(), N(), $t(e);
12704
+ }, useOptimistic: function(e, n) {
12705
+ return z = "useOptimistic", D(), N(), of(e, n);
12706
+ }, useMemoCache: function(e) {
12707
+ return D(), Oa(e);
12708
+ }, useHostTransitionStatus: ia, useCacheRefresh: function() {
12709
+ return z = "useCacheRefresh", N(), xe().memoizedState;
12710
+ }, useEffectEvent: function(e) {
12711
+ return z = "useEffectEvent", D(), N(), oa(e);
12712
+ } };
12713
+ var Fy = {}, Hy = /* @__PURE__ */ new Set(), Ay = /* @__PURE__ */ new Set(), jy = /* @__PURE__ */ new Set(), Dy = /* @__PURE__ */ new Set(), Wy = /* @__PURE__ */ new Set(), Uy = /* @__PURE__ */ new Set(), By = /* @__PURE__ */ new Set(), Oy = /* @__PURE__ */ new Set(), My = /* @__PURE__ */ new Set(), Qy = /* @__PURE__ */ new Set();
12714
+ Object.freeze(Fy);
12715
+ var zg = { enqueueSetState: function(e, n, o) {
12716
+ e = e._reactInternals;
12717
+ var i = Nt(e), s = zo(i);
12718
+ s.payload = n, o != null && (df(o), s.callback = o), n = Mt(e, s, i), n !== null && (ur(i, "this.setState()", e), We(n, e, i), Bi(n, e, i));
12719
+ }, enqueueReplaceState: function(e, n, o) {
12720
+ e = e._reactInternals;
12721
+ var i = Nt(e), s = zo(i);
12722
+ s.tag = Cy, s.payload = n, o != null && (df(o), s.callback = o), n = Mt(e, s, i), n !== null && (ur(i, "this.replaceState()", e), We(n, e, i), Bi(n, e, i));
12723
+ }, enqueueForceUpdate: function(e, n) {
12724
+ e = e._reactInternals;
12725
+ var o = Nt(e), i = zo(o);
12726
+ i.tag = Ty, n != null && (df(n), i.callback = n), n = Mt(e, i, o), n !== null && (ur(o, "this.forceUpdate()", e), We(n, e, o), Bi(n, e, o));
12727
+ } }, bd = null, Cg = null, Tg = Error("This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue."), Cn = false, $y = {}, Vy = {}, qy = {}, Gy = {}, vd = false, Jy = {}, fm = {}, _g = { dehydrated: null, treeContext: null, retryLane: 0, hydrationErrors: null }, Zy = false, Yy = null;
12728
+ Yy = /* @__PURE__ */ new Set();
12729
+ var Si = false, Tn = false, Rg = false, Xy = typeof WeakSet == "function" ? WeakSet : Set, Gn = null, Sd = null, kd = null, _n = null, nr = false, Vo = null, Wn = false, wd = 8192, Vb = { getCacheForType: function(e) {
12730
+ var n = Ee(un), o = n.data.get(e);
12731
+ return o === void 0 && (o = e(), n.data.set(e, o)), o;
12732
+ }, cacheSignal: function() {
12733
+ return Ee(un).controller.signal;
12734
+ }, getOwner: function() {
12735
+ return di;
12736
+ } }, pm = 0, hm = 1, mm = 2, gm = 3, ym = 4;
12737
+ if (typeof Symbol == "function" && Symbol.for) {
12738
+ var bp = Symbol.for;
12739
+ pm = bp("selector.component"), hm = bp("selector.has_pseudo_class"), mm = bp("selector.role"), gm = bp("selector.test_id"), ym = bp("selector.text");
12740
+ }
12741
+ var bm = [], qb = typeof WeakMap == "function" ? WeakMap : Map, Jn = 0, Zn = 2, uo = 4, ki = 0, vp = 1, iu = 2, vm = 3, Tl = 4, Sm = 6, Ky = 5, ye = Jn, je = null, se = null, ae = 0, tr = 0, km = 1, lu = 2, Sp = 3, eb = 4, Eg = 5, kp = 6, wm = 7, Ig = 8, su = 9, Le = tr, Er = null, _l = false, Pd = false, Lg = false, Ta = 0, nn = ki, Rl = 0, El = 0, Ng = 0, rr = 0, uu = 0, wp = null, Bt = null, Pm = false, xm = 0, nb = 0, tb = 300, Pp = 1 / 0, Fg = 500, xp = null, gn = null, Il = null, zm = 0, Hg = 1, Ag = 2, rb = 3, Ll = 0, ob = 1, ab = 2, ib = 3, lb = 4, Cm = 5, Rn = 0, Nl = null, xd = null, qo = 0, jg = 0, Dg = -0, Wg = null, sb = null, ub = null, Go = zm, cb = null, Gb = 50, zp = 0, Ug = null, Bg = false, Tm = false, Jb = 50, cu = 0, Cp = null, zd = false, _m = null, db = false, fb = /* @__PURE__ */ new Set(), Zb = {}, co = null, Cd = null, pb = false;
12742
+ try {
12743
+ var o0 = Object.preventExtensions({});
12744
+ } catch {
12745
+ pb = true;
12746
+ }
12747
+ var hb = false, mb = {}, gb = null, yb = null, bb = null, vb = null, Sb = null, kb = null, wb = null, Pb = null, xb = null, zb = null;
12748
+ return gb = function(e, n, o, i) {
12749
+ n = Yn(e, n), n !== null && (o = _d(n.memoizedState, o, 0, i), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
12750
+ }, yb = function(e, n, o) {
12751
+ n = Yn(e, n), n !== null && (o = du(n.memoizedState, o, 0), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
12752
+ }, bb = function(e, n, o, i) {
12753
+ n = Yn(e, n), n !== null && (o = F(n.memoizedState, o, i), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
12754
+ }, vb = function(e, n, o) {
12755
+ e.pendingProps = _d(e.memoizedProps, n, 0, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
12756
+ }, Sb = function(e, n) {
12757
+ e.pendingProps = du(e.memoizedProps, n, 0), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
12758
+ }, kb = function(e, n, o) {
12759
+ e.pendingProps = F(e.memoizedProps, n, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
12760
+ }, wb = function(e) {
12761
+ var n = On(e, 2);
12762
+ n !== null && We(n, e, 2);
12763
+ }, Pb = function(e) {
12764
+ var n = ut(), o = On(e, n);
12765
+ o !== null && We(o, e, n);
12766
+ }, xb = function(e) {
12767
+ pu = e;
12768
+ }, zb = function(e) {
12769
+ fu = e;
12770
+ }, le.attemptContinuousHydration = function(e) {
12771
+ if (e.tag === 13 || e.tag === 31) {
12772
+ var n = On(e, 67108864);
12773
+ n !== null && We(n, e, 67108864), rl(e, 67108864);
12774
+ }
12775
+ }, le.attemptHydrationAtCurrentPriority = function(e) {
12776
+ if (e.tag === 13 || e.tag === 31) {
12777
+ var n = Nt(e);
12778
+ n = Xo(n);
12779
+ var o = On(e, n);
12780
+ o !== null && We(o, e, n), rl(e, n);
12781
+ }
12782
+ }, le.attemptSynchronousHydration = function(e) {
12783
+ switch (e.tag) {
12784
+ case 3:
12785
+ if (e = e.stateNode, e.current.memoizedState.isDehydrated) {
12786
+ var n = _t(e.pendingLanes);
12787
+ if (n !== 0) {
12788
+ for (e.pendingLanes |= 2, e.entangledLanes |= 2; n; ) {
12789
+ var o = 1 << 31 - vn(n);
12790
+ e.entanglements[1] |= o, n &= ~o;
12791
+ }
12792
+ Kn(e), (ye & (Zn | uo)) === Jn && (Pp = me() + Fg, Wa(0));
12793
+ }
12794
+ }
12795
+ break;
12796
+ case 31:
12797
+ case 13:
12798
+ n = On(e, 2), n !== null && We(n, e, 2), Ls(), rl(e, 2);
12799
+ }
12800
+ }, le.batchedUpdates = function(e, n) {
12801
+ return e(n);
12802
+ }, le.createComponentSelector = function(e) {
12803
+ return { $$typeof: pm, value: e };
12804
+ }, le.createContainer = function(e, n, o, i, s, u, f, p, g, S) {
12805
+ return Ka(e, n, false, null, o, i, u, null, f, p, g, S);
12806
+ }, le.createHasPseudoClassSelector = function(e) {
12807
+ return { $$typeof: hm, value: e };
12808
+ }, le.createHydrationContainer = function(e, n, o, i, s, u, f, p, g, S, T, _, I, O) {
12809
+ return e = Ka(o, i, true, e, s, u, p, O, g, S, T, _), e.context = Dh(null), o = e.current, i = Nt(o), i = Xo(i), s = zo(i), s.callback = n ?? null, Mt(o, s, i), ur(i, "hydrateRoot()", null), n = i, e.current.lanes = n, Ci(e, n), Kn(e), e;
12810
+ }, le.createPortal = function(e, n, o) {
12811
+ var i = 3 < arguments.length && arguments[3] !== void 0 ? arguments[3] : null;
12812
+ try {
12813
+ vt(i);
12814
+ var s = false;
12815
+ } catch {
12816
+ s = true;
12817
+ }
12818
+ return s && (console.error("The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", typeof Symbol == "function" && Symbol.toStringTag && i[Symbol.toStringTag] || i.constructor.name || "Object"), vt(i)), { $$typeof: Ao, key: i == null ? null : "" + i, children: e, containerInfo: n, implementation: o };
12819
+ }, le.createRoleSelector = function(e) {
12820
+ return { $$typeof: mm, value: e };
12821
+ }, le.createTestNameSelector = function(e) {
12822
+ return { $$typeof: gm, value: e };
12823
+ }, le.createTextSelector = function(e) {
12824
+ return { $$typeof: ym, value: e };
12825
+ }, le.defaultOnCaughtError = function(e) {
12826
+ var n = bd ? "The above error occurred in the <" + bd + "> component." : "The above error occurred in one of your React components.", o = "React will try to recreate this component tree from scratch using the error boundary you provided, " + ((Cg || "Anonymous") + ".");
12827
+ typeof e == "object" && e !== null && typeof e.environmentName == "string" ? ri("error", [`%o
12828
+
12829
+ %s
12830
+
12831
+ %s
12832
+ `, e, n, o], e.environmentName)() : console.error(`%o
12833
+
12834
+ %s
12835
+
12836
+ %s
12837
+ `, e, n, o);
12838
+ }, le.defaultOnRecoverableError = function(e) {
12839
+ qg(e);
12840
+ }, le.defaultOnUncaughtError = function(e) {
12841
+ qg(e), console.warn(`%s
12842
+
12843
+ %s
12844
+ `, bd ? "An error occurred in the <" + bd + "> component." : "An error occurred in one of your React components.", `Consider adding an error boundary to your tree to customize error handling behavior.
12845
+ Visit https://react.dev/link/error-boundaries to learn more about error boundaries.`);
12846
+ }, le.deferredUpdates = function(e) {
12847
+ var n = x.T, o = wt();
12848
+ try {
12849
+ return an(32), x.T = null, e();
13315
12850
  } finally {
13316
- x.H = o;
12851
+ an(o), x.T = n;
13317
12852
  }
13318
- }, useReducer: function(e, n, o) {
13319
- z = "useReducer", D(), N();
13320
- var i = x.H;
13321
- x.H = $o;
12853
+ }, le.discreteUpdates = function(e, n, o, i, s) {
12854
+ var u = x.T, f = wt();
13322
12855
  try {
13323
- return Br(e, n, o);
12856
+ return an(2), x.T = null, e(n, o, i, s);
13324
12857
  } finally {
13325
- x.H = i;
12858
+ an(f), x.T = u, ye === Jn && (Pp = me() + Fg);
13326
12859
  }
13327
- }, useRef: function() {
13328
- return z = "useRef", D(), N(), xe().memoizedState;
13329
- }, useState: function() {
13330
- z = "useState", D(), N();
13331
- var e = x.H;
13332
- x.H = $o;
13333
- try {
13334
- return Br(gr);
13335
- } finally {
13336
- x.H = e;
12860
+ }, le.findAllNodes = kc, le.findBoundingRects = function(e, n) {
12861
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12862
+ n = kc(e, n), e = [];
12863
+ for (var o = 0; o < n.length; o++) e.push(ma(n[o]));
12864
+ for (n = e.length - 1; 0 < n; n--) {
12865
+ o = e[n];
12866
+ for (var i = o.x, s = i + o.width, u = o.y, f = u + o.height, p = n - 1; 0 <= p; p--) if (n !== p) {
12867
+ var g = e[p], S = g.x, T = S + g.width, _ = g.y, I = _ + g.height;
12868
+ if (i >= S && u >= _ && s <= T && f <= I) {
12869
+ e.splice(n, 1);
12870
+ break;
12871
+ } else if (i !== S || o.width !== g.width || I < u || _ > f) {
12872
+ if (!(u !== _ || o.height !== g.height || T < i || S > s)) {
12873
+ S > i && (g.width += S - i, g.x = i), T < s && (g.width = s - S), e.splice(n, 1);
12874
+ break;
12875
+ }
12876
+ } else {
12877
+ _ > u && (g.height += _ - u, g.y = u), I < f && (g.height = f - _), e.splice(n, 1);
12878
+ break;
12879
+ }
12880
+ }
13337
12881
  }
13338
- }, useDebugValue: function() {
13339
- z = "useDebugValue", D(), N();
13340
- }, useDeferredValue: function(e, n) {
13341
- return z = "useDeferredValue", D(), N(), nc(e, n);
13342
- }, useTransition: function() {
13343
- return z = "useTransition", D(), N(), Qp();
13344
- }, useSyncExternalStore: function(e, n, o) {
13345
- return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
13346
- }, useId: function() {
13347
- return z = "useId", D(), N(), xe().memoizedState;
13348
- }, useFormState: function(e) {
13349
- return z = "useFormState", D(), N(), hs(e);
13350
- }, useActionState: function(e) {
13351
- return z = "useActionState", D(), N(), hs(e);
13352
- }, useOptimistic: function(e, n) {
13353
- return z = "useOptimistic", D(), N(), rf(e, n);
13354
- }, useMemoCache: function(e) {
13355
- return D(), Oa(e);
13356
- }, useHostTransitionStatus: ia, useCacheRefresh: function() {
13357
- return z = "useCacheRefresh", N(), xe().memoizedState;
13358
- }, useEffectEvent: function(e) {
13359
- return z = "useEffectEvent", D(), N(), oa(e);
13360
- } }, dm = { readContext: function(e) {
13361
- return Ce(), Ee(e);
13362
- }, use: function(e) {
13363
- return D(), we(e);
13364
- }, useCallback: function(e, n) {
13365
- return z = "useCallback", D(), N(), Ma(e, n);
13366
- }, useContext: function(e) {
13367
- return z = "useContext", D(), N(), Ee(e);
13368
- }, useEffect: function(e, n) {
13369
- z = "useEffect", D(), N(), Qn(2048, Ut, e, n);
13370
- }, useImperativeHandle: function(e, n, o) {
13371
- return z = "useImperativeHandle", D(), N(), aa(e, n, o);
13372
- }, useInsertionEffect: function(e, n) {
13373
- return z = "useInsertionEffect", D(), N(), Qn(4, Wt, e, n);
13374
- }, useLayoutEffect: function(e, n) {
13375
- return z = "useLayoutEffect", D(), N(), Qn(4, Rr, e, n);
13376
- }, useMemo: function(e, n) {
13377
- z = "useMemo", D(), N();
13378
- var o = x.H;
13379
- x.H = $o;
13380
- try {
13381
- return Vi(e, n);
13382
- } finally {
13383
- x.H = o;
12882
+ return e;
12883
+ }, le.findHostInstance = function(e) {
12884
+ var n = e._reactInternals;
12885
+ if (n === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
12886
+ return e = mu(n), e === null ? null : ot(e.stateNode);
12887
+ }, le.findHostInstanceWithNoPortals = function(e) {
12888
+ return e = Ed(e), e = e !== null ? _p(e) : null, e === null ? null : ot(e.stateNode);
12889
+ }, le.findHostInstanceWithWarning = function(e, n) {
12890
+ var o = e._reactInternals;
12891
+ if (o === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
12892
+ if (e = mu(o), e === null) return null;
12893
+ if (e.mode & 8) {
12894
+ var i = G(o) || "Component";
12895
+ mb[i] || (mb[i] = true, B(e, function() {
12896
+ o.mode & 8 ? console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i) : console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i);
12897
+ }));
13384
12898
  }
13385
- }, useReducer: function(e, n, o) {
13386
- z = "useReducer", D(), N();
13387
- var i = x.H;
13388
- x.H = $o;
12899
+ return ot(e.stateNode);
12900
+ }, le.flushPassiveEffects = el, le.flushSyncFromReconciler = function(e) {
12901
+ var n = ye;
12902
+ ye |= 1;
12903
+ var o = x.T, i = wt();
13389
12904
  try {
13390
- return Qi(e, n, o);
12905
+ if (an(2), x.T = null, e) return e();
13391
12906
  } finally {
13392
- x.H = i;
12907
+ an(i), x.T = o, ye = n, (ye & (Zn | uo)) === Jn && Wa(0);
13393
12908
  }
13394
- }, useRef: function() {
13395
- return z = "useRef", D(), N(), xe().memoizedState;
13396
- }, useState: function() {
13397
- z = "useState", D(), N();
13398
- var e = x.H;
13399
- x.H = $o;
13400
- try {
13401
- return Qi(gr);
13402
- } finally {
13403
- x.H = e;
12909
+ }, le.flushSyncWork = Ls, le.focusWithin = function(e, n) {
12910
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12911
+ for (e = Ef(e), n = hh(e, n), n = Array.from(n), e = 0; e < n.length; ) {
12912
+ var o = n[e++], i = o.tag;
12913
+ if (!Kr(o)) {
12914
+ if ((i === 5 || i === 26 || i === 27) && Ft(o.stateNode)) return true;
12915
+ for (o = o.child; o !== null; ) n.push(o), o = o.sibling;
12916
+ }
12917
+ }
12918
+ return false;
12919
+ }, le.getFindAllNodesFailureDescription = function(e, n) {
12920
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12921
+ var o = 0, i = [];
12922
+ e = [Ef(e), 0];
12923
+ for (var s = 0; s < e.length; ) {
12924
+ var u = e[s++], f = u.tag, p = e[s++], g = n[p];
12925
+ if ((f !== 5 && f !== 26 && f !== 27 || !Kr(u)) && (If(u, g) && (i.push(Sc(g)), p++, p > o && (o = p)), p < n.length)) for (u = u.child; u !== null; ) e.push(u, p), u = u.sibling;
12926
+ }
12927
+ if (o < n.length) {
12928
+ for (e = []; o < n.length; o++) e.push(Sc(n[o]));
12929
+ return `findAllNodes was able to match part of the selector:
12930
+ ` + (i.join(" > ") + `
12931
+
12932
+ No matching component was found for:
12933
+ `) + e.join(" > ");
12934
+ }
12935
+ return null;
12936
+ }, le.getPublicRootInstance = function(e) {
12937
+ if (e = e.current, !e.child) return null;
12938
+ switch (e.child.tag) {
12939
+ case 27:
12940
+ case 5:
12941
+ return ot(e.child.stateNode);
12942
+ default:
12943
+ return e.child.stateNode;
12944
+ }
12945
+ }, le.injectIntoDevTools = function() {
12946
+ var e = { bundleType: 1, version: Jt, rendererPackageName: Zt, currentDispatcherRef: x, reconcilerVersion: "19.2.0" };
12947
+ return jo !== null && (e.rendererConfig = jo), e.overrideHookState = gb, e.overrideHookStateDeletePath = yb, e.overrideHookStateRenamePath = bb, e.overrideProps = vb, e.overridePropsDeletePath = Sb, e.overridePropsRenamePath = kb, e.scheduleUpdate = wb, e.scheduleRetry = Pb, e.setErrorHandler = xb, e.setSuspenseHandler = zb, e.scheduleRefresh = hu, e.scheduleRoot = Fl, e.setRefreshHandler = Ir, e.getCurrentFiber = Ic, Ep(e);
12948
+ }, le.isAlreadyRendering = Ns, le.observeVisibleRects = function(e, n, o, i) {
12949
+ function s() {
12950
+ var S = kc(e, n);
12951
+ u.forEach(function(T) {
12952
+ 0 > S.indexOf(T) && g(T);
12953
+ }), S.forEach(function(T) {
12954
+ 0 > u.indexOf(T) && p(T);
12955
+ });
12956
+ }
12957
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12958
+ var u = kc(e, n);
12959
+ o = zr(u, o, i);
12960
+ var f = o.disconnect, p = o.observe, g = o.unobserve;
12961
+ return bm.push(s), { disconnect: function() {
12962
+ var S = bm.indexOf(s);
12963
+ 0 <= S && bm.splice(S, 1), f();
12964
+ } };
12965
+ }, le.shouldError = function(e) {
12966
+ return pu(e);
12967
+ }, le.shouldSuspend = function(e) {
12968
+ return fu(e);
12969
+ }, le.startHostTransition = function(e, n, o, i) {
12970
+ if (e.tag !== 5) throw Error("Expected the form instance to be a HostComponent. This is a bug in React.");
12971
+ var s = uf(e).queue;
12972
+ Hp(e), nt(e, s, n, Xt, o === null ? Em : function() {
12973
+ x.T === null && console.error("requestFormReset was called outside a transition or action. To fix, move to an action, or wrap with startTransition.");
12974
+ var u = uf(e);
12975
+ return u.next === null && (u = e.alternate.memoizedState), qi(e, u.next.queue, {}, Nt(e)), o(i);
12976
+ });
12977
+ }, le.updateContainer = function(e, n, o, i) {
12978
+ var s = n.current, u = Nt(s);
12979
+ return As(s, u, e, n, o, i), u;
12980
+ }, le.updateContainerSync = Wh, le;
12981
+ }, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true }));
12982
+ })(Mg)), Mg.exports;
12983
+ }
12984
+ var Eb;
12985
+ function n0() {
12986
+ return Eb || (Eb = 1, process.env.NODE_ENV === "production" ? Rm.exports = Kb() : Rm.exports = e0()), Rm.exports;
12987
+ }
12988
+ var t0 = n0();
12989
+ const r0 = Xb(t0);
12990
+
12991
+ const DEFAULT_POINTER_ID = 0;
12992
+ const XR_POINTER_ID_START = 1e3;
12993
+ function getPointerState(internal, pointerId) {
12994
+ let state = internal.pointerMap.get(pointerId);
12995
+ if (!state) {
12996
+ state = {
12997
+ hovered: /* @__PURE__ */ new Map(),
12998
+ captured: /* @__PURE__ */ new Map(),
12999
+ initialClick: [0, 0],
13000
+ initialHits: []
13001
+ };
13002
+ internal.pointerMap.set(pointerId, state);
13003
+ }
13004
+ return state;
13005
+ }
13006
+ function getPointerId(event) {
13007
+ return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
13008
+ }
13009
+ function makeId(event) {
13010
+ return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
13011
+ }
13012
+ function releaseInternalPointerCapture(internal, obj, pointerId) {
13013
+ const pointerState = internal.pointerMap.get(pointerId);
13014
+ if (!pointerState) return;
13015
+ const captureData = pointerState.captured.get(obj);
13016
+ if (captureData) {
13017
+ pointerState.captured.delete(obj);
13018
+ try {
13019
+ captureData.target.releasePointerCapture?.(pointerId);
13020
+ } catch {
13021
+ }
13022
+ }
13023
+ }
13024
+ function swapInteractivity(store, object, newObject) {
13025
+ const { internal } = store.getState();
13026
+ for (let i = 0; i < internal.interaction.length; i++) {
13027
+ if (internal.interaction[i] === object) internal.interaction[i] = newObject;
13028
+ }
13029
+ for (const pointerState of internal.pointerMap.values()) {
13030
+ for (let i = 0; i < pointerState.initialHits.length; i++) {
13031
+ if (pointerState.initialHits[i] === object) pointerState.initialHits[i] = newObject;
13032
+ }
13033
+ pointerState.hovered.forEach((value, key) => {
13034
+ if (value.eventObject === object || value.object === object) {
13035
+ pointerState.hovered.delete(key);
13036
+ const next = {
13037
+ ...value,
13038
+ eventObject: value.eventObject === object ? newObject : value.eventObject,
13039
+ object: value.object === object ? newObject : value.object
13040
+ };
13041
+ pointerState.hovered.set(makeId(next), next);
13042
+ }
13043
+ });
13044
+ const captureData = pointerState.captured.get(object);
13045
+ if (captureData) {
13046
+ pointerState.captured.delete(object);
13047
+ pointerState.captured.set(newObject, {
13048
+ ...captureData,
13049
+ intersection: {
13050
+ ...captureData.intersection,
13051
+ object: captureData.intersection.object === object ? newObject : captureData.intersection.object,
13052
+ eventObject: captureData.intersection.eventObject === object ? newObject : captureData.intersection.eventObject
13404
13053
  }
13405
- }, useDebugValue: function() {
13406
- z = "useDebugValue", D(), N();
13407
- }, useDeferredValue: function(e, n) {
13408
- return z = "useDeferredValue", D(), N(), sf(e, n);
13409
- }, useTransition: function() {
13410
- return z = "useTransition", D(), N(), Ro();
13411
- }, useSyncExternalStore: function(e, n, o) {
13412
- return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
13413
- }, useId: function() {
13414
- return z = "useId", D(), N(), xe().memoizedState;
13415
- }, useFormState: function(e) {
13416
- return z = "useFormState", D(), N(), $t(e);
13417
- }, useActionState: function(e) {
13418
- return z = "useActionState", D(), N(), $t(e);
13419
- }, useOptimistic: function(e, n) {
13420
- return z = "useOptimistic", D(), N(), of(e, n);
13421
- }, useMemoCache: function(e) {
13422
- return D(), Oa(e);
13423
- }, useHostTransitionStatus: ia, useCacheRefresh: function() {
13424
- return z = "useCacheRefresh", N(), xe().memoizedState;
13425
- }, useEffectEvent: function(e) {
13426
- return z = "useEffectEvent", D(), N(), oa(e);
13427
- } };
13428
- var Fy = {}, Hy = /* @__PURE__ */ new Set(), Ay = /* @__PURE__ */ new Set(), jy = /* @__PURE__ */ new Set(), Dy = /* @__PURE__ */ new Set(), Wy = /* @__PURE__ */ new Set(), Uy = /* @__PURE__ */ new Set(), By = /* @__PURE__ */ new Set(), Oy = /* @__PURE__ */ new Set(), My = /* @__PURE__ */ new Set(), Qy = /* @__PURE__ */ new Set();
13429
- Object.freeze(Fy);
13430
- var zg = { enqueueSetState: function(e, n, o) {
13431
- e = e._reactInternals;
13432
- var i = Nt(e), s = zo(i);
13433
- s.payload = n, o != null && (df(o), s.callback = o), n = Mt(e, s, i), n !== null && (ur(i, "this.setState()", e), We(n, e, i), Bi(n, e, i));
13434
- }, enqueueReplaceState: function(e, n, o) {
13435
- e = e._reactInternals;
13436
- var i = Nt(e), s = zo(i);
13437
- s.tag = Cy, s.payload = n, o != null && (df(o), s.callback = o), n = Mt(e, s, i), n !== null && (ur(i, "this.replaceState()", e), We(n, e, i), Bi(n, e, i));
13438
- }, enqueueForceUpdate: function(e, n) {
13439
- e = e._reactInternals;
13440
- var o = Nt(e), i = zo(o);
13441
- i.tag = Ty, n != null && (df(n), i.callback = n), n = Mt(e, i, o), n !== null && (ur(o, "this.forceUpdate()", e), We(n, e, o), Bi(n, e, o));
13442
- } }, bd = null, Cg = null, Tg = Error("This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue."), Cn = false, $y = {}, Vy = {}, qy = {}, Gy = {}, vd = false, Jy = {}, fm = {}, _g = { dehydrated: null, treeContext: null, retryLane: 0, hydrationErrors: null }, Zy = false, Yy = null;
13443
- Yy = /* @__PURE__ */ new Set();
13444
- var Si = false, Tn = false, Rg = false, Xy = typeof WeakSet == "function" ? WeakSet : Set, Gn = null, Sd = null, kd = null, _n = null, nr = false, Vo = null, Wn = false, wd = 8192, Vb = { getCacheForType: function(e) {
13445
- var n = Ee(un), o = n.data.get(e);
13446
- return o === void 0 && (o = e(), n.data.set(e, o)), o;
13447
- }, cacheSignal: function() {
13448
- return Ee(un).controller.signal;
13449
- }, getOwner: function() {
13450
- return di;
13451
- } }, pm = 0, hm = 1, mm = 2, gm = 3, ym = 4;
13452
- if (typeof Symbol == "function" && Symbol.for) {
13453
- var bp = Symbol.for;
13454
- pm = bp("selector.component"), hm = bp("selector.has_pseudo_class"), mm = bp("selector.role"), gm = bp("selector.test_id"), ym = bp("selector.text");
13054
+ });
13055
+ }
13056
+ }
13057
+ unregisterVisibility(store, object);
13058
+ }
13059
+ function removeInteractivity(store, object) {
13060
+ const { internal } = store.getState();
13061
+ internal.interaction = internal.interaction.filter((o) => o !== object);
13062
+ for (const [pointerId, pointerState] of internal.pointerMap) {
13063
+ pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
13064
+ pointerState.hovered.forEach((value, key) => {
13065
+ if (value.eventObject === object || value.object === object) {
13066
+ pointerState.hovered.delete(key);
13455
13067
  }
13456
- var bm = [], qb = typeof WeakMap == "function" ? WeakMap : Map, Jn = 0, Zn = 2, uo = 4, ki = 0, vp = 1, iu = 2, vm = 3, Tl = 4, Sm = 6, Ky = 5, ye = Jn, je = null, se = null, ae = 0, tr = 0, km = 1, lu = 2, Sp = 3, eb = 4, Eg = 5, kp = 6, wm = 7, Ig = 8, su = 9, Le = tr, Er = null, _l = false, Pd = false, Lg = false, Ta = 0, nn = ki, Rl = 0, El = 0, Ng = 0, rr = 0, uu = 0, wp = null, Bt = null, Pm = false, xm = 0, nb = 0, tb = 300, Pp = 1 / 0, Fg = 500, xp = null, gn = null, Il = null, zm = 0, Hg = 1, Ag = 2, rb = 3, Ll = 0, ob = 1, ab = 2, ib = 3, lb = 4, Cm = 5, Rn = 0, Nl = null, xd = null, qo = 0, jg = 0, Dg = -0, Wg = null, sb = null, ub = null, Go = zm, cb = null, Gb = 50, zp = 0, Ug = null, Bg = false, Tm = false, Jb = 50, cu = 0, Cp = null, zd = false, _m = null, db = false, fb = /* @__PURE__ */ new Set(), Zb = {}, co = null, Cd = null, pb = false;
13457
- try {
13458
- var o0 = Object.preventExtensions({});
13459
- } catch {
13460
- pb = true;
13068
+ });
13069
+ if (pointerState.captured.has(object)) {
13070
+ releaseInternalPointerCapture(internal, object, pointerId);
13071
+ }
13072
+ }
13073
+ unregisterVisibility(store, object);
13074
+ }
13075
+ function createEvents(store) {
13076
+ function calculateDistance(event, pointerId) {
13077
+ const { internal } = store.getState();
13078
+ const pointerState = internal.pointerMap.get(pointerId);
13079
+ if (!pointerState) return 0;
13080
+ const [initialX, initialY] = pointerState.initialClick;
13081
+ const dx = event.offsetX - initialX;
13082
+ const dy = event.offsetY - initialY;
13083
+ return Math.round(Math.sqrt(dx * dx + dy * dy));
13084
+ }
13085
+ function filterPointerEvents(objects) {
13086
+ return objects.filter(
13087
+ (obj) => ["Move", "Over", "Enter", "Out", "Leave"].some(
13088
+ (name) => obj.__r3f?.handlers["onPointer" + name]
13089
+ ) || ["OverEnter", "OverLeave", "Over"].some(
13090
+ (name) => obj.__r3f?.handlers["onDrag" + name]
13091
+ ) || obj.__r3f?.handlers.onDrop
13092
+ );
13093
+ }
13094
+ function intersect(event, filter) {
13095
+ const state = store.getState();
13096
+ const duplicates = /* @__PURE__ */ new Set();
13097
+ const intersections = [];
13098
+ const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction;
13099
+ for (let i = 0; i < eventsObjects.length; i++) {
13100
+ const state2 = getRootState(eventsObjects[i]);
13101
+ if (state2) {
13102
+ state2.raycaster.camera = void 0;
13461
13103
  }
13462
- var hb = false, mb = {}, gb = null, yb = null, bb = null, vb = null, Sb = null, kb = null, wb = null, Pb = null, xb = null, zb = null;
13463
- return gb = function(e, n, o, i) {
13464
- n = Yn(e, n), n !== null && (o = _d(n.memoizedState, o, 0, i), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
13465
- }, yb = function(e, n, o) {
13466
- n = Yn(e, n), n !== null && (o = du(n.memoizedState, o, 0), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
13467
- }, bb = function(e, n, o, i) {
13468
- n = Yn(e, n), n !== null && (o = F(n.memoizedState, o, i), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
13469
- }, vb = function(e, n, o) {
13470
- e.pendingProps = _d(e.memoizedProps, n, 0, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
13471
- }, Sb = function(e, n) {
13472
- e.pendingProps = du(e.memoizedProps, n, 0), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
13473
- }, kb = function(e, n, o) {
13474
- e.pendingProps = F(e.memoizedProps, n, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
13475
- }, wb = function(e) {
13476
- var n = On(e, 2);
13477
- n !== null && We(n, e, 2);
13478
- }, Pb = function(e) {
13479
- var n = ut(), o = On(e, n);
13480
- o !== null && We(o, e, n);
13481
- }, xb = function(e) {
13482
- pu = e;
13483
- }, zb = function(e) {
13484
- fu = e;
13485
- }, le.attemptContinuousHydration = function(e) {
13486
- if (e.tag === 13 || e.tag === 31) {
13487
- var n = On(e, 67108864);
13488
- n !== null && We(n, e, 67108864), rl(e, 67108864);
13104
+ }
13105
+ if (!state.previousRoot) {
13106
+ state.events.compute?.(event, state);
13107
+ }
13108
+ function handleRaycast(obj) {
13109
+ const state2 = getRootState(obj);
13110
+ if (!state2 || !state2.events.enabled || state2.raycaster.camera === null) return [];
13111
+ if (state2.raycaster.camera === void 0) {
13112
+ state2.events.compute?.(event, state2, state2.previousRoot?.getState());
13113
+ if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
13114
+ }
13115
+ if (!state2.raycaster.camera) return [];
13116
+ obj.updateWorldMatrix(true, true);
13117
+ return state2.raycaster.intersectObject(obj, true);
13118
+ }
13119
+ let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
13120
+ const aInteractivePriority = a.object.userData?.interactivePriority;
13121
+ const bInteractivePriority = b.object.userData?.interactivePriority;
13122
+ if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
13123
+ if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
13124
+ if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
13125
+ if (aInteractivePriority !== bInteractivePriority) {
13126
+ return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
13489
13127
  }
13490
- }, le.attemptHydrationAtCurrentPriority = function(e) {
13491
- if (e.tag === 13 || e.tag === 31) {
13492
- var n = Nt(e);
13493
- n = Xo(n);
13494
- var o = On(e, n);
13495
- o !== null && We(o, e, n), rl(e, n);
13128
+ }
13129
+ const aState = getRootState(a.object);
13130
+ const bState = getRootState(b.object);
13131
+ const aPriority = aState?.events?.priority ?? 1;
13132
+ const bPriority = bState?.events?.priority ?? 1;
13133
+ return bPriority - aPriority || a.distance - b.distance;
13134
+ }).filter((item) => {
13135
+ const id = makeId(item);
13136
+ if (duplicates.has(id)) return false;
13137
+ duplicates.add(id);
13138
+ return true;
13139
+ });
13140
+ if (state.events.filter) hits = state.events.filter(hits, state);
13141
+ for (const hit of hits) {
13142
+ let eventObject = hit.object;
13143
+ while (eventObject) {
13144
+ if (eventObject.__r3f?.eventCount) {
13145
+ intersections.push({ ...hit, eventObject });
13496
13146
  }
13497
- }, le.attemptSynchronousHydration = function(e) {
13498
- switch (e.tag) {
13499
- case 3:
13500
- if (e = e.stateNode, e.current.memoizedState.isDehydrated) {
13501
- var n = _t(e.pendingLanes);
13502
- if (n !== 0) {
13503
- for (e.pendingLanes |= 2, e.entangledLanes |= 2; n; ) {
13504
- var o = 1 << 31 - vn(n);
13505
- e.entanglements[1] |= o, n &= ~o;
13147
+ eventObject = eventObject.parent;
13148
+ }
13149
+ }
13150
+ if ("pointerId" in event) {
13151
+ const pointerId = event.pointerId;
13152
+ const pointerState = state.internal.pointerMap.get(pointerId);
13153
+ if (pointerState?.captured.size) {
13154
+ for (const captureData of pointerState.captured.values()) {
13155
+ if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
13156
+ }
13157
+ }
13158
+ }
13159
+ return intersections;
13160
+ }
13161
+ function handleIntersects(intersections, event, delta, callback) {
13162
+ if (intersections.length) {
13163
+ const localState = { stopped: false };
13164
+ for (const hit of intersections) {
13165
+ const state = getRootState(hit.object);
13166
+ if (state) {
13167
+ const { raycaster, pointer, camera, internal } = state;
13168
+ const unprojectedPoint = new webgpu.Vector3(pointer.x, pointer.y, 0).unproject(camera);
13169
+ const hasPointerCapture = (id) => {
13170
+ const pointerState = internal.pointerMap.get(id);
13171
+ return pointerState?.captured.has(hit.eventObject) ?? false;
13172
+ };
13173
+ const setPointerCapture = (id) => {
13174
+ const captureData = { intersection: hit, target: event.target };
13175
+ const pointerState = getPointerState(internal, id);
13176
+ pointerState.captured.set(hit.eventObject, captureData);
13177
+ event.target.setPointerCapture(id);
13178
+ };
13179
+ const releasePointerCapture = (id) => {
13180
+ releaseInternalPointerCapture(internal, hit.eventObject, id);
13181
+ };
13182
+ const extractEventProps = {};
13183
+ for (const prop in event) {
13184
+ const property = event[prop];
13185
+ if (typeof property !== "function") extractEventProps[prop] = property;
13186
+ }
13187
+ const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
13188
+ const raycastEvent = {
13189
+ ...hit,
13190
+ ...extractEventProps,
13191
+ pointer,
13192
+ intersections,
13193
+ stopped: localState.stopped,
13194
+ delta,
13195
+ unprojectedPoint,
13196
+ ray: raycaster.ray,
13197
+ camera,
13198
+ pointerId: eventPointerId,
13199
+ // Hijack stopPropagation, which just sets a flag
13200
+ stopPropagation() {
13201
+ const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
13202
+ if (
13203
+ // ...if this pointer hasn't been captured
13204
+ !pointerState?.captured.size || // ... or if the hit object is capturing the pointer
13205
+ pointerState.captured.has(hit.eventObject)
13206
+ ) {
13207
+ raycastEvent.stopped = localState.stopped = true;
13208
+ if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
13209
+ const higher = intersections.slice(0, intersections.indexOf(hit));
13210
+ cancelPointer([...higher, hit], eventPointerId);
13506
13211
  }
13507
- Kn(e), (ye & (Zn | uo)) === Jn && (Pp = me() + Fg, Wa(0));
13508
13212
  }
13509
- }
13510
- break;
13511
- case 31:
13512
- case 13:
13513
- n = On(e, 2), n !== null && We(n, e, 2), Ls(), rl(e, 2);
13213
+ },
13214
+ // there should be a distinction between target and currentTarget
13215
+ target: { hasPointerCapture, setPointerCapture, releasePointerCapture },
13216
+ currentTarget: { hasPointerCapture, setPointerCapture, releasePointerCapture },
13217
+ nativeEvent: event
13218
+ };
13219
+ callback(raycastEvent);
13220
+ if (localState.stopped === true) break;
13514
13221
  }
13515
- }, le.batchedUpdates = function(e, n) {
13516
- return e(n);
13517
- }, le.createComponentSelector = function(e) {
13518
- return { $$typeof: pm, value: e };
13519
- }, le.createContainer = function(e, n, o, i, s, u, f, p, g, S) {
13520
- return Ka(e, n, false, null, o, i, u, null, f, p, g, S);
13521
- }, le.createHasPseudoClassSelector = function(e) {
13522
- return { $$typeof: hm, value: e };
13523
- }, le.createHydrationContainer = function(e, n, o, i, s, u, f, p, g, S, T, _, I, O) {
13524
- return e = Ka(o, i, true, e, s, u, p, O, g, S, T, _), e.context = Dh(null), o = e.current, i = Nt(o), i = Xo(i), s = zo(i), s.callback = n ?? null, Mt(o, s, i), ur(i, "hydrateRoot()", null), n = i, e.current.lanes = n, Ci(e, n), Kn(e), e;
13525
- }, le.createPortal = function(e, n, o) {
13526
- var i = 3 < arguments.length && arguments[3] !== void 0 ? arguments[3] : null;
13527
- try {
13528
- vt(i);
13529
- var s = false;
13530
- } catch {
13531
- s = true;
13222
+ }
13223
+ }
13224
+ return intersections;
13225
+ }
13226
+ function cancelPointer(intersections, pointerId) {
13227
+ const { internal } = store.getState();
13228
+ const pid = pointerId ?? DEFAULT_POINTER_ID;
13229
+ const pointerState = internal.pointerMap.get(pid);
13230
+ if (!pointerState) return;
13231
+ for (const [hoveredId, hoveredObj] of pointerState.hovered) {
13232
+ if (!intersections.length || !intersections.find(
13233
+ (hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
13234
+ )) {
13235
+ const eventObject = hoveredObj.eventObject;
13236
+ const instance = eventObject.__r3f;
13237
+ pointerState.hovered.delete(hoveredId);
13238
+ if (instance?.eventCount) {
13239
+ const handlers = instance.handlers;
13240
+ const data = { ...hoveredObj, intersections };
13241
+ handlers.onPointerOut?.(data);
13242
+ handlers.onPointerLeave?.(data);
13243
+ handlers.onDragOverLeave?.(data);
13532
13244
  }
13533
- return s && (console.error("The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", typeof Symbol == "function" && Symbol.toStringTag && i[Symbol.toStringTag] || i.constructor.name || "Object"), vt(i)), { $$typeof: Ao, key: i == null ? null : "" + i, children: e, containerInfo: n, implementation: o };
13534
- }, le.createRoleSelector = function(e) {
13535
- return { $$typeof: mm, value: e };
13536
- }, le.createTestNameSelector = function(e) {
13537
- return { $$typeof: gm, value: e };
13538
- }, le.createTextSelector = function(e) {
13539
- return { $$typeof: ym, value: e };
13540
- }, le.defaultOnCaughtError = function(e) {
13541
- var n = bd ? "The above error occurred in the <" + bd + "> component." : "The above error occurred in one of your React components.", o = "React will try to recreate this component tree from scratch using the error boundary you provided, " + ((Cg || "Anonymous") + ".");
13542
- typeof e == "object" && e !== null && typeof e.environmentName == "string" ? ri("error", [`%o
13543
-
13544
- %s
13545
-
13546
- %s
13547
- `, e, n, o], e.environmentName)() : console.error(`%o
13548
-
13549
- %s
13550
-
13551
- %s
13552
- `, e, n, o);
13553
- }, le.defaultOnRecoverableError = function(e) {
13554
- qg(e);
13555
- }, le.defaultOnUncaughtError = function(e) {
13556
- qg(e), console.warn(`%s
13557
-
13558
- %s
13559
- `, bd ? "An error occurred in the <" + bd + "> component." : "An error occurred in one of your React components.", `Consider adding an error boundary to your tree to customize error handling behavior.
13560
- Visit https://react.dev/link/error-boundaries to learn more about error boundaries.`);
13561
- }, le.deferredUpdates = function(e) {
13562
- var n = x.T, o = wt();
13563
- try {
13564
- return an(32), x.T = null, e();
13565
- } finally {
13566
- an(o), x.T = n;
13245
+ }
13246
+ }
13247
+ }
13248
+ function pointerMissed(event, objects) {
13249
+ for (let i = 0; i < objects.length; i++) {
13250
+ const instance = objects[i].__r3f;
13251
+ instance?.handlers.onPointerMissed?.(event);
13252
+ }
13253
+ }
13254
+ function dragOverMissed(event, objects) {
13255
+ for (let i = 0; i < objects.length; i++) {
13256
+ const instance = objects[i].__r3f;
13257
+ instance?.handlers.onDragOverMissed?.(event);
13258
+ }
13259
+ }
13260
+ function dropMissed(event, objects) {
13261
+ for (let i = 0; i < objects.length; i++) {
13262
+ const instance = objects[i].__r3f;
13263
+ instance?.handlers.onDropMissed?.(event);
13264
+ }
13265
+ }
13266
+ function cleanupPointer(pointerId) {
13267
+ const { internal } = store.getState();
13268
+ const pointerState = internal.pointerMap.get(pointerId);
13269
+ if (pointerState) {
13270
+ for (const [, hoveredObj] of pointerState.hovered) {
13271
+ const eventObject = hoveredObj.eventObject;
13272
+ const instance = eventObject.__r3f;
13273
+ if (instance?.eventCount) {
13274
+ const handlers = instance.handlers;
13275
+ const data = { ...hoveredObj, intersections: [] };
13276
+ handlers.onPointerOut?.(data);
13277
+ handlers.onPointerLeave?.(data);
13567
13278
  }
13568
- }, le.discreteUpdates = function(e, n, o, i, s) {
13569
- var u = x.T, f = wt();
13570
- try {
13571
- return an(2), x.T = null, e(n, o, i, s);
13572
- } finally {
13573
- an(f), x.T = u, ye === Jn && (Pp = me() + Fg);
13279
+ }
13280
+ internal.pointerMap.delete(pointerId);
13281
+ }
13282
+ internal.pointerDirty.delete(pointerId);
13283
+ }
13284
+ function processDeferredPointer(event, pointerId) {
13285
+ const state = store.getState();
13286
+ const { internal } = state;
13287
+ if (!state.events.enabled) return;
13288
+ const filter = filterPointerEvents;
13289
+ const hits = intersect(event, filter);
13290
+ cancelPointer(hits, pointerId);
13291
+ function onIntersect(data) {
13292
+ const eventObject = data.eventObject;
13293
+ const instance = eventObject.__r3f;
13294
+ if (!instance?.eventCount) return;
13295
+ const handlers = instance.handlers;
13296
+ if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
13297
+ const id = makeId(data);
13298
+ const pointerState = getPointerState(internal, pointerId);
13299
+ const hoveredItem = pointerState.hovered.get(id);
13300
+ if (!hoveredItem) {
13301
+ pointerState.hovered.set(id, data);
13302
+ handlers.onPointerOver?.(data);
13303
+ handlers.onPointerEnter?.(data);
13304
+ } else if (hoveredItem.stopped) {
13305
+ data.stopPropagation();
13574
13306
  }
13575
- }, le.findAllNodes = kc, le.findBoundingRects = function(e, n) {
13576
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13577
- n = kc(e, n), e = [];
13578
- for (var o = 0; o < n.length; o++) e.push(ma(n[o]));
13579
- for (n = e.length - 1; 0 < n; n--) {
13580
- o = e[n];
13581
- for (var i = o.x, s = i + o.width, u = o.y, f = u + o.height, p = n - 1; 0 <= p; p--) if (n !== p) {
13582
- var g = e[p], S = g.x, T = S + g.width, _ = g.y, I = _ + g.height;
13583
- if (i >= S && u >= _ && s <= T && f <= I) {
13584
- e.splice(n, 1);
13585
- break;
13586
- } else if (i !== S || o.width !== g.width || I < u || _ > f) {
13587
- if (!(u !== _ || o.height !== g.height || T < i || S > s)) {
13588
- S > i && (g.width += S - i, g.x = i), T < s && (g.width = s - S), e.splice(n, 1);
13589
- break;
13307
+ }
13308
+ handlers.onPointerMove?.(data);
13309
+ }
13310
+ handleIntersects(hits, event, 0, onIntersect);
13311
+ }
13312
+ function handlePointer(name) {
13313
+ switch (name) {
13314
+ case "onPointerLeave":
13315
+ case "onDragLeave":
13316
+ return () => cancelPointer([]);
13317
+ // Global cancel of these events
13318
+ case "onPointerCancel":
13319
+ return (event) => {
13320
+ const pointerId = getPointerId(event);
13321
+ cleanupPointer(pointerId);
13322
+ };
13323
+ case "onLostPointerCapture":
13324
+ return (event) => {
13325
+ const { internal } = store.getState();
13326
+ const pointerId = getPointerId(event);
13327
+ const pointerState = internal.pointerMap.get(pointerId);
13328
+ if (pointerState?.captured.size) {
13329
+ requestAnimationFrame(() => {
13330
+ const pointerState2 = internal.pointerMap.get(pointerId);
13331
+ if (pointerState2?.captured.size) {
13332
+ pointerState2.captured.clear();
13590
13333
  }
13591
- } else {
13592
- _ > u && (g.height += _ - u, g.y = u), I < f && (g.height = f - _), e.splice(n, 1);
13593
- break;
13334
+ cancelPointer([], pointerId);
13335
+ });
13336
+ }
13337
+ };
13338
+ }
13339
+ return function handleEvent(event) {
13340
+ const state = store.getState();
13341
+ const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
13342
+ const pointerId = getPointerId(event);
13343
+ internal.lastEvent.current = event;
13344
+ if (!events.enabled) return;
13345
+ const isPointerMove = name === "onPointerMove";
13346
+ const isDragOver = name === "onDragOver";
13347
+ const isDrop = name === "onDrop";
13348
+ const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
13349
+ const isPointerDown = name === "onPointerDown";
13350
+ const isPointerUp = name === "onPointerUp";
13351
+ const isWheel = name === "onWheel";
13352
+ const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
13353
+ if (isPointerMove && canDeferRaycasts) {
13354
+ events.compute?.(event, state);
13355
+ internal.pointerDirty.set(pointerId, event);
13356
+ return;
13357
+ }
13358
+ if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
13359
+ events.compute?.(event, state);
13360
+ internal.pointerDirty.set(pointerId, event);
13361
+ return;
13362
+ }
13363
+ if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
13364
+ const deferredEvent = internal.pointerDirty.get(pointerId);
13365
+ internal.pointerDirty.delete(pointerId);
13366
+ processDeferredPointer(deferredEvent, pointerId);
13367
+ }
13368
+ const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
13369
+ const hits = intersect(event, filter);
13370
+ const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
13371
+ if (isPointerDown) {
13372
+ const pointerState2 = getPointerState(internal, pointerId);
13373
+ pointerState2.initialClick = [event.offsetX, event.offsetY];
13374
+ pointerState2.initialHits = hits.map((hit) => hit.eventObject);
13375
+ }
13376
+ const pointerState = internal.pointerMap.get(pointerId);
13377
+ const initialHits = pointerState?.initialHits ?? [];
13378
+ if (isClickEvent && !hits.length) {
13379
+ if (delta <= 2) {
13380
+ pointerMissed(event, internal.interaction);
13381
+ if (onPointerMissed) onPointerMissed(event);
13382
+ }
13383
+ }
13384
+ if (isDragOver && !hits.length) {
13385
+ dragOverMissed(event, internal.interaction);
13386
+ if (onDragOverMissed) onDragOverMissed(event);
13387
+ }
13388
+ if (isDrop && !hits.length) {
13389
+ dropMissed(event, internal.interaction);
13390
+ if (onDropMissed) onDropMissed(event);
13391
+ }
13392
+ if (isPointerMove || isDragOver) {
13393
+ cancelPointer(hits, pointerId);
13394
+ }
13395
+ function onIntersect(data) {
13396
+ const eventObject = data.eventObject;
13397
+ const instance = eventObject.__r3f;
13398
+ if (!instance?.eventCount) return;
13399
+ const handlers = instance.handlers;
13400
+ if (isPointerMove) {
13401
+ if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
13402
+ const id = makeId(data);
13403
+ const pointerState2 = getPointerState(internal, pointerId);
13404
+ const hoveredItem = pointerState2.hovered.get(id);
13405
+ if (!hoveredItem) {
13406
+ pointerState2.hovered.set(id, data);
13407
+ handlers.onPointerOver?.(data);
13408
+ handlers.onPointerEnter?.(data);
13409
+ } else if (hoveredItem.stopped) {
13410
+ data.stopPropagation();
13594
13411
  }
13595
13412
  }
13596
- }
13597
- return e;
13598
- }, le.findHostInstance = function(e) {
13599
- var n = e._reactInternals;
13600
- if (n === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
13601
- return e = mu(n), e === null ? null : ot(e.stateNode);
13602
- }, le.findHostInstanceWithNoPortals = function(e) {
13603
- return e = Ed(e), e = e !== null ? _p(e) : null, e === null ? null : ot(e.stateNode);
13604
- }, le.findHostInstanceWithWarning = function(e, n) {
13605
- var o = e._reactInternals;
13606
- if (o === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
13607
- if (e = mu(o), e === null) return null;
13608
- if (e.mode & 8) {
13609
- var i = G(o) || "Component";
13610
- mb[i] || (mb[i] = true, B(e, function() {
13611
- o.mode & 8 ? console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i) : console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i);
13612
- }));
13613
- }
13614
- return ot(e.stateNode);
13615
- }, le.flushPassiveEffects = el, le.flushSyncFromReconciler = function(e) {
13616
- var n = ye;
13617
- ye |= 1;
13618
- var o = x.T, i = wt();
13619
- try {
13620
- if (an(2), x.T = null, e) return e();
13621
- } finally {
13622
- an(i), x.T = o, ye = n, (ye & (Zn | uo)) === Jn && Wa(0);
13623
- }
13624
- }, le.flushSyncWork = Ls, le.focusWithin = function(e, n) {
13625
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13626
- for (e = Ef(e), n = hh(e, n), n = Array.from(n), e = 0; e < n.length; ) {
13627
- var o = n[e++], i = o.tag;
13628
- if (!Kr(o)) {
13629
- if ((i === 5 || i === 26 || i === 27) && Ft(o.stateNode)) return true;
13630
- for (o = o.child; o !== null; ) n.push(o), o = o.sibling;
13413
+ handlers.onPointerMove?.(data);
13414
+ } else if (isDragOver) {
13415
+ const id = makeId(data);
13416
+ const pointerState2 = getPointerState(internal, pointerId);
13417
+ const hoveredItem = pointerState2.hovered.get(id);
13418
+ if (!hoveredItem) {
13419
+ pointerState2.hovered.set(id, data);
13420
+ handlers.onDragOverEnter?.(data);
13421
+ } else if (hoveredItem.stopped) {
13422
+ data.stopPropagation();
13423
+ }
13424
+ handlers.onDragOver?.(data);
13425
+ } else if (isDrop) {
13426
+ handlers.onDrop?.(data);
13427
+ } else {
13428
+ const handler = handlers[name];
13429
+ if (handler) {
13430
+ if (!isClickEvent || initialHits.includes(eventObject)) {
13431
+ pointerMissed(
13432
+ event,
13433
+ internal.interaction.filter((object) => !initialHits.includes(object))
13434
+ );
13435
+ handler(data);
13436
+ }
13437
+ } else {
13438
+ if (isClickEvent && initialHits.includes(eventObject)) {
13439
+ pointerMissed(
13440
+ event,
13441
+ internal.interaction.filter((object) => !initialHits.includes(object))
13442
+ );
13443
+ }
13631
13444
  }
13632
13445
  }
13633
- return false;
13634
- }, le.getFindAllNodesFailureDescription = function(e, n) {
13635
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13636
- var o = 0, i = [];
13637
- e = [Ef(e), 0];
13638
- for (var s = 0; s < e.length; ) {
13639
- var u = e[s++], f = u.tag, p = e[s++], g = n[p];
13640
- if ((f !== 5 && f !== 26 && f !== 27 || !Kr(u)) && (If(u, g) && (i.push(Sc(g)), p++, p > o && (o = p)), p < n.length)) for (u = u.child; u !== null; ) e.push(u, p), u = u.sibling;
13446
+ }
13447
+ handleIntersects(hits, event, delta, onIntersect);
13448
+ };
13449
+ }
13450
+ function flushDeferredPointers() {
13451
+ const { internal, events } = store.getState();
13452
+ if (!events.frameTimedRaycasts) return;
13453
+ for (const [pointerId, event] of internal.pointerDirty) {
13454
+ processDeferredPointer(event, pointerId);
13455
+ }
13456
+ internal.pointerDirty.clear();
13457
+ }
13458
+ return { handlePointer, flushDeferredPointers, processDeferredPointer };
13459
+ }
13460
+ const DOM_EVENTS = {
13461
+ onClick: ["click", false],
13462
+ onContextMenu: ["contextmenu", false],
13463
+ onDoubleClick: ["dblclick", false],
13464
+ onDragEnter: ["dragenter", false],
13465
+ onDragLeave: ["dragleave", false],
13466
+ onDragOver: ["dragover", false],
13467
+ onDrop: ["drop", false],
13468
+ onWheel: ["wheel", true],
13469
+ onPointerDown: ["pointerdown", true],
13470
+ onPointerUp: ["pointerup", true],
13471
+ onPointerLeave: ["pointerleave", true],
13472
+ onPointerMove: ["pointermove", true],
13473
+ onPointerCancel: ["pointercancel", true],
13474
+ onLostPointerCapture: ["lostpointercapture", true]
13475
+ };
13476
+ function createPointerEvents(store) {
13477
+ const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
13478
+ let nextXRPointerId = XR_POINTER_ID_START;
13479
+ const xrPointers = /* @__PURE__ */ new Map();
13480
+ return {
13481
+ priority: 1,
13482
+ enabled: true,
13483
+ frameTimedRaycasts: true,
13484
+ alwaysFireOnScroll: true,
13485
+ updateOnFrame: false,
13486
+ compute(event, state) {
13487
+ state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
13488
+ state.raycaster.setFromCamera(state.pointer, state.camera);
13489
+ },
13490
+ connected: void 0,
13491
+ handlers: Object.keys(DOM_EVENTS).reduce(
13492
+ (acc, key) => ({ ...acc, [key]: handlePointer(key) }),
13493
+ {}
13494
+ ),
13495
+ update: (pointerId) => {
13496
+ const { events, internal } = store.getState();
13497
+ if (!events.handlers) return;
13498
+ if (pointerId !== void 0) {
13499
+ const event = internal.pointerDirty.get(pointerId);
13500
+ if (event) {
13501
+ internal.pointerDirty.delete(pointerId);
13502
+ processDeferredPointer(event, pointerId);
13503
+ } else if (internal.lastEvent?.current) {
13504
+ processDeferredPointer(internal.lastEvent.current, pointerId);
13641
13505
  }
13642
- if (o < n.length) {
13643
- for (e = []; o < n.length; o++) e.push(Sc(n[o]));
13644
- return `findAllNodes was able to match part of the selector:
13645
- ` + (i.join(" > ") + `
13646
-
13647
- No matching component was found for:
13648
- `) + e.join(" > ");
13506
+ } else {
13507
+ flushDeferredPointers();
13508
+ if (internal.lastEvent?.current) {
13509
+ events.handlers.onPointerMove(internal.lastEvent.current);
13649
13510
  }
13650
- return null;
13651
- }, le.getPublicRootInstance = function(e) {
13652
- if (e = e.current, !e.child) return null;
13653
- switch (e.child.tag) {
13654
- case 27:
13655
- case 5:
13656
- return ot(e.child.stateNode);
13657
- default:
13658
- return e.child.stateNode;
13511
+ }
13512
+ },
13513
+ flush: () => {
13514
+ const { events, internal } = store.getState();
13515
+ flushDeferredPointers();
13516
+ if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
13517
+ events.handlers.onPointerMove(internal.lastEvent.current);
13518
+ }
13519
+ },
13520
+ connect: (target) => {
13521
+ if (!target) return;
13522
+ const { set, events } = store.getState();
13523
+ events.disconnect?.();
13524
+ set((state) => ({ events: { ...state.events, connected: target } }));
13525
+ if (events.handlers) {
13526
+ for (const name in events.handlers) {
13527
+ const event = events.handlers[name];
13528
+ const [eventName, passive] = DOM_EVENTS[name];
13529
+ target.addEventListener(eventName, event, { passive });
13659
13530
  }
13660
- }, le.injectIntoDevTools = function() {
13661
- var e = { bundleType: 1, version: Jt, rendererPackageName: Zt, currentDispatcherRef: x, reconcilerVersion: "19.2.0" };
13662
- return jo !== null && (e.rendererConfig = jo), e.overrideHookState = gb, e.overrideHookStateDeletePath = yb, e.overrideHookStateRenamePath = bb, e.overrideProps = vb, e.overridePropsDeletePath = Sb, e.overridePropsRenamePath = kb, e.scheduleUpdate = wb, e.scheduleRetry = Pb, e.setErrorHandler = xb, e.setSuspenseHandler = zb, e.scheduleRefresh = hu, e.scheduleRoot = Fl, e.setRefreshHandler = Ir, e.getCurrentFiber = Ic, Ep(e);
13663
- }, le.isAlreadyRendering = Ns, le.observeVisibleRects = function(e, n, o, i) {
13664
- function s() {
13665
- var S = kc(e, n);
13666
- u.forEach(function(T) {
13667
- 0 > S.indexOf(T) && g(T);
13668
- }), S.forEach(function(T) {
13669
- 0 > u.indexOf(T) && p(T);
13670
- });
13531
+ }
13532
+ },
13533
+ disconnect: () => {
13534
+ const { set, events } = store.getState();
13535
+ if (events.connected) {
13536
+ if (events.handlers) {
13537
+ for (const name in events.handlers) {
13538
+ const event = events.handlers[name];
13539
+ const [eventName] = DOM_EVENTS[name];
13540
+ events.connected.removeEventListener(eventName, event);
13541
+ }
13671
13542
  }
13672
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13673
- var u = kc(e, n);
13674
- o = zr(u, o, i);
13675
- var f = o.disconnect, p = o.observe, g = o.unobserve;
13676
- return bm.push(s), { disconnect: function() {
13677
- var S = bm.indexOf(s);
13678
- 0 <= S && bm.splice(S, 1), f();
13679
- } };
13680
- }, le.shouldError = function(e) {
13681
- return pu(e);
13682
- }, le.shouldSuspend = function(e) {
13683
- return fu(e);
13684
- }, le.startHostTransition = function(e, n, o, i) {
13685
- if (e.tag !== 5) throw Error("Expected the form instance to be a HostComponent. This is a bug in React.");
13686
- var s = uf(e).queue;
13687
- Hp(e), nt(e, s, n, Xt, o === null ? Em : function() {
13688
- x.T === null && console.error("requestFormReset was called outside a transition or action. To fix, move to an action, or wrap with startTransition.");
13689
- var u = uf(e);
13690
- return u.next === null && (u = e.alternate.memoizedState), qi(e, u.next.queue, {}, Nt(e)), o(i);
13691
- });
13692
- }, le.updateContainer = function(e, n, o, i) {
13693
- var s = n.current, u = Nt(s);
13694
- return As(s, u, e, n, o, i), u;
13695
- }, le.updateContainerSync = Wh, le;
13696
- }, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true }));
13697
- })(Mg)), Mg.exports;
13698
- }
13699
- var Eb;
13700
- function n0() {
13701
- return Eb || (Eb = 1, process.env.NODE_ENV === "production" ? Rm.exports = Kb() : Rm.exports = e0()), Rm.exports;
13543
+ set((state) => ({ events: { ...state.events, connected: void 0 } }));
13544
+ }
13545
+ },
13546
+ // PREVIEW (A8): the XR pointer registration API may change before stable.
13547
+ registerPointer: (config) => {
13548
+ const pointerId = nextXRPointerId++;
13549
+ xrPointers.set(pointerId, config);
13550
+ const { internal } = store.getState();
13551
+ getPointerState(internal, pointerId);
13552
+ return pointerId;
13553
+ },
13554
+ unregisterPointer: (pointerId) => {
13555
+ xrPointers.delete(pointerId);
13556
+ const { internal } = store.getState();
13557
+ const pointerState = internal.pointerMap.get(pointerId);
13558
+ if (pointerState) {
13559
+ for (const [, hoveredObj] of pointerState.hovered) {
13560
+ const eventObject = hoveredObj.eventObject;
13561
+ const instance = eventObject.__r3f;
13562
+ if (instance?.eventCount) {
13563
+ const handlers = instance.handlers;
13564
+ const data = { ...hoveredObj, intersections: [] };
13565
+ handlers.onPointerOut?.(data);
13566
+ handlers.onPointerLeave?.(data);
13567
+ }
13568
+ }
13569
+ internal.pointerMap.delete(pointerId);
13570
+ }
13571
+ internal.pointerDirty.delete(pointerId);
13572
+ }
13573
+ };
13702
13574
  }
13703
- var t0 = n0();
13704
- const r0 = Xb(t0);
13705
-
13706
- const t = 1, o = 8, r = 32, e = 2;
13707
13575
 
13708
13576
  function createReconciler(config) {
13709
13577
  const reconciler2 = r0(config);
@@ -13723,7 +13591,10 @@ function extend(objects) {
13723
13591
  catalogue[Component] = objects;
13724
13592
  return Component;
13725
13593
  } else {
13726
- Object.assign(catalogue, objects);
13594
+ for (const name in objects) {
13595
+ const object = objects[name];
13596
+ if (isConstructor(object)) catalogue[name] = object;
13597
+ }
13727
13598
  }
13728
13599
  }
13729
13600
  function validateInstance(type, props) {
@@ -13868,7 +13739,15 @@ function setFiberRef(fiber, publicInstance) {
13868
13739
  }
13869
13740
  }
13870
13741
  const reconstructed = [];
13871
- function swapInstances() {
13742
+ function flushReconstructedInstances() {
13743
+ if (reconstructed.length === 0) return;
13744
+ try {
13745
+ swapReconstructedInstances();
13746
+ } finally {
13747
+ reconstructed.length = 0;
13748
+ }
13749
+ }
13750
+ function swapReconstructedInstances() {
13872
13751
  for (const [instance] of reconstructed) {
13873
13752
  const parent = instance.parent;
13874
13753
  if (parent) {
@@ -13886,7 +13765,9 @@ function swapInstances() {
13886
13765
  }
13887
13766
  }
13888
13767
  if (instance.isHidden) unhideInstance(instance);
13889
- if (isObject3D(instance.object)) removeInteractivity(findInitialRoot(instance), instance.object);
13768
+ if (isObject3D(instance.object) && !instance.parent) {
13769
+ removeInteractivity(findInitialRoot(instance), instance.object);
13770
+ }
13890
13771
  if (instance.object.__r3f) delete instance.object.__r3f;
13891
13772
  if (instance.type !== "primitive") disposeOnIdle(instance.object);
13892
13773
  }
@@ -13895,9 +13776,13 @@ function swapInstances() {
13895
13776
  const parent = instance.parent;
13896
13777
  if (parent) {
13897
13778
  const target = catalogue[toPascalCase(instance.type)];
13779
+ const prevObject = instance.object;
13898
13780
  instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
13899
13781
  instance.object.__r3f = instance;
13900
13782
  setFiberRef(fiber, instance.object);
13783
+ if (isObject3D(prevObject) && isObject3D(instance.object)) {
13784
+ swapInteractivity(findInitialRoot(instance), prevObject, instance.object);
13785
+ }
13901
13786
  delete instance.appliedOnce;
13902
13787
  instance.eventCount = 0;
13903
13788
  instance.handlers = {};
@@ -13917,14 +13802,114 @@ function swapInstances() {
13917
13802
  invalidateInstance(instance);
13918
13803
  }
13919
13804
  }
13920
- reconstructed.length = 0;
13921
13805
  }
13922
13806
  const handleTextInstance = () => {
13923
13807
  };
13924
13808
  const NO_CONTEXT = {};
13925
13809
  let currentUpdatePriority = NoEventPriority;
13926
- const NoFlags = 0;
13927
- const Update = 4;
13810
+ function getEventPriority(type) {
13811
+ switch (type) {
13812
+ case "beforetoggle":
13813
+ case "cancel":
13814
+ case "click":
13815
+ case "close":
13816
+ case "contextmenu":
13817
+ case "copy":
13818
+ case "cut":
13819
+ case "auxclick":
13820
+ case "dblclick":
13821
+ case "dragend":
13822
+ case "dragstart":
13823
+ case "drop":
13824
+ case "focusin":
13825
+ case "focusout":
13826
+ case "input":
13827
+ case "invalid":
13828
+ case "keydown":
13829
+ case "keypress":
13830
+ case "keyup":
13831
+ case "mousedown":
13832
+ case "mouseup":
13833
+ case "paste":
13834
+ case "pause":
13835
+ case "play":
13836
+ case "pointercancel":
13837
+ case "pointerdown":
13838
+ case "pointerup":
13839
+ case "ratechange":
13840
+ case "reset":
13841
+ case "resize":
13842
+ case "seeked":
13843
+ case "submit":
13844
+ case "touchcancel":
13845
+ case "touchend":
13846
+ case "touchstart":
13847
+ case "volumechange":
13848
+ case "change":
13849
+ case "selectionchange":
13850
+ case "compositionstart":
13851
+ case "compositionend":
13852
+ case "compositionupdate":
13853
+ case "beforeinput":
13854
+ case "blur":
13855
+ case "fullscreenchange":
13856
+ case "focus":
13857
+ case "hashchange":
13858
+ case "popstate":
13859
+ case "select":
13860
+ case "selectstart":
13861
+ return e;
13862
+ case "drag":
13863
+ case "dragenter":
13864
+ case "dragexit":
13865
+ case "dragleave":
13866
+ case "dragover":
13867
+ case "mousemove":
13868
+ case "mouseout":
13869
+ case "mouseover":
13870
+ case "pointermove":
13871
+ case "pointerout":
13872
+ case "pointerover":
13873
+ case "scroll":
13874
+ case "touchmove":
13875
+ case "wheel":
13876
+ case "mouseenter":
13877
+ case "mouseleave":
13878
+ case "pointerenter":
13879
+ case "pointerleave":
13880
+ return o;
13881
+ case "message": {
13882
+ switch (Tb.unstable_getCurrentPriorityLevel()) {
13883
+ case Tb.unstable_ImmediatePriority:
13884
+ return e;
13885
+ case Tb.unstable_UserBlockingPriority:
13886
+ return o;
13887
+ case Tb.unstable_NormalPriority:
13888
+ case Tb.unstable_LowPriority:
13889
+ return r;
13890
+ case Tb.unstable_IdlePriority:
13891
+ return i$1;
13892
+ default:
13893
+ return r;
13894
+ }
13895
+ }
13896
+ default:
13897
+ return r;
13898
+ }
13899
+ }
13900
+ function scheduleMicrotask(callback) {
13901
+ if (typeof queueMicrotask === "function") {
13902
+ queueMicrotask(callback);
13903
+ } else if (typeof Promise !== "undefined") {
13904
+ Promise.resolve().then(callback).catch((error) => {
13905
+ setTimeout(() => {
13906
+ throw error;
13907
+ });
13908
+ });
13909
+ } else {
13910
+ setTimeout(callback);
13911
+ }
13912
+ }
13928
13913
  const reconciler = /* @__PURE__ */ createReconciler({
13929
13914
  isPrimaryRenderer: false,
13930
13915
  warnsIfNotActing: false,
@@ -13957,22 +13942,21 @@ const reconciler = /* @__PURE__ */ createReconciler({
13957
13942
  getRootHostContext: () => NO_CONTEXT,
13958
13943
  getChildHostContext: () => NO_CONTEXT,
13959
13944
  commitUpdate(instance, type, oldProps, newProps, fiber) {
13960
- validateInstance(type, newProps);
13945
+ validateInstance(instance.type, newProps);
13961
13946
  let reconstruct = false;
13962
13947
  if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
13963
13948
  else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
13964
13949
  else if (newProps.args?.some((value, index) => value !== oldProps.args?.[index])) reconstruct = true;
13965
13950
  if (reconstruct) {
13966
- reconstructed.push([instance, { ...newProps }, fiber]);
13951
+ reconstructed.push([instance, getInstanceProps(newProps), fiber]);
13967
13952
  } else {
13968
13953
  const changedProps = diffProps(instance, newProps);
13969
- if (Object.keys(changedProps).length) {
13970
- Object.assign(instance.props, changedProps);
13971
- applyProps(instance.object, changedProps);
13972
- }
13954
+ const attach2 = instance.props.attach;
13955
+ instance.props = getInstanceProps(newProps);
13956
+ if (attach2 !== void 0) instance.props.attach = attach2;
13957
+ else delete instance.props.attach;
13958
+ if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
13973
13959
  }
13974
- const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
13975
- if (isTailSibling) swapInstances();
13976
13960
  },
13977
13961
  finalizeInitialChildren: (instance) => {
13978
13962
  for (const prop in instance.props) {
@@ -13985,8 +13969,8 @@ const reconciler = /* @__PURE__ */ createReconciler({
13985
13969
  for (const prop in instance.props) {
13986
13970
  const value = instance.props[prop];
13987
13971
  if (isFromRef(value)) {
13988
- const ref = value[FROM_REF];
13989
- if (ref.current != null) resolved[prop] = ref.current;
13972
+ const { [FROM_REF]: ref, transform } = value;
13973
+ if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
13990
13974
  }
13991
13975
  }
13992
13976
  if (Object.keys(resolved).length) applyProps(instance.object, resolved);
@@ -13997,8 +13981,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
13997
13981
  const target = container.getState().internal.container ?? container.getState().scene;
13998
13982
  return prepare(target, container, "", {});
13999
13983
  },
14000
- resetAfterCommit: () => {
14001
- },
13984
+ // Reconstructed instances are swapped once all mutations are committed,
13985
+ // before layout effects run so refs point to the new objects
13986
+ resetAfterCommit: flushReconstructedInstances,
14002
13987
  shouldSetTextContent: () => false,
14003
13988
  clearContainer: () => false,
14004
13989
  hideInstance,
@@ -14006,6 +13991,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
14006
13991
  createTextInstance: handleTextInstance,
14007
13992
  hideTextInstance: handleTextInstance,
14008
13993
  unhideTextInstance: handleTextInstance,
13994
+ // Mirrors react-dom, which flushes discrete work in microtasks
13995
+ supportsMicrotasks: true,
13996
+ scheduleMicrotask,
14009
13997
  scheduleTimeout: typeof setTimeout === "function" ? setTimeout : void 0,
14010
13998
  cancelTimeout: typeof clearTimeout === "function" ? clearTimeout : void 0,
14011
13999
  noTimeout: -1,
@@ -14046,28 +14034,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
14046
14034
  },
14047
14035
  resolveUpdatePriority() {
14048
14036
  if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
14049
- switch (typeof window !== "undefined" && window.event?.type) {
14050
- case "click":
14051
- case "contextmenu":
14052
- case "dblclick":
14053
- case "dragenter":
14054
- case "dragleave":
14055
- case "drop":
14056
- case "pointercancel":
14057
- case "pointerdown":
14058
- case "pointerup":
14059
- return e;
14060
- case "dragover":
14061
- case "pointermove":
14062
- case "pointerout":
14063
- case "pointerover":
14064
- case "pointerenter":
14065
- case "pointerleave":
14066
- case "wheel":
14067
- return o;
14068
- default:
14069
- return r;
14070
- }
14037
+ const eventType = typeof window !== "undefined" ? window.event?.type : void 0;
14038
+ if (eventType === void 0) return r;
14039
+ return getEventPriority(eventType);
14071
14040
  },
14072
14041
  resetFormInstance() {
14073
14042
  },
@@ -14282,9 +14251,8 @@ function createRoot(canvas) {
14282
14251
  if (!renderer.hasInitialized?.()) {
14283
14252
  const size2 = computeInitialSize(canvas, propsSize);
14284
14253
  if (size2.width > 0 && size2.height > 0) {
14285
- const pixelRatio = calculateDpr(dpr);
14286
- canvas.width = size2.width * pixelRatio;
14287
- canvas.height = size2.height * pixelRatio;
14254
+ renderer.setPixelRatio(calculateDpr(dpr));
14255
+ renderer.setSize(size2.width, size2.height, false);
14288
14256
  }
14289
14257
  await renderer.init();
14290
14258
  }
@@ -14293,7 +14261,7 @@ function createRoot(canvas) {
14293
14261
  state.internal.actualRenderer = renderer;
14294
14262
  state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
14295
14263
  if (canvasId && !state.internal.isSecondary) {
14296
- const canvasTarget = new webgpu.CanvasTarget(canvas);
14264
+ const canvasTarget = renderer.getCanvasTarget?.();
14297
14265
  const unregisterPrimary = registerPrimary(canvasId, renderer, store);
14298
14266
  state.set((prev) => ({
14299
14267
  internal: {
@@ -14407,7 +14375,7 @@ function createRoot(canvas) {
14407
14375
  const handleXRFrame = (timestamp, _frame) => {
14408
14376
  const state2 = store.getState();
14409
14377
  if (state2.frameloop === "never") return;
14410
- advance(timestamp);
14378
+ advance(timestamp, true, state2);
14411
14379
  };
14412
14380
  const actualRenderer = state.internal.actualRenderer;
14413
14381
  const handleSessionChange = () => {
@@ -14415,7 +14383,7 @@ function createRoot(canvas) {
14415
14383
  const renderer2 = state2.internal.actualRenderer;
14416
14384
  actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
14417
14385
  renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
14418
- if (!renderer2.xr.isPresenting) invalidate();
14386
+ if (!renderer2.xr.isPresenting) invalidate(state2);
14419
14387
  };
14420
14388
  const xr = {
14421
14389
  connect() {
@@ -14497,14 +14465,23 @@ function createRoot(canvas) {
14497
14465
  const newRootId = canvasId || scheduler$1.generateRootId();
14498
14466
  const unregisterRoot = scheduler$1.registerRoot(newRootId, {
14499
14467
  getState: () => store.getState(),
14500
- onError: (err) => store.getState().setError(err)
14468
+ onError: (err) => store.getState().setError(err),
14469
+ frameloop: store.getState().frameloop,
14470
+ before: schedulerConfig?.before,
14471
+ after: schedulerConfig?.after,
14472
+ order: schedulerConfig?.order
14501
14473
  });
14502
14474
  const unregisterCanvasTarget = scheduler$1.register(
14503
14475
  () => {
14504
14476
  const state2 = store.getState();
14505
- if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
14477
+ const canvasTarget = state2.internal.canvasTarget;
14478
+ if (canvasTarget) {
14506
14479
  const renderer2 = state2.internal.actualRenderer;
14507
- renderer2.setCanvasTarget(state2.internal.canvasTarget);
14480
+ if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
14481
+ if (state2.internal.canvasTargetSizeDirty) {
14482
+ state2.internal.canvasTargetSizeDirty = false;
14483
+ renderer2.backend?.updateSize?.();
14484
+ }
14508
14485
  }
14509
14486
  },
14510
14487
  {
@@ -14573,8 +14550,7 @@ function createRoot(canvas) {
14573
14550
  phase: "render",
14574
14551
  system: true,
14575
14552
  // Internal flag: this is a system job, not user-controlled
14576
- // Apply scheduler config for render ordering and rate limiting
14577
- ...schedulerConfig?.after && { after: schedulerConfig.after },
14553
+ // FPS throttles only the default render job; Canvas ordering belongs to the root.
14578
14554
  ...schedulerConfig?.fps && { fps: schedulerConfig.fps }
14579
14555
  }
14580
14556
  );
@@ -14593,8 +14569,21 @@ function createRoot(canvas) {
14593
14569
  scheduler: scheduler$1
14594
14570
  }
14595
14571
  }));
14572
+ } else {
14573
+ const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
14574
+ if (constraintsChanged) {
14575
+ scheduler$1.setRootConstraints(rootId, {
14576
+ before: schedulerConfig?.before,
14577
+ after: schedulerConfig?.after
14578
+ });
14579
+ }
14580
+ if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
14581
+ scheduler$1.setRootOrder(rootId, schedulerConfig?.order ?? 0);
14582
+ }
14596
14583
  }
14597
- scheduler$1.frameloop = frameloop;
14584
+ lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
14585
+ lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
14586
+ lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
14598
14587
  onCreated = onCreatedCallback;
14599
14588
  configured = true;
14600
14589
  resolve();
@@ -14636,18 +14625,23 @@ function unmountComponentAtNode(canvas, callback) {
14636
14625
  const fiber = root?.fiber;
14637
14626
  if (fiber) {
14638
14627
  const state = root?.store.getState();
14639
- if (state) state.internal.active = false;
14628
+ if (state) {
14629
+ state.internal.active = false;
14630
+ const unregisterRoot = state.internal.unregisterRoot;
14631
+ if (unregisterRoot) {
14632
+ unregisterRoot();
14633
+ state.internal.unregisterRoot = void 0;
14634
+ }
14635
+ }
14640
14636
  reconciler.updateContainer(null, fiber, null, () => {
14641
14637
  if (state) {
14642
14638
  setTimeout(() => {
14643
14639
  try {
14644
14640
  const renderer = state.internal.actualRenderer;
14645
- const unregisterRoot = state.internal.unregisterRoot;
14646
- if (unregisterRoot) unregisterRoot();
14647
14641
  const unregisterPrimary = state.internal.unregisterPrimary;
14648
14642
  if (unregisterPrimary) unregisterPrimary();
14649
14643
  const canvasTarget = state.internal.canvasTarget;
14650
- if (canvasTarget?.dispose) canvasTarget.dispose();
14644
+ if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
14651
14645
  state.events.disconnect?.();
14652
14646
  cleanupHelperGroup(root.store);
14653
14647
  if (state.isLegacy && renderer) {
@@ -14773,6 +14767,207 @@ function flushSync(fn) {
14773
14767
  return reconciler.flushSyncFromReconciler(fn);
14774
14768
  }
14775
14769
 
14770
+ const isRef = (obj) => obj.current && obj.current.isScene;
14771
+ const resolveScene = (scene) => isRef(scene) ? scene.current : scene;
14772
+ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
14773
+ sceneProps = {
14774
+ backgroundBlurriness: 0,
14775
+ backgroundIntensity: 1,
14776
+ backgroundRotation: [0, 0, 0],
14777
+ environmentIntensity: 1,
14778
+ environmentRotation: [0, 0, 0],
14779
+ ...sceneProps
14780
+ };
14781
+ const target = resolveScene(scene || defaultScene);
14782
+ const oldbg = target.background;
14783
+ const oldenv = target.environment;
14784
+ const oldSceneProps = {
14785
+ backgroundBlurriness: target.backgroundBlurriness,
14786
+ backgroundIntensity: target.backgroundIntensity,
14787
+ backgroundRotation: target.backgroundRotation.clone(),
14788
+ environmentIntensity: target.environmentIntensity,
14789
+ environmentRotation: target.environmentRotation.clone()
14790
+ };
14791
+ if (background !== "only") target.environment = texture;
14792
+ if (background) target.background = texture;
14793
+ applyProps(target, sceneProps);
14794
+ return () => {
14795
+ if (background !== "only") target.environment = oldenv;
14796
+ if (background) target.background = oldbg;
14797
+ applyProps(target, oldSceneProps);
14798
+ };
14799
+ }
14800
+ function EnvironmentMap({ scene, background = false, map, ...config }) {
14801
+ const defaultScene = useThree$1((state) => state.scene);
14802
+ React__namespace.useLayoutEffect(() => {
14803
+ if (map) return setEnvProps(background, scene, defaultScene, map, config);
14804
+ });
14805
+ return null;
14806
+ }
14807
+ function EnvironmentCube({
14808
+ background = false,
14809
+ scene,
14810
+ blur,
14811
+ backgroundBlurriness,
14812
+ backgroundIntensity,
14813
+ backgroundRotation,
14814
+ environmentIntensity,
14815
+ environmentRotation,
14816
+ ...rest
14817
+ }) {
14818
+ const texture = useEnvironment(rest);
14819
+ const defaultScene = useThree$1((state) => state.scene);
14820
+ React__namespace.useLayoutEffect(() => {
14821
+ return setEnvProps(background, scene, defaultScene, texture, {
14822
+ backgroundBlurriness: blur ?? backgroundBlurriness,
14823
+ backgroundIntensity,
14824
+ backgroundRotation,
14825
+ environmentIntensity,
14826
+ environmentRotation
14827
+ });
14828
+ });
14829
+ React__namespace.useEffect(() => {
14830
+ return () => {
14831
+ texture.dispose();
14832
+ };
14833
+ }, [texture]);
14834
+ return null;
14835
+ }
14836
+ function EnvironmentPortal({
14837
+ children,
14838
+ near = 0.1,
14839
+ far = 1e3,
14840
+ resolution = 256,
14841
+ frames = 1,
14842
+ map,
14843
+ background = false,
14844
+ blur,
14845
+ backgroundBlurriness,
14846
+ backgroundIntensity,
14847
+ backgroundRotation,
14848
+ environmentIntensity,
14849
+ environmentRotation,
14850
+ scene,
14851
+ files,
14852
+ path,
14853
+ preset = void 0,
14854
+ extensions
14855
+ }) {
14856
+ const renderer = useThree$1((state) => state.renderer);
14857
+ const isLegacy = useThree$1((state) => state.isLegacy);
14858
+ const defaultScene = useThree$1((state) => state.scene);
14859
+ const camera = React__namespace.useRef(null);
14860
+ const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
14861
+ const fbo = React__namespace.useMemo(() => {
14862
+ const fbo2 = isLegacy ? new WebGLCubeRenderTarget(resolution) : new webgpu.CubeRenderTarget(resolution);
14863
+ fbo2.texture.type = webgpu.HalfFloatType;
14864
+ return fbo2;
14865
+ }, [resolution, isLegacy]);
14866
+ React__namespace.useEffect(() => {
14867
+ return () => {
14868
+ fbo.dispose();
14869
+ };
14870
+ }, [fbo]);
14871
+ React__namespace.useLayoutEffect(() => {
14872
+ if (frames === 1) {
14873
+ const autoClear = renderer.autoClear;
14874
+ renderer.autoClear = true;
14875
+ camera.current.update(renderer, virtualScene);
14876
+ renderer.autoClear = autoClear;
14877
+ }
14878
+ return setEnvProps(background, scene, defaultScene, fbo.texture, {
14879
+ backgroundBlurriness: blur ?? backgroundBlurriness,
14880
+ backgroundIntensity,
14881
+ backgroundRotation,
14882
+ environmentIntensity,
14883
+ environmentRotation
14884
+ });
14885
+ }, [
14886
+ children,
14887
+ virtualScene,
14888
+ fbo.texture,
14889
+ scene,
14890
+ defaultScene,
14891
+ background,
14892
+ frames,
14893
+ renderer,
14894
+ blur,
14895
+ backgroundBlurriness,
14896
+ backgroundIntensity,
14897
+ backgroundRotation,
14898
+ environmentIntensity,
14899
+ environmentRotation
14900
+ ]);
14901
+ let count = 1;
14902
+ useFrame$1(() => {
14903
+ if (frames === Infinity || count < frames) {
14904
+ const autoClear = renderer.autoClear;
14905
+ renderer.autoClear = true;
14906
+ camera.current.update(renderer, virtualScene);
14907
+ renderer.autoClear = autoClear;
14908
+ count++;
14909
+ }
14910
+ });
14911
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: createPortal(
14912
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14913
+ children,
14914
+ /* @__PURE__ */ jsxRuntime.jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
14915
+ files || preset ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { background: true, map, extensions }) : null
14916
+ ] }),
14917
+ virtualScene
14918
+ ) });
14919
+ }
14920
+ function EnvironmentGround(props) {
14921
+ const textureDefault = useEnvironment(props);
14922
+ const texture = props.map || textureDefault;
14923
+ React__namespace.useMemo(() => extend({ GroundProjectedEnvImpl: GroundedSkybox_js.GroundedSkybox }), []);
14924
+ React__namespace.useEffect(() => {
14925
+ return () => {
14926
+ textureDefault.dispose();
14927
+ };
14928
+ }, [textureDefault]);
14929
+ const height = props.ground?.height ?? 15;
14930
+ const radius = props.ground?.radius ?? 60;
14931
+ const scale = props.ground?.scale ?? 1e3;
14932
+ const args = React__namespace.useMemo(
14933
+ () => [texture, height, radius],
14934
+ [texture, height, radius]
14935
+ );
14936
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14937
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props, map: texture }),
14938
+ /* @__PURE__ */ jsxRuntime.jsx("groundProjectedEnvImpl", { args, scale })
14939
+ ] });
14940
+ }
14941
+ function EnvironmentColor({ color, scene }) {
14942
+ const defaultScene = useThree$1((state) => state.scene);
14943
+ React__namespace.useLayoutEffect(() => {
14944
+ if (color === void 0) return;
14945
+ const target = resolveScene(scene || defaultScene);
14946
+ const oldBg = target.background;
14947
+ target.background = new webgpu.Color(color);
14948
+ return () => {
14949
+ target.background = oldBg;
14950
+ };
14951
+ });
14952
+ return null;
14953
+ }
14954
+ function EnvironmentDualSource(props) {
14955
+ const { backgroundFiles, ...envProps } = props;
14956
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14957
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...envProps, background: false }),
14958
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
14959
+ ] });
14960
+ }
14961
+ function Environment(props) {
14962
+ if (props.color && !props.files && !props.preset && !props.map) {
14963
+ return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentColor, { ...props });
14964
+ }
14965
+ if (props.backgroundFiles && props.backgroundFiles !== props.files) {
14966
+ return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentDualSource, { ...props });
14967
+ }
14968
+ return props.ground ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props });
14969
+ }
14970
+
14776
14971
  function parseBackground(background) {
14777
14972
  if (!background) return null;
14778
14973
  if (typeof background === "object" && !background.isColor) {
@@ -14982,9 +15177,9 @@ function CanvasImpl({
14982
15177
  React__namespace.useMemo(() => extend(THREE), []);
14983
15178
  const Bridge = useBridge();
14984
15179
  const backgroundProps = React__namespace.useMemo(() => parseBackground(background), [background]);
14985
- const hasInitialSizeRef = React__namespace.useRef(false);
15180
+ const [hasInitialSize, setHasInitialSize] = React__namespace.useState(false);
14986
15181
  const measureConfig = React__namespace.useMemo(() => {
14987
- if (!hasInitialSizeRef.current) {
15182
+ if (!hasInitialSize) {
14988
15183
  return {
14989
15184
  ...resize,
14990
15185
  scroll: resize?.scroll ?? true,
@@ -14996,7 +15191,7 @@ function CanvasImpl({
14996
15191
  debounce: { scroll: 50, resize: 0 },
14997
15192
  ...resize
14998
15193
  };
14999
- }, [resize, hasInitialSizeRef.current]);
15194
+ }, [hasInitialSize, resize]);
15000
15195
  const [containerRef, containerRect] = useMeasure__default(measureConfig);
15001
15196
  const effectiveSize = React__namespace.useMemo(() => {
15002
15197
  let w = width ?? containerRect.width;
@@ -15012,9 +15207,7 @@ function CanvasImpl({
15012
15207
  left: containerRect.left
15013
15208
  };
15014
15209
  }, [width, height, containerRect, forceEven]);
15015
- if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
15016
- hasInitialSizeRef.current = true;
15017
- }
15210
+ if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
15018
15211
  const canvasRef = React__namespace.useRef(null);
15019
15212
  const divRef = React__namespace.useRef(null);
15020
15213
  React__namespace.useImperativeHandle(ref, () => canvasRef.current);
@@ -15079,7 +15272,7 @@ function CanvasImpl({
15079
15272
  onDropMissed: (...args) => handleDropMissed.current?.(...args),
15080
15273
  onCreated: (state) => {
15081
15274
  state.events.connect?.(
15082
- eventSource ? isRef(eventSource) ? eventSource.current : eventSource : divRef.current
15275
+ eventSource ? isRef$1(eventSource) ? eventSource.current : eventSource : divRef.current
15083
15276
  );
15084
15277
  if (eventPrefix) {
15085
15278
  state.setEvents({
@@ -15128,6 +15321,7 @@ function CanvasImpl({
15128
15321
  const canvas = canvasRef.current;
15129
15322
  if (canvas) {
15130
15323
  return () => {
15324
+ if (canvas.isConnected) return;
15131
15325
  unmountComponentAtNode(canvas);
15132
15326
  root.current = null;
15133
15327
  };
@@ -15186,20 +15380,36 @@ function CanvasImpl({
15186
15380
  }
15187
15381
  );
15188
15382
  }
15189
- function Canvas(props) {
15383
+ function Canvas$1(props) {
15190
15384
  return /* @__PURE__ */ jsxRuntime.jsx(itsFine.FiberProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(CanvasImpl, { ...props }) });
15191
15385
  }
15192
15386
 
15387
+ const isObjectLike = (value) => value !== null && (typeof value === "object" || typeof value === "function");
15388
+ const hasValidLegacyNodeMarkers = (value) => {
15389
+ const hasUuid = "uuid" in value;
15390
+ const hasNodeType = "nodeType" in value;
15391
+ const uuid = Reflect.get(value, "uuid");
15392
+ const nodeType = Reflect.get(value, "nodeType");
15393
+ return (hasUuid || hasNodeType) && (!hasUuid || uuid === void 0 || typeof uuid === "string") && (!hasNodeType || nodeType === void 0 || nodeType === null || typeof nodeType === "string");
15394
+ };
15395
+ const isUniformNode = (value) => isObjectLike(value) && "isUniformNode" in value && value.isUniformNode === true;
15396
+ const isTSLNode = (value) => isObjectLike(value) && (Reflect.get(value, "isNode") === true || Reflect.get(value, "shaderNode") !== void 0 && typeof Reflect.get(value, "id") === "number" || hasValidLegacyNodeMarkers(value));
15397
+ const isBufferLike = (value) => ArrayBuffer.isView(value) && !(value instanceof DataView) || isObjectLike(value) && ("isBufferAttribute" in value || "isInterleavedBufferAttribute" in value || isTSLNode(value));
15398
+ const isStorageLike = (value) => isObjectLike(value) && ("isTexture" in value || "isData3DTexture" in value || isTSLNode(value));
15399
+
15193
15400
  var __defProp = Object.defineProperty;
15194
15401
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
15195
15402
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
15196
- var _a;
15403
+ var _a, _b;
15197
15404
  const INTERNAL_DATA = Symbol("ScopedStore.data");
15198
- _a = INTERNAL_DATA;
15405
+ const INTERNAL_IS_LEAF = Symbol("ScopedStore.isLeaf");
15406
+ _b = INTERNAL_DATA, _a = INTERNAL_IS_LEAF;
15199
15407
  const _ScopedStore = class _ScopedStore {
15200
- constructor(data) {
15408
+ constructor(data, isLeaf) {
15409
+ __publicField(this, _b);
15201
15410
  __publicField(this, _a);
15202
15411
  this[INTERNAL_DATA] = data;
15412
+ this[INTERNAL_IS_LEAF] = isLeaf;
15203
15413
  return new Proxy(this, {
15204
15414
  get(target, prop, receiver) {
15205
15415
  if (typeof prop === "string") {
@@ -15233,10 +15443,10 @@ const _ScopedStore = class _ScopedStore {
15233
15443
  * If the key doesn't exist or isn't a scope object, returns an empty ScopedStore.
15234
15444
  */
15235
15445
  scope(key) {
15236
- const data = this[INTERNAL_DATA][key];
15237
- return new _ScopedStore(
15238
- data && typeof data === "object" ? data : {}
15239
- );
15446
+ const value = this[INTERNAL_DATA][key];
15447
+ const isLeaf = this[INTERNAL_IS_LEAF];
15448
+ const scope = value && typeof value === "object" && !isLeaf(value) ? value : {};
15449
+ return new _ScopedStore(scope, isLeaf);
15240
15450
  }
15241
15451
  /**
15242
15452
  * Check if a key exists in the store.
@@ -15252,8 +15462,8 @@ const _ScopedStore = class _ScopedStore {
15252
15462
  }
15253
15463
  };
15254
15464
  let ScopedStore = _ScopedStore;
15255
- function createScopedStore(data) {
15256
- return new ScopedStore(data);
15465
+ function createScopedStore(data, isLeaf) {
15466
+ return new ScopedStore(data, isLeaf);
15257
15467
  }
15258
15468
  function createLazyCreatorState(state, store) {
15259
15469
  let _uniforms = null;
@@ -15264,22 +15474,22 @@ function createLazyCreatorState(state, store) {
15264
15474
  return Object.create(state, {
15265
15475
  uniforms: {
15266
15476
  get() {
15267
- return _uniforms ?? (_uniforms = createScopedStore(view("uniforms")));
15477
+ return _uniforms ?? (_uniforms = createScopedStore(view("uniforms"), isUniformNode));
15268
15478
  }
15269
15479
  },
15270
15480
  nodes: {
15271
15481
  get() {
15272
- return _nodes ?? (_nodes = createScopedStore(view("nodes")));
15482
+ return _nodes ?? (_nodes = createScopedStore(view("nodes"), isTSLNode));
15273
15483
  }
15274
15484
  },
15275
15485
  buffers: {
15276
15486
  get() {
15277
- return _buffers ?? (_buffers = createScopedStore(view("buffers")));
15487
+ return _buffers ?? (_buffers = createScopedStore(view("buffers"), isBufferLike));
15278
15488
  }
15279
15489
  },
15280
15490
  gpuStorage: {
15281
15491
  get() {
15282
- return _gpuStorage ?? (_gpuStorage = createScopedStore(view("gpuStorage")));
15492
+ return _gpuStorage ?? (_gpuStorage = createScopedStore(view("gpuStorage"), isStorageLike));
15283
15493
  }
15284
15494
  }
15285
15495
  });
@@ -15338,6 +15548,11 @@ function createTextureOperations(set) {
15338
15548
  removeMultiple: (keys) => removeTextures(set, keys)
15339
15549
  };
15340
15550
  }
15551
+ function scopedNodeName(scope, name) {
15552
+ const raw = scope ? `${scope}_${name}` : name;
15553
+ const safe = raw.replace(/[^A-Za-z0-9_]/g, "_");
15554
+ return /^[A-Za-z_]/.test(safe) ? safe : `_${safe}`;
15555
+ }
15341
15556
  function extractTSLValue(value) {
15342
15557
  if (value === null || value === void 0) return value;
15343
15558
  if (typeof value !== "object") return value;
@@ -15375,7 +15590,7 @@ function vectorize(inObject) {
15375
15590
  return extractTSLValue(inObject);
15376
15591
  }
15377
15592
  if (obj.isVector2 || obj.isVector3 || obj.isVector4) return inObject;
15378
- if (obj.isMatrix3 || obj.isMatrix4) return inObject;
15593
+ if (obj.isMatrix2 || obj.isMatrix3 || obj.isMatrix4) return inObject;
15379
15594
  if (obj.isColor || obj.isEuler || obj.isQuaternion || obj.isSpherical) return inObject;
15380
15595
  if ("r" in obj && "g" in obj && "b" in obj && typeof obj.r === "number" && typeof obj.g === "number" && typeof obj.b === "number") {
15381
15596
  const scale = obj.r > 1 || obj.g > 1 || obj.b > 1 ? 1 / 255 : 1;
@@ -15433,22 +15648,21 @@ function useScopedResource(options) {
15433
15648
  return entries;
15434
15649
  }
15435
15650
 
15436
- const isUniformNode$1 = (value) => value !== null && typeof value === "object" && "value" in value && "uuid" in value;
15437
15651
  function useUniforms(creatorOrScope, scope) {
15438
15652
  const store = usePrimaryStore();
15439
15653
  const removeUniforms2 = React.useCallback(
15440
- (names, targetScope) => removeResourceEntries(store, "uniforms", Array.isArray(names) ? names : [names], targetScope, isUniformNode$1),
15654
+ (names, targetScope) => removeResourceEntries(store, "uniforms", Array.isArray(names) ? names : [names], targetScope, isUniformNode),
15441
15655
  [store]
15442
15656
  );
15443
15657
  const clearUniforms = React.useCallback(
15444
- (targetScope) => clearResourceEntries(store, "uniforms", targetScope, isUniformNode$1),
15658
+ (targetScope) => clearResourceEntries(store, "uniforms", targetScope, isUniformNode),
15445
15659
  [store]
15446
15660
  );
15447
15661
  const rebuildUniforms = React.useCallback(
15448
15662
  (targetScope) => rebuildResource(store, "uniforms", targetScope),
15449
15663
  [store]
15450
15664
  );
15451
- const inputForMemoization = React.useMemo(() => {
15665
+ const processedInput = React.useMemo(() => {
15452
15666
  let raw = creatorOrScope;
15453
15667
  if (is.fun(creatorOrScope)) {
15454
15668
  const wrappedState = createLazyCreatorState(store.getState(), store);
@@ -15459,23 +15673,24 @@ function useUniforms(creatorOrScope, scope) {
15459
15673
  for (const [key, value] of Object.entries(raw)) {
15460
15674
  normalized[key] = vectorize(value);
15461
15675
  }
15462
- return normalized;
15676
+ return { candidates: raw, normalized };
15463
15677
  }
15464
- return raw;
15678
+ return { candidates: raw, normalized: raw };
15465
15679
  }, [creatorOrScope, store]);
15466
- const memoizedInput = useCompareMemoize(inputForMemoization);
15680
+ const memoizedInput = useCompareMemoize(processedInput.normalized);
15467
15681
  const isReader = memoizedInput === void 0 || typeof memoizedInput === "string";
15468
15682
  const storeUniforms = usePrimaryThree((s) => s.uniforms);
15469
15683
  const created = useScopedResource({
15470
15684
  store,
15471
15685
  kind: "uniforms",
15472
15686
  scope: isReader ? void 0 : scope,
15473
- isLeaf: isUniformNode$1,
15687
+ isLeaf: isUniformNode,
15474
15688
  input: memoizedInput,
15475
15689
  create: () => {
15476
15690
  if (isReader) return {};
15477
- if (typeof memoizedInput !== "object" || memoizedInput === null) throw new Error("Invalid uniform input");
15478
- return memoizedInput;
15691
+ if (typeof processedInput.candidates !== "object" || processedInput.candidates === null)
15692
+ throw new Error("Invalid uniform input");
15693
+ return processedInput.candidates;
15479
15694
  },
15480
15695
  prepare: (name, candidate) => createUniform(name, candidate, scope),
15481
15696
  reconcile: (existing, candidate) => {
@@ -15497,7 +15712,7 @@ function useUniforms(creatorOrScope, scope) {
15497
15712
  uniforms = storeUniforms;
15498
15713
  } else if (typeof memoizedInput === "string") {
15499
15714
  const scopeData = storeUniforms[memoizedInput];
15500
- uniforms = scopeData && !isUniformNode$1(scopeData) ? scopeData : {};
15715
+ uniforms = scopeData && !isUniformNode(scopeData) ? scopeData : {};
15501
15716
  }
15502
15717
  return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms, rebuildUniforms };
15503
15718
  }
@@ -15512,7 +15727,7 @@ function removeUniforms(set, names, scope) {
15512
15727
  return { uniforms: { ...state.uniforms, [scope]: currentScope } };
15513
15728
  }
15514
15729
  const uniforms = { ...state.uniforms };
15515
- for (const name of names) if (isUniformNode$1(uniforms[name])) delete uniforms[name];
15730
+ for (const name of names) if (isUniformNode(uniforms[name])) delete uniforms[name];
15516
15731
  return { uniforms };
15517
15732
  });
15518
15733
  }
@@ -15526,7 +15741,7 @@ function clearRootUniforms(set) {
15526
15741
  set((state) => {
15527
15742
  const uniforms = {};
15528
15743
  for (const [key, value] of Object.entries(state.uniforms)) {
15529
- if (!isUniformNode$1(value)) uniforms[key] = value;
15744
+ if (!isUniformNode(value)) uniforms[key] = value;
15530
15745
  }
15531
15746
  return { uniforms };
15532
15747
  });
@@ -15536,8 +15751,7 @@ function createUniform(inName, node, scope) {
15536
15751
  const inValue = vectorize(node);
15537
15752
  const newUniform = tsl.uniform(inValue);
15538
15753
  if (typeof newUniform.setName === "function") {
15539
- const name = scope ? `${scope}_${inName}` : inName;
15540
- newUniform.setName(name);
15754
+ newUniform.setName(scopedNodeName(scope, inName));
15541
15755
  }
15542
15756
  return newUniform;
15543
15757
  }
@@ -15563,12 +15777,10 @@ function hasEqualsMethod(value) {
15563
15777
  function isSameThreeType(a, b) {
15564
15778
  const obj_a = a;
15565
15779
  const obj_b = b;
15566
- return obj_a.isColor && obj_b.isColor || obj_a.isMatrix3 && obj_b.isMatrix3 || obj_a.isMatrix4 && obj_b.isMatrix4 || obj_a.isEuler && obj_b.isEuler || obj_a.isQuaternion && obj_b.isQuaternion;
15780
+ return obj_a.isColor && obj_b.isColor || obj_a.isMatrix2 && obj_b.isMatrix2 || obj_a.isMatrix3 && obj_b.isMatrix3 || obj_a.isMatrix4 && obj_b.isMatrix4 || obj_a.isEuler && obj_b.isEuler || obj_a.isQuaternion && obj_b.isQuaternion;
15567
15781
  }
15568
15782
 
15569
15783
  const uniformOf = tsl.uniform;
15570
- const isUniformNode = (value) => value !== null && typeof value === "object" && "value" in value && "uuid" in value;
15571
- const isTSLNode$1 = (value) => value !== null && typeof value === "object" && "uuid" in value && "nodeType" in value;
15572
15784
  function useUniform(name, value) {
15573
15785
  const store = useStore();
15574
15786
  const registered = useScopedResource({
@@ -15580,7 +15792,7 @@ function useUniform(name, value) {
15580
15792
  create: () => value === void 0 ? {} : { [name]: value },
15581
15793
  prepare: createNamedUniform,
15582
15794
  reconcile: (existing2) => {
15583
- if (value !== void 0 && !isTSLNode$1(value) && !isUniformNode(value)) {
15795
+ if (value !== void 0 && !isTSLNode(value) && !isUniformNode(value)) {
15584
15796
  existing2.value = typeof value === "string" ? new webgpu.Color(value) : value;
15585
15797
  }
15586
15798
  }
@@ -15596,7 +15808,7 @@ function createNamedUniform(name, value) {
15596
15808
  let node;
15597
15809
  if (isUniformNode(value)) {
15598
15810
  node = value;
15599
- } else if (isTSLNode$1(value)) {
15811
+ } else if (isTSLNode(value)) {
15600
15812
  node = uniformOf(value);
15601
15813
  } else if (typeof value === "string") {
15602
15814
  node = tsl.uniform(new webgpu.Color(value));
@@ -15609,7 +15821,6 @@ function createNamedUniform(name, value) {
15609
15821
  return node;
15610
15822
  }
15611
15823
 
15612
- const isTSLNode = (value) => value !== null && typeof value === "object" && ("uuid" in value || "nodeType" in value);
15613
15824
  function useNodes(creatorOrScope, scope) {
15614
15825
  const store = usePrimaryStore();
15615
15826
  const removeNodes2 = React.useCallback(
@@ -15636,7 +15847,8 @@ function useNodes(creatorOrScope, scope) {
15636
15847
  return creatorOrScope(createLazyCreatorState(store.getState(), store));
15637
15848
  },
15638
15849
  prepare: (name, node) => {
15639
- node.setName?.(scope ? `${scope}.${name}` : name);
15850
+ const setName = Reflect.get(node, "setName");
15851
+ if (typeof setName === "function") setName.call(node, scopedNodeName(scope, name));
15640
15852
  return node;
15641
15853
  }
15642
15854
  });
@@ -15691,13 +15903,6 @@ function useLocalNodes(creator) {
15691
15903
  }, [store, creator, uniforms, nodes, textures, hmrVersion]);
15692
15904
  }
15693
15905
 
15694
- const isBufferLike = (value) => {
15695
- if (value === null || typeof value !== "object") return false;
15696
- if (ArrayBuffer.isView(value)) return true;
15697
- if ("isBufferAttribute" in value) return true;
15698
- if ("uuid" in value || "nodeType" in value) return true;
15699
- return false;
15700
- };
15701
15906
  const disposeBuffer = (buffer) => {
15702
15907
  if (buffer === null || typeof buffer !== "object") return;
15703
15908
  if ("dispose" in buffer && typeof buffer.dispose === "function") {
@@ -15744,9 +15949,8 @@ function useBuffers(creatorOrScope, scope) {
15744
15949
  return creatorOrScope(createLazyCreatorState(store.getState(), store));
15745
15950
  },
15746
15951
  prepare: (name, buffer) => {
15747
- if ("setName" in buffer && typeof buffer.setName === "function") {
15748
- buffer.setName(scope ? `${scope}.${name}` : name);
15749
- }
15952
+ const setName = Reflect.get(buffer, "setName");
15953
+ if (typeof setName === "function") setName.call(buffer, scopedNodeName(scope, name));
15750
15954
  return buffer;
15751
15955
  }
15752
15956
  });
@@ -15763,13 +15967,6 @@ function rebuildAllBuffers(store, scope) {
15763
15967
  rebuildResource(store, "buffers", scope);
15764
15968
  }
15765
15969
 
15766
- const isStorageLike = (value) => {
15767
- if (value === null || typeof value !== "object") return false;
15768
- if ("isTexture" in value) return true;
15769
- if ("isData3DTexture" in value) return true;
15770
- if ("uuid" in value || "nodeType" in value) return true;
15771
- return false;
15772
- };
15773
15970
  const disposeStorage = (storage) => {
15774
15971
  if (storage === null || typeof storage !== "object") return;
15775
15972
  if ("dispose" in storage && typeof storage.dispose === "function") {
@@ -15816,10 +16013,9 @@ function useGPUStorage(creatorOrScope, scope) {
15816
16013
  return creatorOrScope(createLazyCreatorState(store.getState(), store));
15817
16014
  },
15818
16015
  prepare: (name, storage) => {
15819
- const label = scope ? `${scope}.${name}` : name;
15820
- if ("setName" in storage && typeof storage.setName === "function") {
15821
- storage.setName(label);
15822
- }
16016
+ const label = scopedNodeName(scope, name);
16017
+ const setName = Reflect.get(storage, "setName");
16018
+ if (typeof setName === "function") setName.call(storage, label);
15823
16019
  if ("name" in storage && typeof storage.name === "string") {
15824
16020
  storage.name = label;
15825
16021
  }
@@ -15847,9 +16043,10 @@ function rebuildAllStorage(store, scope) {
15847
16043
 
15848
16044
  function useRenderPipeline(mainCB, setupCB) {
15849
16045
  const store = useStore();
15850
- const { scene, camera, renderer, isLegacy } = useThree();
16046
+ const { scene, camera, renderer, isLegacy } = useThree$1();
15851
16047
  const callbacksRanRef = React.useRef(false);
15852
16048
  const scenePassCacheRef = React.useRef(null);
16049
+ const forceScenePassRebuildRef = React.useRef(false);
15853
16050
  const mainCBRef = React.useRef(mainCB);
15854
16051
  const setupCBRef = React.useRef(setupCB);
15855
16052
  mainCBRef.current = mainCB;
@@ -15857,7 +16054,7 @@ function useRenderPipeline(mainCB, setupCB) {
15857
16054
  const [rebuildVersion, setRebuildVersion] = React.useState(0);
15858
16055
  React.useEffect(() => {
15859
16056
  callbacksRanRef.current = false;
15860
- scenePassCacheRef.current = null;
16057
+ forceScenePassRebuildRef.current = true;
15861
16058
  }, []);
15862
16059
  const clearPasses = React.useCallback(() => {
15863
16060
  store.setState({ passes: {} });
@@ -15867,12 +16064,14 @@ function useRenderPipeline(mainCB, setupCB) {
15867
16064
  renderPipeline: null,
15868
16065
  passes: {}
15869
16066
  });
16067
+ scenePassCacheRef.current?.scenePass.dispose();
15870
16068
  callbacksRanRef.current = false;
15871
16069
  scenePassCacheRef.current = null;
16070
+ forceScenePassRebuildRef.current = false;
15872
16071
  }, [store]);
15873
16072
  const rebuild = React.useCallback(() => {
15874
16073
  callbacksRanRef.current = false;
15875
- scenePassCacheRef.current = null;
16074
+ forceScenePassRebuildRef.current = true;
15876
16075
  setRebuildVersion((v) => v + 1);
15877
16076
  }, []);
15878
16077
  React.useLayoutEffect(() => {
@@ -15880,6 +16079,9 @@ function useRenderPipeline(mainCB, setupCB) {
15880
16079
  throw new Error("useRenderPipeline is only available with WebGPU renderer. Set renderer prop on Canvas.");
15881
16080
  }
15882
16081
  if (!renderer || !scene || !camera) return;
16082
+ if (!("isWebGPURenderer" in renderer)) {
16083
+ throw new Error("useRenderPipeline: renderer is not a WebGPURenderer but isLegacy is false.");
16084
+ }
15883
16085
  const state = store.getState();
15884
16086
  const set = store.setState;
15885
16087
  try {
@@ -15890,21 +16092,33 @@ function useRenderPipeline(mainCB, setupCB) {
15890
16092
  pipeline = new webgpu.RenderPipeline(renderer);
15891
16093
  justCreatedPipeline = true;
15892
16094
  }
15893
- const cacheValid = scenePassCacheRef.current && scenePassCacheRef.current.sceneUuid === scene.uuid && scenePassCacheRef.current.cameraUuid === camera.uuid;
16095
+ const cacheValid = !forceScenePassRebuildRef.current && scenePassCacheRef.current && scenePassCacheRef.current.sceneUuid === scene.uuid && scenePassCacheRef.current.cameraUuid === camera.uuid;
16096
+ let outgoingScenePass = null;
15894
16097
  let scenePass;
15895
16098
  if (cacheValid) {
15896
16099
  scenePass = scenePassCacheRef.current.scenePass;
15897
16100
  } else {
16101
+ outgoingScenePass = scenePassCacheRef.current?.scenePass ?? null;
15898
16102
  scenePass = tsl.pass(scene, camera);
15899
16103
  scenePassCacheRef.current = { sceneUuid: scene.uuid, cameraUuid: camera.uuid, scenePass };
16104
+ forceScenePassRebuildRef.current = false;
15900
16105
  }
15901
16106
  currentPasses.scenePass = scenePass;
15902
- if (!pipeline.outputNode || justCreatedPipeline) pipeline.outputNode = scenePass;
16107
+ let outputNodeChanged = false;
16108
+ if (!pipeline.outputNode || justCreatedPipeline || pipeline.outputNode === outgoingScenePass) {
16109
+ pipeline.outputNode = scenePass;
16110
+ outputNodeChanged = true;
16111
+ }
15903
16112
  set({ renderPipeline: pipeline, passes: currentPasses });
15904
16113
  const shouldRunCallbacks = justCreatedPipeline || !callbacksRanRef.current || !cacheValid;
15905
16114
  if (shouldRunCallbacks) {
15906
16115
  if (setupCBRef.current) {
15907
- const freshState = store.getState();
16116
+ const freshState = Object.assign({}, store.getState(), {
16117
+ renderPipeline: pipeline,
16118
+ passes: { ...currentPasses, scenePass },
16119
+ renderer,
16120
+ isLegacy: false
16121
+ });
15908
16122
  const setupResult = setupCBRef.current(freshState);
15909
16123
  if (setupResult && typeof setupResult === "object") {
15910
16124
  currentPasses = { ...currentPasses, ...setupResult };
@@ -15912,33 +16126,38 @@ function useRenderPipeline(mainCB, setupCB) {
15912
16126
  }
15913
16127
  }
15914
16128
  if (mainCBRef.current) {
15915
- const freshState = store.getState();
16129
+ const freshState = Object.assign({}, store.getState(), {
16130
+ renderPipeline: pipeline,
16131
+ passes: { ...currentPasses, scenePass },
16132
+ renderer,
16133
+ isLegacy: false
16134
+ });
15916
16135
  const mainResult = mainCBRef.current(freshState);
15917
16136
  if (mainResult && typeof mainResult === "object") {
15918
16137
  currentPasses = { ...currentPasses, ...mainResult };
15919
16138
  set({ passes: currentPasses });
15920
16139
  }
15921
16140
  }
16141
+ outputNodeChanged = true;
15922
16142
  callbacksRanRef.current = true;
15923
16143
  }
16144
+ if (outputNodeChanged) pipeline.needsUpdate = true;
16145
+ if (outgoingScenePass && outgoingScenePass !== scenePass) outgoingScenePass.dispose();
15924
16146
  } catch (error) {
15925
16147
  console.warn("[useRenderPipeline] Setup failed; the render pipeline was not configured:", error);
15926
16148
  }
15927
16149
  }, [store, renderer, scene, camera, isLegacy, rebuildVersion]);
15928
- const passes = useThree((s) => s.passes);
15929
- const renderPipeline = useThree((s) => s.renderPipeline);
15930
- return {
15931
- passes,
15932
- renderPipeline,
15933
- clearPasses,
15934
- reset,
15935
- rebuild,
15936
- // isReady indicates if RenderPipeline is configured and ready for rendering
15937
- isReady: renderPipeline !== null
15938
- };
16150
+ const passes = useThree$1((s) => s.passes);
16151
+ const renderPipeline = useThree$1((s) => s.renderPipeline);
16152
+ const actions = { passes, clearPasses, reset, rebuild };
16153
+ if (renderPipeline) return { ...actions, isReady: true, renderPipeline };
16154
+ return { ...actions, isReady: false, renderPipeline: null };
15939
16155
  }
15940
16156
 
15941
16157
  extend(THREE);
16158
+ const useThree = useThree$1;
16159
+ const useFrame = useFrame$1;
16160
+ const Canvas = Canvas$1;
15942
16161
 
15943
16162
  exports.Scheduler = scheduler.Scheduler;
15944
16163
  exports.getScheduler = scheduler.getScheduler;
@@ -15959,7 +16178,6 @@ exports.REACT_INTERNAL_PROPS = REACT_INTERNAL_PROPS;
15959
16178
  exports.RESERVED_PROPS = RESERVED_PROPS;
15960
16179
  exports.Texture = Texture;
15961
16180
  exports._roots = _roots;
15962
- exports.act = act;
15963
16181
  exports.addAfterEffect = addAfterEffect;
15964
16182
  exports.addEffect = addEffect;
15965
16183
  exports.addTail = addTail;
@@ -16004,7 +16222,7 @@ exports.isFromRef = isFromRef;
16004
16222
  exports.isObject3D = isObject3D;
16005
16223
  exports.isOnce = isOnce;
16006
16224
  exports.isOrthographicCamera = isOrthographicCamera;
16007
- exports.isRef = isRef;
16225
+ exports.isRef = isRef$1;
16008
16226
  exports.isRenderer = isRenderer;
16009
16227
  exports.isTexture = isTexture;
16010
16228
  exports.isVectorLike = isVectorLike;
@@ -16021,6 +16239,7 @@ exports.removeInteractivity = removeInteractivity;
16021
16239
  exports.removeNodes = removeNodes;
16022
16240
  exports.removeUniforms = removeUniforms;
16023
16241
  exports.resolve = resolve;
16242
+ exports.swapInteractivity = swapInteractivity;
16024
16243
  exports.unmountComponentAtNode = unmountComponentAtNode;
16025
16244
  exports.unregisterPrimary = unregisterPrimary;
16026
16245
  exports.updateCamera = updateCamera;