@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.
package/dist/index.cjs CHANGED
@@ -2,20 +2,19 @@
2
2
 
3
3
  const webgpu = require('three/webgpu');
4
4
  const three = require('three');
5
- const Inspector_js = require('three/addons/inspector/Inspector.js');
6
5
  const jsxRuntime = require('react/jsx-runtime');
7
6
  const React = require('react');
8
7
  const useMeasure = require('react-use-measure');
9
8
  const itsFine = require('its-fine');
10
- const fiber = require('@react-three/fiber');
9
+ const traditional = require('zustand/traditional');
10
+ const scheduler = require('@pmndrs/scheduler');
11
+ const Tb = require('scheduler');
11
12
  const GroundedSkybox_js = require('three/examples/jsm/objects/GroundedSkybox.js');
12
13
  const HDRLoader_js = require('three/examples/jsm/loaders/HDRLoader.js');
14
+ const HDRCubeTextureLoader_js = require('three/examples/jsm/loaders/HDRCubeTextureLoader.js');
13
15
  const EXRLoader_js = require('three/examples/jsm/loaders/EXRLoader.js');
14
16
  const UltraHDRLoader_js = require('three/examples/jsm/loaders/UltraHDRLoader.js');
15
17
  const gainmapJs = require('@monogrid/gainmap-js');
16
- const Tb = require('scheduler');
17
- const traditional = require('zustand/traditional');
18
- const scheduler = require('@pmndrs/scheduler');
19
18
  const suspendReact = require('suspend-react');
20
19
 
21
20
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -53,18 +52,22 @@ const Tb__default = /*#__PURE__*/_interopDefaultCompat(Tb);
53
52
 
54
53
  const R3F_BUILD_LEGACY = true;
55
54
  const R3F_BUILD_WEBGPU = true;
55
+ async function loadInspector() {
56
+ const { Inspector } = await import('three/addons/inspector/Inspector.js');
57
+ return Inspector;
58
+ }
56
59
 
57
60
  const THREE = /*#__PURE__*/_mergeNamespaces({
58
61
  __proto__: null,
59
62
  CubeRenderTarget: webgpu.CubeRenderTarget,
60
63
  CubeRenderTargetCompat: webgpu.CubeRenderTarget,
61
- Inspector: Inspector_js.Inspector,
62
64
  R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
63
65
  R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
64
66
  RenderTargetCompat: webgpu.RenderTarget,
65
67
  WebGLCubeRenderTarget: three.WebGLCubeRenderTarget,
66
68
  WebGLRenderTarget: three.WebGLRenderTarget,
67
- WebGLRenderer: three.WebGLRenderer
69
+ WebGLRenderer: three.WebGLRenderer,
70
+ loadInspector: loadInspector
68
71
  }, [webgpu__namespace]);
69
72
 
70
73
  const primaryRegistry = /* @__PURE__ */ new Map();
@@ -125,823 +128,553 @@ function getPrimaryIds() {
125
128
  return Array.from(primaryRegistry.keys());
126
129
  }
127
130
 
128
- const presetsObj = {
129
- apartment: "lebombo_1k.hdr",
130
- city: "potsdamer_platz_1k.hdr",
131
- dawn: "kiara_1_dawn_1k.hdr",
132
- forest: "forest_slope_1k.hdr",
133
- lobby: "st_fagans_interior_1k.hdr",
134
- night: "dikhololo_night_1k.hdr",
135
- park: "rooitou_park_1k.hdr",
136
- studio: "studio_small_03_1k.hdr",
137
- sunset: "venice_sunset_1k.hdr",
138
- warehouse: "empty_warehouse_01_1k.hdr"
139
- };
131
+ var __defProp = Object.defineProperty;
132
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
133
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
134
+ const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React__namespace.useLayoutEffect : React__namespace.useEffect;
135
+ function useMutableCallback(fn) {
136
+ const ref = React__namespace.useRef(fn);
137
+ useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
138
+ return ref;
139
+ }
140
+ function useBridge() {
141
+ const fiber = itsFine.useFiber();
142
+ const ContextBridge = itsFine.useContextBridge();
143
+ return React__namespace.useMemo(
144
+ () => ({ children }) => {
145
+ const strict = !!itsFine.traverseFiber(fiber, true, (node) => node.type === React__namespace.StrictMode);
146
+ const Root = strict ? React__namespace.StrictMode : React__namespace.Fragment;
147
+ return /* @__PURE__ */ jsxRuntime.jsx(Root, { children: /* @__PURE__ */ jsxRuntime.jsx(ContextBridge, { children }) });
148
+ },
149
+ [fiber, ContextBridge]
150
+ );
151
+ }
152
+ function Block({ set }) {
153
+ useIsomorphicLayoutEffect(() => {
154
+ set(new Promise(() => null));
155
+ return () => set(false);
156
+ }, [set]);
157
+ return null;
158
+ }
159
+ const ErrorBoundary = /* @__PURE__ */ (() => {
160
+ var _a;
161
+ return _a = class extends React__namespace.Component {
162
+ constructor() {
163
+ super(...arguments);
164
+ __publicField(this, "state", { error: false });
165
+ }
166
+ componentDidCatch(err) {
167
+ this.props.set(err);
168
+ }
169
+ render() {
170
+ return this.state.error ? null : this.props.children;
171
+ }
172
+ }, __publicField(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
173
+ })();
140
174
 
141
- const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
142
- const isArray = (arr) => Array.isArray(arr);
143
- const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
144
- function useEnvironment({
145
- files = defaultFiles,
146
- path = "",
147
- preset = void 0,
148
- colorSpace = void 0,
149
- extensions
150
- } = {}) {
151
- if (preset) {
152
- validatePreset(preset);
153
- files = presetsObj[preset];
154
- path = CUBEMAP_ROOT;
155
- }
156
- const multiFile = isArray(files);
157
- const { extension, isCubemap } = getExtension(files);
158
- const loader = getLoader$1(extension);
159
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
160
- const renderer = fiber.useThree((state) => state.renderer);
161
- React.useLayoutEffect(() => {
162
- if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
163
- function clearGainmapTexture() {
164
- fiber.useLoader.clear(loader, multiFile ? [files] : files);
175
+ const is = {
176
+ obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== "function",
177
+ fun: (a) => typeof a === "function",
178
+ str: (a) => typeof a === "string",
179
+ num: (a) => typeof a === "number",
180
+ boo: (a) => typeof a === "boolean",
181
+ und: (a) => a === void 0,
182
+ nul: (a) => a === null,
183
+ arr: (a) => Array.isArray(a),
184
+ equ(a, b, { arrays = "shallow", objects = "reference", strict = true } = {}) {
185
+ if (typeof a !== typeof b || !!a !== !!b) return false;
186
+ if (is.str(a) || is.num(a) || is.boo(a)) return a === b;
187
+ const isObj = is.obj(a);
188
+ if (isObj && objects === "reference") return a === b;
189
+ const isArr = is.arr(a);
190
+ if (isArr && arrays === "reference") return a === b;
191
+ if ((isArr || isObj) && a === b) return true;
192
+ let i;
193
+ for (i in a) if (!(i in b)) return false;
194
+ if (isObj && arrays === "shallow" && objects === "shallow") {
195
+ for (i in strict ? b : a) if (!is.equ(a[i], b[i], { strict, objects: "reference" })) return false;
196
+ } else {
197
+ for (i in strict ? b : a) if (a[i] !== b[i]) return false;
165
198
  }
166
- renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
167
- }, [extension, files, loader, multiFile, renderer.domElement]);
168
- const loaderResult = fiber.useLoader(
169
- loader,
170
- multiFile ? [files] : files,
171
- (loader2) => {
172
- if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
173
- loader2.setRenderer?.(renderer);
174
- }
175
- loader2.setPath?.(path);
176
- if (extensions) extensions(loader2);
199
+ if (is.und(i)) {
200
+ if (isArr && a.length === 0 && b.length === 0) return true;
201
+ if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
202
+ if (a !== b) return false;
177
203
  }
178
- );
179
- let texture = multiFile ? (
180
- // @ts-ignore
181
- loaderResult[0]
182
- ) : loaderResult;
183
- if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
184
- texture = texture.renderTarget?.texture;
204
+ return true;
185
205
  }
186
- texture.mapping = isCubemap ? webgpu.CubeReflectionMapping : webgpu.EquirectangularReflectionMapping;
187
- texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
188
- return texture;
189
- }
190
- const preloadDefaultOptions = {
191
- files: defaultFiles,
192
- path: "",
193
- preset: void 0,
194
- extensions: void 0
195
206
  };
196
- useEnvironment.preload = (preloadOptions) => {
197
- const options = { ...preloadDefaultOptions, ...preloadOptions };
198
- let { files, path = "" } = options;
199
- const { preset, extensions } = options;
200
- if (preset) {
201
- validatePreset(preset);
202
- files = presetsObj[preset];
203
- path = CUBEMAP_ROOT;
207
+ const isOrthographicCamera = (def) => def && def.isOrthographicCamera;
208
+ const isRef$1 = (obj) => obj !== null && typeof obj === "object" && obj.hasOwnProperty("current");
209
+ const isColorRepresentation = (value) => value != null && (typeof value === "string" || typeof value === "number" || value.isColor);
210
+ const isObject3D = (object) => object?.isObject3D;
211
+ const isTexture = (value) => !!value?.isTexture;
212
+ const isVectorLike = (object) => object !== null && typeof object === "object" && "set" in object && typeof object.set === "function";
213
+ const isCopyable = (object) => isVectorLike(object) && "copy" in object && typeof object.copy === "function";
214
+ const hasConstructor = (object) => !!object?.constructor;
215
+
216
+ function calculateDpr(dpr) {
217
+ const target = typeof window !== "undefined" ? window.devicePixelRatio ?? 2 : 1;
218
+ return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
219
+ }
220
+ function getUuidPrefix(uuid) {
221
+ return uuid.split("-")[0];
222
+ }
223
+ function updateCamera(camera, size) {
224
+ if (camera.manual) return;
225
+ if (isOrthographicCamera(camera)) {
226
+ camera.left = size.width / -2;
227
+ camera.right = size.width / 2;
228
+ camera.top = size.height / 2;
229
+ camera.bottom = size.height / -2;
230
+ } else {
231
+ camera.aspect = size.width / size.height;
204
232
  }
205
- const { extension } = getExtension(files);
206
- if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
207
- throw new Error("useEnvironment: Preloading gainmaps is not supported");
233
+ camera.updateProjectionMatrix();
234
+ }
235
+ const frustumMatrix = new webgpu.Matrix4();
236
+ function updateFrustum(camera, frustum) {
237
+ const target = frustum ?? new webgpu.Frustum();
238
+ frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
239
+ target.setFromProjectionMatrix(frustumMatrix);
240
+ return target;
241
+ }
242
+
243
+ const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
244
+ function findInitialRoot(instance) {
245
+ let root = instance.root;
246
+ while (root.getState().previousRoot) root = root.getState().previousRoot;
247
+ return root;
248
+ }
249
+ function getRootState(obj) {
250
+ let state = obj.__r3f?.root.getState();
251
+ if (!state) {
252
+ obj.traverseAncestors((ancestor) => {
253
+ const parentState = ancestor.__r3f?.root.getState();
254
+ if (parentState) {
255
+ state = parentState;
256
+ return false;
257
+ }
258
+ });
208
259
  }
209
- const loader = getLoader$1(extension);
210
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
211
- fiber.useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
212
- loader2.setPath?.(path);
213
- if (extensions) extensions(loader2);
214
- });
215
- };
216
- const clearDefaultOptins = {
217
- files: defaultFiles,
218
- preset: void 0
219
- };
220
- useEnvironment.clear = (clearOptions) => {
221
- const options = { ...clearDefaultOptins, ...clearOptions };
222
- let { files } = options;
223
- const { preset } = options;
224
- if (preset) {
225
- validatePreset(preset);
226
- files = presetsObj[preset];
260
+ return state;
261
+ }
262
+ function buildGraph(object) {
263
+ const data = { nodes: {}, materials: {}, meshes: {} };
264
+ if (object) {
265
+ object.traverse((obj) => {
266
+ if (obj.name) data.nodes[obj.name] = obj;
267
+ if (obj.material) {
268
+ const material = Array.isArray(obj.material) ? obj.material[0] : obj.material;
269
+ const nameAlreadyUsed = data.materials[material.name];
270
+ let materialName = material.name;
271
+ if (nameAlreadyUsed) {
272
+ materialName = materialName + `-${getUuidPrefix(material.uuid)}`;
273
+ material.userData.materialCacheName = materialName;
274
+ }
275
+ data.materials[materialName] = material;
276
+ }
277
+ if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
278
+ });
227
279
  }
228
- const { extension } = getExtension(files);
229
- const loader = getLoader$1(extension);
230
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
231
- fiber.useLoader.clear(loader, isArray(files) ? [files] : files);
232
- };
233
- function validatePreset(preset) {
234
- if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
280
+ return data;
235
281
  }
236
- function getExtension(files) {
237
- const isCubemap = isArray(files) && files.length === 6;
238
- const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
239
- const firstEntry = isArray(files) ? files[0] : files;
240
- 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();
241
- return { extension, isCubemap, isGainmap };
282
+ function dispose(obj) {
283
+ if (obj.type !== "Scene") obj.dispose?.();
284
+ for (const p in obj) {
285
+ const prop = obj[p];
286
+ if (prop?.type !== "Scene") prop?.dispose?.();
287
+ }
242
288
  }
243
- function getLoader$1(extension) {
244
- 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;
245
- return loader;
289
+ function getInstanceProps(pendingProps) {
290
+ const props = {};
291
+ for (const key in pendingProps) {
292
+ if (!REACT_INTERNAL_PROPS.includes(key)) props[key] = pendingProps[key];
293
+ }
294
+ return props;
295
+ }
296
+ function prepare(target, root, type, props) {
297
+ const object = target;
298
+ let instance = object?.__r3f;
299
+ if (!instance) {
300
+ instance = {
301
+ root,
302
+ type,
303
+ parent: null,
304
+ children: [],
305
+ props: getInstanceProps(props),
306
+ object,
307
+ eventCount: 0,
308
+ handlers: {},
309
+ isHidden: false
310
+ };
311
+ if (object) object.__r3f = instance;
312
+ }
313
+ return instance;
314
+ }
315
+ function invalidateInstance(instance) {
316
+ if (!instance.parent) return;
317
+ const state = instance.root?.getState?.();
318
+ if (state && state.internal.frames === 0) state.invalidate();
246
319
  }
247
320
 
248
- const isRef$1 = (obj) => obj.current && obj.current.isScene;
249
- const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
250
- function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
251
- sceneProps = {
252
- backgroundBlurriness: 0,
253
- backgroundIntensity: 1,
254
- backgroundRotation: [0, 0, 0],
255
- environmentIntensity: 1,
256
- environmentRotation: [0, 0, 0],
257
- ...sceneProps
258
- };
259
- const target = resolveScene(scene || defaultScene);
260
- const oldbg = target.background;
261
- const oldenv = target.environment;
262
- const oldSceneProps = {
263
- // @ts-ignore
264
- backgroundBlurriness: target.backgroundBlurriness,
265
- // @ts-ignore
266
- backgroundIntensity: target.backgroundIntensity,
267
- // @ts-ignore
268
- backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
269
- // @ts-ignore
270
- environmentIntensity: target.environmentIntensity,
271
- // @ts-ignore
272
- environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
321
+ const tempFrustum = new webgpu.Frustum();
322
+ let hasWarnedWebGL = false;
323
+ let tslModule = null;
324
+ async function loadTSL() {
325
+ if (tslModule) return tslModule;
326
+ try {
327
+ const tsl = await import('three/tsl');
328
+ tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
329
+ return tslModule;
330
+ } catch {
331
+ return null;
332
+ }
333
+ }
334
+ function createOcclusionObserverNode(store, uniform) {
335
+ const node = new webgpu.Node("float");
336
+ node.updateType = webgpu.NodeUpdateType.OBJECT;
337
+ node.update = function(frame) {
338
+ const { internal } = store.getState();
339
+ const registry = internal.visibilityRegistry;
340
+ const cache = internal.occlusionCache;
341
+ for (const entry of registry.values()) {
342
+ const { object, handlers } = entry;
343
+ if (handlers.onOccluded || handlers.onVisible) {
344
+ const isOccluded = frame.renderer.isOccluded(object);
345
+ cache.set(object, isOccluded);
346
+ }
347
+ }
273
348
  };
274
- if (background !== "only") target.environment = texture;
275
- if (background) target.background = texture;
276
- fiber.applyProps(target, sceneProps);
277
- return () => {
278
- if (background !== "only") target.environment = oldenv;
279
- if (background) target.background = oldbg;
280
- fiber.applyProps(target, oldSceneProps);
349
+ node.setup = function() {
350
+ return uniform(0);
281
351
  };
352
+ return node;
282
353
  }
283
- function EnvironmentMap({ scene, background = false, map, ...config }) {
284
- const defaultScene = fiber.useThree((state) => state.scene);
285
- React__namespace.useLayoutEffect(() => {
286
- if (map) return setEnvProps(background, scene, defaultScene, map, config);
287
- });
288
- return null;
354
+ let occlusionSetupPromise = null;
355
+ function enableOcclusion(store) {
356
+ const state = store.getState();
357
+ const { internal, renderer } = state;
358
+ if (internal.occlusionEnabled || occlusionSetupPromise) return;
359
+ const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
360
+ if (!hasOcclusionSupport) {
361
+ if (!hasWarnedWebGL) {
362
+ console.warn(
363
+ "[R3F] Warning: onOccluded/onVisible occlusion queries require WebGPU renderer. Occlusion events will not fire on WebGL."
364
+ );
365
+ hasWarnedWebGL = true;
366
+ }
367
+ return;
368
+ }
369
+ occlusionSetupPromise = setupOcclusion(store);
289
370
  }
290
- function EnvironmentCube({
291
- background = false,
292
- scene,
293
- blur,
294
- backgroundBlurriness,
295
- backgroundIntensity,
296
- backgroundRotation,
297
- environmentIntensity,
298
- environmentRotation,
299
- ...rest
300
- }) {
301
- const texture = useEnvironment(rest);
302
- const defaultScene = fiber.useThree((state) => state.scene);
303
- React__namespace.useLayoutEffect(() => {
304
- return setEnvProps(background, scene, defaultScene, texture, {
305
- backgroundBlurriness: blur ?? backgroundBlurriness,
306
- backgroundIntensity,
307
- backgroundRotation,
308
- environmentIntensity,
309
- environmentRotation
310
- });
371
+ async function setupOcclusion(store) {
372
+ const state = store.getState();
373
+ const { internal, rootScene, set } = state;
374
+ const tsl = await loadTSL();
375
+ if (!tsl) {
376
+ console.warn("[R3F] Warning: TSL module not available. Occlusion queries disabled.");
377
+ occlusionSetupPromise = null;
378
+ return;
379
+ }
380
+ const { uniform, nodeObject } = tsl;
381
+ let helperGroup = internal.helperGroup;
382
+ if (!helperGroup) {
383
+ helperGroup = new webgpu.Group();
384
+ helperGroup.name = "__r3fInternal";
385
+ helperGroup.__r3fInternal = true;
386
+ rootScene.add(helperGroup);
387
+ }
388
+ const geometry = new webgpu.BoxGeometry(1, 1, 1);
389
+ const material = new webgpu.MeshBasicNodeMaterial({
390
+ transparent: true,
391
+ opacity: 0
311
392
  });
312
- React__namespace.useEffect(() => {
313
- return () => {
314
- texture.dispose();
315
- };
316
- }, [texture]);
317
- return null;
318
- }
319
- function EnvironmentPortal({
320
- children,
321
- near = 0.1,
322
- far = 1e3,
323
- resolution = 256,
324
- frames = 1,
325
- map,
326
- background = false,
327
- blur,
328
- backgroundBlurriness,
329
- backgroundIntensity,
330
- backgroundRotation,
331
- environmentIntensity,
332
- environmentRotation,
333
- scene,
334
- files,
335
- path,
336
- preset = void 0,
337
- extensions
338
- }) {
339
- const renderer = fiber.useThree((state) => state.renderer);
340
- const isLegacy = fiber.useThree((state) => state.isLegacy);
341
- const defaultScene = fiber.useThree((state) => state.scene);
342
- const camera = React__namespace.useRef(null);
343
- const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
344
- const fbo = React__namespace.useMemo(() => {
345
- const fbo2 = isLegacy ? new three.WebGLCubeRenderTarget(resolution) : new webgpu.CubeRenderTarget(resolution);
346
- fbo2.texture.type = webgpu.HalfFloatType;
347
- return fbo2;
348
- }, [resolution, isLegacy]);
349
- React__namespace.useEffect(() => {
350
- return () => {
351
- fbo.dispose();
352
- };
353
- }, [fbo]);
354
- React__namespace.useLayoutEffect(() => {
355
- if (frames === 1) {
356
- const autoClear = renderer.autoClear;
357
- renderer.autoClear = true;
358
- camera.current.update(renderer, virtualScene);
359
- renderer.autoClear = autoClear;
360
- }
361
- return setEnvProps(background, scene, defaultScene, fbo.texture, {
362
- backgroundBlurriness: blur ?? backgroundBlurriness,
363
- backgroundIntensity,
364
- backgroundRotation,
365
- environmentIntensity,
366
- environmentRotation
367
- });
368
- }, [
369
- children,
370
- virtualScene,
371
- fbo.texture,
372
- scene,
373
- defaultScene,
374
- background,
375
- frames,
376
- renderer,
377
- blur,
378
- backgroundBlurriness,
379
- backgroundIntensity,
380
- backgroundRotation,
381
- environmentIntensity,
382
- environmentRotation
383
- ]);
384
- let count = 1;
385
- fiber.useFrame(() => {
386
- if (frames === Infinity || count < frames) {
387
- const autoClear = renderer.autoClear;
388
- renderer.autoClear = true;
389
- camera.current.update(renderer, virtualScene);
390
- renderer.autoClear = autoClear;
391
- count++;
393
+ const observerNode = nodeObject(createOcclusionObserverNode(store, uniform));
394
+ material.colorNode = observerNode;
395
+ material.needsUpdate = true;
396
+ const mesh = new webgpu.Mesh(geometry, material);
397
+ mesh.name = "__r3fOcclusionObserver";
398
+ mesh.scale.setScalar(1e-4);
399
+ mesh.frustumCulled = false;
400
+ mesh.__r3fInternal = true;
401
+ helperGroup.add(mesh);
402
+ set((state2) => ({
403
+ internal: {
404
+ ...state2.internal,
405
+ helperGroup,
406
+ occlusionObserver: mesh,
407
+ occlusionEnabled: true
392
408
  }
393
- });
394
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fiber.createPortal(
395
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
396
- children,
397
- /* @__PURE__ */ jsxRuntime.jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
398
- files || preset ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { background: true, map, extensions }) : null
399
- ] }),
400
- virtualScene
401
- ) });
409
+ }));
410
+ occlusionSetupPromise = null;
402
411
  }
403
- function EnvironmentGround(props) {
404
- const textureDefault = useEnvironment(props);
405
- const texture = props.map || textureDefault;
406
- React__namespace.useMemo(() => fiber.extend({ GroundProjectedEnvImpl: GroundedSkybox_js.GroundedSkybox }), []);
407
- React__namespace.useEffect(() => {
408
- return () => {
409
- textureDefault.dispose();
410
- };
411
- }, [textureDefault]);
412
- const height = props.ground?.height ?? 15;
413
- const radius = props.ground?.radius ?? 60;
414
- const scale = props.ground?.scale ?? 1e3;
415
- const args = React__namespace.useMemo(
416
- () => [texture, height, radius],
417
- [texture, height, radius]
418
- );
419
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
420
- /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props, map: texture }),
421
- /* @__PURE__ */ jsxRuntime.jsx("groundProjectedEnvImpl", { args, scale })
422
- ] });
423
- }
424
- function EnvironmentColor({ color, scene }) {
425
- const defaultScene = fiber.useThree((state) => state.scene);
426
- React__namespace.useLayoutEffect(() => {
427
- if (color === void 0) return;
428
- const target = resolveScene(scene || defaultScene);
429
- const oldBg = target.background;
430
- target.background = new webgpu.Color(color);
431
- return () => {
432
- target.background = oldBg;
433
- };
434
- });
435
- return null;
436
- }
437
- function EnvironmentDualSource(props) {
438
- const { backgroundFiles, ...envProps } = props;
439
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
440
- /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...envProps, background: false }),
441
- /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
442
- ] });
443
- }
444
- function Environment(props) {
445
- if (props.color && !props.files && !props.preset && !props.map) {
446
- return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentColor, { ...props });
412
+ function disableOcclusion(store) {
413
+ const { internal, set } = store.getState();
414
+ if (!internal.occlusionEnabled) return;
415
+ if (internal.occlusionObserver) {
416
+ internal.occlusionObserver.removeFromParent();
417
+ internal.occlusionObserver.geometry.dispose();
418
+ internal.occlusionObserver.material.dispose();
447
419
  }
448
- if (props.backgroundFiles && props.backgroundFiles !== props.files) {
449
- return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentDualSource, { ...props });
420
+ internal.occlusionCache.clear();
421
+ set((state) => ({
422
+ internal: {
423
+ ...state.internal,
424
+ occlusionObserver: null,
425
+ occlusionEnabled: false
426
+ }
427
+ }));
428
+ }
429
+ function cleanupHelperGroup(store) {
430
+ const { internal, set } = store.getState();
431
+ disableOcclusion(store);
432
+ if (internal.helperGroup) {
433
+ internal.helperGroup.removeFromParent();
434
+ set((state) => ({
435
+ internal: {
436
+ ...state.internal,
437
+ helperGroup: null
438
+ }
439
+ }));
450
440
  }
451
- 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 });
452
441
  }
453
-
454
- var __defProp = Object.defineProperty;
455
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
456
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
457
- const act = React__namespace["act"];
458
- const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React__namespace.useLayoutEffect : React__namespace.useEffect;
459
- function useMutableCallback(fn) {
460
- const ref = React__namespace.useRef(fn);
461
- useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
462
- return ref;
442
+ function registerVisibility(store, object, handlers) {
443
+ const { internal } = store.getState();
444
+ const registry = internal.visibilityRegistry;
445
+ const entry = {
446
+ object,
447
+ handlers,
448
+ lastFramedState: null,
449
+ lastOccludedState: null,
450
+ lastVisibleState: null
451
+ };
452
+ registry.set(object.uuid, entry);
453
+ if (handlers.onOccluded || handlers.onVisible) {
454
+ object.occlusionTest = true;
455
+ if (!internal.occlusionEnabled) {
456
+ enableOcclusion(store);
457
+ }
458
+ }
463
459
  }
464
- function useBridge() {
465
- const fiber = itsFine.useFiber();
466
- const ContextBridge = itsFine.useContextBridge();
467
- return React__namespace.useMemo(
468
- () => ({ children }) => {
469
- const strict = !!itsFine.traverseFiber(fiber, true, (node) => node.type === React__namespace.StrictMode);
470
- const Root = strict ? React__namespace.StrictMode : React__namespace.Fragment;
471
- return /* @__PURE__ */ jsxRuntime.jsx(Root, { children: /* @__PURE__ */ jsxRuntime.jsx(ContextBridge, { children }) });
472
- },
473
- [fiber, ContextBridge]
474
- );
460
+ function unregisterVisibility(store, object) {
461
+ const { internal } = store.getState();
462
+ internal.visibilityRegistry.delete(object.uuid);
463
+ internal.occlusionCache.delete(object);
475
464
  }
476
- function Block({ set }) {
477
- useIsomorphicLayoutEffect(() => {
478
- set(new Promise(() => null));
479
- return () => set(false);
480
- }, [set]);
481
- return null;
465
+ function updateVisibilityHandlers(store, object, handlers) {
466
+ const { internal } = store.getState();
467
+ const entry = internal.visibilityRegistry.get(object.uuid);
468
+ if (!entry) return false;
469
+ entry.handlers = handlers;
470
+ if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
471
+ object.occlusionTest = true;
472
+ enableOcclusion(store);
473
+ }
474
+ return true;
482
475
  }
483
- const ErrorBoundary = /* @__PURE__ */ (() => {
484
- var _a;
485
- return _a = class extends React__namespace.Component {
486
- constructor() {
487
- super(...arguments);
488
- __publicField(this, "state", { error: false });
489
- }
490
- componentDidCatch(err) {
491
- this.props.set(err);
492
- }
493
- render() {
494
- return this.state.error ? null : this.props.children;
476
+ function checkVisibility(state) {
477
+ const { internal, camera } = state;
478
+ const registry = internal.visibilityRegistry;
479
+ if (registry.size === 0) return;
480
+ updateFrustum(camera, tempFrustum);
481
+ for (const entry of registry.values()) {
482
+ const { object, handlers, lastFramedState, lastOccludedState, lastVisibleState } = entry;
483
+ let inFrustum = null;
484
+ const computeFrustum = () => {
485
+ if (inFrustum === null) {
486
+ if (object.geometry?.boundingSphere === null) {
487
+ object.geometry?.computeBoundingSphere();
488
+ }
489
+ inFrustum = tempFrustum.intersectsObject(object);
490
+ }
491
+ return inFrustum;
492
+ };
493
+ if (handlers.onFramed) {
494
+ const currentInFrustum = computeFrustum();
495
+ if (currentInFrustum !== lastFramedState) {
496
+ entry.lastFramedState = currentInFrustum;
497
+ handlers.onFramed(currentInFrustum);
498
+ }
495
499
  }
496
- }, __publicField(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
497
- })();
498
-
499
- const is = {
500
- obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== "function",
501
- fun: (a) => typeof a === "function",
502
- str: (a) => typeof a === "string",
503
- num: (a) => typeof a === "number",
504
- boo: (a) => typeof a === "boolean",
505
- und: (a) => a === void 0,
506
- nul: (a) => a === null,
507
- arr: (a) => Array.isArray(a),
508
- equ(a, b, { arrays = "shallow", objects = "reference", strict = true } = {}) {
509
- if (typeof a !== typeof b || !!a !== !!b) return false;
510
- if (is.str(a) || is.num(a) || is.boo(a)) return a === b;
511
- const isObj = is.obj(a);
512
- if (isObj && objects === "reference") return a === b;
513
- const isArr = is.arr(a);
514
- if (isArr && arrays === "reference") return a === b;
515
- if ((isArr || isObj) && a === b) return true;
516
- let i;
517
- for (i in a) if (!(i in b)) return false;
518
- if (isObj && arrays === "shallow" && objects === "shallow") {
519
- for (i in strict ? b : a) if (!is.equ(a[i], b[i], { strict, objects: "reference" })) return false;
520
- } else {
521
- for (i in strict ? b : a) if (a[i] !== b[i]) return false;
500
+ let currentOcclusion = null;
501
+ if (handlers.onOccluded && internal.occlusionEnabled) {
502
+ currentOcclusion = internal.occlusionCache.get(object) ?? null;
503
+ if (currentOcclusion !== null && currentOcclusion !== lastOccludedState) {
504
+ entry.lastOccludedState = currentOcclusion;
505
+ handlers.onOccluded(currentOcclusion);
506
+ }
522
507
  }
523
- if (is.und(i)) {
524
- if (isArr && a.length === 0 && b.length === 0) return true;
525
- if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
526
- if (a !== b) return false;
508
+ if (handlers.onVisible) {
509
+ const currentInFrustum = computeFrustum();
510
+ if (!handlers.onFramed && currentInFrustum !== lastFramedState) {
511
+ entry.lastFramedState = currentInFrustum;
512
+ }
513
+ let isOccluded = currentOcclusion;
514
+ if (isOccluded === null && internal.occlusionEnabled) {
515
+ isOccluded = internal.occlusionCache.get(object) ?? null;
516
+ }
517
+ if (isOccluded === null) isOccluded = false;
518
+ const isVisible = currentInFrustum && !isOccluded && object.visible;
519
+ if (isVisible !== lastVisibleState) {
520
+ entry.lastVisibleState = isVisible;
521
+ handlers.onVisible(isVisible);
522
+ }
527
523
  }
528
- return true;
529
524
  }
530
- };
531
- const isOrthographicCamera = (def) => def && def.isOrthographicCamera;
532
- const isRef = (obj) => obj !== null && typeof obj === "object" && obj.hasOwnProperty("current");
533
- const isColorRepresentation = (value) => value != null && (typeof value === "string" || typeof value === "number" || value.isColor);
534
- const isObject3D = (object) => object?.isObject3D;
535
- const isTexture = (value) => !!value?.isTexture;
536
- const isVectorLike = (object) => object !== null && typeof object === "object" && "set" in object && typeof object.set === "function";
537
- const isCopyable = (object) => isVectorLike(object) && "copy" in object && typeof object.copy === "function";
538
- const hasConstructor = (object) => !!object?.constructor;
539
-
540
- function calculateDpr(dpr) {
541
- const target = typeof window !== "undefined" ? window.devicePixelRatio ?? 2 : 1;
542
- return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
543
525
  }
544
- function getUuidPrefix(uuid) {
545
- return uuid.split("-")[0];
526
+ function hasVisibilityHandlers(handlers) {
527
+ if (!handlers) return false;
528
+ return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
546
529
  }
547
- function updateCamera(camera, size) {
548
- if (camera.manual) return;
549
- if (isOrthographicCamera(camera)) {
550
- camera.left = size.width / -2;
551
- camera.right = size.width / 2;
552
- camera.top = size.height / 2;
553
- camera.bottom = size.height / -2;
554
- } else {
555
- camera.aspect = size.width / size.height;
556
- }
557
- camera.updateProjectionMatrix();
530
+
531
+ const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
532
+ function fromRef(ref, transform) {
533
+ const marker = { [FROM_REF]: ref };
534
+ if (transform) marker.transform = transform;
535
+ return marker;
558
536
  }
559
- const frustumMatrix = new webgpu.Matrix4();
560
- function updateFrustum(camera, frustum) {
561
- const target = frustum ?? new webgpu.Frustum();
562
- frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
563
- target.setFromProjectionMatrix(frustumMatrix);
564
- return target;
537
+ function isFromRef(value) {
538
+ return value !== null && typeof value === "object" && FROM_REF in value;
565
539
  }
566
540
 
567
- const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
568
- function findInitialRoot(instance) {
569
- let root = instance.root;
570
- while (root.getState().previousRoot) root = root.getState().previousRoot;
571
- return root;
541
+ const ONCE = Symbol.for("@react-three/fiber.once");
542
+ function once(...args) {
543
+ return { [ONCE]: args.length ? args : true };
572
544
  }
573
- function getRootState(obj) {
574
- let state = obj.__r3f?.root.getState();
575
- if (!state) {
576
- obj.traverseAncestors((ancestor) => {
577
- const parentState = ancestor.__r3f?.root.getState();
578
- if (parentState) {
579
- state = parentState;
580
- return false;
581
- }
582
- });
583
- }
584
- return state;
545
+ function isOnce(value) {
546
+ return value !== null && typeof value === "object" && ONCE in value;
585
547
  }
586
- function buildGraph(object) {
587
- const data = { nodes: {}, materials: {}, meshes: {} };
588
- if (object) {
589
- object.traverse((obj) => {
590
- if (obj.name) data.nodes[obj.name] = obj;
591
- if (obj.material) {
592
- const material = Array.isArray(obj.material) ? obj.material[0] : obj.material;
593
- const nameAlreadyUsed = data.materials[material.name];
594
- let materialName = material.name;
595
- if (nameAlreadyUsed) {
596
- materialName = materialName + `-${getUuidPrefix(material.uuid)}`;
597
- material.userData.materialCacheName = materialName;
598
- }
599
- data.materials[materialName] = material;
600
- }
601
- if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
602
- });
548
+
549
+ const shownNotices = /* @__PURE__ */ new Set();
550
+ function notifyDepreciated({ heading, body, link }) {
551
+ if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
552
+ return;
603
553
  }
604
- return data;
605
- }
606
- function dispose(obj) {
607
- if (obj.type !== "Scene") obj.dispose?.();
608
- for (const p in obj) {
609
- const prop = obj[p];
610
- if (prop?.type !== "Scene") prop?.dispose?.();
554
+ if (shownNotices.has(heading)) return;
555
+ shownNotices.add(heading);
556
+ const caller = getCallerFrame();
557
+ if (caller) {
558
+ console.log();
611
559
  }
612
- }
613
- function getInstanceProps(pendingProps) {
614
- const props = {};
615
- for (const key in pendingProps) {
616
- if (!REACT_INTERNAL_PROPS.includes(key)) props[key] = pendingProps[key];
560
+ const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
561
+ if (caller) {
562
+ console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
563
+ }
564
+ if (body || link) {
565
+ let message = "";
566
+ if (body) message += body;
567
+ if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
568
+ console.warn(`%c${message}`, "font-weight: bold;");
617
569
  }
618
- return props;
619
570
  }
620
- function prepare(target, root, type, props) {
621
- const object = target;
622
- let instance = object?.__r3f;
623
- if (!instance) {
624
- instance = {
625
- root,
626
- type,
627
- parent: null,
628
- children: [],
629
- props: getInstanceProps(props),
630
- object,
631
- eventCount: 0,
632
- handlers: {},
633
- isHidden: false
634
- };
635
- if (object) object.__r3f = instance;
571
+ function getCallerFrame(depth = 3) {
572
+ const stack = new Error().stack;
573
+ if (!stack) return null;
574
+ const lines = stack.split("\n");
575
+ const frame = lines[depth];
576
+ if (!frame) return null;
577
+ let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
578
+ if (!match) {
579
+ match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
636
580
  }
637
- return instance;
581
+ if (!match) return null;
582
+ const [, fn, url, line] = match;
583
+ return {
584
+ functionName: fn ?? "<anonymous>",
585
+ location: formatLocation(url, Number(line))
586
+ };
638
587
  }
639
- function invalidateInstance(instance) {
640
- if (!instance.parent) return;
641
- instance.props.onUpdate?.(instance.object);
642
- const state = instance.root?.getState?.();
643
- if (state && state.internal.frames === 0) state.invalidate();
588
+ function formatLocation(url, line) {
589
+ const clean = url.split("?")[0];
590
+ const file = clean.split("/").pop() ?? clean;
591
+ return `${file}:${line}`;
644
592
  }
645
-
646
- const tempFrustum = new webgpu.Frustum();
647
- let hasWarnedWebGL = false;
648
- let tslModule = null;
649
- async function loadTSL() {
650
- if (tslModule) return tslModule;
651
- try {
652
- const tsl = await import('three/tsl');
653
- tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
654
- return tslModule;
655
- } catch {
656
- return null;
593
+ function notifyAlpha({ message, link }) {
594
+ if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
595
+ return;
596
+ }
597
+ if (shownNotices.has(message)) return;
598
+ shownNotices.add(message);
599
+ const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
600
+ console.log(`%c\u{1F52C} ${message}`, boxStyle);
601
+ {
602
+ console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
657
603
  }
658
604
  }
659
- function createOcclusionObserverNode(store, uniform) {
660
- const node = new webgpu.Node("float");
661
- node.updateType = webgpu.NodeUpdateType.OBJECT;
662
- node.update = function(frame) {
663
- const { internal } = store.getState();
664
- const registry = internal.visibilityRegistry;
665
- const cache = internal.occlusionCache;
666
- for (const entry of registry.values()) {
667
- const { object, handlers } = entry;
668
- if (handlers.onOccluded || handlers.onVisible) {
669
- const isOccluded = frame.renderer.isOccluded(object);
670
- cache.set(object, isOccluded);
605
+
606
+ const RESERVED_PROPS = [
607
+ "children",
608
+ "key",
609
+ "ref",
610
+ // Instance props
611
+ "args",
612
+ "dispose",
613
+ "attach",
614
+ "object",
615
+ // Behavior flags
616
+ "dispose"
617
+ ];
618
+ const EVENT_REGEX = /^on(Pointer|Drag|Drop|Click|DoubleClick|ContextMenu|Wheel)/;
619
+ const VISIBILITY_EVENT_REGEX = /^on(Framed|Occluded|Visible)$/;
620
+ const INDEX_REGEX = /-\d+$/;
621
+ const MEMOIZED_PROTOTYPES = /* @__PURE__ */ new Map();
622
+ const colorMaps = ["map", "emissiveMap", "sheenColorMap", "specularColorMap", "envMap"];
623
+ function resolve(root, key) {
624
+ if (!key.includes("-")) return { root, key, target: root[key] };
625
+ if (key in root) return { root, key, target: root[key] };
626
+ const originalKey = key;
627
+ let target = root;
628
+ const parts = key.split("-");
629
+ for (const part of parts) {
630
+ if (typeof target !== "object" || target === null) {
631
+ if (target !== void 0) {
632
+ const remaining = parts.slice(parts.indexOf(part)).join("-");
633
+ return { root: target, key: remaining, target: void 0 };
671
634
  }
635
+ return { root, key: originalKey, target: void 0 };
672
636
  }
673
- };
674
- node.setup = function() {
675
- return uniform(0);
676
- };
677
- return node;
637
+ key = part;
638
+ root = target;
639
+ target = target[key];
640
+ }
641
+ return { root, key, target };
678
642
  }
679
- let occlusionSetupPromise = null;
680
- function enableOcclusion(store) {
681
- const state = store.getState();
682
- const { internal, renderer } = state;
683
- if (internal.occlusionEnabled || occlusionSetupPromise) return;
684
- const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
685
- if (!hasOcclusionSupport) {
686
- if (!hasWarnedWebGL) {
687
- console.warn(
688
- "[R3F] Warning: onOccluded/onVisible occlusion queries require WebGPU renderer. Occlusion events will not fire on WebGL."
689
- );
690
- hasWarnedWebGL = true;
643
+ function attach(parent, child) {
644
+ if (is.str(child.props.attach)) {
645
+ if (INDEX_REGEX.test(child.props.attach)) {
646
+ const index = child.props.attach.replace(INDEX_REGEX, "");
647
+ const { root: root2, key: key2 } = resolve(parent.object, index);
648
+ if (!Array.isArray(root2[key2])) root2[key2] = [];
691
649
  }
692
- return;
650
+ const { root, key } = resolve(parent.object, child.props.attach);
651
+ child.previousAttach = root[key];
652
+ root[key] = child.object;
653
+ } else if (is.fun(child.props.attach)) {
654
+ child.previousAttach = child.props.attach(parent.object, child.object);
693
655
  }
694
- occlusionSetupPromise = setupOcclusion(store);
695
656
  }
696
- async function setupOcclusion(store) {
697
- const state = store.getState();
698
- const { internal, rootScene, set } = state;
699
- const tsl = await loadTSL();
700
- if (!tsl) {
701
- console.warn("[R3F] Warning: TSL module not available. Occlusion queries disabled.");
702
- occlusionSetupPromise = null;
703
- return;
704
- }
705
- const { uniform, nodeObject } = tsl;
706
- let helperGroup = internal.helperGroup;
707
- if (!helperGroup) {
708
- helperGroup = new webgpu.Group();
709
- helperGroup.name = "__r3fInternal";
710
- helperGroup.__r3fInternal = true;
711
- rootScene.add(helperGroup);
657
+ function detach(parent, child) {
658
+ if (is.str(child.props.attach)) {
659
+ const { root, key } = resolve(parent.object, child.props.attach);
660
+ const previous = child.previousAttach;
661
+ if (previous === void 0) delete root[key];
662
+ else root[key] = previous;
663
+ } else {
664
+ child.previousAttach?.(parent.object, child.object);
712
665
  }
713
- const geometry = new webgpu.BoxGeometry(1, 1, 1);
714
- const material = new webgpu.MeshBasicNodeMaterial({
715
- transparent: true,
716
- opacity: 0
717
- });
718
- const observerNode = nodeObject(createOcclusionObserverNode(store, uniform));
719
- material.colorNode = observerNode;
720
- material.needsUpdate = true;
721
- const mesh = new webgpu.Mesh(geometry, material);
722
- mesh.name = "__r3fOcclusionObserver";
723
- mesh.scale.setScalar(1e-4);
724
- mesh.frustumCulled = false;
725
- mesh.__r3fInternal = true;
726
- helperGroup.add(mesh);
727
- set((state2) => ({
728
- internal: {
729
- ...state2.internal,
730
- helperGroup,
731
- occlusionObserver: mesh,
732
- occlusionEnabled: true
666
+ delete child.previousAttach;
667
+ }
668
+ function getMemoizedPrototype(root) {
669
+ let ctor = MEMOIZED_PROTOTYPES.get(root.constructor);
670
+ try {
671
+ if (!ctor) {
672
+ ctor = new root.constructor();
673
+ MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
733
674
  }
734
- }));
735
- occlusionSetupPromise = null;
736
- }
737
- function disableOcclusion(store) {
738
- const { internal, set } = store.getState();
739
- if (!internal.occlusionEnabled) return;
740
- if (internal.occlusionObserver) {
741
- internal.occlusionObserver.removeFromParent();
742
- internal.occlusionObserver.geometry.dispose();
743
- internal.occlusionObserver.material.dispose();
744
- }
745
- internal.occlusionCache.clear();
746
- set((state) => ({
747
- internal: {
748
- ...state.internal,
749
- occlusionObserver: null,
750
- occlusionEnabled: false
751
- }
752
- }));
753
- }
754
- function cleanupHelperGroup(store) {
755
- const { internal, set } = store.getState();
756
- disableOcclusion(store);
757
- if (internal.helperGroup) {
758
- internal.helperGroup.removeFromParent();
759
- set((state) => ({
760
- internal: {
761
- ...state.internal,
762
- helperGroup: null
763
- }
764
- }));
765
- }
766
- }
767
- function registerVisibility(store, object, handlers) {
768
- const { internal } = store.getState();
769
- const registry = internal.visibilityRegistry;
770
- const entry = {
771
- object,
772
- handlers,
773
- lastFramedState: null,
774
- lastOccludedState: null,
775
- lastVisibleState: null
776
- };
777
- registry.set(object.uuid, entry);
778
- if (handlers.onOccluded || handlers.onVisible) {
779
- object.occlusionTest = true;
780
- if (!internal.occlusionEnabled) {
781
- enableOcclusion(store);
782
- }
783
- }
784
- }
785
- function unregisterVisibility(store, object) {
786
- const { internal } = store.getState();
787
- internal.visibilityRegistry.delete(object.uuid);
788
- internal.occlusionCache.delete(object);
789
- }
790
- function updateVisibilityHandlers(store, object, handlers) {
791
- const { internal } = store.getState();
792
- const entry = internal.visibilityRegistry.get(object.uuid);
793
- if (!entry) return false;
794
- entry.handlers = handlers;
795
- if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
796
- object.occlusionTest = true;
797
- enableOcclusion(store);
798
- }
799
- return true;
800
- }
801
- function checkVisibility(state) {
802
- const { internal, camera } = state;
803
- const registry = internal.visibilityRegistry;
804
- if (registry.size === 0) return;
805
- updateFrustum(camera, tempFrustum);
806
- for (const entry of registry.values()) {
807
- const { object, handlers, lastFramedState, lastOccludedState, lastVisibleState } = entry;
808
- let inFrustum = null;
809
- const computeFrustum = () => {
810
- if (inFrustum === null) {
811
- if (object.geometry?.boundingSphere === null) {
812
- object.geometry?.computeBoundingSphere();
813
- }
814
- inFrustum = tempFrustum.intersectsObject(object);
815
- }
816
- return inFrustum;
817
- };
818
- if (handlers.onFramed) {
819
- const currentInFrustum = computeFrustum();
820
- if (currentInFrustum !== lastFramedState) {
821
- entry.lastFramedState = currentInFrustum;
822
- handlers.onFramed(currentInFrustum);
823
- }
824
- }
825
- let currentOcclusion = null;
826
- if (handlers.onOccluded && internal.occlusionEnabled) {
827
- currentOcclusion = internal.occlusionCache.get(object) ?? null;
828
- if (currentOcclusion !== null && currentOcclusion !== lastOccludedState) {
829
- entry.lastOccludedState = currentOcclusion;
830
- handlers.onOccluded(currentOcclusion);
831
- }
832
- }
833
- if (handlers.onVisible) {
834
- const currentInFrustum = computeFrustum();
835
- if (!handlers.onFramed && currentInFrustum !== lastFramedState) {
836
- entry.lastFramedState = currentInFrustum;
837
- }
838
- let isOccluded = currentOcclusion;
839
- if (isOccluded === null && internal.occlusionEnabled) {
840
- isOccluded = internal.occlusionCache.get(object) ?? null;
841
- }
842
- if (isOccluded === null) isOccluded = false;
843
- const isVisible = currentInFrustum && !isOccluded && object.visible;
844
- if (isVisible !== lastVisibleState) {
845
- entry.lastVisibleState = isVisible;
846
- handlers.onVisible(isVisible);
847
- }
848
- }
849
- }
850
- }
851
- function hasVisibilityHandlers(handlers) {
852
- if (!handlers) return false;
853
- return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
854
- }
855
-
856
- const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
857
- function fromRef(ref) {
858
- return { [FROM_REF]: ref };
859
- }
860
- function isFromRef(value) {
861
- return value !== null && typeof value === "object" && FROM_REF in value;
862
- }
863
-
864
- const ONCE = Symbol.for("@react-three/fiber.once");
865
- function once(...args) {
866
- return { [ONCE]: args.length ? args : true };
867
- }
868
- function isOnce(value) {
869
- return value !== null && typeof value === "object" && ONCE in value;
870
- }
871
-
872
- const RESERVED_PROPS = [
873
- "children",
874
- "key",
875
- "ref",
876
- // Instance props
877
- "args",
878
- "dispose",
879
- "attach",
880
- "object",
881
- "onUpdate",
882
- // Behavior flags
883
- "dispose"
884
- ];
885
- const EVENT_REGEX = /^on(Pointer|Drag|Drop|Click|DoubleClick|ContextMenu|Wheel)/;
886
- const VISIBILITY_EVENT_REGEX = /^on(Framed|Occluded|Visible)$/;
887
- const INDEX_REGEX = /-\d+$/;
888
- const MEMOIZED_PROTOTYPES = /* @__PURE__ */ new Map();
889
- const colorMaps = ["map", "emissiveMap", "sheenColorMap", "specularColorMap", "envMap"];
890
- function resolve(root, key) {
891
- if (!key.includes("-")) return { root, key, target: root[key] };
892
- if (key in root) return { root, key, target: root[key] };
893
- const originalKey = key;
894
- let target = root;
895
- const parts = key.split("-");
896
- for (const part of parts) {
897
- if (typeof target !== "object" || target === null) {
898
- if (target !== void 0) {
899
- const remaining = parts.slice(parts.indexOf(part)).join("-");
900
- return { root: target, key: remaining, target: void 0 };
901
- }
902
- return { root, key: originalKey, target: void 0 };
903
- }
904
- key = part;
905
- root = target;
906
- target = target[key];
907
- }
908
- return { root, key, target };
909
- }
910
- function attach(parent, child) {
911
- if (is.str(child.props.attach)) {
912
- if (INDEX_REGEX.test(child.props.attach)) {
913
- const index = child.props.attach.replace(INDEX_REGEX, "");
914
- const { root: root2, key: key2 } = resolve(parent.object, index);
915
- if (!Array.isArray(root2[key2])) root2[key2] = [];
916
- }
917
- const { root, key } = resolve(parent.object, child.props.attach);
918
- child.previousAttach = root[key];
919
- root[key] = child.object;
920
- } else if (is.fun(child.props.attach)) {
921
- child.previousAttach = child.props.attach(parent.object, child.object);
922
- }
923
- }
924
- function detach(parent, child) {
925
- if (is.str(child.props.attach)) {
926
- const { root, key } = resolve(parent.object, child.props.attach);
927
- const previous = child.previousAttach;
928
- if (previous === void 0) delete root[key];
929
- else root[key] = previous;
930
- } else {
931
- child.previousAttach?.(parent.object, child.object);
932
- }
933
- delete child.previousAttach;
934
- }
935
- function getMemoizedPrototype(root) {
936
- let ctor = MEMOIZED_PROTOTYPES.get(root.constructor);
937
- try {
938
- if (!ctor) {
939
- ctor = new root.constructor();
940
- MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
941
- }
942
- } catch {
943
- }
944
- return ctor;
675
+ } catch {
676
+ }
677
+ return ctor;
945
678
  }
946
679
  function diffProps(instance, newProps) {
947
680
  const changedProps = {};
@@ -956,11 +689,9 @@ function diffProps(instance, newProps) {
956
689
  for (const prop in instance.props) {
957
690
  if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
958
691
  const { root, key } = resolve(instance.object, prop);
959
- if (root.constructor && root.constructor.length === 0) {
692
+ if (typeof root?.constructor === "function") {
960
693
  const ctor = getMemoizedPrototype(root);
961
- if (!is.und(ctor)) changedProps[key] = ctor[key];
962
- } else {
963
- changedProps[key] = 0;
694
+ if (!is.und(ctor)) changedProps[prop] = ctor[key];
964
695
  }
965
696
  }
966
697
  return changedProps;
@@ -972,6 +703,13 @@ function applyProps(object, props) {
972
703
  for (const prop in props) {
973
704
  const value = props[prop];
974
705
  if (RESERVED_PROPS.includes(prop)) continue;
706
+ if (prop === "onUpdate") {
707
+ notifyDepreciated({
708
+ heading: "onUpdate is no longer an R3F prop",
709
+ 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.",
710
+ link: "https://docs.pmnd.rs/react-three-fiber/migration/v10#onupdate-removed"
711
+ });
712
+ }
975
713
  if (instance && EVENT_REGEX.test(prop)) {
976
714
  if (typeof value === "function") instance.handlers[prop] = value;
977
715
  else delete instance.handlers[prop];
@@ -1077,613 +815,11 @@ function applyProps(object, props) {
1077
815
  return object;
1078
816
  }
1079
817
 
1080
- const DEFAULT_POINTER_ID = 0;
1081
- const XR_POINTER_ID_START = 1e3;
1082
- function getPointerState(internal, pointerId) {
1083
- let state = internal.pointerMap.get(pointerId);
1084
- if (!state) {
1085
- state = {
1086
- hovered: /* @__PURE__ */ new Map(),
1087
- captured: /* @__PURE__ */ new Map(),
1088
- initialClick: [0, 0],
1089
- initialHits: []
1090
- };
1091
- internal.pointerMap.set(pointerId, state);
1092
- }
1093
- return state;
1094
- }
1095
- function getPointerId(event) {
1096
- return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
1097
- }
1098
- function makeId(event) {
1099
- return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
1100
- }
1101
- function releaseInternalPointerCapture(internal, obj, pointerId) {
1102
- const pointerState = internal.pointerMap.get(pointerId);
1103
- if (!pointerState) return;
1104
- const captureData = pointerState.captured.get(obj);
1105
- if (captureData) {
1106
- pointerState.captured.delete(obj);
1107
- captureData.target.releasePointerCapture(pointerId);
1108
- }
1109
- }
1110
- function removeInteractivity(store, object) {
1111
- const { internal } = store.getState();
1112
- internal.interaction = internal.interaction.filter((o) => o !== object);
1113
- for (const [pointerId, pointerState] of internal.pointerMap) {
1114
- pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
1115
- pointerState.hovered.forEach((value, key) => {
1116
- if (value.eventObject === object || value.object === object) {
1117
- pointerState.hovered.delete(key);
1118
- }
1119
- });
1120
- if (pointerState.captured.has(object)) {
1121
- releaseInternalPointerCapture(internal, object, pointerId);
1122
- }
1123
- }
1124
- unregisterVisibility(store, object);
1125
- }
1126
- function createEvents(store) {
1127
- function calculateDistance(event, pointerId) {
1128
- const { internal } = store.getState();
1129
- const pointerState = internal.pointerMap.get(pointerId);
1130
- if (!pointerState) return 0;
1131
- const [initialX, initialY] = pointerState.initialClick;
1132
- const dx = event.offsetX - initialX;
1133
- const dy = event.offsetY - initialY;
1134
- return Math.round(Math.sqrt(dx * dx + dy * dy));
1135
- }
1136
- function filterPointerEvents(objects) {
1137
- return objects.filter(
1138
- (obj) => ["Move", "Over", "Enter", "Out", "Leave"].some(
1139
- (name) => obj.__r3f?.handlers["onPointer" + name]
1140
- ) || ["OverEnter", "OverLeave", "Over"].some(
1141
- (name) => obj.__r3f?.handlers["onDrag" + name]
1142
- ) || obj.__r3f?.handlers.onDrop
1143
- );
1144
- }
1145
- function intersect(event, filter) {
1146
- const state = store.getState();
1147
- const duplicates = /* @__PURE__ */ new Set();
1148
- const intersections = [];
1149
- const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction;
1150
- for (let i = 0; i < eventsObjects.length; i++) {
1151
- const state2 = getRootState(eventsObjects[i]);
1152
- if (state2) {
1153
- state2.raycaster.camera = void 0;
1154
- }
1155
- }
1156
- if (!state.previousRoot) {
1157
- state.events.compute?.(event, state);
1158
- }
1159
- function handleRaycast(obj) {
1160
- const state2 = getRootState(obj);
1161
- if (!state2 || !state2.events.enabled || state2.raycaster.camera === null) return [];
1162
- if (state2.raycaster.camera === void 0) {
1163
- state2.events.compute?.(event, state2, state2.previousRoot?.getState());
1164
- if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
1165
- }
1166
- return state2.raycaster.camera ? state2.raycaster.intersectObject(obj, true) : [];
1167
- }
1168
- let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
1169
- const aInteractivePriority = a.object.userData?.interactivePriority;
1170
- const bInteractivePriority = b.object.userData?.interactivePriority;
1171
- if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
1172
- if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
1173
- if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
1174
- if (aInteractivePriority !== bInteractivePriority) {
1175
- return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
1176
- }
1177
- }
1178
- const aState = getRootState(a.object);
1179
- const bState = getRootState(b.object);
1180
- const aPriority = aState?.events?.priority ?? 1;
1181
- const bPriority = bState?.events?.priority ?? 1;
1182
- return bPriority - aPriority || a.distance - b.distance;
1183
- }).filter((item) => {
1184
- const id = makeId(item);
1185
- if (duplicates.has(id)) return false;
1186
- duplicates.add(id);
1187
- return true;
1188
- });
1189
- if (state.events.filter) hits = state.events.filter(hits, state);
1190
- for (const hit of hits) {
1191
- let eventObject = hit.object;
1192
- while (eventObject) {
1193
- if (eventObject.__r3f?.eventCount) {
1194
- intersections.push({ ...hit, eventObject });
1195
- }
1196
- eventObject = eventObject.parent;
1197
- }
1198
- }
1199
- if ("pointerId" in event) {
1200
- const pointerId = event.pointerId;
1201
- const pointerState = state.internal.pointerMap.get(pointerId);
1202
- if (pointerState?.captured.size) {
1203
- for (const captureData of pointerState.captured.values()) {
1204
- if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
1205
- }
1206
- }
1207
- }
1208
- return intersections;
1209
- }
1210
- function handleIntersects(intersections, event, delta, callback) {
1211
- if (intersections.length) {
1212
- const localState = { stopped: false };
1213
- for (const hit of intersections) {
1214
- const state = getRootState(hit.object);
1215
- if (state) {
1216
- const { raycaster, pointer, camera, internal } = state;
1217
- const unprojectedPoint = new webgpu.Vector3(pointer.x, pointer.y, 0).unproject(camera);
1218
- const hasPointerCapture = (id) => {
1219
- const pointerState = internal.pointerMap.get(id);
1220
- return pointerState?.captured.has(hit.eventObject) ?? false;
1221
- };
1222
- const setPointerCapture = (id) => {
1223
- const captureData = { intersection: hit, target: event.target };
1224
- const pointerState = getPointerState(internal, id);
1225
- pointerState.captured.set(hit.eventObject, captureData);
1226
- event.target.setPointerCapture(id);
1227
- };
1228
- const releasePointerCapture = (id) => {
1229
- releaseInternalPointerCapture(internal, hit.eventObject, id);
1230
- };
1231
- const extractEventProps = {};
1232
- for (const prop in event) {
1233
- const property = event[prop];
1234
- if (typeof property !== "function") extractEventProps[prop] = property;
1235
- }
1236
- const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
1237
- const raycastEvent = {
1238
- ...hit,
1239
- ...extractEventProps,
1240
- pointer,
1241
- intersections,
1242
- stopped: localState.stopped,
1243
- delta,
1244
- unprojectedPoint,
1245
- ray: raycaster.ray,
1246
- camera,
1247
- pointerId: eventPointerId,
1248
- // Hijack stopPropagation, which just sets a flag
1249
- stopPropagation() {
1250
- const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
1251
- if (
1252
- // ...if this pointer hasn't been captured
1253
- !pointerState?.captured.size || // ... or if the hit object is capturing the pointer
1254
- pointerState.captured.has(hit.eventObject)
1255
- ) {
1256
- raycastEvent.stopped = localState.stopped = true;
1257
- if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
1258
- const higher = intersections.slice(0, intersections.indexOf(hit));
1259
- cancelPointer([...higher, hit], eventPointerId);
1260
- }
1261
- }
1262
- },
1263
- // there should be a distinction between target and currentTarget
1264
- target: { hasPointerCapture, setPointerCapture, releasePointerCapture },
1265
- currentTarget: { hasPointerCapture, setPointerCapture, releasePointerCapture },
1266
- nativeEvent: event
1267
- };
1268
- callback(raycastEvent);
1269
- if (localState.stopped === true) break;
1270
- }
1271
- }
1272
- }
1273
- return intersections;
1274
- }
1275
- function cancelPointer(intersections, pointerId) {
1276
- const { internal } = store.getState();
1277
- const pid = pointerId ?? DEFAULT_POINTER_ID;
1278
- const pointerState = internal.pointerMap.get(pid);
1279
- if (!pointerState) return;
1280
- for (const [hoveredId, hoveredObj] of pointerState.hovered) {
1281
- if (!intersections.length || !intersections.find(
1282
- (hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
1283
- )) {
1284
- const eventObject = hoveredObj.eventObject;
1285
- const instance = eventObject.__r3f;
1286
- pointerState.hovered.delete(hoveredId);
1287
- if (instance?.eventCount) {
1288
- const handlers = instance.handlers;
1289
- const data = { ...hoveredObj, intersections };
1290
- handlers.onPointerOut?.(data);
1291
- handlers.onPointerLeave?.(data);
1292
- handlers.onDragOverLeave?.(data);
1293
- }
1294
- }
1295
- }
1296
- }
1297
- function pointerMissed(event, objects) {
1298
- for (let i = 0; i < objects.length; i++) {
1299
- const instance = objects[i].__r3f;
1300
- instance?.handlers.onPointerMissed?.(event);
1301
- }
1302
- }
1303
- function dragOverMissed(event, objects) {
1304
- for (let i = 0; i < objects.length; i++) {
1305
- const instance = objects[i].__r3f;
1306
- instance?.handlers.onDragOverMissed?.(event);
1307
- }
1308
- }
1309
- function dropMissed(event, objects) {
1310
- for (let i = 0; i < objects.length; i++) {
1311
- const instance = objects[i].__r3f;
1312
- instance?.handlers.onDropMissed?.(event);
1313
- }
1314
- }
1315
- function cleanupPointer(pointerId) {
1316
- const { internal } = store.getState();
1317
- const pointerState = internal.pointerMap.get(pointerId);
1318
- if (pointerState) {
1319
- for (const [, hoveredObj] of pointerState.hovered) {
1320
- const eventObject = hoveredObj.eventObject;
1321
- const instance = eventObject.__r3f;
1322
- if (instance?.eventCount) {
1323
- const handlers = instance.handlers;
1324
- const data = { ...hoveredObj, intersections: [] };
1325
- handlers.onPointerOut?.(data);
1326
- handlers.onPointerLeave?.(data);
1327
- }
1328
- }
1329
- internal.pointerMap.delete(pointerId);
1330
- }
1331
- internal.pointerDirty.delete(pointerId);
1332
- }
1333
- function processDeferredPointer(event, pointerId) {
1334
- const state = store.getState();
1335
- const { internal } = state;
1336
- if (!state.events.enabled) return;
1337
- const filter = filterPointerEvents;
1338
- const hits = intersect(event, filter);
1339
- cancelPointer(hits, pointerId);
1340
- function onIntersect(data) {
1341
- const eventObject = data.eventObject;
1342
- const instance = eventObject.__r3f;
1343
- if (!instance?.eventCount) return;
1344
- const handlers = instance.handlers;
1345
- if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
1346
- const id = makeId(data);
1347
- const pointerState = getPointerState(internal, pointerId);
1348
- const hoveredItem = pointerState.hovered.get(id);
1349
- if (!hoveredItem) {
1350
- pointerState.hovered.set(id, data);
1351
- handlers.onPointerOver?.(data);
1352
- handlers.onPointerEnter?.(data);
1353
- } else if (hoveredItem.stopped) {
1354
- data.stopPropagation();
1355
- }
1356
- }
1357
- handlers.onPointerMove?.(data);
1358
- }
1359
- handleIntersects(hits, event, 0, onIntersect);
1360
- }
1361
- function handlePointer(name) {
1362
- switch (name) {
1363
- case "onPointerLeave":
1364
- case "onDragLeave":
1365
- return () => cancelPointer([]);
1366
- // Global cancel of these events
1367
- case "onPointerCancel":
1368
- return (event) => {
1369
- const pointerId = getPointerId(event);
1370
- cleanupPointer(pointerId);
1371
- };
1372
- case "onLostPointerCapture":
1373
- return (event) => {
1374
- const { internal } = store.getState();
1375
- const pointerId = getPointerId(event);
1376
- const pointerState = internal.pointerMap.get(pointerId);
1377
- if (pointerState?.captured.size) {
1378
- requestAnimationFrame(() => {
1379
- const pointerState2 = internal.pointerMap.get(pointerId);
1380
- if (pointerState2?.captured.size) {
1381
- pointerState2.captured.clear();
1382
- }
1383
- cancelPointer([], pointerId);
1384
- });
1385
- }
1386
- };
1387
- }
1388
- return function handleEvent(event) {
1389
- const state = store.getState();
1390
- const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
1391
- const pointerId = getPointerId(event);
1392
- internal.lastEvent.current = event;
1393
- if (!events.enabled) return;
1394
- const isPointerMove = name === "onPointerMove";
1395
- const isDragOver = name === "onDragOver";
1396
- const isDrop = name === "onDrop";
1397
- const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
1398
- const isPointerDown = name === "onPointerDown";
1399
- const isPointerUp = name === "onPointerUp";
1400
- const isWheel = name === "onWheel";
1401
- const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
1402
- if (isPointerMove && canDeferRaycasts) {
1403
- events.compute?.(event, state);
1404
- internal.pointerDirty.set(pointerId, event);
1405
- return;
1406
- }
1407
- if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
1408
- events.compute?.(event, state);
1409
- internal.pointerDirty.set(pointerId, event);
1410
- return;
1411
- }
1412
- if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
1413
- const deferredEvent = internal.pointerDirty.get(pointerId);
1414
- internal.pointerDirty.delete(pointerId);
1415
- processDeferredPointer(deferredEvent, pointerId);
1416
- }
1417
- const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
1418
- const hits = intersect(event, filter);
1419
- const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
1420
- if (isPointerDown) {
1421
- const pointerState2 = getPointerState(internal, pointerId);
1422
- pointerState2.initialClick = [event.offsetX, event.offsetY];
1423
- pointerState2.initialHits = hits.map((hit) => hit.eventObject);
1424
- }
1425
- const pointerState = internal.pointerMap.get(pointerId);
1426
- const initialHits = pointerState?.initialHits ?? [];
1427
- if (isClickEvent && !hits.length) {
1428
- if (delta <= 2) {
1429
- pointerMissed(event, internal.interaction);
1430
- if (onPointerMissed) onPointerMissed(event);
1431
- }
1432
- }
1433
- if (isDragOver && !hits.length) {
1434
- dragOverMissed(event, internal.interaction);
1435
- if (onDragOverMissed) onDragOverMissed(event);
1436
- }
1437
- if (isDrop && !hits.length) {
1438
- dropMissed(event, internal.interaction);
1439
- if (onDropMissed) onDropMissed(event);
1440
- }
1441
- if (isPointerMove || isDragOver) {
1442
- cancelPointer(hits, pointerId);
1443
- }
1444
- function onIntersect(data) {
1445
- const eventObject = data.eventObject;
1446
- const instance = eventObject.__r3f;
1447
- if (!instance?.eventCount) return;
1448
- const handlers = instance.handlers;
1449
- if (isPointerMove) {
1450
- if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
1451
- const id = makeId(data);
1452
- const pointerState2 = getPointerState(internal, pointerId);
1453
- const hoveredItem = pointerState2.hovered.get(id);
1454
- if (!hoveredItem) {
1455
- pointerState2.hovered.set(id, data);
1456
- handlers.onPointerOver?.(data);
1457
- handlers.onPointerEnter?.(data);
1458
- } else if (hoveredItem.stopped) {
1459
- data.stopPropagation();
1460
- }
1461
- }
1462
- handlers.onPointerMove?.(data);
1463
- } else if (isDragOver) {
1464
- const id = makeId(data);
1465
- const pointerState2 = getPointerState(internal, pointerId);
1466
- const hoveredItem = pointerState2.hovered.get(id);
1467
- if (!hoveredItem) {
1468
- pointerState2.hovered.set(id, data);
1469
- handlers.onDragOverEnter?.(data);
1470
- } else if (hoveredItem.stopped) {
1471
- data.stopPropagation();
1472
- }
1473
- handlers.onDragOver?.(data);
1474
- } else if (isDrop) {
1475
- handlers.onDrop?.(data);
1476
- } else {
1477
- const handler = handlers[name];
1478
- if (handler) {
1479
- if (!isClickEvent || initialHits.includes(eventObject)) {
1480
- pointerMissed(
1481
- event,
1482
- internal.interaction.filter((object) => !initialHits.includes(object))
1483
- );
1484
- handler(data);
1485
- }
1486
- } else {
1487
- if (isClickEvent && initialHits.includes(eventObject)) {
1488
- pointerMissed(
1489
- event,
1490
- internal.interaction.filter((object) => !initialHits.includes(object))
1491
- );
1492
- }
1493
- }
1494
- }
1495
- }
1496
- handleIntersects(hits, event, delta, onIntersect);
1497
- };
1498
- }
1499
- function flushDeferredPointers() {
1500
- const { internal, events } = store.getState();
1501
- if (!events.frameTimedRaycasts) return;
1502
- for (const [pointerId, event] of internal.pointerDirty) {
1503
- processDeferredPointer(event, pointerId);
1504
- }
1505
- internal.pointerDirty.clear();
1506
- }
1507
- return { handlePointer, flushDeferredPointers, processDeferredPointer };
1508
- }
1509
- const DOM_EVENTS = {
1510
- onClick: ["click", false],
1511
- onContextMenu: ["contextmenu", false],
1512
- onDoubleClick: ["dblclick", false],
1513
- onDragEnter: ["dragenter", false],
1514
- onDragLeave: ["dragleave", false],
1515
- onDragOver: ["dragover", false],
1516
- onDrop: ["drop", false],
1517
- onWheel: ["wheel", true],
1518
- onPointerDown: ["pointerdown", true],
1519
- onPointerUp: ["pointerup", true],
1520
- onPointerLeave: ["pointerleave", true],
1521
- onPointerMove: ["pointermove", true],
1522
- onPointerCancel: ["pointercancel", true],
1523
- onLostPointerCapture: ["lostpointercapture", true]
1524
- };
1525
- function createPointerEvents(store) {
1526
- const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
1527
- let nextXRPointerId = XR_POINTER_ID_START;
1528
- const xrPointers = /* @__PURE__ */ new Map();
1529
- return {
1530
- priority: 1,
1531
- enabled: true,
1532
- frameTimedRaycasts: true,
1533
- alwaysFireOnScroll: true,
1534
- updateOnFrame: false,
1535
- compute(event, state) {
1536
- state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
1537
- state.raycaster.setFromCamera(state.pointer, state.camera);
1538
- },
1539
- connected: void 0,
1540
- handlers: Object.keys(DOM_EVENTS).reduce(
1541
- (acc, key) => ({ ...acc, [key]: handlePointer(key) }),
1542
- {}
1543
- ),
1544
- update: (pointerId) => {
1545
- const { events, internal } = store.getState();
1546
- if (!events.handlers) return;
1547
- if (pointerId !== void 0) {
1548
- const event = internal.pointerDirty.get(pointerId);
1549
- if (event) {
1550
- internal.pointerDirty.delete(pointerId);
1551
- processDeferredPointer(event, pointerId);
1552
- } else if (internal.lastEvent?.current) {
1553
- processDeferredPointer(internal.lastEvent.current, pointerId);
1554
- }
1555
- } else {
1556
- flushDeferredPointers();
1557
- if (internal.lastEvent?.current) {
1558
- events.handlers.onPointerMove(internal.lastEvent.current);
1559
- }
1560
- }
1561
- },
1562
- flush: () => {
1563
- const { events, internal } = store.getState();
1564
- flushDeferredPointers();
1565
- if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
1566
- events.handlers.onPointerMove(internal.lastEvent.current);
1567
- }
1568
- },
1569
- connect: (target) => {
1570
- if (!target) return;
1571
- const { set, events } = store.getState();
1572
- events.disconnect?.();
1573
- set((state) => ({ events: { ...state.events, connected: target } }));
1574
- if (events.handlers) {
1575
- for (const name in events.handlers) {
1576
- const event = events.handlers[name];
1577
- const [eventName, passive] = DOM_EVENTS[name];
1578
- target.addEventListener(eventName, event, { passive });
1579
- }
1580
- }
1581
- },
1582
- disconnect: () => {
1583
- const { set, events } = store.getState();
1584
- if (events.connected) {
1585
- if (events.handlers) {
1586
- for (const name in events.handlers) {
1587
- const event = events.handlers[name];
1588
- const [eventName] = DOM_EVENTS[name];
1589
- events.connected.removeEventListener(eventName, event);
1590
- }
1591
- }
1592
- set((state) => ({ events: { ...state.events, connected: void 0 } }));
1593
- }
1594
- },
1595
- // PREVIEW (A8): the XR pointer registration API may change before stable.
1596
- registerPointer: (config) => {
1597
- const pointerId = nextXRPointerId++;
1598
- xrPointers.set(pointerId, config);
1599
- const { internal } = store.getState();
1600
- getPointerState(internal, pointerId);
1601
- return pointerId;
1602
- },
1603
- unregisterPointer: (pointerId) => {
1604
- xrPointers.delete(pointerId);
1605
- const { internal } = store.getState();
1606
- const pointerState = internal.pointerMap.get(pointerId);
1607
- if (pointerState) {
1608
- for (const [, hoveredObj] of pointerState.hovered) {
1609
- const eventObject = hoveredObj.eventObject;
1610
- const instance = eventObject.__r3f;
1611
- if (instance?.eventCount) {
1612
- const handlers = instance.handlers;
1613
- const data = { ...hoveredObj, intersections: [] };
1614
- handlers.onPointerOut?.(data);
1615
- handlers.onPointerLeave?.(data);
1616
- }
1617
- }
1618
- internal.pointerMap.delete(pointerId);
1619
- }
1620
- internal.pointerDirty.delete(pointerId);
1621
- }
1622
- };
1623
- }
1624
-
1625
- const shownNotices = /* @__PURE__ */ new Set();
1626
- function notifyDepreciated({ heading, body, link }) {
1627
- if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
1628
- return;
1629
- }
1630
- if (shownNotices.has(heading)) return;
1631
- shownNotices.add(heading);
1632
- const caller = getCallerFrame();
1633
- if (caller) {
1634
- console.log();
1635
- }
1636
- const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
1637
- if (caller) {
1638
- console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
1639
- }
1640
- if (body || link) {
1641
- let message = "";
1642
- if (body) message += body;
1643
- if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
1644
- console.warn(`%c${message}`, "font-weight: bold;");
1645
- }
1646
- }
1647
- function getCallerFrame(depth = 3) {
1648
- const stack = new Error().stack;
1649
- if (!stack) return null;
1650
- const lines = stack.split("\n");
1651
- const frame = lines[depth];
1652
- if (!frame) return null;
1653
- let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
1654
- if (!match) {
1655
- match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
1656
- }
1657
- if (!match) return null;
1658
- const [, fn, url, line] = match;
1659
- return {
1660
- functionName: fn ?? "<anonymous>",
1661
- location: formatLocation(url, Number(line))
1662
- };
1663
- }
1664
- function formatLocation(url, line) {
1665
- const clean = url.split("?")[0];
1666
- const file = clean.split("/").pop() ?? clean;
1667
- return `${file}:${line}`;
1668
- }
1669
- function notifyAlpha({ message, link }) {
1670
- if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
1671
- return;
1672
- }
1673
- if (shownNotices.has(message)) return;
1674
- shownNotices.add(message);
1675
- const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
1676
- console.log(`%c\u{1F52C} ${message}`, boxStyle);
1677
- {
1678
- console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
1679
- }
1680
- }
1681
-
1682
- const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
1683
- function isInternalRendererAccess(stack, callerDepth = 2) {
1684
- if (!stack) return false;
1685
- const caller = stack.split("\n")[callerDepth] ?? "";
1686
- return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
818
+ const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
819
+ function isInternalRendererAccess(stack, callerDepth = 2) {
820
+ if (!stack) return false;
821
+ const caller = stack.split("\n")[callerDepth] ?? "";
822
+ return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
1687
823
  }
1688
824
 
1689
825
  const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
@@ -1795,7 +931,7 @@ const createStore = (invalidate, advance) => {
1795
931
  size: newSize,
1796
932
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
1797
933
  }));
1798
- scheduler.getScheduler().invalidate();
934
+ get().invalidate();
1799
935
  }
1800
936
  }
1801
937
  return;
@@ -1810,15 +946,16 @@ const createStore = (invalidate, advance) => {
1810
946
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
1811
947
  _sizeImperative: true
1812
948
  }));
1813
- scheduler.getScheduler().invalidate();
949
+ get().invalidate();
1814
950
  },
1815
951
  setDpr: (dpr) => set((state2) => {
1816
952
  const resolved = calculateDpr(dpr);
1817
953
  return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
1818
954
  }),
1819
955
  setFrameloop: (frameloop = "always") => {
956
+ const rootId = get().internal.rootId;
957
+ if (rootId) scheduler.getScheduler().setRootFrameloop(rootId, frameloop);
1820
958
  set(() => ({ frameloop }));
1821
- scheduler.getScheduler().frameloop = frameloop;
1822
959
  },
1823
960
  setError: (error) => set(() => ({ error })),
1824
961
  error: null,
@@ -1934,17 +1071,11 @@ const createStore = (invalidate, advance) => {
1934
1071
  oldSize = size;
1935
1072
  oldDpr = viewport.dpr;
1936
1073
  updateCamera(camera, size);
1937
- if (internal.isSecondary && canvasTarget) {
1938
- if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
1939
- canvasTarget.setSize(size.width, size.height, false);
1940
- } else {
1941
- if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
1942
- actualRenderer.setSize(size.width, size.height, false);
1943
- if (canvasTarget) {
1944
- if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
1945
- canvasTarget.setSize(size.width, size.height, false);
1946
- }
1947
- }
1074
+ const resizeTarget = canvasTarget ?? actualRenderer;
1075
+ if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
1076
+ resizeTarget.setSize(size.width, size.height, false);
1077
+ const activeTarget = actualRenderer.getCanvasTarget?.();
1078
+ if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
1948
1079
  }
1949
1080
  if (camera !== oldCamera) {
1950
1081
  oldCamera = camera;
@@ -1965,7 +1096,7 @@ const createStore = (invalidate, advance) => {
1965
1096
 
1966
1097
  const memoizedLoaders = /* @__PURE__ */ new WeakMap();
1967
1098
  const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
1968
- function getLoader(Proto) {
1099
+ function getLoader$1(Proto) {
1969
1100
  if (isConstructor$1(Proto)) {
1970
1101
  let loader = memoizedLoaders.get(Proto);
1971
1102
  if (!loader) {
@@ -1978,7 +1109,7 @@ function getLoader(Proto) {
1978
1109
  }
1979
1110
  function loadingFn(extensions, onProgress) {
1980
1111
  return function(Proto, input) {
1981
- const loader = getLoader(Proto);
1112
+ const loader = getLoader$1(Proto);
1982
1113
  if (extensions) extensions(loader);
1983
1114
  if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
1984
1115
  return loader.loadAsync(input, onProgress).then((data) => {
@@ -2006,7 +1137,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
2006
1137
  const results = cacheKeys.map(
2007
1138
  (key, index) => suspendReact.suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
2008
1139
  );
2009
- return Array.isArray(input) ? results : results[0];
1140
+ const stableRef = React.useRef(null);
1141
+ const previous = stableRef.current;
1142
+ const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
1143
+ stableRef.current = stable;
1144
+ return Array.isArray(input) ? stable : stable[0];
2010
1145
  }
2011
1146
  useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
2012
1147
  const inputs = Array.isArray(input) ? input : [input];
@@ -2019,7 +1154,7 @@ useLoader.clear = function(loader, input, cacheKey) {
2019
1154
  const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
2020
1155
  cacheKeys.forEach((key) => suspendReact.clear([loader, key]));
2021
1156
  };
2022
- useLoader.loader = getLoader;
1157
+ useLoader.loader = getLoader$1;
2023
1158
 
2024
1159
  function useFrame(callback, priorityOrOptions) {
2025
1160
  const store = React__namespace.useContext(context);
@@ -2126,6 +1261,13 @@ function useFrame(callback, priorityOrOptions) {
2126
1261
  * Use for controlling the entire frame loop, adding phases, etc.
2127
1262
  */
2128
1263
  scheduler: scheduler2,
1264
+ /**
1265
+ * The root that currently owns this job. Resolve on access because ambient
1266
+ * jobs can be adopted by a Canvas after the controls object is created.
1267
+ */
1268
+ get rootId() {
1269
+ return scheduler.getScheduler().getJobRootId(id);
1270
+ },
2129
1271
  /**
2130
1272
  * Manually step this job only.
2131
1273
  * Bypasses FPS limiting - always runs.
@@ -2142,6 +1284,14 @@ function useFrame(callback, priorityOrOptions) {
2142
1284
  stepAll: (timestamp) => {
2143
1285
  scheduler.getScheduler().step(timestamp);
2144
1286
  },
1287
+ /**
1288
+ * Request frames for this job's owning root without waking sibling roots.
1289
+ */
1290
+ invalidate: (frames, stackFrames) => {
1291
+ const scheduler3 = scheduler.getScheduler();
1292
+ const rootId = scheduler3.getJobRootId(id);
1293
+ if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
1294
+ },
2145
1295
  /**
2146
1296
  * Pause this job (set enabled=false).
2147
1297
  * Job remains registered but won't run.
@@ -2171,6 +1321,11 @@ function getUrls(input) {
2171
1321
  if (Array.isArray(input)) return input;
2172
1322
  return Object.values(input);
2173
1323
  }
1324
+ function inputSignature(input) {
1325
+ if (typeof input === "string") return input;
1326
+ if (Array.isArray(input)) return input.join("\0");
1327
+ return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
1328
+ }
2174
1329
  function allUrlsCached(urls, textureCache) {
2175
1330
  return urls.every((url) => textureCache.has(url));
2176
1331
  }
@@ -2196,24 +1351,37 @@ function useTexture(input, optionsOrOnLoad) {
2196
1351
  const onLoadRef = React.useRef(onLoad);
2197
1352
  onLoadRef.current = onLoad;
2198
1353
  const onLoadCalledForRef = React.useRef(null);
2199
- const urls = React.useMemo(() => getUrls(input), [input]);
1354
+ const inputKey = React.useMemo(() => inputSignature(input), [input]);
1355
+ const stableInput = React.useMemo(() => input, [inputKey]);
1356
+ const urls = React.useMemo(() => getUrls(stableInput), [stableInput]);
2200
1357
  const cachedResult = React.useMemo(() => {
2201
1358
  if (!cache) return null;
2202
1359
  const textures = store.getState().textures;
2203
1360
  if (!allUrlsCached(urls, textures)) return null;
2204
- return buildFromCache(input, textures);
2205
- }, [cache, urls, input, store]);
1361
+ return buildFromCache(stableInput, textures);
1362
+ }, [cache, urls, stableInput, store]);
2206
1363
  const loadedTextures = useLoader(
2207
1364
  webgpu.TextureLoader,
2208
- IsObject(input) ? Object.values(input) : input
1365
+ IsObject(stableInput) ? Object.values(stableInput) : stableInput
2209
1366
  );
2210
- const inputKey = urls.join("\0");
1367
+ const mappedTextures = React.useMemo(() => {
1368
+ if (cachedResult) return cachedResult;
1369
+ if (IsObject(stableInput)) {
1370
+ const keyed = {};
1371
+ const textureArray = loadedTextures;
1372
+ let i = 0;
1373
+ for (const key in stableInput) keyed[key] = textureArray[i++];
1374
+ return keyed;
1375
+ } else {
1376
+ return loadedTextures;
1377
+ }
1378
+ }, [stableInput, loadedTextures, cachedResult]);
2211
1379
  React.useLayoutEffect(() => {
2212
1380
  if (cachedResult) return;
2213
1381
  if (onLoadCalledForRef.current === inputKey) return;
2214
1382
  onLoadCalledForRef.current = inputKey;
2215
- onLoadRef.current?.(loadedTextures);
2216
- }, [cachedResult, loadedTextures, inputKey]);
1383
+ onLoadRef.current?.(mappedTextures);
1384
+ }, [cachedResult, mappedTextures, inputKey]);
2217
1385
  React.useEffect(() => {
2218
1386
  if (cachedResult) return;
2219
1387
  if ("initTexture" in renderer) {
@@ -2232,30 +1400,18 @@ function useTexture(input, optionsOrOnLoad) {
2232
1400
  });
2233
1401
  }
2234
1402
  }, [renderer, loadedTextures, cachedResult]);
2235
- const mappedTextures = React.useMemo(() => {
2236
- if (cachedResult) return cachedResult;
2237
- if (IsObject(input)) {
2238
- const keyed = {};
2239
- const textureArray = loadedTextures;
2240
- let i = 0;
2241
- for (const key in input) keyed[key] = textureArray[i++];
2242
- return keyed;
2243
- } else {
2244
- return loadedTextures;
2245
- }
2246
- }, [input, loadedTextures, cachedResult]);
2247
1403
  React.useEffect(() => {
2248
1404
  if (!cache) return;
2249
1405
  const urlTextureMap = [];
2250
- if (typeof input === "string") {
2251
- urlTextureMap.push([input, mappedTextures]);
2252
- } else if (Array.isArray(input)) {
1406
+ if (typeof stableInput === "string") {
1407
+ urlTextureMap.push([stableInput, mappedTextures]);
1408
+ } else if (Array.isArray(stableInput)) {
2253
1409
  const textureArray = mappedTextures;
2254
- input.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
2255
- } else if (IsObject(input)) {
1410
+ stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
1411
+ } else if (IsObject(stableInput)) {
2256
1412
  const textureRecord = mappedTextures;
2257
- for (const key in input) {
2258
- const url = input[key];
1413
+ for (const key in stableInput) {
1414
+ const url = stableInput[key];
2259
1415
  urlTextureMap.push([url, textureRecord[key]]);
2260
1416
  }
2261
1417
  }
@@ -2284,7 +1440,7 @@ function useTexture(input, optionsOrOnLoad) {
2284
1440
  }
2285
1441
  return { _textureRefs: refs };
2286
1442
  });
2287
- }, [cache, input, mappedTextures, store]);
1443
+ }, [cache, stableInput, mappedTextures, store]);
2288
1444
  return mappedTextures;
2289
1445
  }
2290
1446
  useTexture.preload = (url) => useLoader.preload(webgpu.TextureLoader, url);
@@ -2379,13 +1535,134 @@ function useRenderTarget(widthOrOptions, heightOrOptions, options) {
2379
1535
  height = widthOrOptions;
2380
1536
  }
2381
1537
  }
2382
- return React.useMemo(() => {
2383
- const w = width ?? size.width;
2384
- const h = height ?? size.height;
2385
- {
2386
- return isLegacy ? new three.WebGLRenderTarget(w, h, opts) : new webgpu.RenderTarget(w, h, opts);
2387
- }
2388
- }, [width, height, size.width, size.height, opts, isLegacy]);
1538
+ return React.useMemo(() => {
1539
+ const w = width ?? size.width;
1540
+ const h = height ?? size.height;
1541
+ {
1542
+ return isLegacy ? new three.WebGLRenderTarget(w, h, opts) : new webgpu.RenderTarget(w, h, opts);
1543
+ }
1544
+ }, [width, height, size.width, size.height, opts, isLegacy]);
1545
+ }
1546
+
1547
+ const presetsObj = {
1548
+ apartment: "lebombo_1k.hdr",
1549
+ city: "potsdamer_platz_1k.hdr",
1550
+ dawn: "kiara_1_dawn_1k.hdr",
1551
+ forest: "forest_slope_1k.hdr",
1552
+ lobby: "st_fagans_interior_1k.hdr",
1553
+ night: "dikhololo_night_1k.hdr",
1554
+ park: "rooitou_park_1k.hdr",
1555
+ studio: "studio_small_03_1k.hdr",
1556
+ sunset: "venice_sunset_1k.hdr",
1557
+ warehouse: "empty_warehouse_01_1k.hdr"
1558
+ };
1559
+
1560
+ const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
1561
+ const isArray = (arr) => Array.isArray(arr);
1562
+ const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
1563
+ function useEnvironment({
1564
+ files = defaultFiles,
1565
+ path = "",
1566
+ preset = void 0,
1567
+ colorSpace = void 0,
1568
+ extensions
1569
+ } = {}) {
1570
+ if (preset) {
1571
+ validatePreset(preset);
1572
+ files = presetsObj[preset];
1573
+ path = CUBEMAP_ROOT;
1574
+ }
1575
+ const multiFile = isArray(files);
1576
+ const { extension, isCubemap } = getExtension(files);
1577
+ const loader = getLoader(extension);
1578
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1579
+ const renderer = useThree((state) => state.renderer);
1580
+ React.useLayoutEffect(() => {
1581
+ if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
1582
+ function clearGainmapTexture() {
1583
+ useLoader.clear(loader, multiFile ? [files] : files);
1584
+ }
1585
+ renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
1586
+ }, [extension, files, loader, multiFile, renderer.domElement]);
1587
+ const loaderResult = useLoader(
1588
+ loader,
1589
+ multiFile ? [files] : files,
1590
+ (loader2) => {
1591
+ if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
1592
+ loader2.setRenderer?.(renderer);
1593
+ }
1594
+ loader2.setPath?.(path);
1595
+ if (extensions) extensions(loader2);
1596
+ }
1597
+ );
1598
+ let texture = multiFile ? (
1599
+ // @ts-ignore
1600
+ loaderResult[0]
1601
+ ) : loaderResult;
1602
+ if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
1603
+ texture = texture.renderTarget?.texture;
1604
+ }
1605
+ texture.mapping = isCubemap ? webgpu.CubeReflectionMapping : webgpu.EquirectangularReflectionMapping;
1606
+ texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
1607
+ return texture;
1608
+ }
1609
+ const preloadDefaultOptions = {
1610
+ files: defaultFiles,
1611
+ path: "",
1612
+ preset: void 0,
1613
+ extensions: void 0
1614
+ };
1615
+ useEnvironment.preload = (preloadOptions) => {
1616
+ const options = { ...preloadDefaultOptions, ...preloadOptions };
1617
+ let { files, path = "" } = options;
1618
+ const { preset, extensions } = options;
1619
+ if (preset) {
1620
+ validatePreset(preset);
1621
+ files = presetsObj[preset];
1622
+ path = CUBEMAP_ROOT;
1623
+ }
1624
+ const { extension } = getExtension(files);
1625
+ if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
1626
+ throw new Error("useEnvironment: Preloading gainmaps is not supported");
1627
+ }
1628
+ const loader = getLoader(extension);
1629
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1630
+ useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
1631
+ loader2.setPath?.(path);
1632
+ if (extensions) extensions(loader2);
1633
+ });
1634
+ };
1635
+ const clearDefaultOptins = {
1636
+ files: defaultFiles,
1637
+ preset: void 0
1638
+ };
1639
+ useEnvironment.clear = (clearOptions) => {
1640
+ const options = { ...clearDefaultOptins, ...clearOptions };
1641
+ let { files } = options;
1642
+ const { preset } = options;
1643
+ if (preset) {
1644
+ validatePreset(preset);
1645
+ files = presetsObj[preset];
1646
+ }
1647
+ const { extension } = getExtension(files);
1648
+ const loader = getLoader(extension);
1649
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1650
+ useLoader.clear(loader, isArray(files) ? [files] : files);
1651
+ };
1652
+ function validatePreset(preset) {
1653
+ if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
1654
+ }
1655
+ function getExtension(files) {
1656
+ const isCubemap = isArray(files) && files.length === 6;
1657
+ const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
1658
+ const firstEntry = isArray(files) ? files[0] : files;
1659
+ const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
1660
+ 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;
1661
+ return { extension, isCubemap, isGainmap };
1662
+ }
1663
+ function getLoader(extension) {
1664
+ 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;
1665
+ return loader;
2389
1666
  }
2390
1667
 
2391
1668
  function useStore() {
@@ -2405,6 +1682,8 @@ function useGraph(object) {
2405
1682
  return React.useMemo(() => buildGraph(object), [object]);
2406
1683
  }
2407
1684
 
1685
+ const t = 1, o = 8, r = 32, e = 2, i$1 = 268435456;
1686
+
2408
1687
  let effectId = 0;
2409
1688
  function addEffect(callback) {
2410
1689
  notifyDepreciated({
@@ -2433,13 +1712,19 @@ function addTail(callback) {
2433
1712
  return scheduler.getScheduler().onIdle(callback);
2434
1713
  }
2435
1714
  function invalidate(state, frames = 1, stackFrames = false) {
2436
- scheduler.getScheduler().invalidate(frames, stackFrames);
1715
+ const rootId = state?.internal?.rootId;
1716
+ const scheduler$1 = scheduler.getScheduler();
1717
+ if (rootId) scheduler$1.invalidateRoot(rootId, frames, stackFrames);
1718
+ else scheduler$1.invalidate(frames, stackFrames);
2437
1719
  }
2438
- function advance(timestamp) {
2439
- scheduler.getScheduler().step(timestamp);
1720
+ function advance(timestamp, runGlobalEffects, state) {
1721
+ const rootId = state?.internal?.rootId;
1722
+ const scheduler$1 = scheduler.getScheduler();
1723
+ if (rootId) scheduler$1.stepRoot(rootId, timestamp);
1724
+ else scheduler$1.step(timestamp);
2440
1725
  }
2441
1726
 
2442
- const version = "10.0.0-alpha.3";
1727
+ const version = "10.0.0-alpha.5";
2443
1728
  const packageData = {
2444
1729
  version: version};
2445
1730
 
@@ -13312,390 +12597,973 @@ Check the top-level render call using <` + i + ">.");
13312
12597
  var i = x.H;
13313
12598
  x.H = $o;
13314
12599
  try {
13315
- return Br(e, n, o);
13316
- } finally {
13317
- x.H = i;
12600
+ return Br(e, n, o);
12601
+ } finally {
12602
+ x.H = i;
12603
+ }
12604
+ }, useRef: function() {
12605
+ return z = "useRef", D(), N(), xe().memoizedState;
12606
+ }, useState: function() {
12607
+ z = "useState", D(), N();
12608
+ var e = x.H;
12609
+ x.H = $o;
12610
+ try {
12611
+ return Br(gr);
12612
+ } finally {
12613
+ x.H = e;
12614
+ }
12615
+ }, useDebugValue: function() {
12616
+ z = "useDebugValue", D(), N();
12617
+ }, useDeferredValue: function(e, n) {
12618
+ return z = "useDeferredValue", D(), N(), nc(e, n);
12619
+ }, useTransition: function() {
12620
+ return z = "useTransition", D(), N(), Qp();
12621
+ }, useSyncExternalStore: function(e, n, o) {
12622
+ return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
12623
+ }, useId: function() {
12624
+ return z = "useId", D(), N(), xe().memoizedState;
12625
+ }, useFormState: function(e) {
12626
+ return z = "useFormState", D(), N(), hs(e);
12627
+ }, useActionState: function(e) {
12628
+ return z = "useActionState", D(), N(), hs(e);
12629
+ }, useOptimistic: function(e, n) {
12630
+ return z = "useOptimistic", D(), N(), rf(e, n);
12631
+ }, useMemoCache: function(e) {
12632
+ return D(), Oa(e);
12633
+ }, useHostTransitionStatus: ia, useCacheRefresh: function() {
12634
+ return z = "useCacheRefresh", N(), xe().memoizedState;
12635
+ }, useEffectEvent: function(e) {
12636
+ return z = "useEffectEvent", D(), N(), oa(e);
12637
+ } }, dm = { readContext: function(e) {
12638
+ return Ce(), Ee(e);
12639
+ }, use: function(e) {
12640
+ return D(), we(e);
12641
+ }, useCallback: function(e, n) {
12642
+ return z = "useCallback", D(), N(), Ma(e, n);
12643
+ }, useContext: function(e) {
12644
+ return z = "useContext", D(), N(), Ee(e);
12645
+ }, useEffect: function(e, n) {
12646
+ z = "useEffect", D(), N(), Qn(2048, Ut, e, n);
12647
+ }, useImperativeHandle: function(e, n, o) {
12648
+ return z = "useImperativeHandle", D(), N(), aa(e, n, o);
12649
+ }, useInsertionEffect: function(e, n) {
12650
+ return z = "useInsertionEffect", D(), N(), Qn(4, Wt, e, n);
12651
+ }, useLayoutEffect: function(e, n) {
12652
+ return z = "useLayoutEffect", D(), N(), Qn(4, Rr, e, n);
12653
+ }, useMemo: function(e, n) {
12654
+ z = "useMemo", D(), N();
12655
+ var o = x.H;
12656
+ x.H = $o;
12657
+ try {
12658
+ return Vi(e, n);
12659
+ } finally {
12660
+ x.H = o;
12661
+ }
12662
+ }, useReducer: function(e, n, o) {
12663
+ z = "useReducer", D(), N();
12664
+ var i = x.H;
12665
+ x.H = $o;
12666
+ try {
12667
+ return Qi(e, n, o);
12668
+ } finally {
12669
+ x.H = i;
12670
+ }
12671
+ }, useRef: function() {
12672
+ return z = "useRef", D(), N(), xe().memoizedState;
12673
+ }, useState: function() {
12674
+ z = "useState", D(), N();
12675
+ var e = x.H;
12676
+ x.H = $o;
12677
+ try {
12678
+ return Qi(gr);
12679
+ } finally {
12680
+ x.H = e;
12681
+ }
12682
+ }, useDebugValue: function() {
12683
+ z = "useDebugValue", D(), N();
12684
+ }, useDeferredValue: function(e, n) {
12685
+ return z = "useDeferredValue", D(), N(), sf(e, n);
12686
+ }, useTransition: function() {
12687
+ return z = "useTransition", D(), N(), Ro();
12688
+ }, useSyncExternalStore: function(e, n, o) {
12689
+ return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
12690
+ }, useId: function() {
12691
+ return z = "useId", D(), N(), xe().memoizedState;
12692
+ }, useFormState: function(e) {
12693
+ return z = "useFormState", D(), N(), $t(e);
12694
+ }, useActionState: function(e) {
12695
+ return z = "useActionState", D(), N(), $t(e);
12696
+ }, useOptimistic: function(e, n) {
12697
+ return z = "useOptimistic", D(), N(), of(e, n);
12698
+ }, useMemoCache: function(e) {
12699
+ return D(), Oa(e);
12700
+ }, useHostTransitionStatus: ia, useCacheRefresh: function() {
12701
+ return z = "useCacheRefresh", N(), xe().memoizedState;
12702
+ }, useEffectEvent: function(e) {
12703
+ return z = "useEffectEvent", D(), N(), oa(e);
12704
+ } };
12705
+ 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();
12706
+ Object.freeze(Fy);
12707
+ var zg = { enqueueSetState: function(e, n, o) {
12708
+ e = e._reactInternals;
12709
+ var i = Nt(e), s = zo(i);
12710
+ 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));
12711
+ }, enqueueReplaceState: function(e, n, o) {
12712
+ e = e._reactInternals;
12713
+ var i = Nt(e), s = zo(i);
12714
+ 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));
12715
+ }, enqueueForceUpdate: function(e, n) {
12716
+ e = e._reactInternals;
12717
+ var o = Nt(e), i = zo(o);
12718
+ 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));
12719
+ } }, 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;
12720
+ Yy = /* @__PURE__ */ new Set();
12721
+ 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) {
12722
+ var n = Ee(un), o = n.data.get(e);
12723
+ return o === void 0 && (o = e(), n.data.set(e, o)), o;
12724
+ }, cacheSignal: function() {
12725
+ return Ee(un).controller.signal;
12726
+ }, getOwner: function() {
12727
+ return di;
12728
+ } }, pm = 0, hm = 1, mm = 2, gm = 3, ym = 4;
12729
+ if (typeof Symbol == "function" && Symbol.for) {
12730
+ var bp = Symbol.for;
12731
+ pm = bp("selector.component"), hm = bp("selector.has_pseudo_class"), mm = bp("selector.role"), gm = bp("selector.test_id"), ym = bp("selector.text");
12732
+ }
12733
+ 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;
12734
+ try {
12735
+ var o0 = Object.preventExtensions({});
12736
+ } catch {
12737
+ pb = true;
12738
+ }
12739
+ var hb = false, mb = {}, gb = null, yb = null, bb = null, vb = null, Sb = null, kb = null, wb = null, Pb = null, xb = null, zb = null;
12740
+ return gb = function(e, n, o, i) {
12741
+ 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));
12742
+ }, yb = function(e, n, o) {
12743
+ 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));
12744
+ }, bb = function(e, n, o, i) {
12745
+ 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));
12746
+ }, vb = function(e, n, o) {
12747
+ 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);
12748
+ }, Sb = function(e, n) {
12749
+ e.pendingProps = du(e.memoizedProps, n, 0), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
12750
+ }, kb = function(e, n, o) {
12751
+ e.pendingProps = F(e.memoizedProps, n, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
12752
+ }, wb = function(e) {
12753
+ var n = On(e, 2);
12754
+ n !== null && We(n, e, 2);
12755
+ }, Pb = function(e) {
12756
+ var n = ut(), o = On(e, n);
12757
+ o !== null && We(o, e, n);
12758
+ }, xb = function(e) {
12759
+ pu = e;
12760
+ }, zb = function(e) {
12761
+ fu = e;
12762
+ }, le.attemptContinuousHydration = function(e) {
12763
+ if (e.tag === 13 || e.tag === 31) {
12764
+ var n = On(e, 67108864);
12765
+ n !== null && We(n, e, 67108864), rl(e, 67108864);
12766
+ }
12767
+ }, le.attemptHydrationAtCurrentPriority = function(e) {
12768
+ if (e.tag === 13 || e.tag === 31) {
12769
+ var n = Nt(e);
12770
+ n = Xo(n);
12771
+ var o = On(e, n);
12772
+ o !== null && We(o, e, n), rl(e, n);
12773
+ }
12774
+ }, le.attemptSynchronousHydration = function(e) {
12775
+ switch (e.tag) {
12776
+ case 3:
12777
+ if (e = e.stateNode, e.current.memoizedState.isDehydrated) {
12778
+ var n = _t(e.pendingLanes);
12779
+ if (n !== 0) {
12780
+ for (e.pendingLanes |= 2, e.entangledLanes |= 2; n; ) {
12781
+ var o = 1 << 31 - vn(n);
12782
+ e.entanglements[1] |= o, n &= ~o;
12783
+ }
12784
+ Kn(e), (ye & (Zn | uo)) === Jn && (Pp = me() + Fg, Wa(0));
12785
+ }
12786
+ }
12787
+ break;
12788
+ case 31:
12789
+ case 13:
12790
+ n = On(e, 2), n !== null && We(n, e, 2), Ls(), rl(e, 2);
12791
+ }
12792
+ }, le.batchedUpdates = function(e, n) {
12793
+ return e(n);
12794
+ }, le.createComponentSelector = function(e) {
12795
+ return { $$typeof: pm, value: e };
12796
+ }, le.createContainer = function(e, n, o, i, s, u, f, p, g, S) {
12797
+ return Ka(e, n, false, null, o, i, u, null, f, p, g, S);
12798
+ }, le.createHasPseudoClassSelector = function(e) {
12799
+ return { $$typeof: hm, value: e };
12800
+ }, le.createHydrationContainer = function(e, n, o, i, s, u, f, p, g, S, T, _, I, O) {
12801
+ 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;
12802
+ }, le.createPortal = function(e, n, o) {
12803
+ var i = 3 < arguments.length && arguments[3] !== void 0 ? arguments[3] : null;
12804
+ try {
12805
+ vt(i);
12806
+ var s = false;
12807
+ } catch {
12808
+ s = true;
13318
12809
  }
13319
- }, useRef: function() {
13320
- return z = "useRef", D(), N(), xe().memoizedState;
13321
- }, useState: function() {
13322
- z = "useState", D(), N();
13323
- var e = x.H;
13324
- x.H = $o;
12810
+ 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 };
12811
+ }, le.createRoleSelector = function(e) {
12812
+ return { $$typeof: mm, value: e };
12813
+ }, le.createTestNameSelector = function(e) {
12814
+ return { $$typeof: gm, value: e };
12815
+ }, le.createTextSelector = function(e) {
12816
+ return { $$typeof: ym, value: e };
12817
+ }, le.defaultOnCaughtError = function(e) {
12818
+ 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") + ".");
12819
+ typeof e == "object" && e !== null && typeof e.environmentName == "string" ? ri("error", [`%o
12820
+
12821
+ %s
12822
+
12823
+ %s
12824
+ `, e, n, o], e.environmentName)() : console.error(`%o
12825
+
12826
+ %s
12827
+
12828
+ %s
12829
+ `, e, n, o);
12830
+ }, le.defaultOnRecoverableError = function(e) {
12831
+ qg(e);
12832
+ }, le.defaultOnUncaughtError = function(e) {
12833
+ qg(e), console.warn(`%s
12834
+
12835
+ %s
12836
+ `, 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.
12837
+ Visit https://react.dev/link/error-boundaries to learn more about error boundaries.`);
12838
+ }, le.deferredUpdates = function(e) {
12839
+ var n = x.T, o = wt();
13325
12840
  try {
13326
- return Br(gr);
12841
+ return an(32), x.T = null, e();
13327
12842
  } finally {
13328
- x.H = e;
12843
+ an(o), x.T = n;
13329
12844
  }
13330
- }, useDebugValue: function() {
13331
- z = "useDebugValue", D(), N();
13332
- }, useDeferredValue: function(e, n) {
13333
- return z = "useDeferredValue", D(), N(), nc(e, n);
13334
- }, useTransition: function() {
13335
- return z = "useTransition", D(), N(), Qp();
13336
- }, useSyncExternalStore: function(e, n, o) {
13337
- return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
13338
- }, useId: function() {
13339
- return z = "useId", D(), N(), xe().memoizedState;
13340
- }, useFormState: function(e) {
13341
- return z = "useFormState", D(), N(), hs(e);
13342
- }, useActionState: function(e) {
13343
- return z = "useActionState", D(), N(), hs(e);
13344
- }, useOptimistic: function(e, n) {
13345
- return z = "useOptimistic", D(), N(), rf(e, n);
13346
- }, useMemoCache: function(e) {
13347
- return D(), Oa(e);
13348
- }, useHostTransitionStatus: ia, useCacheRefresh: function() {
13349
- return z = "useCacheRefresh", N(), xe().memoizedState;
13350
- }, useEffectEvent: function(e) {
13351
- return z = "useEffectEvent", D(), N(), oa(e);
13352
- } }, dm = { readContext: function(e) {
13353
- return Ce(), Ee(e);
13354
- }, use: function(e) {
13355
- return D(), we(e);
13356
- }, useCallback: function(e, n) {
13357
- return z = "useCallback", D(), N(), Ma(e, n);
13358
- }, useContext: function(e) {
13359
- return z = "useContext", D(), N(), Ee(e);
13360
- }, useEffect: function(e, n) {
13361
- z = "useEffect", D(), N(), Qn(2048, Ut, e, n);
13362
- }, useImperativeHandle: function(e, n, o) {
13363
- return z = "useImperativeHandle", D(), N(), aa(e, n, o);
13364
- }, useInsertionEffect: function(e, n) {
13365
- return z = "useInsertionEffect", D(), N(), Qn(4, Wt, e, n);
13366
- }, useLayoutEffect: function(e, n) {
13367
- return z = "useLayoutEffect", D(), N(), Qn(4, Rr, e, n);
13368
- }, useMemo: function(e, n) {
13369
- z = "useMemo", D(), N();
13370
- var o = x.H;
13371
- x.H = $o;
12845
+ }, le.discreteUpdates = function(e, n, o, i, s) {
12846
+ var u = x.T, f = wt();
13372
12847
  try {
13373
- return Vi(e, n);
12848
+ return an(2), x.T = null, e(n, o, i, s);
13374
12849
  } finally {
13375
- x.H = o;
12850
+ an(f), x.T = u, ye === Jn && (Pp = me() + Fg);
13376
12851
  }
13377
- }, useReducer: function(e, n, o) {
13378
- z = "useReducer", D(), N();
13379
- var i = x.H;
13380
- x.H = $o;
13381
- try {
13382
- return Qi(e, n, o);
13383
- } finally {
13384
- x.H = i;
12852
+ }, le.findAllNodes = kc, le.findBoundingRects = function(e, n) {
12853
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12854
+ n = kc(e, n), e = [];
12855
+ for (var o = 0; o < n.length; o++) e.push(ma(n[o]));
12856
+ for (n = e.length - 1; 0 < n; n--) {
12857
+ o = e[n];
12858
+ 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) {
12859
+ var g = e[p], S = g.x, T = S + g.width, _ = g.y, I = _ + g.height;
12860
+ if (i >= S && u >= _ && s <= T && f <= I) {
12861
+ e.splice(n, 1);
12862
+ break;
12863
+ } else if (i !== S || o.width !== g.width || I < u || _ > f) {
12864
+ if (!(u !== _ || o.height !== g.height || T < i || S > s)) {
12865
+ S > i && (g.width += S - i, g.x = i), T < s && (g.width = s - S), e.splice(n, 1);
12866
+ break;
12867
+ }
12868
+ } else {
12869
+ _ > u && (g.height += _ - u, g.y = u), I < f && (g.height = f - _), e.splice(n, 1);
12870
+ break;
12871
+ }
12872
+ }
13385
12873
  }
13386
- }, useRef: function() {
13387
- return z = "useRef", D(), N(), xe().memoizedState;
13388
- }, useState: function() {
13389
- z = "useState", D(), N();
13390
- var e = x.H;
13391
- x.H = $o;
12874
+ return e;
12875
+ }, le.findHostInstance = function(e) {
12876
+ var n = e._reactInternals;
12877
+ 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));
12878
+ return e = mu(n), e === null ? null : ot(e.stateNode);
12879
+ }, le.findHostInstanceWithNoPortals = function(e) {
12880
+ return e = Ed(e), e = e !== null ? _p(e) : null, e === null ? null : ot(e.stateNode);
12881
+ }, le.findHostInstanceWithWarning = function(e, n) {
12882
+ var o = e._reactInternals;
12883
+ 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));
12884
+ if (e = mu(o), e === null) return null;
12885
+ if (e.mode & 8) {
12886
+ var i = G(o) || "Component";
12887
+ mb[i] || (mb[i] = true, B(e, function() {
12888
+ 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);
12889
+ }));
12890
+ }
12891
+ return ot(e.stateNode);
12892
+ }, le.flushPassiveEffects = el, le.flushSyncFromReconciler = function(e) {
12893
+ var n = ye;
12894
+ ye |= 1;
12895
+ var o = x.T, i = wt();
13392
12896
  try {
13393
- return Qi(gr);
12897
+ if (an(2), x.T = null, e) return e();
13394
12898
  } finally {
13395
- x.H = e;
12899
+ an(i), x.T = o, ye = n, (ye & (Zn | uo)) === Jn && Wa(0);
12900
+ }
12901
+ }, le.flushSyncWork = Ls, le.focusWithin = function(e, n) {
12902
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12903
+ for (e = Ef(e), n = hh(e, n), n = Array.from(n), e = 0; e < n.length; ) {
12904
+ var o = n[e++], i = o.tag;
12905
+ if (!Kr(o)) {
12906
+ if ((i === 5 || i === 26 || i === 27) && Ft(o.stateNode)) return true;
12907
+ for (o = o.child; o !== null; ) n.push(o), o = o.sibling;
12908
+ }
12909
+ }
12910
+ return false;
12911
+ }, le.getFindAllNodesFailureDescription = function(e, n) {
12912
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12913
+ var o = 0, i = [];
12914
+ e = [Ef(e), 0];
12915
+ for (var s = 0; s < e.length; ) {
12916
+ var u = e[s++], f = u.tag, p = e[s++], g = n[p];
12917
+ 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;
12918
+ }
12919
+ if (o < n.length) {
12920
+ for (e = []; o < n.length; o++) e.push(Sc(n[o]));
12921
+ return `findAllNodes was able to match part of the selector:
12922
+ ` + (i.join(" > ") + `
12923
+
12924
+ No matching component was found for:
12925
+ `) + e.join(" > ");
12926
+ }
12927
+ return null;
12928
+ }, le.getPublicRootInstance = function(e) {
12929
+ if (e = e.current, !e.child) return null;
12930
+ switch (e.child.tag) {
12931
+ case 27:
12932
+ case 5:
12933
+ return ot(e.child.stateNode);
12934
+ default:
12935
+ return e.child.stateNode;
12936
+ }
12937
+ }, le.injectIntoDevTools = function() {
12938
+ var e = { bundleType: 1, version: Jt, rendererPackageName: Zt, currentDispatcherRef: x, reconcilerVersion: "19.2.0" };
12939
+ 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);
12940
+ }, le.isAlreadyRendering = Ns, le.observeVisibleRects = function(e, n, o, i) {
12941
+ function s() {
12942
+ var S = kc(e, n);
12943
+ u.forEach(function(T) {
12944
+ 0 > S.indexOf(T) && g(T);
12945
+ }), S.forEach(function(T) {
12946
+ 0 > u.indexOf(T) && p(T);
12947
+ });
12948
+ }
12949
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12950
+ var u = kc(e, n);
12951
+ o = zr(u, o, i);
12952
+ var f = o.disconnect, p = o.observe, g = o.unobserve;
12953
+ return bm.push(s), { disconnect: function() {
12954
+ var S = bm.indexOf(s);
12955
+ 0 <= S && bm.splice(S, 1), f();
12956
+ } };
12957
+ }, le.shouldError = function(e) {
12958
+ return pu(e);
12959
+ }, le.shouldSuspend = function(e) {
12960
+ return fu(e);
12961
+ }, le.startHostTransition = function(e, n, o, i) {
12962
+ if (e.tag !== 5) throw Error("Expected the form instance to be a HostComponent. This is a bug in React.");
12963
+ var s = uf(e).queue;
12964
+ Hp(e), nt(e, s, n, Xt, o === null ? Em : function() {
12965
+ x.T === null && console.error("requestFormReset was called outside a transition or action. To fix, move to an action, or wrap with startTransition.");
12966
+ var u = uf(e);
12967
+ return u.next === null && (u = e.alternate.memoizedState), qi(e, u.next.queue, {}, Nt(e)), o(i);
12968
+ });
12969
+ }, le.updateContainer = function(e, n, o, i) {
12970
+ var s = n.current, u = Nt(s);
12971
+ return As(s, u, e, n, o, i), u;
12972
+ }, le.updateContainerSync = Wh, le;
12973
+ }, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true }));
12974
+ })(Mg)), Mg.exports;
12975
+ }
12976
+ var Eb;
12977
+ function n0() {
12978
+ return Eb || (Eb = 1, process.env.NODE_ENV === "production" ? Rm.exports = Kb() : Rm.exports = e0()), Rm.exports;
12979
+ }
12980
+ var t0 = n0();
12981
+ const r0 = Xb(t0);
12982
+
12983
+ const DEFAULT_POINTER_ID = 0;
12984
+ const XR_POINTER_ID_START = 1e3;
12985
+ function getPointerState(internal, pointerId) {
12986
+ let state = internal.pointerMap.get(pointerId);
12987
+ if (!state) {
12988
+ state = {
12989
+ hovered: /* @__PURE__ */ new Map(),
12990
+ captured: /* @__PURE__ */ new Map(),
12991
+ initialClick: [0, 0],
12992
+ initialHits: []
12993
+ };
12994
+ internal.pointerMap.set(pointerId, state);
12995
+ }
12996
+ return state;
12997
+ }
12998
+ function getPointerId(event) {
12999
+ return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
13000
+ }
13001
+ function makeId(event) {
13002
+ return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
13003
+ }
13004
+ function releaseInternalPointerCapture(internal, obj, pointerId) {
13005
+ const pointerState = internal.pointerMap.get(pointerId);
13006
+ if (!pointerState) return;
13007
+ const captureData = pointerState.captured.get(obj);
13008
+ if (captureData) {
13009
+ pointerState.captured.delete(obj);
13010
+ try {
13011
+ captureData.target.releasePointerCapture?.(pointerId);
13012
+ } catch {
13013
+ }
13014
+ }
13015
+ }
13016
+ function swapInteractivity(store, object, newObject) {
13017
+ const { internal } = store.getState();
13018
+ for (let i = 0; i < internal.interaction.length; i++) {
13019
+ if (internal.interaction[i] === object) internal.interaction[i] = newObject;
13020
+ }
13021
+ for (const pointerState of internal.pointerMap.values()) {
13022
+ for (let i = 0; i < pointerState.initialHits.length; i++) {
13023
+ if (pointerState.initialHits[i] === object) pointerState.initialHits[i] = newObject;
13024
+ }
13025
+ pointerState.hovered.forEach((value, key) => {
13026
+ if (value.eventObject === object || value.object === object) {
13027
+ pointerState.hovered.delete(key);
13028
+ const next = {
13029
+ ...value,
13030
+ eventObject: value.eventObject === object ? newObject : value.eventObject,
13031
+ object: value.object === object ? newObject : value.object
13032
+ };
13033
+ pointerState.hovered.set(makeId(next), next);
13034
+ }
13035
+ });
13036
+ const captureData = pointerState.captured.get(object);
13037
+ if (captureData) {
13038
+ pointerState.captured.delete(object);
13039
+ pointerState.captured.set(newObject, {
13040
+ ...captureData,
13041
+ intersection: {
13042
+ ...captureData.intersection,
13043
+ object: captureData.intersection.object === object ? newObject : captureData.intersection.object,
13044
+ eventObject: captureData.intersection.eventObject === object ? newObject : captureData.intersection.eventObject
13396
13045
  }
13397
- }, useDebugValue: function() {
13398
- z = "useDebugValue", D(), N();
13399
- }, useDeferredValue: function(e, n) {
13400
- return z = "useDeferredValue", D(), N(), sf(e, n);
13401
- }, useTransition: function() {
13402
- return z = "useTransition", D(), N(), Ro();
13403
- }, useSyncExternalStore: function(e, n, o) {
13404
- return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
13405
- }, useId: function() {
13406
- return z = "useId", D(), N(), xe().memoizedState;
13407
- }, useFormState: function(e) {
13408
- return z = "useFormState", D(), N(), $t(e);
13409
- }, useActionState: function(e) {
13410
- return z = "useActionState", D(), N(), $t(e);
13411
- }, useOptimistic: function(e, n) {
13412
- return z = "useOptimistic", D(), N(), of(e, n);
13413
- }, useMemoCache: function(e) {
13414
- return D(), Oa(e);
13415
- }, useHostTransitionStatus: ia, useCacheRefresh: function() {
13416
- return z = "useCacheRefresh", N(), xe().memoizedState;
13417
- }, useEffectEvent: function(e) {
13418
- return z = "useEffectEvent", D(), N(), oa(e);
13419
- } };
13420
- 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();
13421
- Object.freeze(Fy);
13422
- var zg = { enqueueSetState: function(e, n, o) {
13423
- e = e._reactInternals;
13424
- var i = Nt(e), s = zo(i);
13425
- 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));
13426
- }, enqueueReplaceState: function(e, n, o) {
13427
- e = e._reactInternals;
13428
- var i = Nt(e), s = zo(i);
13429
- 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));
13430
- }, enqueueForceUpdate: function(e, n) {
13431
- e = e._reactInternals;
13432
- var o = Nt(e), i = zo(o);
13433
- 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));
13434
- } }, 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;
13435
- Yy = /* @__PURE__ */ new Set();
13436
- 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) {
13437
- var n = Ee(un), o = n.data.get(e);
13438
- return o === void 0 && (o = e(), n.data.set(e, o)), o;
13439
- }, cacheSignal: function() {
13440
- return Ee(un).controller.signal;
13441
- }, getOwner: function() {
13442
- return di;
13443
- } }, pm = 0, hm = 1, mm = 2, gm = 3, ym = 4;
13444
- if (typeof Symbol == "function" && Symbol.for) {
13445
- var bp = Symbol.for;
13446
- pm = bp("selector.component"), hm = bp("selector.has_pseudo_class"), mm = bp("selector.role"), gm = bp("selector.test_id"), ym = bp("selector.text");
13046
+ });
13047
+ }
13048
+ }
13049
+ unregisterVisibility(store, object);
13050
+ }
13051
+ function removeInteractivity(store, object) {
13052
+ const { internal } = store.getState();
13053
+ internal.interaction = internal.interaction.filter((o) => o !== object);
13054
+ for (const [pointerId, pointerState] of internal.pointerMap) {
13055
+ pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
13056
+ pointerState.hovered.forEach((value, key) => {
13057
+ if (value.eventObject === object || value.object === object) {
13058
+ pointerState.hovered.delete(key);
13447
13059
  }
13448
- 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;
13449
- try {
13450
- var o0 = Object.preventExtensions({});
13451
- } catch {
13452
- pb = true;
13060
+ });
13061
+ if (pointerState.captured.has(object)) {
13062
+ releaseInternalPointerCapture(internal, object, pointerId);
13063
+ }
13064
+ }
13065
+ unregisterVisibility(store, object);
13066
+ }
13067
+ function createEvents(store) {
13068
+ function calculateDistance(event, pointerId) {
13069
+ const { internal } = store.getState();
13070
+ const pointerState = internal.pointerMap.get(pointerId);
13071
+ if (!pointerState) return 0;
13072
+ const [initialX, initialY] = pointerState.initialClick;
13073
+ const dx = event.offsetX - initialX;
13074
+ const dy = event.offsetY - initialY;
13075
+ return Math.round(Math.sqrt(dx * dx + dy * dy));
13076
+ }
13077
+ function filterPointerEvents(objects) {
13078
+ return objects.filter(
13079
+ (obj) => ["Move", "Over", "Enter", "Out", "Leave"].some(
13080
+ (name) => obj.__r3f?.handlers["onPointer" + name]
13081
+ ) || ["OverEnter", "OverLeave", "Over"].some(
13082
+ (name) => obj.__r3f?.handlers["onDrag" + name]
13083
+ ) || obj.__r3f?.handlers.onDrop
13084
+ );
13085
+ }
13086
+ function intersect(event, filter) {
13087
+ const state = store.getState();
13088
+ const duplicates = /* @__PURE__ */ new Set();
13089
+ const intersections = [];
13090
+ const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction;
13091
+ for (let i = 0; i < eventsObjects.length; i++) {
13092
+ const state2 = getRootState(eventsObjects[i]);
13093
+ if (state2) {
13094
+ state2.raycaster.camera = void 0;
13453
13095
  }
13454
- var hb = false, mb = {}, gb = null, yb = null, bb = null, vb = null, Sb = null, kb = null, wb = null, Pb = null, xb = null, zb = null;
13455
- return gb = function(e, n, o, i) {
13456
- 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));
13457
- }, yb = function(e, n, o) {
13458
- 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));
13459
- }, bb = function(e, n, o, i) {
13460
- 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));
13461
- }, vb = function(e, n, o) {
13462
- 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);
13463
- }, Sb = function(e, n) {
13464
- e.pendingProps = du(e.memoizedProps, n, 0), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
13465
- }, kb = function(e, n, o) {
13466
- e.pendingProps = F(e.memoizedProps, n, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
13467
- }, wb = function(e) {
13468
- var n = On(e, 2);
13469
- n !== null && We(n, e, 2);
13470
- }, Pb = function(e) {
13471
- var n = ut(), o = On(e, n);
13472
- o !== null && We(o, e, n);
13473
- }, xb = function(e) {
13474
- pu = e;
13475
- }, zb = function(e) {
13476
- fu = e;
13477
- }, le.attemptContinuousHydration = function(e) {
13478
- if (e.tag === 13 || e.tag === 31) {
13479
- var n = On(e, 67108864);
13480
- n !== null && We(n, e, 67108864), rl(e, 67108864);
13096
+ }
13097
+ if (!state.previousRoot) {
13098
+ state.events.compute?.(event, state);
13099
+ }
13100
+ function handleRaycast(obj) {
13101
+ const state2 = getRootState(obj);
13102
+ if (!state2 || !state2.events.enabled || state2.raycaster.camera === null) return [];
13103
+ if (state2.raycaster.camera === void 0) {
13104
+ state2.events.compute?.(event, state2, state2.previousRoot?.getState());
13105
+ if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
13106
+ }
13107
+ if (!state2.raycaster.camera) return [];
13108
+ obj.updateWorldMatrix(true, true);
13109
+ return state2.raycaster.intersectObject(obj, true);
13110
+ }
13111
+ let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
13112
+ const aInteractivePriority = a.object.userData?.interactivePriority;
13113
+ const bInteractivePriority = b.object.userData?.interactivePriority;
13114
+ if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
13115
+ if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
13116
+ if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
13117
+ if (aInteractivePriority !== bInteractivePriority) {
13118
+ return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
13481
13119
  }
13482
- }, le.attemptHydrationAtCurrentPriority = function(e) {
13483
- if (e.tag === 13 || e.tag === 31) {
13484
- var n = Nt(e);
13485
- n = Xo(n);
13486
- var o = On(e, n);
13487
- o !== null && We(o, e, n), rl(e, n);
13120
+ }
13121
+ const aState = getRootState(a.object);
13122
+ const bState = getRootState(b.object);
13123
+ const aPriority = aState?.events?.priority ?? 1;
13124
+ const bPriority = bState?.events?.priority ?? 1;
13125
+ return bPriority - aPriority || a.distance - b.distance;
13126
+ }).filter((item) => {
13127
+ const id = makeId(item);
13128
+ if (duplicates.has(id)) return false;
13129
+ duplicates.add(id);
13130
+ return true;
13131
+ });
13132
+ if (state.events.filter) hits = state.events.filter(hits, state);
13133
+ for (const hit of hits) {
13134
+ let eventObject = hit.object;
13135
+ while (eventObject) {
13136
+ if (eventObject.__r3f?.eventCount) {
13137
+ intersections.push({ ...hit, eventObject });
13488
13138
  }
13489
- }, le.attemptSynchronousHydration = function(e) {
13490
- switch (e.tag) {
13491
- case 3:
13492
- if (e = e.stateNode, e.current.memoizedState.isDehydrated) {
13493
- var n = _t(e.pendingLanes);
13494
- if (n !== 0) {
13495
- for (e.pendingLanes |= 2, e.entangledLanes |= 2; n; ) {
13496
- var o = 1 << 31 - vn(n);
13497
- e.entanglements[1] |= o, n &= ~o;
13139
+ eventObject = eventObject.parent;
13140
+ }
13141
+ }
13142
+ if ("pointerId" in event) {
13143
+ const pointerId = event.pointerId;
13144
+ const pointerState = state.internal.pointerMap.get(pointerId);
13145
+ if (pointerState?.captured.size) {
13146
+ for (const captureData of pointerState.captured.values()) {
13147
+ if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
13148
+ }
13149
+ }
13150
+ }
13151
+ return intersections;
13152
+ }
13153
+ function handleIntersects(intersections, event, delta, callback) {
13154
+ if (intersections.length) {
13155
+ const localState = { stopped: false };
13156
+ for (const hit of intersections) {
13157
+ const state = getRootState(hit.object);
13158
+ if (state) {
13159
+ const { raycaster, pointer, camera, internal } = state;
13160
+ const unprojectedPoint = new webgpu.Vector3(pointer.x, pointer.y, 0).unproject(camera);
13161
+ const hasPointerCapture = (id) => {
13162
+ const pointerState = internal.pointerMap.get(id);
13163
+ return pointerState?.captured.has(hit.eventObject) ?? false;
13164
+ };
13165
+ const setPointerCapture = (id) => {
13166
+ const captureData = { intersection: hit, target: event.target };
13167
+ const pointerState = getPointerState(internal, id);
13168
+ pointerState.captured.set(hit.eventObject, captureData);
13169
+ event.target.setPointerCapture(id);
13170
+ };
13171
+ const releasePointerCapture = (id) => {
13172
+ releaseInternalPointerCapture(internal, hit.eventObject, id);
13173
+ };
13174
+ const extractEventProps = {};
13175
+ for (const prop in event) {
13176
+ const property = event[prop];
13177
+ if (typeof property !== "function") extractEventProps[prop] = property;
13178
+ }
13179
+ const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
13180
+ const raycastEvent = {
13181
+ ...hit,
13182
+ ...extractEventProps,
13183
+ pointer,
13184
+ intersections,
13185
+ stopped: localState.stopped,
13186
+ delta,
13187
+ unprojectedPoint,
13188
+ ray: raycaster.ray,
13189
+ camera,
13190
+ pointerId: eventPointerId,
13191
+ // Hijack stopPropagation, which just sets a flag
13192
+ stopPropagation() {
13193
+ const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
13194
+ if (
13195
+ // ...if this pointer hasn't been captured
13196
+ !pointerState?.captured.size || // ... or if the hit object is capturing the pointer
13197
+ pointerState.captured.has(hit.eventObject)
13198
+ ) {
13199
+ raycastEvent.stopped = localState.stopped = true;
13200
+ if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
13201
+ const higher = intersections.slice(0, intersections.indexOf(hit));
13202
+ cancelPointer([...higher, hit], eventPointerId);
13498
13203
  }
13499
- Kn(e), (ye & (Zn | uo)) === Jn && (Pp = me() + Fg, Wa(0));
13500
13204
  }
13501
- }
13502
- break;
13503
- case 31:
13504
- case 13:
13505
- n = On(e, 2), n !== null && We(n, e, 2), Ls(), rl(e, 2);
13205
+ },
13206
+ // there should be a distinction between target and currentTarget
13207
+ target: { hasPointerCapture, setPointerCapture, releasePointerCapture },
13208
+ currentTarget: { hasPointerCapture, setPointerCapture, releasePointerCapture },
13209
+ nativeEvent: event
13210
+ };
13211
+ callback(raycastEvent);
13212
+ if (localState.stopped === true) break;
13506
13213
  }
13507
- }, le.batchedUpdates = function(e, n) {
13508
- return e(n);
13509
- }, le.createComponentSelector = function(e) {
13510
- return { $$typeof: pm, value: e };
13511
- }, le.createContainer = function(e, n, o, i, s, u, f, p, g, S) {
13512
- return Ka(e, n, false, null, o, i, u, null, f, p, g, S);
13513
- }, le.createHasPseudoClassSelector = function(e) {
13514
- return { $$typeof: hm, value: e };
13515
- }, le.createHydrationContainer = function(e, n, o, i, s, u, f, p, g, S, T, _, I, O) {
13516
- 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;
13517
- }, le.createPortal = function(e, n, o) {
13518
- var i = 3 < arguments.length && arguments[3] !== void 0 ? arguments[3] : null;
13519
- try {
13520
- vt(i);
13521
- var s = false;
13522
- } catch {
13523
- s = true;
13214
+ }
13215
+ }
13216
+ return intersections;
13217
+ }
13218
+ function cancelPointer(intersections, pointerId) {
13219
+ const { internal } = store.getState();
13220
+ const pid = pointerId ?? DEFAULT_POINTER_ID;
13221
+ const pointerState = internal.pointerMap.get(pid);
13222
+ if (!pointerState) return;
13223
+ for (const [hoveredId, hoveredObj] of pointerState.hovered) {
13224
+ if (!intersections.length || !intersections.find(
13225
+ (hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
13226
+ )) {
13227
+ const eventObject = hoveredObj.eventObject;
13228
+ const instance = eventObject.__r3f;
13229
+ pointerState.hovered.delete(hoveredId);
13230
+ if (instance?.eventCount) {
13231
+ const handlers = instance.handlers;
13232
+ const data = { ...hoveredObj, intersections };
13233
+ handlers.onPointerOut?.(data);
13234
+ handlers.onPointerLeave?.(data);
13235
+ handlers.onDragOverLeave?.(data);
13524
13236
  }
13525
- 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 };
13526
- }, le.createRoleSelector = function(e) {
13527
- return { $$typeof: mm, value: e };
13528
- }, le.createTestNameSelector = function(e) {
13529
- return { $$typeof: gm, value: e };
13530
- }, le.createTextSelector = function(e) {
13531
- return { $$typeof: ym, value: e };
13532
- }, le.defaultOnCaughtError = function(e) {
13533
- 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") + ".");
13534
- typeof e == "object" && e !== null && typeof e.environmentName == "string" ? ri("error", [`%o
13535
-
13536
- %s
13537
-
13538
- %s
13539
- `, e, n, o], e.environmentName)() : console.error(`%o
13540
-
13541
- %s
13542
-
13543
- %s
13544
- `, e, n, o);
13545
- }, le.defaultOnRecoverableError = function(e) {
13546
- qg(e);
13547
- }, le.defaultOnUncaughtError = function(e) {
13548
- qg(e), console.warn(`%s
13549
-
13550
- %s
13551
- `, 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.
13552
- Visit https://react.dev/link/error-boundaries to learn more about error boundaries.`);
13553
- }, le.deferredUpdates = function(e) {
13554
- var n = x.T, o = wt();
13555
- try {
13556
- return an(32), x.T = null, e();
13557
- } finally {
13558
- an(o), x.T = n;
13237
+ }
13238
+ }
13239
+ }
13240
+ function pointerMissed(event, objects) {
13241
+ for (let i = 0; i < objects.length; i++) {
13242
+ const instance = objects[i].__r3f;
13243
+ instance?.handlers.onPointerMissed?.(event);
13244
+ }
13245
+ }
13246
+ function dragOverMissed(event, objects) {
13247
+ for (let i = 0; i < objects.length; i++) {
13248
+ const instance = objects[i].__r3f;
13249
+ instance?.handlers.onDragOverMissed?.(event);
13250
+ }
13251
+ }
13252
+ function dropMissed(event, objects) {
13253
+ for (let i = 0; i < objects.length; i++) {
13254
+ const instance = objects[i].__r3f;
13255
+ instance?.handlers.onDropMissed?.(event);
13256
+ }
13257
+ }
13258
+ function cleanupPointer(pointerId) {
13259
+ const { internal } = store.getState();
13260
+ const pointerState = internal.pointerMap.get(pointerId);
13261
+ if (pointerState) {
13262
+ for (const [, hoveredObj] of pointerState.hovered) {
13263
+ const eventObject = hoveredObj.eventObject;
13264
+ const instance = eventObject.__r3f;
13265
+ if (instance?.eventCount) {
13266
+ const handlers = instance.handlers;
13267
+ const data = { ...hoveredObj, intersections: [] };
13268
+ handlers.onPointerOut?.(data);
13269
+ handlers.onPointerLeave?.(data);
13559
13270
  }
13560
- }, le.discreteUpdates = function(e, n, o, i, s) {
13561
- var u = x.T, f = wt();
13562
- try {
13563
- return an(2), x.T = null, e(n, o, i, s);
13564
- } finally {
13565
- an(f), x.T = u, ye === Jn && (Pp = me() + Fg);
13271
+ }
13272
+ internal.pointerMap.delete(pointerId);
13273
+ }
13274
+ internal.pointerDirty.delete(pointerId);
13275
+ }
13276
+ function processDeferredPointer(event, pointerId) {
13277
+ const state = store.getState();
13278
+ const { internal } = state;
13279
+ if (!state.events.enabled) return;
13280
+ const filter = filterPointerEvents;
13281
+ const hits = intersect(event, filter);
13282
+ cancelPointer(hits, pointerId);
13283
+ function onIntersect(data) {
13284
+ const eventObject = data.eventObject;
13285
+ const instance = eventObject.__r3f;
13286
+ if (!instance?.eventCount) return;
13287
+ const handlers = instance.handlers;
13288
+ if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
13289
+ const id = makeId(data);
13290
+ const pointerState = getPointerState(internal, pointerId);
13291
+ const hoveredItem = pointerState.hovered.get(id);
13292
+ if (!hoveredItem) {
13293
+ pointerState.hovered.set(id, data);
13294
+ handlers.onPointerOver?.(data);
13295
+ handlers.onPointerEnter?.(data);
13296
+ } else if (hoveredItem.stopped) {
13297
+ data.stopPropagation();
13566
13298
  }
13567
- }, le.findAllNodes = kc, le.findBoundingRects = function(e, n) {
13568
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13569
- n = kc(e, n), e = [];
13570
- for (var o = 0; o < n.length; o++) e.push(ma(n[o]));
13571
- for (n = e.length - 1; 0 < n; n--) {
13572
- o = e[n];
13573
- 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) {
13574
- var g = e[p], S = g.x, T = S + g.width, _ = g.y, I = _ + g.height;
13575
- if (i >= S && u >= _ && s <= T && f <= I) {
13576
- e.splice(n, 1);
13577
- break;
13578
- } else if (i !== S || o.width !== g.width || I < u || _ > f) {
13579
- if (!(u !== _ || o.height !== g.height || T < i || S > s)) {
13580
- S > i && (g.width += S - i, g.x = i), T < s && (g.width = s - S), e.splice(n, 1);
13581
- break;
13299
+ }
13300
+ handlers.onPointerMove?.(data);
13301
+ }
13302
+ handleIntersects(hits, event, 0, onIntersect);
13303
+ }
13304
+ function handlePointer(name) {
13305
+ switch (name) {
13306
+ case "onPointerLeave":
13307
+ case "onDragLeave":
13308
+ return () => cancelPointer([]);
13309
+ // Global cancel of these events
13310
+ case "onPointerCancel":
13311
+ return (event) => {
13312
+ const pointerId = getPointerId(event);
13313
+ cleanupPointer(pointerId);
13314
+ };
13315
+ case "onLostPointerCapture":
13316
+ return (event) => {
13317
+ const { internal } = store.getState();
13318
+ const pointerId = getPointerId(event);
13319
+ const pointerState = internal.pointerMap.get(pointerId);
13320
+ if (pointerState?.captured.size) {
13321
+ requestAnimationFrame(() => {
13322
+ const pointerState2 = internal.pointerMap.get(pointerId);
13323
+ if (pointerState2?.captured.size) {
13324
+ pointerState2.captured.clear();
13582
13325
  }
13583
- } else {
13584
- _ > u && (g.height += _ - u, g.y = u), I < f && (g.height = f - _), e.splice(n, 1);
13585
- break;
13326
+ cancelPointer([], pointerId);
13327
+ });
13328
+ }
13329
+ };
13330
+ }
13331
+ return function handleEvent(event) {
13332
+ const state = store.getState();
13333
+ const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
13334
+ const pointerId = getPointerId(event);
13335
+ internal.lastEvent.current = event;
13336
+ if (!events.enabled) return;
13337
+ const isPointerMove = name === "onPointerMove";
13338
+ const isDragOver = name === "onDragOver";
13339
+ const isDrop = name === "onDrop";
13340
+ const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
13341
+ const isPointerDown = name === "onPointerDown";
13342
+ const isPointerUp = name === "onPointerUp";
13343
+ const isWheel = name === "onWheel";
13344
+ const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
13345
+ if (isPointerMove && canDeferRaycasts) {
13346
+ events.compute?.(event, state);
13347
+ internal.pointerDirty.set(pointerId, event);
13348
+ return;
13349
+ }
13350
+ if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
13351
+ events.compute?.(event, state);
13352
+ internal.pointerDirty.set(pointerId, event);
13353
+ return;
13354
+ }
13355
+ if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
13356
+ const deferredEvent = internal.pointerDirty.get(pointerId);
13357
+ internal.pointerDirty.delete(pointerId);
13358
+ processDeferredPointer(deferredEvent, pointerId);
13359
+ }
13360
+ const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
13361
+ const hits = intersect(event, filter);
13362
+ const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
13363
+ if (isPointerDown) {
13364
+ const pointerState2 = getPointerState(internal, pointerId);
13365
+ pointerState2.initialClick = [event.offsetX, event.offsetY];
13366
+ pointerState2.initialHits = hits.map((hit) => hit.eventObject);
13367
+ }
13368
+ const pointerState = internal.pointerMap.get(pointerId);
13369
+ const initialHits = pointerState?.initialHits ?? [];
13370
+ if (isClickEvent && !hits.length) {
13371
+ if (delta <= 2) {
13372
+ pointerMissed(event, internal.interaction);
13373
+ if (onPointerMissed) onPointerMissed(event);
13374
+ }
13375
+ }
13376
+ if (isDragOver && !hits.length) {
13377
+ dragOverMissed(event, internal.interaction);
13378
+ if (onDragOverMissed) onDragOverMissed(event);
13379
+ }
13380
+ if (isDrop && !hits.length) {
13381
+ dropMissed(event, internal.interaction);
13382
+ if (onDropMissed) onDropMissed(event);
13383
+ }
13384
+ if (isPointerMove || isDragOver) {
13385
+ cancelPointer(hits, pointerId);
13386
+ }
13387
+ function onIntersect(data) {
13388
+ const eventObject = data.eventObject;
13389
+ const instance = eventObject.__r3f;
13390
+ if (!instance?.eventCount) return;
13391
+ const handlers = instance.handlers;
13392
+ if (isPointerMove) {
13393
+ if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
13394
+ const id = makeId(data);
13395
+ const pointerState2 = getPointerState(internal, pointerId);
13396
+ const hoveredItem = pointerState2.hovered.get(id);
13397
+ if (!hoveredItem) {
13398
+ pointerState2.hovered.set(id, data);
13399
+ handlers.onPointerOver?.(data);
13400
+ handlers.onPointerEnter?.(data);
13401
+ } else if (hoveredItem.stopped) {
13402
+ data.stopPropagation();
13586
13403
  }
13587
13404
  }
13588
- }
13589
- return e;
13590
- }, le.findHostInstance = function(e) {
13591
- var n = e._reactInternals;
13592
- 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));
13593
- return e = mu(n), e === null ? null : ot(e.stateNode);
13594
- }, le.findHostInstanceWithNoPortals = function(e) {
13595
- return e = Ed(e), e = e !== null ? _p(e) : null, e === null ? null : ot(e.stateNode);
13596
- }, le.findHostInstanceWithWarning = function(e, n) {
13597
- var o = e._reactInternals;
13598
- 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));
13599
- if (e = mu(o), e === null) return null;
13600
- if (e.mode & 8) {
13601
- var i = G(o) || "Component";
13602
- mb[i] || (mb[i] = true, B(e, function() {
13603
- 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);
13604
- }));
13605
- }
13606
- return ot(e.stateNode);
13607
- }, le.flushPassiveEffects = el, le.flushSyncFromReconciler = function(e) {
13608
- var n = ye;
13609
- ye |= 1;
13610
- var o = x.T, i = wt();
13611
- try {
13612
- if (an(2), x.T = null, e) return e();
13613
- } finally {
13614
- an(i), x.T = o, ye = n, (ye & (Zn | uo)) === Jn && Wa(0);
13615
- }
13616
- }, le.flushSyncWork = Ls, le.focusWithin = function(e, n) {
13617
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13618
- for (e = Ef(e), n = hh(e, n), n = Array.from(n), e = 0; e < n.length; ) {
13619
- var o = n[e++], i = o.tag;
13620
- if (!Kr(o)) {
13621
- if ((i === 5 || i === 26 || i === 27) && Ft(o.stateNode)) return true;
13622
- for (o = o.child; o !== null; ) n.push(o), o = o.sibling;
13405
+ handlers.onPointerMove?.(data);
13406
+ } else if (isDragOver) {
13407
+ const id = makeId(data);
13408
+ const pointerState2 = getPointerState(internal, pointerId);
13409
+ const hoveredItem = pointerState2.hovered.get(id);
13410
+ if (!hoveredItem) {
13411
+ pointerState2.hovered.set(id, data);
13412
+ handlers.onDragOverEnter?.(data);
13413
+ } else if (hoveredItem.stopped) {
13414
+ data.stopPropagation();
13415
+ }
13416
+ handlers.onDragOver?.(data);
13417
+ } else if (isDrop) {
13418
+ handlers.onDrop?.(data);
13419
+ } else {
13420
+ const handler = handlers[name];
13421
+ if (handler) {
13422
+ if (!isClickEvent || initialHits.includes(eventObject)) {
13423
+ pointerMissed(
13424
+ event,
13425
+ internal.interaction.filter((object) => !initialHits.includes(object))
13426
+ );
13427
+ handler(data);
13428
+ }
13429
+ } else {
13430
+ if (isClickEvent && initialHits.includes(eventObject)) {
13431
+ pointerMissed(
13432
+ event,
13433
+ internal.interaction.filter((object) => !initialHits.includes(object))
13434
+ );
13435
+ }
13623
13436
  }
13624
13437
  }
13625
- return false;
13626
- }, le.getFindAllNodesFailureDescription = function(e, n) {
13627
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13628
- var o = 0, i = [];
13629
- e = [Ef(e), 0];
13630
- for (var s = 0; s < e.length; ) {
13631
- var u = e[s++], f = u.tag, p = e[s++], g = n[p];
13632
- 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;
13438
+ }
13439
+ handleIntersects(hits, event, delta, onIntersect);
13440
+ };
13441
+ }
13442
+ function flushDeferredPointers() {
13443
+ const { internal, events } = store.getState();
13444
+ if (!events.frameTimedRaycasts) return;
13445
+ for (const [pointerId, event] of internal.pointerDirty) {
13446
+ processDeferredPointer(event, pointerId);
13447
+ }
13448
+ internal.pointerDirty.clear();
13449
+ }
13450
+ return { handlePointer, flushDeferredPointers, processDeferredPointer };
13451
+ }
13452
+ const DOM_EVENTS = {
13453
+ onClick: ["click", false],
13454
+ onContextMenu: ["contextmenu", false],
13455
+ onDoubleClick: ["dblclick", false],
13456
+ onDragEnter: ["dragenter", false],
13457
+ onDragLeave: ["dragleave", false],
13458
+ onDragOver: ["dragover", false],
13459
+ onDrop: ["drop", false],
13460
+ onWheel: ["wheel", true],
13461
+ onPointerDown: ["pointerdown", true],
13462
+ onPointerUp: ["pointerup", true],
13463
+ onPointerLeave: ["pointerleave", true],
13464
+ onPointerMove: ["pointermove", true],
13465
+ onPointerCancel: ["pointercancel", true],
13466
+ onLostPointerCapture: ["lostpointercapture", true]
13467
+ };
13468
+ function createPointerEvents(store) {
13469
+ const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
13470
+ let nextXRPointerId = XR_POINTER_ID_START;
13471
+ const xrPointers = /* @__PURE__ */ new Map();
13472
+ return {
13473
+ priority: 1,
13474
+ enabled: true,
13475
+ frameTimedRaycasts: true,
13476
+ alwaysFireOnScroll: true,
13477
+ updateOnFrame: false,
13478
+ compute(event, state) {
13479
+ state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
13480
+ state.raycaster.setFromCamera(state.pointer, state.camera);
13481
+ },
13482
+ connected: void 0,
13483
+ handlers: Object.keys(DOM_EVENTS).reduce(
13484
+ (acc, key) => ({ ...acc, [key]: handlePointer(key) }),
13485
+ {}
13486
+ ),
13487
+ update: (pointerId) => {
13488
+ const { events, internal } = store.getState();
13489
+ if (!events.handlers) return;
13490
+ if (pointerId !== void 0) {
13491
+ const event = internal.pointerDirty.get(pointerId);
13492
+ if (event) {
13493
+ internal.pointerDirty.delete(pointerId);
13494
+ processDeferredPointer(event, pointerId);
13495
+ } else if (internal.lastEvent?.current) {
13496
+ processDeferredPointer(internal.lastEvent.current, pointerId);
13633
13497
  }
13634
- if (o < n.length) {
13635
- for (e = []; o < n.length; o++) e.push(Sc(n[o]));
13636
- return `findAllNodes was able to match part of the selector:
13637
- ` + (i.join(" > ") + `
13638
-
13639
- No matching component was found for:
13640
- `) + e.join(" > ");
13498
+ } else {
13499
+ flushDeferredPointers();
13500
+ if (internal.lastEvent?.current) {
13501
+ events.handlers.onPointerMove(internal.lastEvent.current);
13641
13502
  }
13642
- return null;
13643
- }, le.getPublicRootInstance = function(e) {
13644
- if (e = e.current, !e.child) return null;
13645
- switch (e.child.tag) {
13646
- case 27:
13647
- case 5:
13648
- return ot(e.child.stateNode);
13649
- default:
13650
- return e.child.stateNode;
13503
+ }
13504
+ },
13505
+ flush: () => {
13506
+ const { events, internal } = store.getState();
13507
+ flushDeferredPointers();
13508
+ if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
13509
+ events.handlers.onPointerMove(internal.lastEvent.current);
13510
+ }
13511
+ },
13512
+ connect: (target) => {
13513
+ if (!target) return;
13514
+ const { set, events } = store.getState();
13515
+ events.disconnect?.();
13516
+ set((state) => ({ events: { ...state.events, connected: target } }));
13517
+ if (events.handlers) {
13518
+ for (const name in events.handlers) {
13519
+ const event = events.handlers[name];
13520
+ const [eventName, passive] = DOM_EVENTS[name];
13521
+ target.addEventListener(eventName, event, { passive });
13651
13522
  }
13652
- }, le.injectIntoDevTools = function() {
13653
- var e = { bundleType: 1, version: Jt, rendererPackageName: Zt, currentDispatcherRef: x, reconcilerVersion: "19.2.0" };
13654
- 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);
13655
- }, le.isAlreadyRendering = Ns, le.observeVisibleRects = function(e, n, o, i) {
13656
- function s() {
13657
- var S = kc(e, n);
13658
- u.forEach(function(T) {
13659
- 0 > S.indexOf(T) && g(T);
13660
- }), S.forEach(function(T) {
13661
- 0 > u.indexOf(T) && p(T);
13662
- });
13523
+ }
13524
+ },
13525
+ disconnect: () => {
13526
+ const { set, events } = store.getState();
13527
+ if (events.connected) {
13528
+ if (events.handlers) {
13529
+ for (const name in events.handlers) {
13530
+ const event = events.handlers[name];
13531
+ const [eventName] = DOM_EVENTS[name];
13532
+ events.connected.removeEventListener(eventName, event);
13533
+ }
13534
+ }
13535
+ set((state) => ({ events: { ...state.events, connected: void 0 } }));
13536
+ }
13537
+ },
13538
+ // PREVIEW (A8): the XR pointer registration API may change before stable.
13539
+ registerPointer: (config) => {
13540
+ const pointerId = nextXRPointerId++;
13541
+ xrPointers.set(pointerId, config);
13542
+ const { internal } = store.getState();
13543
+ getPointerState(internal, pointerId);
13544
+ return pointerId;
13545
+ },
13546
+ unregisterPointer: (pointerId) => {
13547
+ xrPointers.delete(pointerId);
13548
+ const { internal } = store.getState();
13549
+ const pointerState = internal.pointerMap.get(pointerId);
13550
+ if (pointerState) {
13551
+ for (const [, hoveredObj] of pointerState.hovered) {
13552
+ const eventObject = hoveredObj.eventObject;
13553
+ const instance = eventObject.__r3f;
13554
+ if (instance?.eventCount) {
13555
+ const handlers = instance.handlers;
13556
+ const data = { ...hoveredObj, intersections: [] };
13557
+ handlers.onPointerOut?.(data);
13558
+ handlers.onPointerLeave?.(data);
13559
+ }
13663
13560
  }
13664
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13665
- var u = kc(e, n);
13666
- o = zr(u, o, i);
13667
- var f = o.disconnect, p = o.observe, g = o.unobserve;
13668
- return bm.push(s), { disconnect: function() {
13669
- var S = bm.indexOf(s);
13670
- 0 <= S && bm.splice(S, 1), f();
13671
- } };
13672
- }, le.shouldError = function(e) {
13673
- return pu(e);
13674
- }, le.shouldSuspend = function(e) {
13675
- return fu(e);
13676
- }, le.startHostTransition = function(e, n, o, i) {
13677
- if (e.tag !== 5) throw Error("Expected the form instance to be a HostComponent. This is a bug in React.");
13678
- var s = uf(e).queue;
13679
- Hp(e), nt(e, s, n, Xt, o === null ? Em : function() {
13680
- x.T === null && console.error("requestFormReset was called outside a transition or action. To fix, move to an action, or wrap with startTransition.");
13681
- var u = uf(e);
13682
- return u.next === null && (u = e.alternate.memoizedState), qi(e, u.next.queue, {}, Nt(e)), o(i);
13683
- });
13684
- }, le.updateContainer = function(e, n, o, i) {
13685
- var s = n.current, u = Nt(s);
13686
- return As(s, u, e, n, o, i), u;
13687
- }, le.updateContainerSync = Wh, le;
13688
- }, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true }));
13689
- })(Mg)), Mg.exports;
13690
- }
13691
- var Eb;
13692
- function n0() {
13693
- return Eb || (Eb = 1, process.env.NODE_ENV === "production" ? Rm.exports = Kb() : Rm.exports = e0()), Rm.exports;
13561
+ internal.pointerMap.delete(pointerId);
13562
+ }
13563
+ internal.pointerDirty.delete(pointerId);
13564
+ }
13565
+ };
13694
13566
  }
13695
- var t0 = n0();
13696
- const r0 = Xb(t0);
13697
-
13698
- const t = 1, o = 8, r = 32, e = 2;
13699
13567
 
13700
13568
  function createReconciler(config) {
13701
13569
  const reconciler2 = r0(config);
@@ -13715,7 +13583,10 @@ function extend(objects) {
13715
13583
  catalogue[Component] = objects;
13716
13584
  return Component;
13717
13585
  } else {
13718
- Object.assign(catalogue, objects);
13586
+ for (const name in objects) {
13587
+ const object = objects[name];
13588
+ if (isConstructor(object)) catalogue[name] = object;
13589
+ }
13719
13590
  }
13720
13591
  }
13721
13592
  function validateInstance(type, props) {
@@ -13860,7 +13731,15 @@ function setFiberRef(fiber, publicInstance) {
13860
13731
  }
13861
13732
  }
13862
13733
  const reconstructed = [];
13863
- function swapInstances() {
13734
+ function flushReconstructedInstances() {
13735
+ if (reconstructed.length === 0) return;
13736
+ try {
13737
+ swapReconstructedInstances();
13738
+ } finally {
13739
+ reconstructed.length = 0;
13740
+ }
13741
+ }
13742
+ function swapReconstructedInstances() {
13864
13743
  for (const [instance] of reconstructed) {
13865
13744
  const parent = instance.parent;
13866
13745
  if (parent) {
@@ -13878,7 +13757,9 @@ function swapInstances() {
13878
13757
  }
13879
13758
  }
13880
13759
  if (instance.isHidden) unhideInstance(instance);
13881
- if (isObject3D(instance.object)) removeInteractivity(findInitialRoot(instance), instance.object);
13760
+ if (isObject3D(instance.object) && !instance.parent) {
13761
+ removeInteractivity(findInitialRoot(instance), instance.object);
13762
+ }
13882
13763
  if (instance.object.__r3f) delete instance.object.__r3f;
13883
13764
  if (instance.type !== "primitive") disposeOnIdle(instance.object);
13884
13765
  }
@@ -13887,9 +13768,13 @@ function swapInstances() {
13887
13768
  const parent = instance.parent;
13888
13769
  if (parent) {
13889
13770
  const target = catalogue[toPascalCase(instance.type)];
13771
+ const prevObject = instance.object;
13890
13772
  instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
13891
13773
  instance.object.__r3f = instance;
13892
13774
  setFiberRef(fiber, instance.object);
13775
+ if (isObject3D(prevObject) && isObject3D(instance.object)) {
13776
+ swapInteractivity(findInitialRoot(instance), prevObject, instance.object);
13777
+ }
13893
13778
  delete instance.appliedOnce;
13894
13779
  instance.eventCount = 0;
13895
13780
  instance.handlers = {};
@@ -13909,14 +13794,114 @@ function swapInstances() {
13909
13794
  invalidateInstance(instance);
13910
13795
  }
13911
13796
  }
13912
- reconstructed.length = 0;
13913
13797
  }
13914
13798
  const handleTextInstance = () => {
13915
13799
  };
13916
13800
  const NO_CONTEXT = {};
13917
13801
  let currentUpdatePriority = NoEventPriority;
13918
- const NoFlags = 0;
13919
- const Update = 4;
13802
+ function getEventPriority(type) {
13803
+ switch (type) {
13804
+ case "beforetoggle":
13805
+ case "cancel":
13806
+ case "click":
13807
+ case "close":
13808
+ case "contextmenu":
13809
+ case "copy":
13810
+ case "cut":
13811
+ case "auxclick":
13812
+ case "dblclick":
13813
+ case "dragend":
13814
+ case "dragstart":
13815
+ case "drop":
13816
+ case "focusin":
13817
+ case "focusout":
13818
+ case "input":
13819
+ case "invalid":
13820
+ case "keydown":
13821
+ case "keypress":
13822
+ case "keyup":
13823
+ case "mousedown":
13824
+ case "mouseup":
13825
+ case "paste":
13826
+ case "pause":
13827
+ case "play":
13828
+ case "pointercancel":
13829
+ case "pointerdown":
13830
+ case "pointerup":
13831
+ case "ratechange":
13832
+ case "reset":
13833
+ case "resize":
13834
+ case "seeked":
13835
+ case "submit":
13836
+ case "touchcancel":
13837
+ case "touchend":
13838
+ case "touchstart":
13839
+ case "volumechange":
13840
+ case "change":
13841
+ case "selectionchange":
13842
+ case "compositionstart":
13843
+ case "compositionend":
13844
+ case "compositionupdate":
13845
+ case "beforeinput":
13846
+ case "blur":
13847
+ case "fullscreenchange":
13848
+ case "focus":
13849
+ case "hashchange":
13850
+ case "popstate":
13851
+ case "select":
13852
+ case "selectstart":
13853
+ return e;
13854
+ case "drag":
13855
+ case "dragenter":
13856
+ case "dragexit":
13857
+ case "dragleave":
13858
+ case "dragover":
13859
+ case "mousemove":
13860
+ case "mouseout":
13861
+ case "mouseover":
13862
+ case "pointermove":
13863
+ case "pointerout":
13864
+ case "pointerover":
13865
+ case "scroll":
13866
+ case "touchmove":
13867
+ case "wheel":
13868
+ case "mouseenter":
13869
+ case "mouseleave":
13870
+ case "pointerenter":
13871
+ case "pointerleave":
13872
+ return o;
13873
+ case "message": {
13874
+ switch (Tb.unstable_getCurrentPriorityLevel()) {
13875
+ case Tb.unstable_ImmediatePriority:
13876
+ return e;
13877
+ case Tb.unstable_UserBlockingPriority:
13878
+ return o;
13879
+ case Tb.unstable_NormalPriority:
13880
+ case Tb.unstable_LowPriority:
13881
+ return r;
13882
+ case Tb.unstable_IdlePriority:
13883
+ return i$1;
13884
+ default:
13885
+ return r;
13886
+ }
13887
+ }
13888
+ default:
13889
+ return r;
13890
+ }
13891
+ }
13892
+ function scheduleMicrotask(callback) {
13893
+ if (typeof queueMicrotask === "function") {
13894
+ queueMicrotask(callback);
13895
+ } else if (typeof Promise !== "undefined") {
13896
+ Promise.resolve().then(callback).catch((error) => {
13897
+ setTimeout(() => {
13898
+ throw error;
13899
+ });
13900
+ });
13901
+ } else {
13902
+ setTimeout(callback);
13903
+ }
13904
+ }
13920
13905
  const reconciler = /* @__PURE__ */ createReconciler({
13921
13906
  isPrimaryRenderer: false,
13922
13907
  warnsIfNotActing: false,
@@ -13949,22 +13934,21 @@ const reconciler = /* @__PURE__ */ createReconciler({
13949
13934
  getRootHostContext: () => NO_CONTEXT,
13950
13935
  getChildHostContext: () => NO_CONTEXT,
13951
13936
  commitUpdate(instance, type, oldProps, newProps, fiber) {
13952
- validateInstance(type, newProps);
13937
+ validateInstance(instance.type, newProps);
13953
13938
  let reconstruct = false;
13954
13939
  if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
13955
13940
  else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
13956
13941
  else if (newProps.args?.some((value, index) => value !== oldProps.args?.[index])) reconstruct = true;
13957
13942
  if (reconstruct) {
13958
- reconstructed.push([instance, { ...newProps }, fiber]);
13943
+ reconstructed.push([instance, getInstanceProps(newProps), fiber]);
13959
13944
  } else {
13960
13945
  const changedProps = diffProps(instance, newProps);
13961
- if (Object.keys(changedProps).length) {
13962
- Object.assign(instance.props, changedProps);
13963
- applyProps(instance.object, changedProps);
13964
- }
13946
+ const attach2 = instance.props.attach;
13947
+ instance.props = getInstanceProps(newProps);
13948
+ if (attach2 !== void 0) instance.props.attach = attach2;
13949
+ else delete instance.props.attach;
13950
+ if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
13965
13951
  }
13966
- const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
13967
- if (isTailSibling) swapInstances();
13968
13952
  },
13969
13953
  finalizeInitialChildren: (instance) => {
13970
13954
  for (const prop in instance.props) {
@@ -13977,8 +13961,8 @@ const reconciler = /* @__PURE__ */ createReconciler({
13977
13961
  for (const prop in instance.props) {
13978
13962
  const value = instance.props[prop];
13979
13963
  if (isFromRef(value)) {
13980
- const ref = value[FROM_REF];
13981
- if (ref.current != null) resolved[prop] = ref.current;
13964
+ const { [FROM_REF]: ref, transform } = value;
13965
+ if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
13982
13966
  }
13983
13967
  }
13984
13968
  if (Object.keys(resolved).length) applyProps(instance.object, resolved);
@@ -13989,8 +13973,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
13989
13973
  const target = container.getState().internal.container ?? container.getState().scene;
13990
13974
  return prepare(target, container, "", {});
13991
13975
  },
13992
- resetAfterCommit: () => {
13993
- },
13976
+ // Reconstructed instances are swapped once all mutations are committed,
13977
+ // before layout effects run so refs point to the new objects
13978
+ resetAfterCommit: flushReconstructedInstances,
13994
13979
  shouldSetTextContent: () => false,
13995
13980
  clearContainer: () => false,
13996
13981
  hideInstance,
@@ -13998,6 +13983,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
13998
13983
  createTextInstance: handleTextInstance,
13999
13984
  hideTextInstance: handleTextInstance,
14000
13985
  unhideTextInstance: handleTextInstance,
13986
+ // Mirrors react-dom, which flushes discrete work in microtasks
13987
+ supportsMicrotasks: true,
13988
+ scheduleMicrotask,
14001
13989
  scheduleTimeout: typeof setTimeout === "function" ? setTimeout : void 0,
14002
13990
  cancelTimeout: typeof clearTimeout === "function" ? clearTimeout : void 0,
14003
13991
  noTimeout: -1,
@@ -14038,28 +14026,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
14038
14026
  },
14039
14027
  resolveUpdatePriority() {
14040
14028
  if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
14041
- switch (typeof window !== "undefined" && window.event?.type) {
14042
- case "click":
14043
- case "contextmenu":
14044
- case "dblclick":
14045
- case "dragenter":
14046
- case "dragleave":
14047
- case "drop":
14048
- case "pointercancel":
14049
- case "pointerdown":
14050
- case "pointerup":
14051
- return e;
14052
- case "dragover":
14053
- case "pointermove":
14054
- case "pointerout":
14055
- case "pointerover":
14056
- case "pointerenter":
14057
- case "pointerleave":
14058
- case "wheel":
14059
- return o;
14060
- default:
14061
- return r;
14062
- }
14029
+ const eventType = typeof window !== "undefined" ? window.event?.type : void 0;
14030
+ if (eventType === void 0) return r;
14031
+ return getEventPriority(eventType);
14063
14032
  },
14064
14033
  resetFormInstance() {
14065
14034
  },
@@ -14292,9 +14261,8 @@ function createRoot(canvas) {
14292
14261
  if (!renderer.hasInitialized?.()) {
14293
14262
  const size2 = computeInitialSize(canvas, propsSize);
14294
14263
  if (size2.width > 0 && size2.height > 0) {
14295
- const pixelRatio = calculateDpr(dpr);
14296
- canvas.width = size2.width * pixelRatio;
14297
- canvas.height = size2.height * pixelRatio;
14264
+ renderer.setPixelRatio(calculateDpr(dpr));
14265
+ renderer.setSize(size2.width, size2.height, false);
14298
14266
  }
14299
14267
  await renderer.init();
14300
14268
  }
@@ -14303,7 +14271,7 @@ function createRoot(canvas) {
14303
14271
  state.internal.actualRenderer = renderer;
14304
14272
  state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
14305
14273
  if (canvasId && !state.internal.isSecondary) {
14306
- const canvasTarget = new webgpu.CanvasTarget(canvas);
14274
+ const canvasTarget = renderer.getCanvasTarget?.();
14307
14275
  const unregisterPrimary = registerPrimary(canvasId, renderer, store);
14308
14276
  state.set((prev) => ({
14309
14277
  internal: {
@@ -14417,7 +14385,7 @@ function createRoot(canvas) {
14417
14385
  const handleXRFrame = (timestamp, _frame) => {
14418
14386
  const state2 = store.getState();
14419
14387
  if (state2.frameloop === "never") return;
14420
- advance(timestamp);
14388
+ advance(timestamp, true, state2);
14421
14389
  };
14422
14390
  const actualRenderer = state.internal.actualRenderer;
14423
14391
  const handleSessionChange = () => {
@@ -14425,7 +14393,7 @@ function createRoot(canvas) {
14425
14393
  const renderer2 = state2.internal.actualRenderer;
14426
14394
  actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
14427
14395
  renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
14428
- if (!renderer2.xr.isPresenting) invalidate();
14396
+ if (!renderer2.xr.isPresenting) invalidate(state2);
14429
14397
  };
14430
14398
  const xr = {
14431
14399
  connect() {
@@ -14507,14 +14475,23 @@ function createRoot(canvas) {
14507
14475
  const newRootId = canvasId || scheduler$1.generateRootId();
14508
14476
  const unregisterRoot = scheduler$1.registerRoot(newRootId, {
14509
14477
  getState: () => store.getState(),
14510
- onError: (err) => store.getState().setError(err)
14478
+ onError: (err) => store.getState().setError(err),
14479
+ frameloop: store.getState().frameloop,
14480
+ before: schedulerConfig?.before,
14481
+ after: schedulerConfig?.after,
14482
+ order: schedulerConfig?.order
14511
14483
  });
14512
14484
  const unregisterCanvasTarget = scheduler$1.register(
14513
14485
  () => {
14514
14486
  const state2 = store.getState();
14515
- if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
14487
+ const canvasTarget = state2.internal.canvasTarget;
14488
+ if (canvasTarget) {
14516
14489
  const renderer2 = state2.internal.actualRenderer;
14517
- renderer2.setCanvasTarget(state2.internal.canvasTarget);
14490
+ if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
14491
+ if (state2.internal.canvasTargetSizeDirty) {
14492
+ state2.internal.canvasTargetSizeDirty = false;
14493
+ renderer2.backend?.updateSize?.();
14494
+ }
14518
14495
  }
14519
14496
  },
14520
14497
  {
@@ -14583,8 +14560,7 @@ function createRoot(canvas) {
14583
14560
  phase: "render",
14584
14561
  system: true,
14585
14562
  // Internal flag: this is a system job, not user-controlled
14586
- // Apply scheduler config for render ordering and rate limiting
14587
- ...schedulerConfig?.after && { after: schedulerConfig.after },
14563
+ // FPS throttles only the default render job; Canvas ordering belongs to the root.
14588
14564
  ...schedulerConfig?.fps && { fps: schedulerConfig.fps }
14589
14565
  }
14590
14566
  );
@@ -14603,8 +14579,21 @@ function createRoot(canvas) {
14603
14579
  scheduler: scheduler$1
14604
14580
  }
14605
14581
  }));
14582
+ } else {
14583
+ const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
14584
+ if (constraintsChanged) {
14585
+ scheduler$1.setRootConstraints(rootId, {
14586
+ before: schedulerConfig?.before,
14587
+ after: schedulerConfig?.after
14588
+ });
14589
+ }
14590
+ if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
14591
+ scheduler$1.setRootOrder(rootId, schedulerConfig?.order ?? 0);
14592
+ }
14606
14593
  }
14607
- scheduler$1.frameloop = frameloop;
14594
+ lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
14595
+ lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
14596
+ lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
14608
14597
  onCreated = onCreatedCallback;
14609
14598
  configured = true;
14610
14599
  resolve();
@@ -14646,18 +14635,23 @@ function unmountComponentAtNode(canvas, callback) {
14646
14635
  const fiber = root?.fiber;
14647
14636
  if (fiber) {
14648
14637
  const state = root?.store.getState();
14649
- if (state) state.internal.active = false;
14638
+ if (state) {
14639
+ state.internal.active = false;
14640
+ const unregisterRoot = state.internal.unregisterRoot;
14641
+ if (unregisterRoot) {
14642
+ unregisterRoot();
14643
+ state.internal.unregisterRoot = void 0;
14644
+ }
14645
+ }
14650
14646
  reconciler.updateContainer(null, fiber, null, () => {
14651
14647
  if (state) {
14652
14648
  setTimeout(() => {
14653
14649
  try {
14654
14650
  const renderer = state.internal.actualRenderer;
14655
- const unregisterRoot = state.internal.unregisterRoot;
14656
- if (unregisterRoot) unregisterRoot();
14657
14651
  const unregisterPrimary = state.internal.unregisterPrimary;
14658
14652
  if (unregisterPrimary) unregisterPrimary();
14659
14653
  const canvasTarget = state.internal.canvasTarget;
14660
- if (canvasTarget?.dispose) canvasTarget.dispose();
14654
+ if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
14661
14655
  state.events.disconnect?.();
14662
14656
  cleanupHelperGroup(root.store);
14663
14657
  if (state.isLegacy && renderer) {
@@ -14783,6 +14777,207 @@ function flushSync(fn) {
14783
14777
  return reconciler.flushSyncFromReconciler(fn);
14784
14778
  }
14785
14779
 
14780
+ const isRef = (obj) => obj.current && obj.current.isScene;
14781
+ const resolveScene = (scene) => isRef(scene) ? scene.current : scene;
14782
+ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
14783
+ sceneProps = {
14784
+ backgroundBlurriness: 0,
14785
+ backgroundIntensity: 1,
14786
+ backgroundRotation: [0, 0, 0],
14787
+ environmentIntensity: 1,
14788
+ environmentRotation: [0, 0, 0],
14789
+ ...sceneProps
14790
+ };
14791
+ const target = resolveScene(scene || defaultScene);
14792
+ const oldbg = target.background;
14793
+ const oldenv = target.environment;
14794
+ const oldSceneProps = {
14795
+ backgroundBlurriness: target.backgroundBlurriness,
14796
+ backgroundIntensity: target.backgroundIntensity,
14797
+ backgroundRotation: target.backgroundRotation.clone(),
14798
+ environmentIntensity: target.environmentIntensity,
14799
+ environmentRotation: target.environmentRotation.clone()
14800
+ };
14801
+ if (background !== "only") target.environment = texture;
14802
+ if (background) target.background = texture;
14803
+ applyProps(target, sceneProps);
14804
+ return () => {
14805
+ if (background !== "only") target.environment = oldenv;
14806
+ if (background) target.background = oldbg;
14807
+ applyProps(target, oldSceneProps);
14808
+ };
14809
+ }
14810
+ function EnvironmentMap({ scene, background = false, map, ...config }) {
14811
+ const defaultScene = useThree((state) => state.scene);
14812
+ React__namespace.useLayoutEffect(() => {
14813
+ if (map) return setEnvProps(background, scene, defaultScene, map, config);
14814
+ });
14815
+ return null;
14816
+ }
14817
+ function EnvironmentCube({
14818
+ background = false,
14819
+ scene,
14820
+ blur,
14821
+ backgroundBlurriness,
14822
+ backgroundIntensity,
14823
+ backgroundRotation,
14824
+ environmentIntensity,
14825
+ environmentRotation,
14826
+ ...rest
14827
+ }) {
14828
+ const texture = useEnvironment(rest);
14829
+ const defaultScene = useThree((state) => state.scene);
14830
+ React__namespace.useLayoutEffect(() => {
14831
+ return setEnvProps(background, scene, defaultScene, texture, {
14832
+ backgroundBlurriness: blur ?? backgroundBlurriness,
14833
+ backgroundIntensity,
14834
+ backgroundRotation,
14835
+ environmentIntensity,
14836
+ environmentRotation
14837
+ });
14838
+ });
14839
+ React__namespace.useEffect(() => {
14840
+ return () => {
14841
+ texture.dispose();
14842
+ };
14843
+ }, [texture]);
14844
+ return null;
14845
+ }
14846
+ function EnvironmentPortal({
14847
+ children,
14848
+ near = 0.1,
14849
+ far = 1e3,
14850
+ resolution = 256,
14851
+ frames = 1,
14852
+ map,
14853
+ background = false,
14854
+ blur,
14855
+ backgroundBlurriness,
14856
+ backgroundIntensity,
14857
+ backgroundRotation,
14858
+ environmentIntensity,
14859
+ environmentRotation,
14860
+ scene,
14861
+ files,
14862
+ path,
14863
+ preset = void 0,
14864
+ extensions
14865
+ }) {
14866
+ const renderer = useThree((state) => state.renderer);
14867
+ const isLegacy = useThree((state) => state.isLegacy);
14868
+ const defaultScene = useThree((state) => state.scene);
14869
+ const camera = React__namespace.useRef(null);
14870
+ const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
14871
+ const fbo = React__namespace.useMemo(() => {
14872
+ const fbo2 = isLegacy ? new three.WebGLCubeRenderTarget(resolution) : new webgpu.CubeRenderTarget(resolution);
14873
+ fbo2.texture.type = webgpu.HalfFloatType;
14874
+ return fbo2;
14875
+ }, [resolution, isLegacy]);
14876
+ React__namespace.useEffect(() => {
14877
+ return () => {
14878
+ fbo.dispose();
14879
+ };
14880
+ }, [fbo]);
14881
+ React__namespace.useLayoutEffect(() => {
14882
+ if (frames === 1) {
14883
+ const autoClear = renderer.autoClear;
14884
+ renderer.autoClear = true;
14885
+ camera.current.update(renderer, virtualScene);
14886
+ renderer.autoClear = autoClear;
14887
+ }
14888
+ return setEnvProps(background, scene, defaultScene, fbo.texture, {
14889
+ backgroundBlurriness: blur ?? backgroundBlurriness,
14890
+ backgroundIntensity,
14891
+ backgroundRotation,
14892
+ environmentIntensity,
14893
+ environmentRotation
14894
+ });
14895
+ }, [
14896
+ children,
14897
+ virtualScene,
14898
+ fbo.texture,
14899
+ scene,
14900
+ defaultScene,
14901
+ background,
14902
+ frames,
14903
+ renderer,
14904
+ blur,
14905
+ backgroundBlurriness,
14906
+ backgroundIntensity,
14907
+ backgroundRotation,
14908
+ environmentIntensity,
14909
+ environmentRotation
14910
+ ]);
14911
+ let count = 1;
14912
+ useFrame(() => {
14913
+ if (frames === Infinity || count < frames) {
14914
+ const autoClear = renderer.autoClear;
14915
+ renderer.autoClear = true;
14916
+ camera.current.update(renderer, virtualScene);
14917
+ renderer.autoClear = autoClear;
14918
+ count++;
14919
+ }
14920
+ });
14921
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: createPortal(
14922
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14923
+ children,
14924
+ /* @__PURE__ */ jsxRuntime.jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
14925
+ files || preset ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { background: true, map, extensions }) : null
14926
+ ] }),
14927
+ virtualScene
14928
+ ) });
14929
+ }
14930
+ function EnvironmentGround(props) {
14931
+ const textureDefault = useEnvironment(props);
14932
+ const texture = props.map || textureDefault;
14933
+ React__namespace.useMemo(() => extend({ GroundProjectedEnvImpl: GroundedSkybox_js.GroundedSkybox }), []);
14934
+ React__namespace.useEffect(() => {
14935
+ return () => {
14936
+ textureDefault.dispose();
14937
+ };
14938
+ }, [textureDefault]);
14939
+ const height = props.ground?.height ?? 15;
14940
+ const radius = props.ground?.radius ?? 60;
14941
+ const scale = props.ground?.scale ?? 1e3;
14942
+ const args = React__namespace.useMemo(
14943
+ () => [texture, height, radius],
14944
+ [texture, height, radius]
14945
+ );
14946
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14947
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props, map: texture }),
14948
+ /* @__PURE__ */ jsxRuntime.jsx("groundProjectedEnvImpl", { args, scale })
14949
+ ] });
14950
+ }
14951
+ function EnvironmentColor({ color, scene }) {
14952
+ const defaultScene = useThree((state) => state.scene);
14953
+ React__namespace.useLayoutEffect(() => {
14954
+ if (color === void 0) return;
14955
+ const target = resolveScene(scene || defaultScene);
14956
+ const oldBg = target.background;
14957
+ target.background = new webgpu.Color(color);
14958
+ return () => {
14959
+ target.background = oldBg;
14960
+ };
14961
+ });
14962
+ return null;
14963
+ }
14964
+ function EnvironmentDualSource(props) {
14965
+ const { backgroundFiles, ...envProps } = props;
14966
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14967
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...envProps, background: false }),
14968
+ /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
14969
+ ] });
14970
+ }
14971
+ function Environment(props) {
14972
+ if (props.color && !props.files && !props.preset && !props.map) {
14973
+ return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentColor, { ...props });
14974
+ }
14975
+ if (props.backgroundFiles && props.backgroundFiles !== props.files) {
14976
+ return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentDualSource, { ...props });
14977
+ }
14978
+ 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 });
14979
+ }
14980
+
14786
14981
  function parseBackground(background) {
14787
14982
  if (!background) return null;
14788
14983
  if (typeof background === "object" && !background.isColor) {
@@ -14895,9 +15090,9 @@ function CanvasImpl({
14895
15090
  React__namespace.useMemo(() => extend(THREE), []);
14896
15091
  const Bridge = useBridge();
14897
15092
  const backgroundProps = React__namespace.useMemo(() => parseBackground(background), [background]);
14898
- const hasInitialSizeRef = React__namespace.useRef(false);
15093
+ const [hasInitialSize, setHasInitialSize] = React__namespace.useState(false);
14899
15094
  const measureConfig = React__namespace.useMemo(() => {
14900
- if (!hasInitialSizeRef.current) {
15095
+ if (!hasInitialSize) {
14901
15096
  return {
14902
15097
  ...resize,
14903
15098
  scroll: resize?.scroll ?? true,
@@ -14909,7 +15104,7 @@ function CanvasImpl({
14909
15104
  debounce: { scroll: 50, resize: 0 },
14910
15105
  ...resize
14911
15106
  };
14912
- }, [resize, hasInitialSizeRef.current]);
15107
+ }, [hasInitialSize, resize]);
14913
15108
  const [containerRef, containerRect] = useMeasure__default(measureConfig);
14914
15109
  const effectiveSize = React__namespace.useMemo(() => {
14915
15110
  let w = width ?? containerRect.width;
@@ -14925,9 +15120,7 @@ function CanvasImpl({
14925
15120
  left: containerRect.left
14926
15121
  };
14927
15122
  }, [width, height, containerRect, forceEven]);
14928
- if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
14929
- hasInitialSizeRef.current = true;
14930
- }
15123
+ if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
14931
15124
  const canvasRef = React__namespace.useRef(null);
14932
15125
  const divRef = React__namespace.useRef(null);
14933
15126
  React__namespace.useImperativeHandle(ref, () => canvasRef.current);
@@ -14992,7 +15185,7 @@ function CanvasImpl({
14992
15185
  onDropMissed: (...args) => handleDropMissed.current?.(...args),
14993
15186
  onCreated: (state) => {
14994
15187
  state.events.connect?.(
14995
- eventSource ? isRef(eventSource) ? eventSource.current : eventSource : divRef.current
15188
+ eventSource ? isRef$1(eventSource) ? eventSource.current : eventSource : divRef.current
14996
15189
  );
14997
15190
  if (eventPrefix) {
14998
15191
  state.setEvents({
@@ -15041,6 +15234,7 @@ function CanvasImpl({
15041
15234
  const canvas = canvasRef.current;
15042
15235
  if (canvas) {
15043
15236
  return () => {
15237
+ if (canvas.isConnected) return;
15044
15238
  unmountComponentAtNode(canvas);
15045
15239
  root.current = null;
15046
15240
  };
@@ -15124,7 +15318,6 @@ exports.REACT_INTERNAL_PROPS = REACT_INTERNAL_PROPS;
15124
15318
  exports.RESERVED_PROPS = RESERVED_PROPS;
15125
15319
  exports.Texture = Texture;
15126
15320
  exports._roots = _roots;
15127
- exports.act = act;
15128
15321
  exports.addAfterEffect = addAfterEffect;
15129
15322
  exports.addEffect = addEffect;
15130
15323
  exports.addTail = addTail;
@@ -15163,7 +15356,7 @@ exports.isFromRef = isFromRef;
15163
15356
  exports.isObject3D = isObject3D;
15164
15357
  exports.isOnce = isOnce;
15165
15358
  exports.isOrthographicCamera = isOrthographicCamera;
15166
- exports.isRef = isRef;
15359
+ exports.isRef = isRef$1;
15167
15360
  exports.isRenderer = isRenderer;
15168
15361
  exports.isTexture = isTexture;
15169
15362
  exports.isVectorLike = isVectorLike;
@@ -15174,6 +15367,7 @@ exports.reconciler = reconciler;
15174
15367
  exports.registerPrimary = registerPrimary;
15175
15368
  exports.removeInteractivity = removeInteractivity;
15176
15369
  exports.resolve = resolve;
15370
+ exports.swapInteractivity = swapInteractivity;
15177
15371
  exports.unmountComponentAtNode = unmountComponentAtNode;
15178
15372
  exports.unregisterPrimary = unregisterPrimary;
15179
15373
  exports.updateCamera = updateCamera;