├── .gitignore ├── .prettierrc.json ├── LICENSE ├── README.md ├── hdri └── hdri.exr ├── index.html ├── main.js ├── material ├── material.json ├── material_albedo.png ├── material_displace.png ├── material_metal.png ├── material_normal.png ├── material_occlusion.png └── material_rough.png ├── mm_target └── meshstandardmat.mme ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | test/ 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # Snowpack dependency directory (https://snowpack.dev/) 49 | web_modules/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional stylelint cache 61 | .stylelintcache 62 | 63 | # Microbundle cache 64 | .rpt2_cache/ 65 | .rts2_cache_cjs/ 66 | .rts2_cache_es/ 67 | .rts2_cache_umd/ 68 | 69 | # Optional REPL history 70 | .node_repl_history 71 | 72 | # Output of 'npm pack' 73 | *.tgz 74 | 75 | # Yarn Integrity file 76 | .yarn-integrity 77 | 78 | # dotenv environment variable files 79 | .env 80 | .env.development.local 81 | .env.test.local 82 | .env.production.local 83 | .env.local 84 | 85 | # parcel-bundler cache (https://parceljs.org/) 86 | .cache 87 | .parcel-cache 88 | 89 | # Next.js build output 90 | .next 91 | out 92 | 93 | # Nuxt.js build / generate output 94 | .nuxt 95 | dist 96 | 97 | # Gatsby files 98 | .cache/ 99 | # Comment in the public line in if your project uses Gatsby and not Next.js 100 | # https://nextjs.org/blog/next-9-1#public-directory-support 101 | # public 102 | 103 | # vuepress build output 104 | .vuepress/dist 105 | 106 | # vuepress v2.x temp and cache directory 107 | .temp 108 | .cache 109 | 110 | # vitepress build output 111 | **/.vitepress/dist 112 | 113 | # vitepress cache directory 114 | **/.vitepress/cache 115 | 116 | # Docusaurus cache and generated files 117 | .docusaurus 118 | 119 | # Serverless directories 120 | .serverless/ 121 | 122 | # FuseBox cache 123 | .fusebox/ 124 | 125 | # DynamoDB Local files 126 | .dynamodb/ 127 | 128 | # TernJS port file 129 | .tern-port 130 | 131 | # Stores VSCode versions used for testing VSCode extensions 132 | .vscode-test 133 | 134 | # yarn v2 135 | .yarn/cache 136 | .yarn/unplugged 137 | .yarn/build-state.yml 138 | .yarn/install-state.gz 139 | .pnp.* 140 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "useTabs": false, 4 | "semi": true, 5 | "singleQuote": true, 6 | "trailingComma": "all", 7 | "arrowParens": "always", 8 | "printWidth": 100 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 MW 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # material-maker-threejs 2 | 3 | 4 | Basic three.js viewer for Material Maker (Standard PBR Material) 5 | 6 | [Live Demo](https://williamchange.github.io/projects/mmthreejs/) 7 | 8 | ## Screenshot 9 | image 10 | 11 | ## Export Target 12 | Custom export target is used in Material Maker (download [here](https://raw.githubusercontent.com/williamchange/material-maker-threejs/refs/heads/master/mm_target/meshstandardmat.mme)) which creates a ([MeshStandardMaterial](https://threejs.org/docs/#api/en/materials/MeshStandardMaterial)) .json file with associated textures, and can be imported using [MaterialLoader](https://threejs.org/docs/#api/en/loaders/MaterialLoader) (not directly, textures are still loaded seperately) in three.js 13 | 14 | ## Running the project 15 | 16 | The following should give you a local development server running on http://localhost:XXXX, which you can then run in your browser 17 | 18 | ```text 19 | npm install 20 | npx vite 21 | ``` 22 | 23 | ## Limitation 24 | 25 | Currently the following are exported (more to be added): 26 | - Albedo 27 | - Roughness Map 28 | - Metalic Map 29 | - Normal 30 | - Ambient Occulusion 31 | - Depth (Displacement/Height Map) 32 | 33 | ## Credit / Links 34 | 35 | Materials (CC0) by [Pavel Oliva](https://x.com/pavel_Oliva) 36 | - [Celestial Floor](https://materialmaker.org/material?id=751) 37 | - [Seigaiha Cobblestone](https://materialmaker.org/material?id=982) 38 | - [Mossy Rooftiles](https://materialmaker.org/material?id=1088) 39 | 40 | [Epping Forest 1K](https://polyhaven.com/a/epping_forest_01) via [Polyhaven](https://dev.polyhaven.com/) (CC0) 41 | 42 | [Material Maker](https://github.com/RodZill4/material-maker/) Project by [RodzLabs](https://github.com/RodZill4) -------------------------------------------------------------------------------- /hdri/hdri.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamchange/material-maker-threejs/d55780881a7276b823f4132e6814a2620f7cd386/hdri/hdri.exr -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Three.js MM Demo 6 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three'; 2 | 3 | import Stats from 'three/addons/libs/stats.module.js'; 4 | 5 | import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; 6 | import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; 7 | import { EXRLoader } from 'three/addons/loaders/EXRLoader.js'; 8 | 9 | let preset = {}; 10 | let container, stats; 11 | let camera, scene, renderer, controls, light; 12 | let mesh; 13 | let exrCubeRenderTarget; 14 | let exrBackground; 15 | 16 | const hdri_path = './hdri/hdri.exr'; 17 | 18 | const base_path = './material/'; 19 | const json_path = base_path + 'material.json'; 20 | 21 | // gui params 22 | const params = { 23 | geometry: 'Sphere', 24 | clearbg: false, 25 | clearbgcolor: 0x333333, 26 | tonemap: 'ACES', 27 | roughness: 0.0, 28 | metalness: 0.0, 29 | displacementscale: 1.0, 30 | displacementbias: 0.0, 31 | normalscale: 1.0, 32 | aointensity: 1.0, 33 | exposure: 1.0, 34 | rotationspeed: 0.33, 35 | rotate: true, 36 | ambientlightcolor: 0x404040, 37 | ambientlightintensity: 1.0, 38 | textureuscale: 4.0, 39 | texturevscale: 2.0, 40 | envmaprotz: 0, 41 | }; 42 | const geo = { 43 | "plane": new THREE.PlaneGeometry(48, 48, 512, 512), 44 | "sphere": new THREE.SphereGeometry(32.0, 1024, 2048), 45 | } 46 | 47 | init(); 48 | 49 | function loadTexture(path) { 50 | let tex = null; 51 | tex = new THREE.TextureLoader().load(path); 52 | tex.repeat.x = 100; 53 | tex.wrapS = tex.wrapT = THREE.RepeatWrapping; 54 | tex.repeat.set(4, 2); 55 | return tex; 56 | } 57 | 58 | function updateSceneMesh() { 59 | mesh.geometry.dispose(); 60 | mesh.geometry = geo[params.geometry.toLowerCase()] 61 | } 62 | 63 | function init() { 64 | container = document.createElement('div'); 65 | document.body.appendChild(container); 66 | 67 | camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); 68 | 69 | camera.position.set(0, 0, 120); 70 | 71 | scene = new THREE.Scene(); 72 | 73 | renderer = new THREE.WebGLRenderer(); 74 | renderer.setPixelRatio(window.devicePixelRatio); 75 | renderer.setSize(window.innerWidth, window.innerHeight); 76 | renderer.setAnimationLoop(animate); 77 | 78 | container.appendChild(renderer.domElement); 79 | 80 | let geometry = geo.sphere 81 | let material = new THREE.MeshStandardMaterial(); 82 | mesh = new THREE.Mesh(geometry, material); 83 | scene.add(mesh); 84 | 85 | light = new THREE.AmbientLight(params.ambientlightcolor); 86 | light.intensity = params.ambientlightintensity; 87 | scene.add(light); 88 | 89 | THREE.DefaultLoadingManager.onLoad = function () { 90 | pmremGenerator.dispose(); 91 | }; 92 | 93 | new EXRLoader().load(hdri_path, function (texture) { 94 | texture.mapping = THREE.EquirectangularReflectionMapping; 95 | exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture); 96 | exrBackground = texture; 97 | }); 98 | 99 | const pmremGenerator = new THREE.PMREMGenerator(renderer); 100 | pmremGenerator.compileEquirectangularShader(); 101 | 102 | stats = new Stats(); 103 | container.appendChild(stats.dom); 104 | 105 | controls = new OrbitControls(camera, renderer.domElement); 106 | controls.minDistance = 50; 107 | controls.maxDistance = 300; 108 | 109 | window.addEventListener('resize', onWindowResize); 110 | 111 | const gui = new GUI(); 112 | 113 | const loader = new THREE.MaterialLoader(); 114 | fetch(json_path) 115 | .then((res) => res.json()) 116 | .then((o) => { 117 | loader.load(json_path, (mat) => { 118 | mesh.material = mat; 119 | 120 | // load textures from json 121 | for (const tex in o.textures) { 122 | mesh.material[tex] = loadTexture(base_path + o.textures[tex]); 123 | } 124 | mesh.material.map.colorSpace = THREE.SRGBColorSpace; 125 | 126 | // set gui params from loaded material 127 | params.roughness = mat.roughness; 128 | params.metalness = mat.metalness; 129 | params.displacementscale = mesh.material.displacementScale; 130 | params.displacementbias = mesh.material.displacementBias; 131 | params.normalscale = o.normalScale; 132 | 133 | // Mesh 134 | const meshFolder = gui.addFolder('Mesh'); 135 | meshFolder 136 | .add(params, 'geometry', ['Plane', 'Sphere']) 137 | .name('Mesh') 138 | .onChange(updateSceneMesh); 139 | 140 | // Environment 141 | const envFolder = gui.addFolder('Environment'); 142 | envFolder.add(params, 'envmaprotz', -1.0, 1.0, 0.01).name('Environment Rotation'); 143 | envFolder.add(params, 'clearbg').name('Clear BG'); 144 | envFolder.addColor(params, 'clearbgcolor').name('Clear BG Color'); 145 | envFolder 146 | .add(params, 'tonemap', [ 147 | 'Linear', 148 | 'Reinhard', 149 | 'Cineon', 150 | 'ACES', 151 | 'AgX', 152 | 'Neutral', 153 | ]) 154 | .name('Tonemapping'); 155 | envFolder.add(params, 'exposure', 0, 2, 0.01).name('Exposure'); 156 | envFolder.addColor(params, 'ambientlightcolor').name('Ambient Light'); 157 | envFolder 158 | .add(params, 'ambientlightintensity', 0, 10, 0.01) 159 | .name('Ambient Light Intensity'); 160 | 161 | // Material 162 | const matFolder = gui.addFolder('Material'); 163 | matFolder.add(params, 'textureuscale', 1, 16, 1).name('U Scale'); 164 | matFolder.add(params, 'texturevscale', 1, 16, 1).name('V Scale'); 165 | matFolder.add(params, 'roughness', 0, 1, 0.01).name('Roughness'); 166 | matFolder.add(params, 'metalness', 0, 1, 0.01).name('Metalness'); 167 | 168 | matFolder.add(params, 'normalscale', 0.0, 1.0, 0.01).name('Normal Scale'); 169 | matFolder.add(params, 'aointensity', 0.0, 1.0, 0.01).name('AO Intensity'); 170 | 171 | matFolder.add(params, 'displacementscale', 0, 4, 0.01).name('Displacement Scale'); 172 | matFolder.add(params, 'displacementbias', -2, 2, 0.01).name('Displacement Bias'); 173 | 174 | // Animation 175 | const animFolder = gui.addFolder('Animation'); 176 | animFolder.add(params, 'rotationspeed', 0.0, 1.0, 0.01).name('Rotation Speed'); 177 | animFolder.add(params, 'rotate').name('Rotate'); 178 | 179 | // Reset to default 180 | params.reset = () => { 181 | gui.load(preset); 182 | }; 183 | gui.add(params, 'reset').name('Reset'); 184 | preset = gui.save(); 185 | 186 | gui.open(); 187 | }); 188 | }); 189 | } 190 | 191 | function onWindowResize() { 192 | const width = window.innerWidth; 193 | const height = window.innerHeight; 194 | 195 | camera.aspect = width / height; 196 | camera.updateProjectionMatrix(); 197 | 198 | renderer.setSize(width, height); 199 | } 200 | 201 | function animate() { 202 | stats.begin(); 203 | render(); 204 | stats.end(); 205 | } 206 | 207 | function render() { 208 | let newEnvMap = mesh.material.envMap; 209 | let background = scene.background; 210 | let tonemapping; 211 | 212 | newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null; 213 | background = exrBackground; 214 | 215 | tonemapping = { 216 | Linear: THREE.LinearToneMapping, 217 | Reinhard: THREE.ReinhardToneMapping, 218 | Cineon: THREE.CineonToneMapping, 219 | ACES: THREE.ACESFilmicToneMapping, 220 | AgX: THREE.AgXToneMapping, 221 | Neutral: THREE.NeutralToneMapping, 222 | }[params.tonemap]; 223 | 224 | if (newEnvMap !== mesh.material.envMap) { 225 | mesh.material.envMap = newEnvMap; 226 | mesh.material.needsUpdate = true; 227 | } 228 | 229 | // gui config 230 | const uvs = new THREE.Vector2(params.textureuscale, params.texturevscale); 231 | 232 | if (mesh.material.map) mesh.material.map.repeat.set(uvs.x, uvs.y); 233 | 234 | mesh.material.displacementScale = params.displacementscale; 235 | mesh.material.displacementBias = params.displacementbias; 236 | if (mesh.material.displacementMap) mesh.material.displacementMap.repeat.set(uvs.x, uvs.y); 237 | 238 | mesh.material.normalScale = new THREE.Vector2(1 * params.normalscale); 239 | if (mesh.material.normalMap) mesh.material.normalMap.repeat.set(uvs.x, uvs.y); 240 | 241 | if (mesh.material.aoMap) mesh.material.aoMap.repeat.set(uvs.x, uvs.y); 242 | mesh.material.aoMapIntensity = params.aointensity; 243 | 244 | mesh.material.roughness = params.roughness; 245 | if (mesh.material.roughnessMap) mesh.material.roughnessMap.repeat.set(uvs.x, uvs.y); 246 | 247 | mesh.material.metalness = params.metalness; 248 | if (mesh.material.metalnessMap) mesh.material.metalnessMap.repeat.set(uvs.x, uvs.y); 249 | 250 | mesh.material.envMapRotation.y = params.envmaprotz * 6.283; 251 | 252 | // animate mesh rotation 253 | mesh.rotation.y += 0.005 * params.rotationspeed * (params.rotate ? 1.0 : 0.0); 254 | 255 | // clear bg 256 | if (!params.clearbg) { 257 | scene.background = background; 258 | scene.backgroundRotation.y = params.envmaprotz * 6.283; 259 | } else { 260 | scene.background = new THREE.Color(params.clearbgcolor); 261 | } 262 | 263 | // ambient light 264 | light.color = new THREE.Color(params.ambientlightcolor); 265 | light.intensity = params.ambientlightintensity; 266 | 267 | // tonemapping / exposure 268 | renderer.toneMapping = tonemapping; 269 | renderer.toneMappingExposure = params.exposure; 270 | 271 | renderer.render(scene, camera); 272 | } 273 | -------------------------------------------------------------------------------- /material/material.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "MeshStandardMaterial", 3 | "roughness": 1.0, 4 | "metalness": 0.0, 5 | "displacementScale": 1.0, 6 | "displacementBias": 0.5, 7 | "normalScale": 1.0, 8 | "textures": { 9 | "map": "material_albedo.png", 10 | "normalMap": "material_normal.png", 11 | "aoMap": "material_occlusion.png", 12 | "roughnessMap": "material_rough.png", 13 | "metalnessMap": "material_metal.png", 14 | "displacementMap": "material_displace.png", 15 | "_": "" 16 | } 17 | } -------------------------------------------------------------------------------- /material/material_albedo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamchange/material-maker-threejs/d55780881a7276b823f4132e6814a2620f7cd386/material/material_albedo.png -------------------------------------------------------------------------------- /material/material_displace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamchange/material-maker-threejs/d55780881a7276b823f4132e6814a2620f7cd386/material/material_displace.png -------------------------------------------------------------------------------- /material/material_metal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamchange/material-maker-threejs/d55780881a7276b823f4132e6814a2620f7cd386/material/material_metal.png -------------------------------------------------------------------------------- /material/material_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamchange/material-maker-threejs/d55780881a7276b823f4132e6814a2620f7cd386/material/material_normal.png -------------------------------------------------------------------------------- /material/material_occlusion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamchange/material-maker-threejs/d55780881a7276b823f4132e6814a2620f7cd386/material/material_occlusion.png -------------------------------------------------------------------------------- /material/material_rough.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamchange/material-maker-threejs/d55780881a7276b823f4132e6814a2620f7cd386/material/material_rough.png -------------------------------------------------------------------------------- /mm_target/meshstandardmat.mme: -------------------------------------------------------------------------------- 1 | { 2 | "custom": "", 3 | "export_extension": "json", 4 | "files": [ 5 | { 6 | "conditions": "$(connected:albedo_tex)", 7 | "file_name": "$(path_prefix)_albedo.png", 8 | "output": 0, 9 | "type": "texture" 10 | }, 11 | { 12 | "conditions": "$(connected:roughness_tex)", 13 | "file_name": "$(path_prefix)_rough.png", 14 | "output": 13, 15 | "type": "texture" 16 | }, 17 | { 18 | "conditions": "$(connected:metallic_tex)", 19 | "file_name": "$(path_prefix)_metal.png", 20 | "output": 12, 21 | "type": "texture" 22 | }, 23 | { 24 | "conditions": "$(connected:normal_tex)", 25 | "file_name": "$(path_prefix)_normal.png", 26 | "output": 7, 27 | "type": "texture" 28 | }, 29 | { 30 | "conditions": "$(connected:depth_tex)", 31 | "file_name": "$(path_prefix)_displace.png", 32 | "output": 8, 33 | "type": "texture" 34 | }, 35 | { 36 | "conditions": "$(connected:ao_tex)", 37 | "file_name": "$(path_prefix)_occlusion.png", 38 | "output": 9, 39 | "type": "texture" 40 | }, 41 | { 42 | "file_name": "$(path_prefix).json", 43 | "template": "{\n \"type\": \"MeshStandardMaterial\",\n \"roughness\": $(param:roughness),\n \"metalness\": $(param:metallic),\n \"displacementScale\": $(param:depth_scale),\n \"displacementBias\": 0.5,\n \"normalScale\": $(param:normal),\n \"textures\": {\n$if $(connected:albedo_tex)\n \"map\": \"$(file_prefix)_albedo.png\",\n$fi\n$if $(connected:normal_tex)\n \"normalMap\": \"$(file_prefix)_normal.png\",\n$fi\n$if $(connected:ao_tex)\n \"aoMap\": \"$(file_prefix)_occlusion.png\",\n$fi\n$if $(connected:roughness_tex)\n \"roughnessMap\": \"$(file_prefix)_rough.png\",\n$fi\n$if $(connected:metallic_tex)\n \"metalnessMap\": \"$(file_prefix)_metal.png\",\n$fi\n$if $(connected:depth_tex)\n \"displacementMap\": \"$(file_prefix)_displace.png\",\n$fi\n \"_\": \"\"\n }\n}\n", 44 | "type": "template" 45 | } 46 | ], 47 | "name": "Web/MeshStandardMaterial" 48 | } 49 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "material-maker-threejs", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "three": "^0.176.0" 9 | }, 10 | "devDependencies": { 11 | "lil-gui": "^0.20.0", 12 | "vite": "^6.3.5" 13 | } 14 | }, 15 | "node_modules/@esbuild/aix-ppc64": { 16 | "version": "0.25.4", 17 | "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", 18 | "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", 19 | "cpu": [ 20 | "ppc64" 21 | ], 22 | "dev": true, 23 | "license": "MIT", 24 | "optional": true, 25 | "os": [ 26 | "aix" 27 | ], 28 | "engines": { 29 | "node": ">=18" 30 | } 31 | }, 32 | "node_modules/@esbuild/android-arm": { 33 | "version": "0.25.4", 34 | "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.4.tgz", 35 | "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", 36 | "cpu": [ 37 | "arm" 38 | ], 39 | "dev": true, 40 | "license": "MIT", 41 | "optional": true, 42 | "os": [ 43 | "android" 44 | ], 45 | "engines": { 46 | "node": ">=18" 47 | } 48 | }, 49 | "node_modules/@esbuild/android-arm64": { 50 | "version": "0.25.4", 51 | "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", 52 | "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", 53 | "cpu": [ 54 | "arm64" 55 | ], 56 | "dev": true, 57 | "license": "MIT", 58 | "optional": true, 59 | "os": [ 60 | "android" 61 | ], 62 | "engines": { 63 | "node": ">=18" 64 | } 65 | }, 66 | "node_modules/@esbuild/android-x64": { 67 | "version": "0.25.4", 68 | "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.4.tgz", 69 | "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", 70 | "cpu": [ 71 | "x64" 72 | ], 73 | "dev": true, 74 | "license": "MIT", 75 | "optional": true, 76 | "os": [ 77 | "android" 78 | ], 79 | "engines": { 80 | "node": ">=18" 81 | } 82 | }, 83 | "node_modules/@esbuild/darwin-arm64": { 84 | "version": "0.25.4", 85 | "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", 86 | "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", 87 | "cpu": [ 88 | "arm64" 89 | ], 90 | "dev": true, 91 | "license": "MIT", 92 | "optional": true, 93 | "os": [ 94 | "darwin" 95 | ], 96 | "engines": { 97 | "node": ">=18" 98 | } 99 | }, 100 | "node_modules/@esbuild/darwin-x64": { 101 | "version": "0.25.4", 102 | "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", 103 | "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", 104 | "cpu": [ 105 | "x64" 106 | ], 107 | "dev": true, 108 | "license": "MIT", 109 | "optional": true, 110 | "os": [ 111 | "darwin" 112 | ], 113 | "engines": { 114 | "node": ">=18" 115 | } 116 | }, 117 | "node_modules/@esbuild/freebsd-arm64": { 118 | "version": "0.25.4", 119 | "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", 120 | "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", 121 | "cpu": [ 122 | "arm64" 123 | ], 124 | "dev": true, 125 | "license": "MIT", 126 | "optional": true, 127 | "os": [ 128 | "freebsd" 129 | ], 130 | "engines": { 131 | "node": ">=18" 132 | } 133 | }, 134 | "node_modules/@esbuild/freebsd-x64": { 135 | "version": "0.25.4", 136 | "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", 137 | "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", 138 | "cpu": [ 139 | "x64" 140 | ], 141 | "dev": true, 142 | "license": "MIT", 143 | "optional": true, 144 | "os": [ 145 | "freebsd" 146 | ], 147 | "engines": { 148 | "node": ">=18" 149 | } 150 | }, 151 | "node_modules/@esbuild/linux-arm": { 152 | "version": "0.25.4", 153 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", 154 | "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", 155 | "cpu": [ 156 | "arm" 157 | ], 158 | "dev": true, 159 | "license": "MIT", 160 | "optional": true, 161 | "os": [ 162 | "linux" 163 | ], 164 | "engines": { 165 | "node": ">=18" 166 | } 167 | }, 168 | "node_modules/@esbuild/linux-arm64": { 169 | "version": "0.25.4", 170 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", 171 | "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", 172 | "cpu": [ 173 | "arm64" 174 | ], 175 | "dev": true, 176 | "license": "MIT", 177 | "optional": true, 178 | "os": [ 179 | "linux" 180 | ], 181 | "engines": { 182 | "node": ">=18" 183 | } 184 | }, 185 | "node_modules/@esbuild/linux-ia32": { 186 | "version": "0.25.4", 187 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", 188 | "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", 189 | "cpu": [ 190 | "ia32" 191 | ], 192 | "dev": true, 193 | "license": "MIT", 194 | "optional": true, 195 | "os": [ 196 | "linux" 197 | ], 198 | "engines": { 199 | "node": ">=18" 200 | } 201 | }, 202 | "node_modules/@esbuild/linux-loong64": { 203 | "version": "0.25.4", 204 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", 205 | "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", 206 | "cpu": [ 207 | "loong64" 208 | ], 209 | "dev": true, 210 | "license": "MIT", 211 | "optional": true, 212 | "os": [ 213 | "linux" 214 | ], 215 | "engines": { 216 | "node": ">=18" 217 | } 218 | }, 219 | "node_modules/@esbuild/linux-mips64el": { 220 | "version": "0.25.4", 221 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", 222 | "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", 223 | "cpu": [ 224 | "mips64el" 225 | ], 226 | "dev": true, 227 | "license": "MIT", 228 | "optional": true, 229 | "os": [ 230 | "linux" 231 | ], 232 | "engines": { 233 | "node": ">=18" 234 | } 235 | }, 236 | "node_modules/@esbuild/linux-ppc64": { 237 | "version": "0.25.4", 238 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", 239 | "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", 240 | "cpu": [ 241 | "ppc64" 242 | ], 243 | "dev": true, 244 | "license": "MIT", 245 | "optional": true, 246 | "os": [ 247 | "linux" 248 | ], 249 | "engines": { 250 | "node": ">=18" 251 | } 252 | }, 253 | "node_modules/@esbuild/linux-riscv64": { 254 | "version": "0.25.4", 255 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", 256 | "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", 257 | "cpu": [ 258 | "riscv64" 259 | ], 260 | "dev": true, 261 | "license": "MIT", 262 | "optional": true, 263 | "os": [ 264 | "linux" 265 | ], 266 | "engines": { 267 | "node": ">=18" 268 | } 269 | }, 270 | "node_modules/@esbuild/linux-s390x": { 271 | "version": "0.25.4", 272 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", 273 | "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", 274 | "cpu": [ 275 | "s390x" 276 | ], 277 | "dev": true, 278 | "license": "MIT", 279 | "optional": true, 280 | "os": [ 281 | "linux" 282 | ], 283 | "engines": { 284 | "node": ">=18" 285 | } 286 | }, 287 | "node_modules/@esbuild/linux-x64": { 288 | "version": "0.25.4", 289 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", 290 | "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", 291 | "cpu": [ 292 | "x64" 293 | ], 294 | "dev": true, 295 | "license": "MIT", 296 | "optional": true, 297 | "os": [ 298 | "linux" 299 | ], 300 | "engines": { 301 | "node": ">=18" 302 | } 303 | }, 304 | "node_modules/@esbuild/netbsd-arm64": { 305 | "version": "0.25.4", 306 | "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", 307 | "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", 308 | "cpu": [ 309 | "arm64" 310 | ], 311 | "dev": true, 312 | "license": "MIT", 313 | "optional": true, 314 | "os": [ 315 | "netbsd" 316 | ], 317 | "engines": { 318 | "node": ">=18" 319 | } 320 | }, 321 | "node_modules/@esbuild/netbsd-x64": { 322 | "version": "0.25.4", 323 | "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", 324 | "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", 325 | "cpu": [ 326 | "x64" 327 | ], 328 | "dev": true, 329 | "license": "MIT", 330 | "optional": true, 331 | "os": [ 332 | "netbsd" 333 | ], 334 | "engines": { 335 | "node": ">=18" 336 | } 337 | }, 338 | "node_modules/@esbuild/openbsd-arm64": { 339 | "version": "0.25.4", 340 | "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", 341 | "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", 342 | "cpu": [ 343 | "arm64" 344 | ], 345 | "dev": true, 346 | "license": "MIT", 347 | "optional": true, 348 | "os": [ 349 | "openbsd" 350 | ], 351 | "engines": { 352 | "node": ">=18" 353 | } 354 | }, 355 | "node_modules/@esbuild/openbsd-x64": { 356 | "version": "0.25.4", 357 | "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", 358 | "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", 359 | "cpu": [ 360 | "x64" 361 | ], 362 | "dev": true, 363 | "license": "MIT", 364 | "optional": true, 365 | "os": [ 366 | "openbsd" 367 | ], 368 | "engines": { 369 | "node": ">=18" 370 | } 371 | }, 372 | "node_modules/@esbuild/sunos-x64": { 373 | "version": "0.25.4", 374 | "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", 375 | "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", 376 | "cpu": [ 377 | "x64" 378 | ], 379 | "dev": true, 380 | "license": "MIT", 381 | "optional": true, 382 | "os": [ 383 | "sunos" 384 | ], 385 | "engines": { 386 | "node": ">=18" 387 | } 388 | }, 389 | "node_modules/@esbuild/win32-arm64": { 390 | "version": "0.25.4", 391 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", 392 | "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", 393 | "cpu": [ 394 | "arm64" 395 | ], 396 | "dev": true, 397 | "license": "MIT", 398 | "optional": true, 399 | "os": [ 400 | "win32" 401 | ], 402 | "engines": { 403 | "node": ">=18" 404 | } 405 | }, 406 | "node_modules/@esbuild/win32-ia32": { 407 | "version": "0.25.4", 408 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", 409 | "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", 410 | "cpu": [ 411 | "ia32" 412 | ], 413 | "dev": true, 414 | "license": "MIT", 415 | "optional": true, 416 | "os": [ 417 | "win32" 418 | ], 419 | "engines": { 420 | "node": ">=18" 421 | } 422 | }, 423 | "node_modules/@esbuild/win32-x64": { 424 | "version": "0.25.4", 425 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", 426 | "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", 427 | "cpu": [ 428 | "x64" 429 | ], 430 | "dev": true, 431 | "license": "MIT", 432 | "optional": true, 433 | "os": [ 434 | "win32" 435 | ], 436 | "engines": { 437 | "node": ">=18" 438 | } 439 | }, 440 | "node_modules/@rollup/rollup-android-arm-eabi": { 441 | "version": "4.40.2", 442 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", 443 | "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", 444 | "cpu": [ 445 | "arm" 446 | ], 447 | "dev": true, 448 | "license": "MIT", 449 | "optional": true, 450 | "os": [ 451 | "android" 452 | ] 453 | }, 454 | "node_modules/@rollup/rollup-android-arm64": { 455 | "version": "4.40.2", 456 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.2.tgz", 457 | "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", 458 | "cpu": [ 459 | "arm64" 460 | ], 461 | "dev": true, 462 | "license": "MIT", 463 | "optional": true, 464 | "os": [ 465 | "android" 466 | ] 467 | }, 468 | "node_modules/@rollup/rollup-darwin-arm64": { 469 | "version": "4.40.2", 470 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.2.tgz", 471 | "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", 472 | "cpu": [ 473 | "arm64" 474 | ], 475 | "dev": true, 476 | "license": "MIT", 477 | "optional": true, 478 | "os": [ 479 | "darwin" 480 | ] 481 | }, 482 | "node_modules/@rollup/rollup-darwin-x64": { 483 | "version": "4.40.2", 484 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.2.tgz", 485 | "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", 486 | "cpu": [ 487 | "x64" 488 | ], 489 | "dev": true, 490 | "license": "MIT", 491 | "optional": true, 492 | "os": [ 493 | "darwin" 494 | ] 495 | }, 496 | "node_modules/@rollup/rollup-freebsd-arm64": { 497 | "version": "4.40.2", 498 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.2.tgz", 499 | "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", 500 | "cpu": [ 501 | "arm64" 502 | ], 503 | "dev": true, 504 | "license": "MIT", 505 | "optional": true, 506 | "os": [ 507 | "freebsd" 508 | ] 509 | }, 510 | "node_modules/@rollup/rollup-freebsd-x64": { 511 | "version": "4.40.2", 512 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.2.tgz", 513 | "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", 514 | "cpu": [ 515 | "x64" 516 | ], 517 | "dev": true, 518 | "license": "MIT", 519 | "optional": true, 520 | "os": [ 521 | "freebsd" 522 | ] 523 | }, 524 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 525 | "version": "4.40.2", 526 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.2.tgz", 527 | "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", 528 | "cpu": [ 529 | "arm" 530 | ], 531 | "dev": true, 532 | "license": "MIT", 533 | "optional": true, 534 | "os": [ 535 | "linux" 536 | ] 537 | }, 538 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 539 | "version": "4.40.2", 540 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.2.tgz", 541 | "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", 542 | "cpu": [ 543 | "arm" 544 | ], 545 | "dev": true, 546 | "license": "MIT", 547 | "optional": true, 548 | "os": [ 549 | "linux" 550 | ] 551 | }, 552 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 553 | "version": "4.40.2", 554 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.2.tgz", 555 | "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", 556 | "cpu": [ 557 | "arm64" 558 | ], 559 | "dev": true, 560 | "license": "MIT", 561 | "optional": true, 562 | "os": [ 563 | "linux" 564 | ] 565 | }, 566 | "node_modules/@rollup/rollup-linux-arm64-musl": { 567 | "version": "4.40.2", 568 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.2.tgz", 569 | "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", 570 | "cpu": [ 571 | "arm64" 572 | ], 573 | "dev": true, 574 | "license": "MIT", 575 | "optional": true, 576 | "os": [ 577 | "linux" 578 | ] 579 | }, 580 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 581 | "version": "4.40.2", 582 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.2.tgz", 583 | "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", 584 | "cpu": [ 585 | "loong64" 586 | ], 587 | "dev": true, 588 | "license": "MIT", 589 | "optional": true, 590 | "os": [ 591 | "linux" 592 | ] 593 | }, 594 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 595 | "version": "4.40.2", 596 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.2.tgz", 597 | "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", 598 | "cpu": [ 599 | "ppc64" 600 | ], 601 | "dev": true, 602 | "license": "MIT", 603 | "optional": true, 604 | "os": [ 605 | "linux" 606 | ] 607 | }, 608 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 609 | "version": "4.40.2", 610 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.2.tgz", 611 | "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", 612 | "cpu": [ 613 | "riscv64" 614 | ], 615 | "dev": true, 616 | "license": "MIT", 617 | "optional": true, 618 | "os": [ 619 | "linux" 620 | ] 621 | }, 622 | "node_modules/@rollup/rollup-linux-riscv64-musl": { 623 | "version": "4.40.2", 624 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.2.tgz", 625 | "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", 626 | "cpu": [ 627 | "riscv64" 628 | ], 629 | "dev": true, 630 | "license": "MIT", 631 | "optional": true, 632 | "os": [ 633 | "linux" 634 | ] 635 | }, 636 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 637 | "version": "4.40.2", 638 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.2.tgz", 639 | "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", 640 | "cpu": [ 641 | "s390x" 642 | ], 643 | "dev": true, 644 | "license": "MIT", 645 | "optional": true, 646 | "os": [ 647 | "linux" 648 | ] 649 | }, 650 | "node_modules/@rollup/rollup-linux-x64-gnu": { 651 | "version": "4.40.2", 652 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", 653 | "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", 654 | "cpu": [ 655 | "x64" 656 | ], 657 | "dev": true, 658 | "license": "MIT", 659 | "optional": true, 660 | "os": [ 661 | "linux" 662 | ] 663 | }, 664 | "node_modules/@rollup/rollup-linux-x64-musl": { 665 | "version": "4.40.2", 666 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.2.tgz", 667 | "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", 668 | "cpu": [ 669 | "x64" 670 | ], 671 | "dev": true, 672 | "license": "MIT", 673 | "optional": true, 674 | "os": [ 675 | "linux" 676 | ] 677 | }, 678 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 679 | "version": "4.40.2", 680 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.2.tgz", 681 | "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", 682 | "cpu": [ 683 | "arm64" 684 | ], 685 | "dev": true, 686 | "license": "MIT", 687 | "optional": true, 688 | "os": [ 689 | "win32" 690 | ] 691 | }, 692 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 693 | "version": "4.40.2", 694 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.2.tgz", 695 | "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", 696 | "cpu": [ 697 | "ia32" 698 | ], 699 | "dev": true, 700 | "license": "MIT", 701 | "optional": true, 702 | "os": [ 703 | "win32" 704 | ] 705 | }, 706 | "node_modules/@rollup/rollup-win32-x64-msvc": { 707 | "version": "4.40.2", 708 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.2.tgz", 709 | "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", 710 | "cpu": [ 711 | "x64" 712 | ], 713 | "dev": true, 714 | "license": "MIT", 715 | "optional": true, 716 | "os": [ 717 | "win32" 718 | ] 719 | }, 720 | "node_modules/@types/estree": { 721 | "version": "1.0.7", 722 | "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.7.tgz", 723 | "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", 724 | "dev": true, 725 | "license": "MIT" 726 | }, 727 | "node_modules/esbuild": { 728 | "version": "0.25.4", 729 | "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.4.tgz", 730 | "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", 731 | "dev": true, 732 | "hasInstallScript": true, 733 | "license": "MIT", 734 | "bin": { 735 | "esbuild": "bin/esbuild" 736 | }, 737 | "engines": { 738 | "node": ">=18" 739 | }, 740 | "optionalDependencies": { 741 | "@esbuild/aix-ppc64": "0.25.4", 742 | "@esbuild/android-arm": "0.25.4", 743 | "@esbuild/android-arm64": "0.25.4", 744 | "@esbuild/android-x64": "0.25.4", 745 | "@esbuild/darwin-arm64": "0.25.4", 746 | "@esbuild/darwin-x64": "0.25.4", 747 | "@esbuild/freebsd-arm64": "0.25.4", 748 | "@esbuild/freebsd-x64": "0.25.4", 749 | "@esbuild/linux-arm": "0.25.4", 750 | "@esbuild/linux-arm64": "0.25.4", 751 | "@esbuild/linux-ia32": "0.25.4", 752 | "@esbuild/linux-loong64": "0.25.4", 753 | "@esbuild/linux-mips64el": "0.25.4", 754 | "@esbuild/linux-ppc64": "0.25.4", 755 | "@esbuild/linux-riscv64": "0.25.4", 756 | "@esbuild/linux-s390x": "0.25.4", 757 | "@esbuild/linux-x64": "0.25.4", 758 | "@esbuild/netbsd-arm64": "0.25.4", 759 | "@esbuild/netbsd-x64": "0.25.4", 760 | "@esbuild/openbsd-arm64": "0.25.4", 761 | "@esbuild/openbsd-x64": "0.25.4", 762 | "@esbuild/sunos-x64": "0.25.4", 763 | "@esbuild/win32-arm64": "0.25.4", 764 | "@esbuild/win32-ia32": "0.25.4", 765 | "@esbuild/win32-x64": "0.25.4" 766 | } 767 | }, 768 | "node_modules/fdir": { 769 | "version": "6.4.4", 770 | "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.4.4.tgz", 771 | "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", 772 | "dev": true, 773 | "license": "MIT", 774 | "peerDependencies": { 775 | "picomatch": "^3 || ^4" 776 | }, 777 | "peerDependenciesMeta": { 778 | "picomatch": { 779 | "optional": true 780 | } 781 | } 782 | }, 783 | "node_modules/fsevents": { 784 | "version": "2.3.3", 785 | "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", 786 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 787 | "dev": true, 788 | "hasInstallScript": true, 789 | "license": "MIT", 790 | "optional": true, 791 | "os": [ 792 | "darwin" 793 | ], 794 | "engines": { 795 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 796 | } 797 | }, 798 | "node_modules/lil-gui": { 799 | "version": "0.20.0", 800 | "resolved": "https://registry.npmmirror.com/lil-gui/-/lil-gui-0.20.0.tgz", 801 | "integrity": "sha512-k7Ipr0ztqslMA2XvM5z5ZaWhxQtnEOwJBfI/hmSuRh6q4iMG9L0boqqrnZSzBR1jzyJ28OMl47l65ILzRe1TdA==", 802 | "dev": true, 803 | "license": "MIT" 804 | }, 805 | "node_modules/nanoid": { 806 | "version": "3.3.11", 807 | "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", 808 | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", 809 | "dev": true, 810 | "funding": [ 811 | { 812 | "type": "github", 813 | "url": "https://github.com/sponsors/ai" 814 | } 815 | ], 816 | "license": "MIT", 817 | "bin": { 818 | "nanoid": "bin/nanoid.cjs" 819 | }, 820 | "engines": { 821 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 822 | } 823 | }, 824 | "node_modules/picocolors": { 825 | "version": "1.1.1", 826 | "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", 827 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 828 | "dev": true, 829 | "license": "ISC" 830 | }, 831 | "node_modules/picomatch": { 832 | "version": "4.0.2", 833 | "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz", 834 | "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", 835 | "dev": true, 836 | "license": "MIT", 837 | "engines": { 838 | "node": ">=12" 839 | }, 840 | "funding": { 841 | "url": "https://github.com/sponsors/jonschlinkert" 842 | } 843 | }, 844 | "node_modules/postcss": { 845 | "version": "8.5.3", 846 | "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.3.tgz", 847 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", 848 | "dev": true, 849 | "funding": [ 850 | { 851 | "type": "opencollective", 852 | "url": "https://opencollective.com/postcss/" 853 | }, 854 | { 855 | "type": "tidelift", 856 | "url": "https://tidelift.com/funding/github/npm/postcss" 857 | }, 858 | { 859 | "type": "github", 860 | "url": "https://github.com/sponsors/ai" 861 | } 862 | ], 863 | "license": "MIT", 864 | "dependencies": { 865 | "nanoid": "^3.3.8", 866 | "picocolors": "^1.1.1", 867 | "source-map-js": "^1.2.1" 868 | }, 869 | "engines": { 870 | "node": "^10 || ^12 || >=14" 871 | } 872 | }, 873 | "node_modules/rollup": { 874 | "version": "4.40.2", 875 | "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.40.2.tgz", 876 | "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", 877 | "dev": true, 878 | "license": "MIT", 879 | "dependencies": { 880 | "@types/estree": "1.0.7" 881 | }, 882 | "bin": { 883 | "rollup": "dist/bin/rollup" 884 | }, 885 | "engines": { 886 | "node": ">=18.0.0", 887 | "npm": ">=8.0.0" 888 | }, 889 | "optionalDependencies": { 890 | "@rollup/rollup-android-arm-eabi": "4.40.2", 891 | "@rollup/rollup-android-arm64": "4.40.2", 892 | "@rollup/rollup-darwin-arm64": "4.40.2", 893 | "@rollup/rollup-darwin-x64": "4.40.2", 894 | "@rollup/rollup-freebsd-arm64": "4.40.2", 895 | "@rollup/rollup-freebsd-x64": "4.40.2", 896 | "@rollup/rollup-linux-arm-gnueabihf": "4.40.2", 897 | "@rollup/rollup-linux-arm-musleabihf": "4.40.2", 898 | "@rollup/rollup-linux-arm64-gnu": "4.40.2", 899 | "@rollup/rollup-linux-arm64-musl": "4.40.2", 900 | "@rollup/rollup-linux-loongarch64-gnu": "4.40.2", 901 | "@rollup/rollup-linux-powerpc64le-gnu": "4.40.2", 902 | "@rollup/rollup-linux-riscv64-gnu": "4.40.2", 903 | "@rollup/rollup-linux-riscv64-musl": "4.40.2", 904 | "@rollup/rollup-linux-s390x-gnu": "4.40.2", 905 | "@rollup/rollup-linux-x64-gnu": "4.40.2", 906 | "@rollup/rollup-linux-x64-musl": "4.40.2", 907 | "@rollup/rollup-win32-arm64-msvc": "4.40.2", 908 | "@rollup/rollup-win32-ia32-msvc": "4.40.2", 909 | "@rollup/rollup-win32-x64-msvc": "4.40.2", 910 | "fsevents": "~2.3.2" 911 | } 912 | }, 913 | "node_modules/source-map-js": { 914 | "version": "1.2.1", 915 | "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", 916 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 917 | "dev": true, 918 | "license": "BSD-3-Clause", 919 | "engines": { 920 | "node": ">=0.10.0" 921 | } 922 | }, 923 | "node_modules/three": { 924 | "version": "0.176.0", 925 | "resolved": "https://registry.npmmirror.com/three/-/three-0.176.0.tgz", 926 | "integrity": "sha512-PWRKYWQo23ojf9oZSlRGH8K09q7nRSWx6LY/HF/UUrMdYgN9i1e2OwJYHoQjwc6HF/4lvvYLC5YC1X8UJL2ZpA==", 927 | "license": "MIT" 928 | }, 929 | "node_modules/tinyglobby": { 930 | "version": "0.2.13", 931 | "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.13.tgz", 932 | "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", 933 | "dev": true, 934 | "license": "MIT", 935 | "dependencies": { 936 | "fdir": "^6.4.4", 937 | "picomatch": "^4.0.2" 938 | }, 939 | "engines": { 940 | "node": ">=12.0.0" 941 | }, 942 | "funding": { 943 | "url": "https://github.com/sponsors/SuperchupuDev" 944 | } 945 | }, 946 | "node_modules/vite": { 947 | "version": "6.3.5", 948 | "resolved": "https://registry.npmmirror.com/vite/-/vite-6.3.5.tgz", 949 | "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", 950 | "dev": true, 951 | "license": "MIT", 952 | "dependencies": { 953 | "esbuild": "^0.25.0", 954 | "fdir": "^6.4.4", 955 | "picomatch": "^4.0.2", 956 | "postcss": "^8.5.3", 957 | "rollup": "^4.34.9", 958 | "tinyglobby": "^0.2.13" 959 | }, 960 | "bin": { 961 | "vite": "bin/vite.js" 962 | }, 963 | "engines": { 964 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 965 | }, 966 | "funding": { 967 | "url": "https://github.com/vitejs/vite?sponsor=1" 968 | }, 969 | "optionalDependencies": { 970 | "fsevents": "~2.3.3" 971 | }, 972 | "peerDependencies": { 973 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 974 | "jiti": ">=1.21.0", 975 | "less": "*", 976 | "lightningcss": "^1.21.0", 977 | "sass": "*", 978 | "sass-embedded": "*", 979 | "stylus": "*", 980 | "sugarss": "*", 981 | "terser": "^5.16.0", 982 | "tsx": "^4.8.1", 983 | "yaml": "^2.4.2" 984 | }, 985 | "peerDependenciesMeta": { 986 | "@types/node": { 987 | "optional": true 988 | }, 989 | "jiti": { 990 | "optional": true 991 | }, 992 | "less": { 993 | "optional": true 994 | }, 995 | "lightningcss": { 996 | "optional": true 997 | }, 998 | "sass": { 999 | "optional": true 1000 | }, 1001 | "sass-embedded": { 1002 | "optional": true 1003 | }, 1004 | "stylus": { 1005 | "optional": true 1006 | }, 1007 | "sugarss": { 1008 | "optional": true 1009 | }, 1010 | "terser": { 1011 | "optional": true 1012 | }, 1013 | "tsx": { 1014 | "optional": true 1015 | }, 1016 | "yaml": { 1017 | "optional": true 1018 | } 1019 | } 1020 | } 1021 | } 1022 | } 1023 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "three": "^0.176.0" 4 | }, 5 | "devDependencies": { 6 | "lil-gui": "^0.20.0", 7 | "vite": "^6.3.5" 8 | } 9 | } 10 | --------------------------------------------------------------------------------