diff --git a/examples/jsm/exporters/USDZExporter.js b/examples/jsm/exporters/USDZExporter.js index 2d3ae16dcb696c..6f3744429819d9 100644 --- a/examples/jsm/exporters/USDZExporter.js +++ b/examples/jsm/exporters/USDZExporter.js @@ -2,6 +2,7 @@ import { NoColorSpace, DoubleSide, Color, + PropertyBinding, } from 'three'; import { @@ -76,7 +77,7 @@ class USDNode { const properties = this.properties.map( ( l ) => { - const property = l.property; + const property = l.property.replace( /\n/g, '\n' + pad + '\t' ); const metadata = l.metadata.length ? ` (\n${l.metadata.map( ( m ) => `${pad}\t\t${m}` ).join( '\n' )}\n${pad}\t)` : ''; @@ -199,6 +200,8 @@ class USDZExporter { onlyVisible: true, quickLookCompatible: false, maxTextureSize: 1024, + animations: [], + animationFrameRate: 60, }, options ); @@ -211,6 +214,9 @@ class USDZExporter { // model file should be first in USDZ archive so we init it here files[ modelFileName ] = null; + const animationTracks = buildAnimationTracks( scene, options.animations ); + options.animationTracks = animationTracks; + const root = new USDNode( 'Root', 'Xform' ); const scenesNode = new USDNode( 'Scenes', 'Scope' ); scenesNode.addMetadata( 'kind', '"sceneLibrary"' ); @@ -241,7 +247,15 @@ class USDZExporter { const materials = {}; const textures = {}; - buildHierarchy( scene, sceneNode, materials, usedNames, files, options ); + if ( scene.isScene ) { + + buildHierarchy( scene, sceneNode, materials, usedNames, files, options ); + + } else { + + buildNode( scene, sceneNode, materials, usedNames, files, options ); + + } const materialsNode = buildMaterials( materials, @@ -249,8 +263,12 @@ class USDZExporter { options.quickLookCompatible ); + const timeRange = animationTracks.size > 0 + ? { fps: options.animationFrameRate, endTimeCode: getMaxClipDuration( options.animations ) * options.animationFrameRate } + : null; + output = - buildHeader() + + buildHeader( timeRange ) + '\n' + root.toString() + '\n\n' + @@ -419,7 +437,15 @@ function imageToCanvas( image, flipY, maxTextureSize ) { const PRECISION = 7; -function buildHeader() { +function buildHeader( timeRange = null ) { + + const timeMetadata = timeRange + ? ` + startTimeCode = 0 + endTimeCode = ${timeRange.endTimeCode} + timeCodesPerSecond = ${timeRange.fps} + framesPerSecond = ${timeRange.fps}` + : ''; return `#usda 1.0 ( @@ -428,130 +454,261 @@ function buildHeader() { } defaultPrim = "Root" metersPerUnit = 1 - upAxis = "Y" + upAxis = "Y"${timeMetadata} ) `; } -// Xform +function buildAnimationTracks( scene, clips ) { -function buildHierarchy( object, parentNode, materials, usedNames, files, options ) { + // Map + const tracksByObject = new Map(); - for ( let i = 0, l = object.children.length; i < l; i ++ ) { + for ( let c = 0; c < clips.length; c ++ ) { - const child = object.children[ i ]; + const clip = clips[ c ]; - if ( child.visible === false && options.onlyVisible === true ) continue; + for ( let t = 0; t < clip.tracks.length; t ++ ) { - let childNode; + const track = clip.tracks[ t ]; + const binding = PropertyBinding.parseTrackName( track.name ); + const target = PropertyBinding.findNode( scene, binding.nodeName ); - if ( child.isMesh ) { + if ( target === null || target === undefined ) continue; - const geometry = child.geometry; - const material = child.material; + const property = binding.propertyName; + if ( property !== 'position' && property !== 'quaternion' && property !== 'scale' ) continue; - if ( material.isMeshStandardMaterial ) { + let entry = tracksByObject.get( target ); + if ( entry === undefined ) { - const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usda'; + entry = {}; + tracksByObject.set( target, entry ); - if ( ! ( geometryFileName in files ) ) { + } - const meshObject = buildMeshObject( geometry ); - files[ geometryFileName ] = strToU8( - buildHeader() + '\n' + meshObject.toString() - ); + entry[ property ] = track; - } + } - if ( ! ( material.uuid in materials ) ) { + } - materials[ material.uuid ] = material; + return tracksByObject; - } +} - childNode = buildMesh( - child, - geometry, - materials[ material.uuid ], - usedNames - ); +function getMaxClipDuration( clips ) { - } else { + let max = 0; + for ( let i = 0; i < clips.length; i ++ ) { - console.warn( - 'THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)', - child - ); + if ( clips[ i ].duration > max ) max = clips[ i ].duration; - } + } - } else if ( child.isCamera ) { + return max; - childNode = buildCamera( child, usedNames ); +} - } else { +function buildVector3TimeSamples( opName, opType, track, fps ) { + + const times = track.times; + const values = track.values; + const samples = []; + + for ( let i = 0; i < times.length; i ++ ) { + + const o = i * 3; + samples.push( `${( times[ i ] * fps ).toPrecision( PRECISION )}: (${values[ o ].toPrecision( PRECISION )}, ${values[ o + 1 ].toPrecision( PRECISION )}, ${values[ o + 2 ].toPrecision( PRECISION )})` ); + + } + + return `${opType} ${opName}.timeSamples = {\n\t${samples.join( ',\n\t' )},\n}`; + +} + +function buildQuaternionTimeSamples( track, fps ) { + + const times = track.times; + const values = track.values; + const samples = []; + + // three.js quaternion order: (x, y, z, w); USD quatf order: (w, x, y, z) + for ( let i = 0; i < times.length; i ++ ) { + + const o = i * 4; + samples.push( `${( times[ i ] * fps ).toPrecision( PRECISION )}: (${values[ o + 3 ].toPrecision( PRECISION )}, ${values[ o ].toPrecision( PRECISION )}, ${values[ o + 1 ].toPrecision( PRECISION )}, ${values[ o + 2 ].toPrecision( PRECISION )})` ); + + } - childNode = buildXform( child, usedNames ); + return `quatf xformOp:orient.timeSamples = {\n\t${samples.join( ',\n\t' )},\n}`; + +} + +// Xform + +function buildHierarchy( object, parentNode, materials, usedNames, files, options ) { + + for ( let i = 0, l = object.children.length; i < l; i ++ ) { + + buildNode( object.children[ i ], parentNode, materials, usedNames, files, options ); + + } + +} + +function buildNode( object, parentNode, materials, usedNames, files, options ) { + + if ( object.visible === false && options.onlyVisible === true ) return; + + let childNode; + + if ( object.isMesh ) { + + const geometry = object.geometry; + const material = object.material; + + if ( ! material.isMeshStandardMaterial ) { + + console.warn( 'THREE.USDZExporter: Use MeshStandardMaterial for best results.' ); } - if ( childNode ) { + const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usda'; + + if ( ! ( geometryFileName in files ) ) { - parentNode.addChild( childNode ); - buildHierarchy( child, childNode, materials, usedNames, files, options ); + const meshObject = buildMeshObject( geometry ); + files[ geometryFileName ] = strToU8( + buildHeader() + '\n' + meshObject.toString() + ); } + if ( ! ( material.uuid in materials ) ) { + + materials[ material.uuid ] = material; + + } + + childNode = buildMesh( + object, + geometry, + materials[ material.uuid ], + usedNames, + options + ); + + } else if ( object.isCamera ) { + + childNode = buildCamera( object, usedNames, options ); + + } else { + + childNode = buildXform( object, usedNames, options ); + } + parentNode.addChild( childNode ); + buildHierarchy( object, childNode, materials, usedNames, files, options ); + } -function buildXform( object, usedNames ) { +function addTransformProperties( node, object, options ) { - const name = getName( object, usedNames ); + const animTracks = options.animationTracks.get( object ); + const hasPivot = object.pivot !== null; - if ( object.matrix.determinant() < 0 ) { + if ( ! hasPivot && animTracks === undefined ) { - console.warn( - 'THREE.USDZExporter: USDZ does not support negative scales', - object - ); + const transform = buildMatrix( object.matrix ); + node.addProperty( `matrix4d xformOp:transform = ${transform}` ); + node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' ); + return; } - const node = new USDNode( name, 'Xform' ); + // Per-op layout: animated channels use timeSamples, others stay static. + // Pivot ops (when present) are always static. - if ( object.pivot !== null ) { + const fps = options.animationFrameRate; + const p = object.position; + const q = object.quaternion; + const s = object.scale; - // Export with pivot using separate transform ops - const p = object.position; - const q = object.quaternion; - const s = object.scale; - const piv = object.pivot; + if ( animTracks !== undefined && animTracks.position !== undefined ) { + + node.addProperty( buildVector3TimeSamples( 'xformOp:translate', 'float3', animTracks.position, fps ) ); + + } else { node.addProperty( `float3 xformOp:translate = (${p.x.toPrecision( PRECISION )}, ${p.y.toPrecision( PRECISION )}, ${p.z.toPrecision( PRECISION )})` ); + + } + + if ( hasPivot ) { + + const piv = object.pivot; node.addProperty( `float3 xformOp:translate:pivot = (${piv.x.toPrecision( PRECISION )}, ${piv.y.toPrecision( PRECISION )}, ${piv.z.toPrecision( PRECISION )})` ); + + } + + if ( animTracks !== undefined && animTracks.quaternion !== undefined ) { + + node.addProperty( buildQuaternionTimeSamples( animTracks.quaternion, fps ) ); + + } else { + node.addProperty( `quatf xformOp:orient = (${q.w.toPrecision( PRECISION )}, ${q.x.toPrecision( PRECISION )}, ${q.y.toPrecision( PRECISION )}, ${q.z.toPrecision( PRECISION )})` ); + + } + + if ( animTracks !== undefined && animTracks.scale !== undefined ) { + + node.addProperty( buildVector3TimeSamples( 'xformOp:scale', 'float3', animTracks.scale, fps ) ); + + } else { + node.addProperty( `float3 xformOp:scale = (${s.x.toPrecision( PRECISION )}, ${s.y.toPrecision( PRECISION )}, ${s.z.toPrecision( PRECISION )})` ); + + } + + if ( hasPivot ) { + node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:translate:pivot", "xformOp:orient", "xformOp:scale", "!invert!xformOp:translate:pivot"]' ); } else { - // Export as single transform matrix - const transform = buildMatrix( object.matrix ); - node.addProperty( `matrix4d xformOp:transform = ${transform}` ); - node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' ); + node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]' ); } +} + +function buildXform( object, usedNames, options ) { + + const name = getName( object, usedNames ); + + if ( object.matrix.determinant() < 0 ) { + + console.warn( + 'THREE.USDZExporter: USDZ does not support negative scales', + object + ); + + } + + const node = new USDNode( name, 'Xform' ); + addTransformProperties( node, object, options ); + return node; } -function buildMesh( object, geometry, material, usedNames ) { +function buildMesh( object, geometry, material, usedNames, options ) { - const node = buildXform( object, usedNames ); + const node = buildXform( object, usedNames, options ); node.addMetadata( 'prepend references', @@ -943,33 +1100,39 @@ function buildMaterial( material, textures, quickLookCompatible = false ) { } - if ( material.emissiveMap !== null ) { + if ( material.emissive ) { - previewSurfaceNode.addProperty( - `color3f inputs:emissiveColor.connect = ` - ); + const emissiveIntensity = material.emissiveIntensity ?? 1; - const emissiveColor = new Color( - material.emissive.r * material.emissiveIntensity, - material.emissive.g * material.emissiveIntensity, - material.emissive.b * material.emissiveIntensity - ); - const textureNodes = buildTextureNodes( - material.emissiveMap, - 'emissive', - emissiveColor - ); - textureNodes.forEach( ( node ) => materialNode.addChild( node ) ); + if ( material.emissiveMap ) { - } else if ( material.emissive.getHex() > 0 ) { + previewSurfaceNode.addProperty( + `color3f inputs:emissiveColor.connect = ` + ); - previewSurfaceNode.addProperty( - `color3f inputs:emissiveColor = ${buildColor( material.emissive )}` - ); + const emissiveColor = new Color( + material.emissive.r * emissiveIntensity, + material.emissive.g * emissiveIntensity, + material.emissive.b * emissiveIntensity + ); + const textureNodes = buildTextureNodes( + material.emissiveMap, + 'emissive', + emissiveColor + ); + textureNodes.forEach( ( node ) => materialNode.addChild( node ) ); + + } else if ( material.emissive.getHex() > 0 ) { + + previewSurfaceNode.addProperty( + `color3f inputs:emissiveColor = ${buildColor( material.emissive )}` + ); + + } } - if ( material.normalMap !== null ) { + if ( material.normalMap ) { previewSurfaceNode.addProperty( `normal3f inputs:normal.connect = ` @@ -980,16 +1143,17 @@ function buildMaterial( material, textures, quickLookCompatible = false ) { } - if ( material.aoMap !== null ) { + if ( material.aoMap ) { previewSurfaceNode.addProperty( `float inputs:occlusion.connect = ` ); + const aoMapIntensity = material.aoMapIntensity ?? 1; const aoColor = new Color( - material.aoMapIntensity, - material.aoMapIntensity, - material.aoMapIntensity + aoMapIntensity, + aoMapIntensity, + aoMapIntensity ); const textureNodes = buildTextureNodes( material.aoMap, @@ -1000,7 +1164,7 @@ function buildMaterial( material, textures, quickLookCompatible = false ) { } - if ( material.roughnessMap !== null ) { + if ( material.roughnessMap ) { previewSurfaceNode.addProperty( `float inputs:roughness.connect = ` @@ -1021,12 +1185,12 @@ function buildMaterial( material, textures, quickLookCompatible = false ) { } else { previewSurfaceNode.addProperty( - `float inputs:roughness = ${material.roughness}` + `float inputs:roughness = ${material.roughness ?? 1}` ); } - if ( material.metalnessMap !== null ) { + if ( material.metalnessMap ) { previewSurfaceNode.addProperty( `float inputs:metallic.connect = ` @@ -1047,12 +1211,12 @@ function buildMaterial( material, textures, quickLookCompatible = false ) { } else { previewSurfaceNode.addProperty( - `float inputs:metallic = ${material.metalness}` + `float inputs:metallic = ${material.metalness ?? 0}` ); } - if ( material.alphaMap !== null ) { + if ( material.alphaMap ) { previewSurfaceNode.addProperty( `float inputs:opacity.connect = ` @@ -1159,12 +1323,10 @@ function buildVector2( vector ) { } -function buildCamera( camera, usedNames ) { +function buildCamera( camera, usedNames, options ) { const name = getName( camera, usedNames ); - const transform = buildMatrix( camera.matrix ); - if ( camera.matrix.determinant() < 0 ) { console.warn( @@ -1175,8 +1337,7 @@ function buildCamera( camera, usedNames ) { } const node = new USDNode( name, 'Camera' ); - node.addProperty( `matrix4d xformOp:transform = ${transform}` ); - node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' ); + addTransformProperties( node, camera, options ); const projection = camera.isOrthographicCamera ? 'orthographic' @@ -1245,6 +1406,9 @@ function buildCamera( camera, usedNames ) { * can be configured via `ar.anchoring.type` and `ar.planeAnchoring.alignment`. * @property {boolean} [quickLookCompatible=false] - Whether to make the exported USDZ compatible to QuickLook * which means the asset is modified to accommodate the bugs FB10036297 and FB11442287 (Apple Feedback). + * @property {Array} [animations=[]] - Animation clips to bake into `xformOp` time samples on the + * targeted objects. Only `position`, `quaternion`, and `scale` tracks are exported. + * @property {number} [animationFrameRate=60] - Time codes per second used when writing animation samples. **/ /** diff --git a/examples/jsm/loaders/usd/USDAParser.js b/examples/jsm/loaders/usd/USDAParser.js index 510cedfc758aff..8a79a191777c1f 100644 --- a/examples/jsm/loaders/usd/USDAParser.js +++ b/examples/jsm/loaders/usd/USDAParser.js @@ -3,6 +3,13 @@ const DEF_MATCH_REGEX = /^def\s+(?:(\w+)\s+)?"?([^"]+)"?$/; const VARIANT_STRING_REGEX = /^string\s+(\w+)$/; const ATTR_MATCH_REGEX = /^(?:uniform\s+)?(\w+(?:\[\])?)\s+(.+)$/; +// Spec types (must match USDCParser/USDComposer) +const SpecType = { + Attribute: 1, + Prim: 6, + Relationship: 8 +}; + class USDAParser { parseText( text ) { @@ -429,13 +436,6 @@ class USDAParser { const root = this.parseText( text ); const specsByPath = {}; - // Spec types (must match USDCParser/USDComposer) - const SpecType = { - Attribute: 1, - Prim: 6, - Relationship: 8 - }; - // Parse root metadata const rootFields = {}; if ( '#usda 1.0' in root ) { @@ -524,10 +524,45 @@ class USDAParser { walkTree( root, '/' ); + // Fallback: infer elementSize for primvars:skel:jointIndices/jointWeights + // when not explicitly declared in the USDA text + this._inferSkelElementSize( specsByPath ); + return { specsByPath }; } + _inferSkelElementSize( specsByPath ) { + + // For each mesh prim with primvars:skel:jointIndices/jointWeights but no + // elementSize, infer it from the data: elementSize = array.length / numVertices. + for ( const path in specsByPath ) { + + const spec = specsByPath[ path ]; + if ( spec.specType !== SpecType.Prim || spec.fields.typeName !== 'Mesh' ) continue; + + const pointsSpec = specsByPath[ path + '.points' ]; + if ( ! pointsSpec || ! pointsSpec.fields.default ) continue; + + const numVertices = pointsSpec.fields.default.length / 3; + if ( numVertices === 0 ) continue; + + this._inferElementSize( specsByPath[ path + '.primvars:skel:jointIndices' ], numVertices ); + this._inferElementSize( specsByPath[ path + '.primvars:skel:jointWeights' ], numVertices ); + + } + + } + + _inferElementSize( attrSpec, numVertices ) { + + if ( ! attrSpec || attrSpec.fields.elementSize !== undefined || ! attrSpec.fields.default ) return; + + const len = attrSpec.fields.default.length; + if ( len > 0 && len % numVertices === 0 ) attrSpec.fields.elementSize = len / numVertices; + + } + _extractPrimData( data, path, primFields, specsByPath, SpecType ) { if ( ! data || typeof data !== 'object' ) return; diff --git a/examples/misc_exporter_usdz.html b/examples/misc_exporter_usdz.html index 6fa02a5d817973..1c16fc8ace1dcf 100644 --- a/examples/misc_exporter_usdz.html +++ b/examples/misc_exporter_usdz.html @@ -31,8 +31,8 @@
three.js - USDZ exporter
- Battle Damaged Sci-fi Helmet by - theblueturtle_ + Carbon Frame Bike by + prefrontal cortex
@@ -56,28 +56,33 @@ import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; + import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; + import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; import { USDZExporter } from 'three/addons/exporters/USDZExporter.js'; + import * as WebGLTextureUtils from 'three/addons/utils/WebGLTextureUtils.js'; import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - let camera, scene, renderer; + let camera, scene, renderer, mixer, timer, controls; const params = { exportUSDZ: exportUSDZ }; init(); - render(); function init() { + timer = new THREE.Timer(); + renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); + renderer.setAnimationLoop( animate ); renderer.toneMapping = THREE.ACESFilmicToneMapping; document.body.appendChild( renderer.domElement ); - camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 ); - camera.position.set( - 2.5, 0.6, 3.0 ); + camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 0.25, 20 ); + camera.position.set( - 2.5, 1.6, 3.0 ); const pmremGenerator = new THREE.PMREMGenerator( renderer ); @@ -85,23 +90,32 @@ scene.background = new THREE.Color( 0xf0f0f0 ); scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture; - const loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' ); - loader.load( 'DamagedHelmet.gltf', async function ( gltf ) { + const ktx2loader = new KTX2Loader().setTranscoderPath( 'jsm/libs/basis/' ).detectSupport( renderer ); + const dracoLoader = new DRACOLoader().setDecoderPath( 'jsm/libs/draco/' ); + const gltfLoader = new GLTFLoader(); + + gltfLoader.setDRACOLoader( dracoLoader ); + gltfLoader.setKTX2Loader( ktx2loader ); + gltfLoader.setPath( 'models/gltf/' ); + gltfLoader.load( 'CarbonFrameBike.glb', async function ( gltf ) { scene.add( gltf.scene ); - const shadowMesh = createSpotShadowMesh(); - shadowMesh.position.y = - 1.1; - shadowMesh.position.z = - 0.25; - shadowMesh.scale.setScalar( 2 ); - scene.add( shadowMesh ); + if ( gltf.animations.length > 0 ) { + + mixer = new THREE.AnimationMixer( gltf.scene ); + const action = mixer.clipAction( gltf.animations[ 0 ] ); + action.setLoop( THREE.LoopRepeat, Infinity ); + action.play(); + + } - render(); // USDZ const exporter = new USDZExporter(); - const arraybuffer = await exporter.parseAsync( gltf.scene ); + exporter.setTextureUtils( WebGLTextureUtils ); // for texture decompresssing + const arraybuffer = await exporter.parseAsync( gltf.scene, { animations: gltf.animations } ); const blob = new Blob( [ arraybuffer ], { type: 'application/octet-stream' } ); const link = document.getElementById( 'link' ); @@ -109,11 +123,11 @@ } ); - const controls = new OrbitControls( camera, renderer.domElement ); - controls.addEventListener( 'change', render ); // use if there is no animation loop + controls = new OrbitControls( camera, renderer.domElement ); controls.minDistance = 2; controls.maxDistance = 10; - controls.target.set( 0, - 0.15, - 0.2 ); + controls.enableDamping = true; + controls.target.set( 0, 0.7, 0 ); controls.update(); window.addEventListener( 'resize', onWindowResize ); @@ -131,34 +145,6 @@ } - function createSpotShadowMesh() { - - const canvas = document.createElement( 'canvas' ); - canvas.width = 128; - canvas.height = 128; - - const context = canvas.getContext( '2d' ); - const gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 ); - gradient.addColorStop( 0.1, 'rgba(130,130,130,1)' ); - gradient.addColorStop( 1, 'rgba(255,255,255,1)' ); - - context.fillStyle = gradient; - context.fillRect( 0, 0, canvas.width, canvas.height ); - - const shadowTexture = new THREE.CanvasTexture( canvas ); - - const geometry = new THREE.PlaneGeometry(); - const material = new THREE.MeshBasicMaterial( { - map: shadowTexture, blending: THREE.MultiplyBlending, toneMapped: false, premultipliedAlpha: true - } ); - - const mesh = new THREE.Mesh( geometry, material ); - mesh.rotation.x = - Math.PI / 2; - - return mesh; - - } - function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; @@ -166,8 +152,6 @@ renderer.setSize( window.innerWidth, window.innerHeight ); - render(); - } function exportUSDZ() { @@ -179,7 +163,15 @@ // - function render() { + function animate() { + + timer.update(); + + const delta = timer.getDelta(); + + if ( mixer ) mixer.update( delta ); + + controls.update(); renderer.render( scene, camera ); diff --git a/examples/models/gltf/CarbonFrameBike.glb b/examples/models/gltf/CarbonFrameBike.glb new file mode 100644 index 00000000000000..e4de767cf28bd2 Binary files /dev/null and b/examples/models/gltf/CarbonFrameBike.glb differ diff --git a/examples/screenshots/misc_exporter_usdz.jpg b/examples/screenshots/misc_exporter_usdz.jpg index ad1b20e71388b6..6875bbdc0a2034 100644 Binary files a/examples/screenshots/misc_exporter_usdz.jpg and b/examples/screenshots/misc_exporter_usdz.jpg differ diff --git a/package-lock.json b/package-lock.json index 50a978cab988cf..cd15c3ee5e9cde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "jsdoc": "^4.0.5", "magic-string": "^0.30.0", "pngjs": "^7.0.0", - "puppeteer": "^24.40.0", + "puppeteer": "^25.0.0", "rollup": "^4.6.0", "turndown": "^7.2.2" } @@ -406,25 +406,31 @@ "license": "BSD-2-Clause" }, "node_modules/@puppeteer/browsers": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", - "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.2.tgz", + "integrity": "sha512-JnOSHrAdCQOj27P5QnTrd6bkYd9cXXeFMJS5UJF3UmQbpZQAMMO7AaL0NyrT7i2l/43bwjaHguU+LOpBRyx66w==", "dev": true, "license": "Apache-2.0", "dependencies": { "debug": "^4.4.3", - "extract-zip": "^2.0.1", "progress": "^2.0.3", - "proxy-agent": "^6.5.0", "semver": "^7.7.4", "tar-fs": "^3.1.1", "yargs": "^17.7.2" }, "bin": { - "browsers": "lib/cjs/main-cli.js" + "browsers": "lib/main-cli.js" }, "engines": { - "node": ">=18" + "node": ">=22.12.0" + }, + "peerDependencies": { + "proxy-agent": ">=8.0.1" + }, + "peerDependenciesMeta": { + "proxy-agent": { + "optional": true + } } }, "node_modules/@rollup/plugin-node-resolve": { @@ -900,13 +906,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -946,17 +945,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/node": { - "version": "25.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", - "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "undici-types": "~7.19.0" - } - }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -964,17 +952,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/types": { "version": "8.58.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.2.tgz", @@ -1012,16 +989,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, "node_modules/ajv": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", @@ -1099,19 +1066,6 @@ "dev": true, "license": "CC0-1.0" }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/b4a": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", @@ -1244,16 +1198,6 @@ "node": ">=6.0.0" } }, - "node_modules/basic-ftp": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", - "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -1306,16 +1250,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1385,15 +1319,18 @@ } }, "node_modules/chromium-bidi": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", - "integrity": "sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-16.0.1.tgz", + "integrity": "sha512-J63PGu/9PpeCwLIcKYyzWP6yaVL5pxuBc0shlYCYM8BaAkmlwiQboXO1iNbOgSDbVklEyYFfNEcHD8oOAWacUA==", "dev": true, "license": "Apache-2.0", "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" }, + "engines": { + "node": ">=20.19.0 <22.0.0 || >=22.12.0" + }, "peerDependencies": { "devtools-protocol": "*" } @@ -1492,16 +1429,6 @@ "node": ">= 8" } }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -1537,21 +1464,6 @@ "node": ">=0.10.0" } }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/devtools-protocol": { "version": "0.0.1608973", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1608973.tgz", @@ -1721,28 +1633,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, "node_modules/eslint": { "version": "9.39.4", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", @@ -1966,20 +1856,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -2043,27 +1919,6 @@ "bare-events": "^2.7.0" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2092,16 +1947,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -2188,37 +2033,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-uri": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", - "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2312,34 +2126,6 @@ "entities": "^7.0.1" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2377,16 +2163,6 @@ "node": ">=0.8.19" } }, - "node_modules/ip-address": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", - "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2660,16 +2436,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -2789,16 +2555,6 @@ "dev": true, "license": "MIT" }, - "node_modules/netmask": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", - "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/node-releases": { "version": "2.0.37", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", @@ -2873,40 +2629,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pac-proxy-agent": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", - "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.6", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "dev": true, - "license": "MIT", - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2983,13 +2705,6 @@ "dev": true, "license": "MIT" }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3040,33 +2755,6 @@ "node": ">=0.4.0" } }, - "node_modules/proxy-agent": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", - "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.6", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.1.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true, - "license": "MIT" - }, "node_modules/pump": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", @@ -3099,36 +2787,36 @@ } }, "node_modules/puppeteer": { - "version": "24.43.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.43.1.tgz", - "integrity": "sha512-/FSOViCrqRdb1HDocpsM9Z1giA71gTQPUt3SpHGVRALKAy/rJr1fLFYZW9F23qPxqVxTHQnbh/5B5opJST3kAw==", + "version": "25.0.2", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-25.0.2.tgz", + "integrity": "sha512-cXj/5RlDCzSC7k1YdBIm6prb8lK8lEdmScVbcalX1rBn4fqNN1UNuEz/HZZYiDLsK8dOGvyLpGjh6CgxCyqKtg==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.13.2", - "chromium-bidi": "14.0.0", + "@puppeteer/browsers": "3.0.2", + "chromium-bidi": "16.0.1", "cosmiconfig": "^9.0.0", "devtools-protocol": "0.0.1608973", - "puppeteer-core": "24.43.1", + "puppeteer-core": "25.0.2", "typed-query-selector": "^2.12.2" }, "bin": { - "puppeteer": "lib/cjs/puppeteer/node/cli.js" + "puppeteer": "lib/puppeteer/node/cli.js" }, "engines": { - "node": ">=18" + "node": ">=22.12.0" } }, "node_modules/puppeteer-core": { - "version": "24.43.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.43.1.tgz", - "integrity": "sha512-T5ScUMAsmhdNbgDR41AGESYeS6V9MSgetkSnVhhW+gXvzC42VesKCn5ld87gAZDJ6vLHL9GkRvY9WtQWSnwFbw==", + "version": "25.0.2", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.0.2.tgz", + "integrity": "sha512-Q0IUIHER1S9PiNIfdNFc+pVOj79Tp4b9v0Fv4enigwsLy0Hbgq45KFgqzmN31DeCXh+Uvxnt9r7fMERhAMjs8Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.13.2", - "chromium-bidi": "14.0.0", + "@puppeteer/browsers": "3.0.2", + "chromium-bidi": "16.0.1", "debug": "^4.4.3", "devtools-protocol": "0.0.1608973", "typed-query-selector": "^2.12.2", @@ -3136,7 +2824,7 @@ "ws": "^8.20.0" }, "engines": { - "node": ">=18" + "node": ">=22.12.0" } }, "node_modules/require-directory": { @@ -3295,17 +2983,6 @@ "node": ">=8" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, "node_modules/smob": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.1.tgz", @@ -3316,36 +2993,6 @@ "node": ">=20.0.0" } }, - "node_modules/socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ip-address": "^10.0.1", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3562,13 +3209,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD" - }, "node_modules/turndown": { "version": "7.2.4", "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.4.tgz", @@ -3617,14 +3257,6 @@ "dev": true, "license": "MIT" }, - "node_modules/undici-types": { - "version": "7.19.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", - "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -3792,17 +3424,6 @@ "node": ">=12" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 909f48ae6859f5..16a536bd80e1b7 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "jsdoc": "^4.0.5", "magic-string": "^0.30.0", "pngjs": "^7.0.0", - "puppeteer": "^24.40.0", + "puppeteer": "^25.0.0", "rollup": "^4.6.0", "turndown": "^7.2.2" },