{"_id":"picocad2-web","_rev":"31-2ea070ccf5eb61be98827bf7e3f44fe3","name":"picocad2-web","dist-tags":{"beta":"1.4.0-beta.2","latest":"2.0.4"},"versions":{"0.1.0":{"name":"picocad2-web","version":"0.1.0","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@0.1.0","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"dd8be86dcba08876db88e6815698ff0b112e39fb","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-0.1.0.tgz","fileCount":26,"integrity":"sha512-2CPvrgm/Md8BZpYw4Yc8U2eIzxp1LqU870vxl0Sj94RfaCk0M7WXhjZxWIQpPRbtukU1XZbUMSfyrWboHWQc4A==","signatures":[{"sig":"MEUCIQDu7RH/mTg+BtOsOvZ87FYuP7NXAMXD5rLj44WST6W7UQIgfLVXKLAbiCCgVcmo7tRlHW/6+N5EFff3iz4CoKNECG8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102677},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"4a1a42efad963d2cea129f6ae1a891662cee7007","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_0.1.0_1774183528204_0.500848021065913","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"picocad2-web","version":"0.2.0","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@0.2.0","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"91e7173454d3f88afd5eb8454b67b3b19d83adb6","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-0.2.0.tgz","fileCount":26,"integrity":"sha512-+uSDOA/9sZmDpL+sl+qTQr3+lYNyotwoHFk4elW4x57nfi+syYVk6VxSV1paXpy+jFmP64YtL7+6nqCf4mpjBQ==","signatures":[{"sig":"MEUCIQDBj+3bWgc3bxdp1c4TMJwW3UT7Lde6HuiOfIyRusmTuAIgf+2wqRHX8U5CgKLkKhrB2/ma8BRx8uRfONm4ioaQtJ0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104855},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"594d0ddc16cf4a7e6b24950c63d616a9715baa85","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_0.2.0_1774188244518_0.5069638621347148","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"picocad2-web","version":"1.0.0","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.0.0","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"15ddbe56114eb32a399917e920d37835e340c858","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.0.0.tgz","fileCount":43,"integrity":"sha512-A9bs+gndjFnULmPT9jI3BmldUv+fG0v+q069hCaI5mzoZGTJgMr3rI9VYb/5m6hR2oc0FhugCcTz2IMNmYOmOA==","signatures":[{"sig":"MEYCIQC7AkvZ5VlNNAHuk8LX+U+z9lumEVks/gCS35hkO/5KPgIhAJ525bhrm1BPdzQegBYLO6X5AjYyQMg/yekY8TSg//fm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":161546},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"c3676e45066083b793248346344b11a0bb9f93ea","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.0.0_1774208562383_0.44247787271460526","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"picocad2-web","version":"1.1.0","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.1.0","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"f13c6c7e261cb554e95dc9d99a212fead5a97be7","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.1.0.tgz","fileCount":43,"integrity":"sha512-VycTFrh4LAUF5QvHYxl5PgHnCa4nuvgBlJ4JN6htgzmF03L5gYG0ggybC/zhq44v9iI070TrinlD3JNC0rMuPg==","signatures":[{"sig":"MEUCICK7++GVkolhLS0sJKGJ5PAo/2ROI9JgCNiYBB6OG3LuAiEAkh1ONlPL1puGVfLkZLSuQgDnhBYehS7CoT26aKOzGJw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":176803},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"3567116344f6c32606b2f8c7fe2e15957e601967","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.1.0_1774289350532_0.6702557125891613","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"picocad2-web","version":"1.1.1","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.1.1","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"72259d863541351ef0508799e4fe912379e7c86d","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.1.1.tgz","fileCount":43,"integrity":"sha512-JuXStts1rKhELn29TPHbAxxHNAno7Yh4zmAC44yQsEwbSuyKmhZSsQW9Suvk0rN81APH2CpgUB8/KTe644cvqA==","signatures":[{"sig":"MEUCIDqAJ1+56sJxxLUIdKN7euhi+bVj9+wdlD09iErjgk3vAiEA9iUP0yHdmkOqOrHoT7rKrBGW4MyOBTadkhlZwwFopQU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":176854},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"6693ae5bb1bc385453c64a4987adf40065ea7e18","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.1.1_1774363791878_0.6499496230549267","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"picocad2-web","version":"1.1.2","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.1.2","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"89b1fcefa36bfb09d3deb68fbb721e7737700a02","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.1.2.tgz","fileCount":43,"integrity":"sha512-KVI0d9CQpQIZJrVbyd6vKbywl/Hip0USIgxJv7pKf6B8w2hywmAujGmR19n/zZOX+o1BJrckd8VZepgvU260Nw==","signatures":[{"sig":"MEUCIQDL5tiiLtvgWMy7DNUAx2QMP7WJK81qq301etfxLkhy7AIgOvx25ZLnC5JjcttI4FHLz2o4BqpB1l25kMrE1FivveE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":178749},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"5c2b0ee7c8e0959227c427e6ef9e7c381f9039cd","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.1.2_1774453436726_0.4477813900058043","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"picocad2-web","version":"1.2.0","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.0","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"1ac0863ca1d3b8c57db9d47be2bd441f79b0b24f","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.0.tgz","fileCount":50,"integrity":"sha512-vPwS+oulbpeOWVeY/qj2NLi7ptvdxZABfG8gbnPJv1+TB6M5NQdhPMBdWo3IF3RnFwpIKiWzsPz6QZ6SDuF4JA==","signatures":[{"sig":"MEUCIAl3S7aBfcWrZctv18gS6NiEJzFCZBnIQNTBrPSZVOARAiEAmrECLWl0c63R0+BE43GKXupS73lPd4FXAhi3sau2l9s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":208753},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"e623d22202793c07c28e2f535f8557518f3b1637","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.0_1774466874123_0.9745434566381592","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"picocad2-web","version":"1.2.1","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.1","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"c58da38eda95b4699b0b3516f12c563bad6486f6","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.1.tgz","fileCount":50,"integrity":"sha512-IQRNeySglwy7j7gv7cTvZ9OTZ7fepxqFDQCMZKjzsZnW0Rt+ePBOLG7Martfg33N+RKC+p9ews3rs2HaCTs1Yg==","signatures":[{"sig":"MEYCIQCklHp+heLZyKPChJ09G+oi0og/dvVg1XnVwEi5y23K2gIhAIwbs3bDikg+s/wDz5c5jruXkmg/+MeLSzemHJKu0kR4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":209256},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"a4f60915836666d9b58e00f13e48e4d8f8c02cb3","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.1_1774558144748_0.8727226945405226","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"picocad2-web","version":"1.2.2","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.2","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"69882e0d2c32e80f1ce25bccaf538e9a7fe1d0a7","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.2.tgz","fileCount":50,"integrity":"sha512-oj25aeaEfscR7AIRojSra2Lf43MAqZo5/gO7lX/OoqN/un+cARFWuCEtTxzb22WecaREG4T2y8squ+iwT2vyig==","signatures":[{"sig":"MEUCIEgqTaaSak4rK32vvg3hJoGMqiaDjqEo/tDFyuOMc4aGAiEA/c0IAI1WGO/8NA8AdUR+6ykE4o9TjsS4C9vPCQIXrQk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":211504},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"10b29ec4f1bb8f9c42311d10b42ab56c32420b02","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.2_1774628509990_0.6159745919944386","host":"s3://npm-registry-packages-npm-production"}},"1.2.3":{"name":"picocad2-web","version":"1.2.3","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.3","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"9447f663002d6f6b3f93b38be24bf28039b5d78d","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.3.tgz","fileCount":50,"integrity":"sha512-E7nq5Kqdh/yE3QUJI8s+gMAXL+qtY9cYxI+1GttxOrKtqwlFZWsSCp88zZ9QwYq6ZF4dLPanS9x3c+czg7sImw==","signatures":[{"sig":"MEUCIQCCVN4s1kh01m9FWnrhxSTurpUDljK9ubUX8ev7y7N/TgIgVlPp+KeBvl4hf8rRD5Nlg6Mk+L+Ke13JqbTXFu086vc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":211542},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"4e2f26efb4020cf6bfb718374f6421658ad68945","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.3_1774720177312_0.9640251625659788","host":"s3://npm-registry-packages-npm-production"}},"1.2.4":{"name":"picocad2-web","version":"1.2.4","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.4","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"fae811248e05c27563c68fdbe3af9e9202d80b6f","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.4.tgz","fileCount":50,"integrity":"sha512-h9ctNfAD0+vellJZwq3eSvfgU4+ztlpzIwf/+ezD0gD54psEKYcoa6Zd6qmLPMDb3FyJ77VFqDu0jGlFCfeSrw==","signatures":[{"sig":"MEUCIQCznGYe+Ov20eb1EeM/F2CXBfOFWlH787jgcp/GFSGBlwIgHhxDZDy9eVeWw4SoNiZWsnOgfmnEfzx1ibMamm9rdlY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":216211},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"5c99f239397490f307cd5a87ac48380b1946feb4","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.4_1774887920675_0.668697267124913","host":"s3://npm-registry-packages-npm-production"}},"1.2.5":{"name":"picocad2-web","version":"1.2.5","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.5","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"af88feb12523544c9a2d153551c217aafaf227f7","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.5.tgz","fileCount":50,"integrity":"sha512-i4YTYyOsMkxHr9ENsVELWrvSoTvr4KgUHBkWCIJE+DbluMhw+VXCzdOriiBsQgJ1LCqFupAo9QciLNVbnZeZkA==","signatures":[{"sig":"MEUCIQCAdhi/m5sWh2t7Y8ozmM6BwnnfEfDmioStuxtTkh9HWgIgehru+Bvg225V8KSWHSVFrw6KMJKaRRSK9xvJLHdazCY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":217161},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"fe3ecf5fcdc8916315c5283a0d4589f9825641aa","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.5_1775146380012_0.39141442897862544","host":"s3://npm-registry-packages-npm-production"}},"1.2.6":{"name":"picocad2-web","version":"1.2.6","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.6","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"fbaeb33f72b4ed2551dcd60588569e2bcaeb448c","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.6.tgz","fileCount":50,"integrity":"sha512-653pU+OXrZZhV5+ApRIijr17v13S6sR36HYISS1vI/YfbMPhZfZqA2mxauwPrHAMLF7ovcFo7TzkEs9Ztc6++w==","signatures":[{"sig":"MEUCIHl+vwcoX7Vp71GQI4BEtD+ifwU9kaJxsZzuKgKST0FFAiEAnN05Yi3UvaMqGVJRaaV/9yBftI+nMmQJUz90GNMj4y4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":217868},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"a6ec8b939819adbac765bc67e2e37b397c7ab4e2","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.6_1775230076619_0.8884547232040363","host":"s3://npm-registry-packages-npm-production"}},"1.2.7":{"name":"picocad2-web","version":"1.2.7","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.7","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"d1087c9b68266663ad9aa8d546982e17bde053df","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.7.tgz","fileCount":50,"integrity":"sha512-EyauOhMRLqpW0dHxfxuoq6E6+oyf26Gre9SeENHOnU5mDtxDWO6SSZetxZU+pf9VyNm4kJLAF1Z8tjigFOHqdw==","signatures":[{"sig":"MEUCIQDa23nmuHc283OAQ+NYXBZNJi8CmtJVUPf54+x8IQyQbgIgLHtmuOnyWb8ThIJqu6C9CudRJyJinDo0bLwny5vHq28=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":218640},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"1601155884f4f11a72321161463e22de759ca480","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.7_1775239552608_0.007059074266835275","host":"s3://npm-registry-packages-npm-production"}},"1.2.8":{"name":"picocad2-web","version":"1.2.8","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.8","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"02ce67700ea45bad3c469ebdcddefbe502d1ce21","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.8.tgz","fileCount":50,"integrity":"sha512-9t7ShJyg8JKpw65zsERNvWpg2JTPfVgH8r0Ah+BvZmFTzFH9SM4ZHFHLn6ldRs9L+F0F4wsbSQgxmh+Mt1/rkg==","signatures":[{"sig":"MEYCIQDFaN3ZNAzy1YtMlBhUKN4jrYARiXm+t426fAno3D/yqgIhAKSfC0+scS7dspB3sMZzZa1hTPSEEYmbbizniAJHkZox","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":219173},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"c6632534a4e3664350869ff7ca46f24e4d6e4033","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.8_1775290985492_0.36025327449813216","host":"s3://npm-registry-packages-npm-production"}},"1.2.9":{"name":"picocad2-web","version":"1.2.9","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.9","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"88d45572fc3cb7d536ffa9a955e4442237f1b7a2","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.9.tgz","fileCount":50,"integrity":"sha512-x+lDIvZ7ESK20W9IQ4fYUJqdvJ2cY0J8JKEMPQo33J9qXXP5Z/epvn2BYEH0bETzqsAd6zKSJm5SoZMxLRlqEQ==","signatures":[{"sig":"MEQCICqoD8SxQ7fHimtCLHM+j0TY3CvKTXlWYY6G34zUd3MKAiAfZko/SICrcow/aGzI5ubLXx2UTN0lb01iLuQP1Oo8iw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":219423},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"c6632534a4e3664350869ff7ca46f24e4d6e4033","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.9_1775305672519_0.6483297007044178","host":"s3://npm-registry-packages-npm-production"}},"1.2.10":{"name":"picocad2-web","version":"1.2.10","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.10","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"41e3d55cf7ea82301d5786cf831bd1222d418316","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.10.tgz","fileCount":50,"integrity":"sha512-bc+Eos8mS6jmicJUHnPgxVf+87TWcrZsPonL8+7eEDDUWzL/AJnYIJiK9E/rJEUSvZrn7rGhgYycPQbaPEmmig==","signatures":[{"sig":"MEYCIQDjU6Beg7/LICFLXhYlQF/8NyoTKEwJT5cRMM/D8q5w7AIhAMPpBBVLlRlOzOf9hH2fGHxX8/mOBwrfgG81UAIRqZlH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":220074},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"b538cc5574549c52b2f9c500730d43683cae0b22","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.10_1775308571155_0.5772279795925233","host":"s3://npm-registry-packages-npm-production"}},"1.2.11":{"name":"picocad2-web","version":"1.2.11","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.11","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"4aa639d2a61a8a351ef6dc641f7703872ff4fa76","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.11.tgz","fileCount":50,"integrity":"sha512-a6QKDH7/F6RGwMHQ+qWWlgSnv4FjSVcb7FvAgNFJXxFHFGcm4C4OcuypB8Gu8AgMkkj/0pVpl5S22EJvNi0WtA==","signatures":[{"sig":"MEQCIHZgVM7AtzpnQ4J72jycMdX+CgKrO95cwCz7V3fneYzIAiBvnK37sgMslhDwIS9qOlocddMziQs5mLMyiqymcd3HNA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":220092},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"a085a49776f32146bd320c1bc47bb642b6b6661b","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.11_1775309828632_0.7736171827805614","host":"s3://npm-registry-packages-npm-production"}},"1.2.12":{"name":"picocad2-web","version":"1.2.12","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.12","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"d8e0a7ba1dc9789cc522fd4a93879cd97a519599","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.12.tgz","fileCount":50,"integrity":"sha512-jk4gvxK8byVzE+g0DJHs+xrN2kRPATrhTkoyMCV8sydt43dsIcZI5bYkA6xCZnlBnz4y4mxEqEOV+fqdj853wg==","signatures":[{"sig":"MEQCIAcQ0GHztvMjja4bfQcMSRmOVznA8bneXIZLAlybjk8yAiAHWBVa8/cECIbnUrGqpBgW41sT7RAk6fRJVO8pvDhP1Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":220658},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"b4a37dcdf100c63f169a6d4d73004440b6038de1","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.12_1775320148408_0.44147811376614055","host":"s3://npm-registry-packages-npm-production"}},"1.2.13":{"name":"picocad2-web","version":"1.2.13","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":{"name":"hfcRed"},"license":"MIT","_id":"picocad2-web@1.2.13","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"homepage":"https://github.com/hfcRed/PicoCAD2-Web#readme","bugs":{"url":"https://github.com/hfcRed/PicoCAD2-Web/issues"},"dist":{"shasum":"5c85d04fc1bc6e67a1b0796807452b6e4a9d95bc","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.13.tgz","fileCount":50,"integrity":"sha512-+kNmbhJdY2UdQiTMy3LwXUxFBMq+ptliH4Sh2CHgpbEKDHmZquGhKVUodrFnPiBm38cdnyWr1a9qBJAonaK8+w==","signatures":[{"sig":"MEYCIQDePwFRiynNkHJfyVPlUcE5uuwDWkhFzuct/VYNqbmeMQIhAOw1L9V4fHs2sRqAIlky9Xm+8eyoxTpVTITrDSHjrkUZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":220715},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"gitHead":"721caecaf370969c0d3c8f22f6b28dbba0288d34","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"git+https://github.com/hfcRed/PicoCAD2-Web.git","type":"git"},"_npmVersion":"10.9.2","description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"22.13.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.13_1775985669521_0.04037177249232582","host":"s3://npm-registry-packages-npm-production"}},"1.2.14":{"name":"picocad2-web","version":"1.2.14","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@1.2.14","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"409c91fcb0495e47f676fcf59562dd6685aa4f4a","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.14.tgz","fileCount":50,"integrity":"sha512-e5gUDkkmlL1pPDa9bg1Sqzrg3/C1fhlHLCmuPWZHh4eeulFd86vevqBvq7P7o+1ef+R0NUK8O84Y4YqTStrLWg==","signatures":[{"sig":"MEYCIQD5yEK2P5pLT54wY+vkV6zNVg5N3qng3kGSOSCioqmNBwIhAOYoE3ZMbH4ySJqGJqa1F+Tvge8ZNVK4DgxH0LZ+flaG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":220950},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"24.18.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.14_1785612942725_0.004080798500495364","host":"s3://npm-registry-packages-npm-production"}},"1.2.15":{"name":"picocad2-web","version":"1.2.15","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@1.2.15","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"16d85ecea777f7554356231a36f5db429cf16448","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.2.15.tgz","fileCount":50,"integrity":"sha512-Bl//ft5HYjZ390KOw+vlXyei/SSGm1WAZAMLsnPOIuuYjm8mjHGkhD3dBIDyoyeforEdVsnCDgRrrOHKJk4OSg==","signatures":[{"sig":"MEQCIHTxrhVMjbLhcvH17IdXz7xuspVNxY4Bx5Gz/JJe7IDrAiBns0TbpaNocqoXUxNcgSELKHDjogq/7OdueqJ+SunNgQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":221125},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"24.18.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.2.15_1785614457215_0.6898190339325367","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"picocad2-web","version":"1.3.0","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@1.3.0","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"3ae4e118fe727b065854cec9a18428b1e2e449ef","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.3.0.tgz","fileCount":50,"integrity":"sha512-qvJv7aZ+FZczZAdddbA/yvKLApxX7s+wxkoEOXvJlRrgjXI0Q453dUyAYfrn/u1lPahrW2MBcxU+atWQXrEvYw==","signatures":[{"sig":"MEUCIDGTLQ3Xqu8frKgnF4gB6733heXfqlXw+1PrFwC8/k4+AiEAmCbYEHG/sNRtW07EhmCFi3gVJkX3kAHhHD+UVATiFCQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":229720},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"24.18.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.3.0_1785631880173_0.2313982824848786","host":"s3://npm-registry-packages-npm-production"}},"1.4.0-beta.0":{"name":"picocad2-web","version":"1.4.0-beta.0","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@1.4.0-beta.0","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"3602bfc277580f5a0f5d492b587606bbad12751f","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.4.0-beta.0.tgz","fileCount":50,"integrity":"sha512-T2Xoqtgrrg7GQhcWdIORvLGm+3rGOjTv8IOrjP+c8Tu8VSXRzhIQP19QFaTb2DPL0frnE7sRncfsBk4TO2tjbQ==","signatures":[{"sig":"MEQCIEIYQQCNhsfAFfvKLfjVJYT8IKd7yTmmC8Vln5V3gd7hAiBLt1/sn33nbXOXLYTe7KM2pj/OiDk+EZseQChDU3ZVWA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":235401},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"24.18.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.4.0-beta.0_1785788183121_0.2633214575005045","host":"s3://npm-registry-packages-npm-production"}},"1.4.0-beta.1":{"name":"picocad2-web","version":"1.4.0-beta.1","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@1.4.0-beta.1","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"8b38995b67094a22500dc116deb5abbb9fb29f8a","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.4.0-beta.1.tgz","fileCount":50,"integrity":"sha512-WZzacJOpgWfbkho4sRUGNgHgrIO8RKcVczp80UZqL97m6fFmuGNoYgYskCMGZ5+RmOEtuNN7IZZLA95W6/Wtag==","signatures":[{"sig":"MEQCIHZHXiRnHav+Lcdqwgu+WvfVMjbWFprjjQFHgKdhfhftAiAT4mRc3NYi0cyHjC0DoJXpHSMVjMy2oCEpgF8aN2Zwew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":235686},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"24.18.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.4.0-beta.1_1785906101960_0.2060614314342164","host":"s3://npm-registry-packages-npm-production"}},"1.4.0-beta.2":{"name":"picocad2-web","version":"1.4.0-beta.2","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@1.4.0-beta.2","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"6c8a2ecf7dd1ab566c60ba4a5336b8c7f4e46ce8","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-1.4.0-beta.2.tgz","fileCount":50,"integrity":"sha512-DAQHOjaeYreBqfOYrOXlho+nVuvwn4UGgM61Qem0lLYXO3Lt6bW1edDx6WJh8CX0J+6q4jJgl/XpYzXruZ0taA==","signatures":[{"sig":"MEQCIDoKUin6zji8ulbpj/UjueGhkCCYcYzOw1t5EFQ8+xicAiAFX4r/alcr4fvQrhy60cklbwXyyyRjN7rk7J1rM5dh5g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":247456},"type":"module","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write .","format":"biome format --write .","preview":"vite preview"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"26.0.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","typescript":"~5.9.3","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_1.4.0-beta.2_1787440171852_0.9194102580160795","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"picocad2-web","version":"2.0.0","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@2.0.0","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"1a3bf0c9cf5c22776eb2c068af5a12c44457ca78","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-2.0.0.tgz","fileCount":83,"integrity":"sha512-H4V0G4K8H3GwjPDUsi5MylO8Lg0ClqTNyuHty6hZjgPwI0M6EbPvA2KT6TyCL+mZjlN+ehyaNrv/j3q0pS/Wfg==","signatures":[{"sig":"MEUCIBE/N0ku7GQ7X1GZHzgzV13dqNratbM9cdc3iLbK4EzJAiEA3pcdctJeUUKjAaa2OY11SwitD/SInO7pgxWINPPAvNw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":638707},"main":"./dist/main.js","type":"module","types":"./dist/lib/main.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js","default":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write . && node scripts/check-shaders.ts","format":"biome format --write .","preview":"vite preview","release":"node scripts/publish.js","test:perf":"node test/perf/run.ts","test:visual":"node test/visual/run.ts","test:perf:snapshot":"node test/perf/snapshot.ts","test:visual:update":"node test/visual/run.ts --update"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"26.0.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","pngjs":"^7.0.0","playwright":"^1.62.1","typescript":"~5.9.3","@types/node":"^26.4.0","@types/pngjs":"^6.0.5","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_2.0.0_1788884084827_0.590251236018096","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"picocad2-web","version":"2.0.1","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@2.0.1","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"b43ef90c7a14916ecec170126298d03bb6bb5de4","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-2.0.1.tgz","fileCount":83,"integrity":"sha512-bY+KjKGb6eH+c8AT4C0nAIW7WIZmKf4SMPDemDiLvnFdhrTVcVPEiTdNXsKHmnUN8eP2y+8ZrDezNtkTL3u/kQ==","signatures":[{"sig":"MEYCIQDVVlU9BshJuuoNCIYH6833RWWHg3/SL/8F3p+0koEZRgIhAKTgJ+gdneuIOXmoUdIAFrGxSgMlmUEFZQZXvQzMbIVv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":638588},"main":"./dist/main.js","type":"module","types":"./dist/lib/main.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js","default":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write . && node scripts/check-shaders.ts","format":"biome format --write .","preview":"vite preview","release":"node scripts/publish.js","test:perf":"node test/perf/run.ts","test:visual":"node test/visual/run.ts","test:perf:snapshot":"node test/perf/snapshot.ts","test:visual:update":"node test/visual/run.ts --update"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"26.0.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","pngjs":"^7.0.0","playwright":"^1.62.1","typescript":"~5.9.3","@types/node":"^26.4.0","@types/pngjs":"^6.0.5","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_2.0.1_1788889815828_0.959013769853956","host":"s3://npm-registry-packages-npm-production"}},"2.0.2":{"name":"picocad2-web","version":"2.0.2","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@2.0.2","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"de275b38b15c786958d218779f251f4dcaa16fc6","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-2.0.2.tgz","fileCount":83,"integrity":"sha512-lx3IHV41J+qQaY3B54D9UaLogluSNBXe8mtRd2FSLu45KiBjg9aNxkGj7Y/ZzqPDwVI3HVACL+vDwJyJGksv2g==","signatures":[{"sig":"MEUCIQCy9RtC8NZqbzIKUzHP0LNNb6C7Pu16dNnkjRwYMv8XLAIgIPfQ/O62P3mJRymMUpzOqIx7ODODjHrD/loGwIZ1eZI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":638575},"main":"./dist/main.js","type":"module","types":"./dist/lib/main.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js","default":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write . && node scripts/check-shaders.ts","format":"biome format --write .","preview":"vite preview","release":"node scripts/publish.js","test:perf":"node test/perf/run.ts","test:visual":"node test/visual/run.ts","test:perf:snapshot":"node test/perf/snapshot.ts","test:visual:update":"node test/visual/run.ts --update"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"26.0.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","pngjs":"^7.0.0","playwright":"^1.62.1","typescript":"~5.9.3","@types/node":"^26.4.0","@types/pngjs":"^6.0.5","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_2.0.2_1788892459436_0.09856503868318778","host":"s3://npm-registry-packages-npm-production"}},"2.0.3":{"name":"picocad2-web","version":"2.0.3","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"author":"hfcRed","license":"MIT","_id":"picocad2-web@2.0.3","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"dist":{"shasum":"c27051192dc41b937594019d645736a74611a0f2","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-2.0.3.tgz","fileCount":83,"integrity":"sha512-IaUTXiNwH1Ji4U5J57AiHm+unKmKEwV3UH9ab47qqlAcDRSThdt3mE7uzKnH/J0MXhuSRU9lfAdh6nuRHA+b9Q==","signatures":[{"sig":"MEUCIHNlfI+NySUWu6KHS0QAn0HAytTGpb72XsyT92P2PHqbAiEA/OVGOcMzaJ+V5vc6OEeYXrjw4VDGVknU+FVjqjePzig=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":650966},"main":"./dist/main.js","type":"module","types":"./dist/lib/main.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js","default":"./dist/main.js"}},"private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write . && node scripts/check-shaders.ts","format":"biome format --write .","preview":"vite preview","release":"node scripts/publish.js","test:perf":"node test/perf/run.ts","test:visual":"node test/visual/run.ts","test:perf:snapshot":"node test/perf/snapshot.ts","test:visual:update":"node test/visual/run.ts --update"},"_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"_nodeVersion":"26.0.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","pngjs":"^7.0.0","playwright":"^1.62.1","typescript":"~5.9.3","@types/node":"^26.4.0","@types/pngjs":"^6.0.5","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"tmp":"tmp/picocad2-web_2.0.3_1789251336649_0.7514475261664109","host":"s3://npm-registry-packages-npm-production"}},"2.0.4":{"_id":"picocad2-web@2.0.4","dist":{"shasum":"8b95452e39dcac7be50939381a07812d59878482","tarball":"https://registry.npmjs.org/picocad2-web/-/picocad2-web-2.0.4.tgz","fileCount":83,"integrity":"sha512-HhFMM5PLfQyDb7rSTkfNZ2/2sqS54JqhYwJFHFMnZnvkvvd2DaAeu9Xl8k5t4gH/EcU+ks6ykhFudL6jRdkpdw==","signatures":[{"sig":"MEUCIQC/rpionzH3BkQ7QAbFfEWKSwhysiYU/Cv2NhLB9YzRtgIgNIt19hJvZgdTYHPKpdPNy6o8EDWub9x7aw7YYV1QWfU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDP/UYhn3h2l+gd26nypCzQcZMGVH39sUVyYftUVy/itwIgMW5Wcd0XFSbDQQ0x/6sfyKuv0GwBduLl/P5HU/J7iMg="}],"unpackedSize":651852},"main":"./dist/main.js","name":"picocad2-web","type":"module","types":"./dist/lib/main.d.ts","author":"hfcRed","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/lib/main.d.ts","import":"./dist/main.js","default":"./dist/main.js"}},"license":"MIT","private":false,"scripts":{"dev":"vite","lint":"biome lint --write .","build":"tsc -b ./tsconfig.lib.json && vite build","check":"biome check --write . && node scripts/check-shaders.ts","format":"biome format --write .","preview":"vite preview","release":"node scripts/publish.js","test:perf":"node test/perf/run.ts","test:visual":"node test/visual/run.ts","test:perf:snapshot":"node test/perf/snapshot.ts","test:visual:update":"node test/visual/run.ts --update"},"version":"2.0.4","_npmUser":{"name":"hfcred","email":"hfcred@gmx.net"},"keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","directories":{},"maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"_nodeVersion":"26.0.0","dependencies":{"twgl.js":"^7.0.0","gl-matrix":"^3.4.4"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.1","pngjs":"^7.0.0","playwright":"^1.62.1","typescript":"~5.9.3","@types/node":"^26.4.0","@types/pngjs":"^6.0.5","@biomejs/biome":"^2.4.8","vite-plugin-dts":"^4.5.4","vite-plugin-glsl":"^1.5.6"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/picocad2-web_2.0.4_1790098254374_0.33426029250184897"}}},"time":{"created":"2026-03-22T12:45:28.203Z","modified":"2026-09-22T17:30:54.658Z","0.1.0":"2026-03-22T12:45:28.355Z","0.2.0":"2026-03-22T14:04:04.676Z","1.0.0":"2026-03-22T19:42:42.550Z","1.1.0":"2026-03-23T18:09:10.678Z","1.1.1":"2026-03-24T14:49:52.038Z","1.1.2":"2026-03-25T15:43:56.859Z","1.2.0":"2026-03-25T19:27:54.301Z","1.2.1":"2026-03-26T20:49:04.902Z","1.2.2":"2026-03-27T16:21:50.117Z","1.2.3":"2026-03-28T17:49:37.452Z","1.2.4":"2026-03-30T16:25:20.800Z","1.2.5":"2026-04-02T16:13:00.173Z","1.2.6":"2026-04-03T15:27:56.791Z","1.2.7":"2026-04-03T18:05:52.775Z","1.2.8":"2026-04-04T08:23:05.662Z","1.2.9":"2026-04-04T12:27:52.684Z","1.2.10":"2026-04-04T13:16:11.357Z","1.2.11":"2026-04-04T13:37:08.788Z","1.2.12":"2026-04-04T16:29:08.565Z","1.2.13":"2026-04-12T09:21:09.655Z","1.2.14":"2026-08-01T19:35:42.957Z","1.2.15":"2026-08-01T20:00:57.377Z","1.3.0":"2026-08-02T00:51:20.321Z","1.4.0-beta.0":"2026-08-03T20:16:23.264Z","1.4.0-beta.1":"2026-08-05T05:01:42.100Z","1.4.0-beta.2":"2026-08-22T23:09:32.001Z","2.0.0":"2026-09-08T16:14:45.018Z","2.0.1":"2026-09-08T17:50:16.016Z","2.0.2":"2026-09-08T18:34:19.577Z","2.0.3":"2026-09-12T22:15:36.807Z","2.0.4":"2026-09-22T17:30:54.506Z"},"author":"hfcRed","license":"MIT","keywords":["picocad","picocad2","3d","viewer","webgl","browser"],"repository":{"url":"https://github.com/hfcRed/PicoCAD2-Web","type":"git"},"description":"Package for viewing PicoCAD 2 files in the browser","maintainers":[{"name":"hfcred","email":"hfcred@gmx.net"}],"readme":"# picocad2-web\r\n\r\n![NPM Downloads](https://img.shields.io/npm/dm/picocad2-web?style=flat-square)\r\n![NPM Version](https://img.shields.io/npm/v/picocad2-web?style=flat-square)\r\n![Static Badge](https://img.shields.io/badge/PicoCAD2_Compatibility-v2.2.0--b16-green?style=flat-square)\r\n\r\nA JavaScript library for viewing [PicoCAD 2](https://picocad.net/) models in the browser using WebGL 2.\r\n\r\n[Live Demo](https://picocad2-web-viewer.hfcred.workers.dev/)\r\n\r\n## Compatibility\r\n\r\nThe library exports a `COMPATIBLE_VERSION` constant indicating the PicoCAD 2 software version it targets. Currently `\"2.2.0-b16\"` (beta). Files saved by PicoCAD 2.1.0 remain fully supported.\r\n\r\n```typescript\r\nimport { COMPATIBLE_VERSION } from \"picocad2-web\";\r\nconsole.log(COMPATIBLE_VERSION); // \"2.2.0-b16\"\r\n```\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install picocad2-web\r\n```\r\n\r\nBeta releases targeting PicoCAD 2 beta versions are published under the `beta` dist-tag and are never installed by default. To install beta versions run:\r\n\r\n```bash\r\nnpm install picocad2-web@beta\r\n```\r\n\r\n## Quick Start\r\n\r\n```typescript\r\nimport { PicoCAD2Viewer } from \"picocad2-web\";\r\n\r\nconst viewer = new PicoCAD2Viewer({\r\n  canvas: document.querySelector(\"canvas\"),\r\n  resolution: { width: 256, height: 256, scale: 2 },\r\n});\r\n\r\n// Load a model from a .txt file string\r\nviewer.load(modelString);\r\n\r\n// Start rendering and enable camera controls\r\nviewer.startRenderLoop();\r\nviewer.enableCameraControls();\r\n```\r\n\r\n## Sharing a Context\r\n\r\nBrowsers limit the number of active WebGL contexts to 16. When displaying multiple models, it is recommended to create a single `PicoCAD2Context` and share it across viewers:\r\n\r\n```typescript\r\nimport { PicoCAD2Context, PicoCAD2Viewer } from \"picocad2-web\";\r\n\r\nconst context = new PicoCAD2Context();\r\n\r\nconst viewer1 = new PicoCAD2Viewer({ canvas: canvas1, context });\r\nconst viewer2 = new PicoCAD2Viewer({ canvas: canvas2, context });\r\n```\r\n\r\nViewers sharing a context also share a single render loop: each frame, all viewers render into one combined framebuffer that is captured once and distributed to their canvases. Capturing the drawing buffer is expensive (especially on Firefox), so sharing a context scales to much more viewers.\r\n\r\nShader programs compile in the background. Until a program is ready, frames draw with the programs they already have, so enabling an effect never freezes the page. The effect appears a few frames later. Where the browser offers no parallel shader compilation (Firefox), the canvas keeps its last frame until compilation, and `draw()` returns `false` for such a frame so a one-shot caller can try again on a later frame. Pass `shaderCompile: \"sync\"` to block on every compile instead, so the first frame after a change always shows it:\r\n\r\n```typescript\r\nconst context = new PicoCAD2Context({ shaderCompile: \"sync\" });\r\n```\r\n\r\n`context.shadersReady` tells whether every requested program has finished compiling, and `viewer.whenReady()` (see [Image Export](#image-export)) waits for the programs a viewer's current settings need, not for what other viewers on the context are still compiling.\r\n\r\n## Viewer Options\r\n\r\nAll options are optional and can be passed to the `PicoCAD2Viewer` constructor. They are the viewer's own settings, the settings a model file carries are applied by every `load()` and are set as [viewer properties](#viewer-properties) afterwards.\r\n\r\n```typescript\r\nconst viewer = new PicoCAD2Viewer({\r\n  // DOM & context\r\n  canvas: document.querySelector(\"canvas\"),   // Uses or creates a canvas if not specified\r\n  context: sharedContext,                     // Share a PicoCAD2Context across viewers\r\n\r\n  // Resolution\r\n  resolution: { width: 128, height: 128, scale: 2 },\r\n\r\n  // Rendering\r\n  maxFps: 60,                       // Max render loop rate in fps, 0 = display refresh rate (default: 60)\r\n  backgroundColor: [0.1, 0.1, 0.1], // Override background color, or null for model default (default: null)\r\n  transparency: \"dithered\",         // \"dithered\" | \"smooth\", how fades resolve against the background (default: \"dithered\")\r\n  colorScheme: \"auto\",              // \"light\" | \"dark\" | \"auto\", picks dark effect colors, see Color Scheme (default: \"auto\")\r\n\r\n  // Camera\r\n  clampCameraDistance: {          // Keep the camera outside the model's surfaces so the view can't clip into the geometry\r\n    enabled: false,               // (default: false)\r\n    minimumDistance: 0,           // Minimum distance to keep to the surfaces the camera stops at, in world units (default: 0)\r\n  },\r\n\r\n  // Animation\r\n  animationSpeed: 1,              // Animation playback speed multiplier (default: 1)\r\n\r\n  // Effects (all disabled by default)\r\n  extras: {\r\n    bloom: { enabled: true, threshold: 0.6, intensity: 1.5 },\r\n    rimLight: { enabled: true, color: [1, 1, 1] },\r\n    noise: { enabled: true, amount: 0.05 },\r\n  },\r\n\r\n  // Callbacks\r\n  onLoad: (info) => console.log(\"Loaded:\", info),\r\n  onFrame: (dt) => { /* called every frame */ },\r\n  onDispose: () => console.log(\"Disposed\"),\r\n});\r\n```\r\n\r\n## Loading Models\r\n\r\n```typescript\r\n// From a string\r\nviewer.load(modelString);\r\n\r\n// From a File object\r\nawait viewer.loadFromFile(file);\r\n\r\n// Load using the model's bookmarked camera position\r\nviewer.load(modelString, true);\r\n```\r\n\r\nLoading a model applies the settings the file carries. Shading mode, render mode, projection, camera and bookmark, camera mode, outline, scanlines, watermark tags and animation. The viewer's own settings (background override, resolution, max FPS, camera clamp, animation speed and loop, transparency) and the effects are not part of a model, so they keep their configuration across loads. `modelInfo.settings` holds what the file said.\r\n\r\n## Viewer Properties\r\n\r\nAll properties can be read and modified at any time after construction:\r\n\r\n```typescript\r\n// Rendering\r\nviewer.shadingMode = SHADING_MODE.off;   // a file's own value passes through unchanged\r\nviewer.renderMode = RENDER_MODE.color;   // RENDER_MODE.none hides the model\r\nviewer.projectionMode = \"orthographic\";\r\nviewer.backgroundColor = [0.2, 0, 0.3];\r\nviewer.transparency = \"smooth\";          // Fades blend alpha instead of dithering, see Transparency\r\nviewer.colorScheme = \"auto\";             // Follow the page's light or dark mode, see Color Scheme\r\n\r\n// Outline\r\nviewer.outlineSize = 2;\r\nviewer.outlineColor = [1, 1, 1];\r\n\r\n// Scanlines\r\nviewer.scanlines = true;\r\nviewer.scanlineColor = [0.2, 0, 0.4];\r\n\r\n// Camera mode\r\nviewer.cameraMode = \"spin\";\r\nviewer.cameraModeSpeed = 10;\r\nviewer.cameraModeDirection = \"right\";\r\nviewer.clampCameraDistance.enabled = true;        // Prevent the view from clipping into the model\r\nviewer.clampCameraDistance.minimumDistance = 0.5; // Keep at least half a unit to the surfaces\r\n\r\n// Tags (watermark text in viewport corners)\r\nviewer.leftTag = { text: \"picocad2-web\", color: [1, 1, 1] };\r\nviewer.rightTag = { text: \"v1.2.7\" };\r\n\r\n// Check if a model is loaded\r\nif (viewer.loaded) { /* ... */ }\r\n```\r\n\r\n## Render Loop & Drawing\r\n\r\n```typescript\r\n// Continuous rendering\r\nviewer.startRenderLoop();\r\nviewer.stopRenderLoop();\r\n\r\n// Single frame (useful for static scenes or custom loops)\r\nviewer.draw();\r\n\r\n// Advances the internal clock (useful for custom loops)\r\nviewer.advanceTime(deltaTime)\r\n\r\n// By default, camera modes sync their cycle to the animation duration.\r\n// Pass false to use the cameraModeSpeed timer instead.\r\nviewer.startRenderLoop(false);\r\nviewer.draw(false);\r\n```\r\n\r\n## Camera Controls\r\n\r\n```typescript\r\n// Enable mouse/touch orbit controls\r\nviewer.enableCameraControls();\r\nviewer.disableCameraControls();\r\n\r\n// Enable only specific controls (all default to true)\r\nviewer.enableCameraControls({ zoom: true, pan: false, rotate: true });\r\n\r\n// Control spin inertia after releasing (0 = instant stop, 1 = never stops, default 0.92)\r\nviewer.enableCameraControls({ spinInertiaFactor: 0.5 });\r\n\r\n// Temporarily pause camera mode on interaction, then restore after a delay\r\nviewer.enableCameraControls({\r\n  useFixedOnInteract: {\r\n    enabled: true,\r\n    delayBeforeRestore: 2000, // ms after the last interaction or pointer release before restoring\r\n    restoreTime: 500,         // ms to interpolate back to the original camera position (a moving camera mode keeps its horizontal angle and continues from there)\r\n  },\r\n});\r\n\r\n// Access the camera directly (theta is kept short of the poles)\r\nviewer.camera.theta = Math.PI / 4;\r\nviewer.camera.omega = Math.PI / 6;\r\nviewer.camera.distanceToTarget = 5;\r\nviewer.camera.target[1] = 2;    // the orbit target can be edited in place\r\n\r\n// Reset camera to the model's bookmarked position\r\nviewer.useBookmark();\r\n\r\n// Save a new bookmark\r\nviewer.setBookmark({\r\n  target: new Float32Array([0, 2, 0]),\r\n  distanceToTarget: 10,\r\n  theta: 0.3,\r\n  omega: 0.8,\r\n});\r\n```\r\n\r\n## Animation\r\n\r\n```typescript\r\n// Playback controls\r\nviewer.animation.play();\r\nviewer.animation.pause();\r\nviewer.animation.stop();\r\n\r\n// Configuration\r\nviewer.animation.speed = 2;     // 2x speed\r\nviewer.animation.loop = false;  // Don't loop\r\nviewer.animation.setTime(1.5);  // Jump to 1.5 seconds\r\n\r\n// Loop count requested by the model's export settings (PicoCAD 2.2 \"1x\"/\"2x\").\r\nviewer.animation.loops;\r\n```\r\n\r\n## Resolution\r\n\r\n```typescript\r\n// Update resolution at any time\r\nviewer.setResolution(256, 256, 2); // width, height, scale (default: 1)\r\n\r\n// Auto-resize: observe the canvas's parent element and update resolution on size changes\r\nviewer.watchResize(2); // scale factor (default: 1)\r\n\r\n// Stop observing\r\nviewer.unwatchResize();\r\n```\r\n\r\n## Model Info\r\n\r\nAfter loading a model, metadata is available via the `modelInfo` property:\r\n\r\n```typescript\r\nviewer.load(modelString);\r\n\r\nconst info = viewer.modelInfo;\r\n// info.nodeCount         - Total scene nodes\r\n// info.polyCount         - Total polygon faces\r\n// info.animationDuration - Animation length in seconds\r\n// info.hasAnimation      - Whether the model has animation data\r\n// info.backgroundColor   - Rendered background color as [r, g, b] (0-1 range)\r\n// info.transparentColor  - Transparent color as [r, g, b] (0-1 range)\r\n// info.palette           - Full color palette as an array of [r, g, b] (0-1 range)\r\n// info.settings          - The settings the file carries, as load() applied them\r\n```\r\n\r\n## Callbacks\r\n\r\n```typescript\r\n// Called after a model is loaded, receives ModelInfo\r\nviewer.onLoad = (info) => {\r\n  console.log(`Loaded ${info.polyCount} polygons`);\r\n};\r\n\r\n// Called every render loop frame with the delta time in seconds\r\nviewer.onFrame = (dt) => {\r\n  fpsCounter.update(dt);\r\n};\r\n\r\n// Called at the start of dispose(), before resources are freed\r\nviewer.onDispose = () => {\r\n  console.log(\"Viewer disposed\");\r\n};\r\n```\r\n\r\nCallbacks can also be set via constructor options (`onLoad`, `onFrame`, `onDispose`).\r\n\r\n## State Serialization\r\n\r\nA state is the model source plus everything that differs from a plain `load()` of it, in three optional groups. `model` holds the settings the file carries where they differ from the file, `viewer` holds the viewer's own settings where they differ from `VIEWER_SETTINGS_DEFAULTS`, and `extras` holds the effects that differ from their defaults. The source alone is a valid state. `source` is the viewer's own parse of the file and is frozen, so copy it before changing it.\r\n\r\n```typescript\r\n// Capture state (JSON-serializable)\r\nconst state = viewer.getState();\r\nlocalStorage.setItem(\"viewer\", JSON.stringify(state));\r\n\r\n// Restore state (reloads the model, then applies the differences)\r\nconst saved = JSON.parse(localStorage.getItem(\"viewer\"));\r\nviewer.setState(saved);\r\n\r\n// Restore state using the model's bookmarked camera position\r\nviewer.setState(saved, true);\r\n\r\n// A state written by hand only needs what it changes\r\nviewer.setState({\r\n  source: state.source,\r\n  model: { shadingMode: SHADING_MODE.off, outlineSize: 1 },\r\n  viewer: { resolution: { width: 256, height: 256, scale: 2 } },\r\n  extras: { bloom: { enabled: true, threshold: 0.6 } },\r\n});\r\n```\r\n\r\nTo turn a group back into complete settings, lay it over its reference with `mergeDefaults`. `modelInfo.settings` for `model`, `getDefaultViewerSettings()` for `viewer` and `getDefaultExtras()` for `extras`.\r\n\r\n## Image Export\r\n\r\n```typescript\r\n// Export current frame as a Blob (async)\r\nconst blob = await viewer.toBlob(\"image/png\");\r\n\r\n// Export as data URL (sync)\r\nconst dataUrl = viewer.toDataURL(\"image/jpeg\", 0.9);\r\n\r\n// Export raw RGBA pixel data (Uint8Array, length = width * height * 4)\r\nconst pixels = viewer.toPixelData();\r\n```\r\n\r\nShader programs compile in the background (see [Sharing a Context](#sharing-a-context)), so a frame drawn right after enabling an effect may not show it yet. Before exporting, wait for the programs the current settings need and draw once more:\r\n\r\n```typescript\r\nviewer.extras.bloom.enabled = true;\r\nawait viewer.whenReady();\r\nviewer.draw();\r\nconst blob = await viewer.toBlob();\r\n```\r\n\r\n## Effects\r\n\r\nAll effects live on `viewer.extras` and are disabled by default. They fall into four categories depending on where they run:\r\n\r\n- **Material effects** shade the model's surfaces inside the model shader using the models true normals.\r\n- **Geometry effects** reshape the model's own geometry.\r\n- **Scene effects** draw additional geometry into the 3D scene alongside the model.\r\n- **Post-processing effects** are fullscreen passes over the rendered image, applied in a fixed chain.\r\n\r\n```typescript\r\n// Enable an effect\r\nviewer.extras.noise.enabled = true;\r\nviewer.extras.noise.amount = 0.1;\r\n\r\n// Disable it\r\nviewer.extras.noise.enabled = false;\r\n```\r\n\r\nShaders are compiled lazily and in the background, so effects have no GPU cost until first enabled and enabling one never freezes the page. The model shader is compiled per combination of enabled material and geometry effects, so a plain model compiles in milliseconds and a combination only carries the code of its effects. The patterns the interior, the projection and the procedural background sample are part of that combination. Switching a pattern compiles a small program in the background while the previous one keeps drawing. While a program is still compiling, frames keep drawing with the programs they already have, and the effect appears once its program is ready. `await viewer.whenReady()` waits for that, `new PicoCAD2Context({ shaderCompile: \"sync\" })` blocks on every compile instead.\r\n\r\n### Color Masks\r\n\r\nEffects that support masking have a `maskedColors` property: an array of base palette indices (0-15) selecting which of the model's colors the effect applies to. An empty array (the default) applies the effect everywhere.\r\n\r\nMasks select *materials*, not displayed colors: a color is matched whether it is lit or in shadow, and pixels keep their material identity under warping effects (glitch, pixelation, lens distortion, chromatic aberration, video effects) and under material effects like rim light. Non-empty masks only ever match model pixels, never the background or outline.\r\n\r\nMask granularity follows where the mask is tested. Material and post-processing effects test per pixel, so `maskedColors: [12]` means \"texels painted with color 12\". Geometry effects run in the vertex stage where texels don't exist yet, so their masks select faces by the face's *assigned* color instead. On textured faces the two can disagree. Fur is the exception, its strand cutout runs per fragment and samples the texture, so its mask is per texel like the material effects. The billboard effect selects whole nodes by name rather than by color.\r\n\r\n### Node Selection\r\n\r\nEffects that run in the model pass also accept a `nodes` array of scene node names. A named node's descendants are included, so naming a group selects everything in it, and several nodes sharing a name are all selected. Colors and nodes combine, so the effect applies to the selected colors within the selected nodes. An empty array (the default) selects every node.\r\n\r\n```typescript\r\nviewer.extras.emission.maskedColors = [10];       // Color 10...\r\nviewer.extras.emission.nodes = [\"lamp\", \"sign\"];  // ...but only on these nodes and their children\r\nviewer.extras.fur.nodes = [\"body\"];               // Fur on the body only, every color\r\n```\r\n\r\nNode names come from the model file; `modelInfo.nodeCount` gives the total.\r\n\r\n```typescript\r\n// Make palette color 10 glow\r\nviewer.extras.bloom.enabled = true;\r\nviewer.extras.bloom.maskedColors = [10];\r\n\r\n// Glitch only the \"screen\" color of a model\r\nviewer.extras.glitch.enabled = true;\r\nviewer.extras.glitch.maskedColors = [12];\r\n```\r\n\r\nAll material effects support masking, per texel. These post-processing effects support it: bloom, dithering, posterization, color grading, color tint, halftone, noise, glitch, pixelation, chromatic aberration, depth fog, edge detection, and sharpen. Video effects are unmasked by design (they simulate the entire display), but they carry the palette index through their warps so masked effects later in the chain stay correct.\r\n\r\n### Sweeps\r\n\r\nEffects that run a `progress` across the model take a `sweep` group deciding where the front is. `mode` picks the order. `\"uniform\"` applies to the whole model at once, `\"noise\"` applies to random mesh-space cells, `\"directional\"` sweeps a plane along `direction`, `\"point\"` grows a sphere from a world `point`, and `\"proximity\"` runs front to back from the camera. Every mode is normalized to the model's bounds, so `progress` 0 to 1 always spans the whole model. `softness` is the width of the front as a fraction of that span. `wave` turns the front into a band of that width that enters at progress 0 and has left at 1, so the effect travels through the model and restores it behind the wave. The softness ramps sit inside the band, so a softness wider than half the wave lowers its peak. Waves apply to the directional, point and proximity sweeps. `invert` inverts the progress. At 0 the whole model is swept and it restores as the progress rises, so an inverted shatter assembles the model. A uniform sweep has no front, so `softness` and `wave` do nothing there.\r\n\r\n```typescript\r\nviewer.extras.dissolve.sweep.mode = \"directional\"; // Sweep order (default: \"uniform\"; the dissolve uses \"noise\", the triangle shatter and mesh deform \"uniform\")\r\nviewer.extras.dissolve.sweep.direction = [0, 1, 0]; // Sweep direction for \"directional\" (default: [0, 1, 0])\r\nviewer.extras.dissolve.sweep.point = [0, 0, 0];     // World center for \"point\" (default: [0, 0, 0])\r\nviewer.extras.dissolve.sweep.scale = 8;             // Noise cells per mesh unit (default: 8)\r\nviewer.extras.dissolve.sweep.softness = 0.15;       // Width of the front, 0-1 of the sweep range (default: 0.15)\r\nviewer.extras.dissolve.sweep.wave = 0;              // Traveling band width, 0-1 of the sweep range, 0 = a front that stays (default: 0)\r\nviewer.extras.dissolve.sweep.invert = false;        // Invert the progress: swept at 0, restored at 1 (default: false)\r\n```\r\n\r\n### Transparency\r\n\r\nEvery fade against the background shares one viewer setting, `transparency`.\r\n\r\n```typescript\r\nviewer.transparency = \"dithered\";  // \"dithered\" | \"smooth\" (default: \"dithered\")\r\n```\r\n\r\n`\"dithered\"` claims whole pixels through an ordered dither, so the frame stays palette-pure and a GIF, which has no alpha, still shows the fade over a transparent background. `\"smooth\"` blends fractional alpha instead, which reads better over an opaque background.\r\n\r\nThe built-in outline and the gradient outline fade with what they trace, in either mode. Around a dissolving surface the outline continues its dither or its alpha instead of boxing every surviving pixel, and it fades around twinkling particles. The outline runs ahead of the fade, over the upper half of the coverage, so it is gone by the time the surface is half faded and never sits where the fade begins. Included in the viewer state as `viewer.transparency`.\r\n\r\n### Color Scheme\r\n\r\nA model rendered over a transparent background sits on whatever the page paints behind it, and a page with light and dark modes paints two different things. `colorScheme` tells the viewer which one it is rendering for, so effects with a dark variant can switch colors. Currently that is the [gradient outline](#gradient-outline)'s `dark` group.\r\n\r\n```typescript\r\nviewer.colorScheme = \"auto\";  // \"light\" | \"dark\" | \"auto\" (default: \"auto\")\r\n```\r\n\r\n`\"light\"` and `\"dark\"` are set by the page. If the page toggles a class or a `data-theme` attribute, set the scheme from the same code. `\"auto\"` follows the browser's `prefers-color-scheme` on every frame, with no listener to manage. Where `matchMedia` does not exist, `\"auto\"` renders light. The scheme belongs to the page, not to the model, so it is not part of the viewer state and `setState()` leaves it alone.\r\n\r\n```typescript\r\n// A page that flips a data-theme attribute on <html>\r\nviewer.colorScheme = document.documentElement.dataset.theme === \"dark\" ? \"dark\" : \"light\";\r\n\r\n// A page that follows the operating system\r\nviewer.colorScheme = \"auto\";\r\n```\r\n\r\n## Palette Swap & Color Cycling\r\n\r\n`extras.paletteSwap` recolors the model PICO-8 `pal()` style, by rewriting the palette lookup table. A swapped index renders with the target's color *and* the target's shade ramp, so recolored materials shade correctly. Everything that reads the palette follows the swap. The model (including shading), particles, and palette-style effects like SSAO. Effect masks keep matching the original palette indices, which the swap does not change.\r\n\r\n```typescript\r\nconst swap = viewer.extras.paletteSwap;\r\nswap.enabled = true;\r\n\r\n// Display palette color 7 as color 12 (sparse, unlisted indices stay unchanged)\r\nswap.map = [];\r\nswap.map[7] = 12;\r\n\r\n// Demoscene color cycling: these indices rotate through each other\r\nswap.cycleIndices = [8, 9, 10];    // 8 -> 9 -> 10 -> 8 -> ... (default: [])\r\nswap.cycleSpeed = 2;               // Cycle steps per second, negative reverses (default: 2)\r\n```\r\n\r\nCycling applies on top of `map`, and the cycle loops perfectly.\r\n\r\n## Material Effects\r\n\r\nMaterial effects render inside the model shader. Each one has a `style` property choosing how it writes its result:\r\n\r\n- `\"palette\"` (default) — the effect only ever outputs the model's own palette colors: effect colors snap to the nearest palette entry, and soft edges use the same checkerboard dithering as the shading system. The render stays made of palette entries.\r\n- `\"smooth\"` — plain RGB blending for a modern look.\r\n\r\n### Color Cutout\r\n\r\nRenders the selected palette colors as additional transparent colors, punching real holes into the model that outlines and depth-based effects see. Unlike effect masks, an empty `maskedColors` array cuts nothing.\r\n\r\n```typescript\r\nviewer.extras.colorCutout.enabled = true;\r\nviewer.extras.colorCutout.maskedColors = [3, 7];    // These colors become transparent\r\nviewer.extras.colorCutout.nodes = [\"window\"];             // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\n### Dissolve\r\n\r\nDissolves the model texel by texel as `progress` runs from 0 (intact) to 1 (gone), punching holes into the mesh. Survivors near the cut show a dithered edge. Fur strands dissolve with their base surface. Drive `progress` from the host for spawn and despawn animations, or let `cycle` run it back and forth automatically, and combine with the triangle shatter for layered destruction.\r\n\r\n```typescript\r\nviewer.extras.dissolve.enabled = true;\r\nviewer.extras.dissolve.progress = 0.5;             // 0 = intact, 1 = fully dissolved (default: 0)\r\nviewer.extras.dissolve.cycle.enabled = false;      // Run progress 0 → 1 → 0 automatically (default: false)\r\nviewer.extras.dissolve.cycle.mode = \"pingpong\";    // How the progress comes back, \"pingpong\" retraces the sweep, \"loop\" restores along the same direction (default: \"pingpong\")\r\nviewer.extras.dissolve.cycle.duration = 4;         // Seconds per full cycle, holds included (default: 4)\r\nviewer.extras.dissolve.cycle.hold = 0.5;           // Seconds to rest at each end (default: 0.5)\r\nviewer.extras.dissolve.sweep.mode = \"noise\";       // Which texels go first, see Sweeps (default: \"noise\")\r\nviewer.extras.dissolve.edgeWidth = 0.1;            // Ember edge band width, 0 = no edge (default: 0.1)\r\nviewer.extras.dissolve.edgeColor = [1, 0.65, 0.2]; // Edge color (default: [1, 0.65, 0.2])\r\nviewer.extras.dissolve.maskedColors = [7];         // Only these colors dissolve (default: [] = all)\r\nviewer.extras.dissolve.nodes = [\"arm\"];            // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\nThe `sweep` group decides which texels go first (see [Sweeps](#sweeps)). The dissolve defaults to `\"noise\"`. A `\"uniform\"` sweep has no front, so the whole surface fades through the checkerboard instead and shows no edge. While `cycle` is enabled the manual `progress` is ignored. The progress rests at 0 for `hold` seconds. `cycle.mode` decides how the progress comes back. `\"pingpong\"` runs it from 1 back to 0, so the sweep retraces its path, and `\"loop\"` runs the sweep forward a second time to restore the model. Timing follows the viewer's elapsed time, so it pauses with the render loop. In palette style the edge color snaps to the nearest palette entry and the edge band dithers. Smooth style blends it. The dissolving texels themselves follow the viewer's [transparency](#transparency).\r\n\r\n### Interior\r\n\r\nFake depth behind selected palette colors: for masked texels the view ray is marched a few steps into the surface and a procedural 3D field is sampled at each depth, with parallax that tracks the camera.\r\n\r\n```typescript\r\nviewer.extras.interior.enabled = true;\r\nviewer.extras.interior.maskedColors = [7];              // These colors become windows into the pattern\r\nviewer.extras.interior.nodes = [\"visor\"];               // Only within these nodes (default: [] = all nodes)\r\nviewer.extras.interior.pattern = \"stars\";               // Pattern behind the surface (default: \"stars\")\r\n// Available patterns: \"stars\" | \"dust\" | \"voronoi\" | \"lava\" | \"grid\" | \"truchet\" | \"constellations\"\r\nviewer.extras.interior.depth = 2;                       // World units to the deepest layer (default: 2)\r\nviewer.extras.interior.layers = 3;                      // Pattern layers, 1-5 (default: 3)\r\nviewer.extras.interior.scale = 4;                       // Pattern cells per world unit (default: 4)\r\nviewer.extras.interior.speed = 1;                       // Pattern animation rate, 0 = frozen (default: 1)\r\nviewer.extras.interior.seed = 0;                        // Variant of the random patterns, inert for \"grid\" (default: 0)\r\nviewer.extras.interior.color = [1, 1, 1];               // Pattern color (default: [1, 1, 1])\r\nviewer.extras.interior.backgroundColor = [0.06, 0.05, 0.13]; // Fill behind the last layer (default: [0.06, 0.05, 0.13])\r\n```\r\n\r\nUnlike the other material effects, the masked texels are replaced entirely by the interior. An empty `maskedColors` array applies it to every color, turning the whole model into a hologram.\r\n\r\nThe pattern library is shared with the Procedural Background effect, both expose all seven patterns. `\"truchet\"` and `\"constellations\"` are 2D patterns extruded along the world z axis, so inside the interior they read cleanest on faces looking down that axis.\r\n\r\n### Rim Light\r\n\r\nFresnel rim on the model's silhouette. On flat-shaded geometry the rim is chunky per-face, like classic sprite edge-lighting.\r\n\r\n```typescript\r\nviewer.extras.rimLight.enabled = true;\r\nviewer.extras.rimLight.color = [1, 1, 1];    // Rim color (default: [1, 1, 1])\r\nviewer.extras.rimLight.width = 0.35;         // How far the rim reaches in from the silhouette, 0-1 (default: 0.35)\r\nviewer.extras.rimLight.sharpness = 0.7;      // Soft dithered falloff to hard cut, 0-1 (default: 0.7)\r\nviewer.extras.rimLight.lightAlign = 0;       // -1 shadow side only, 0 everywhere, +1 lit side only (default: 0)\r\nviewer.extras.rimLight.blend = 1;            // Mix over the base color, 0-1 (default: 1)\r\nviewer.extras.rimLight.invert = false;       // Light camera-facing geometry instead (default: false)\r\nviewer.extras.rimLight.nodes = [\"body\"];          // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\nThe light is attached to the camera, so `lightAlign = -1` gives a backlight: the silhouette rim tilted away from the light.\r\n\r\n### Gradient Light\r\n\r\nTwo-color tint ramp over the model: lit (or high) areas pull toward one color, shadowed (or low) areas toward another.\r\n\r\n```typescript\r\nviewer.extras.gradientLight.enabled = true;\r\nviewer.extras.gradientLight.litColor = [1, 0.92, 0.6];       // Color where the source is high (default: [1, 0.92, 0.6])\r\nviewer.extras.gradientLight.shadowColor = [0.35, 0.35, 0.7]; // Color where the source is low (default: [0.35, 0.35, 0.7])\r\nviewer.extras.gradientLight.source = \"light\";                // \"light\" | \"worldY\" | \"screenY\" (default: \"light\")\r\nviewer.extras.gradientLight.nodes = [\"body\"];                     // Only within these nodes (default: [] = all nodes)\r\nviewer.extras.gradientLight.blend = 0.5;                     // Tint amount, 0-1 (default: 0.5)\r\n```\r\n\r\n### Specular\r\n\r\nBlinn-Phong highlight from the headlight, plus an optional procedural environment reflection: a two-color sky/ground sampled by the reflected view ray.\r\n\r\n```typescript\r\nviewer.extras.specular.enabled = true;\r\nviewer.extras.specular.strength = 0.5;       // Highlight intensity, 0-1 (default: 0.5)\r\nviewer.extras.specular.smoothness = 0.5;     // Highlight tightness, 0-1 (default: 0.5)\r\nviewer.extras.specular.color = [1, 1, 1];    // Highlight color (default: [1, 1, 1])\r\nviewer.extras.specular.anisotropy = 0;       // Screen-space highlight stretch, 0-1 (default: 0)\r\nviewer.extras.specular.nodes = [\"helmet\"];          // Only within these nodes (default: [] = all nodes)\r\n\r\n// Environment reflection (off by default)\r\nviewer.extras.specular.environment.strength = 0.5;                  // Reflection amount, 0 = off (default: 0)\r\nviewer.extras.specular.environment.skyColor = [0.62, 0.87, 1];      // Reflected by upward-facing surfaces (default: [0.62, 0.87, 1])\r\nviewer.extras.specular.environment.groundColor = [0.42, 0.28, 0.2]; // Reflected by downward-facing surfaces (default: [0.42, 0.28, 0.2])\r\nviewer.extras.specular.environment.horizon = 0.5;                   // Horizon band sharpness, 0-1 (default: 0.5)\r\nviewer.extras.specular.environment.fresnel = 0.5;                   // Edge weighting of reflections, 0-1 (default: 0.5)\r\n```\r\n\r\n### Glitter\r\n\r\nView-angle triggered sparkles that pop in and out as the camera orbits, with a per-cell twinkle over time.\r\n\r\n```typescript\r\nviewer.extras.glitter.enabled = true;\r\nviewer.extras.glitter.space = \"uv\";          // Sparkle space (default: \"uv\")\r\n// Available spaces: \"uv\" (quantized to the texel grid) | \"screen\" | \"world\" (sticks to surfaces under animation)\r\nviewer.extras.glitter.density = 48;          // Sparkle cells per unit (default: 48)\r\nviewer.extras.glitter.size = 0.6;            // Lit fraction of a cell, 0-1 (default: 0.6)\r\nviewer.extras.glitter.nodes = [\"gem\"];           // Only within these nodes (default: [] = all nodes)\r\nviewer.extras.glitter.color = [1, 1, 1];     // Sparkle color (default: [1, 1, 1])\r\nviewer.extras.glitter.brightness = 1;        // Max sparkle intensity (default: 1)\r\nviewer.extras.glitter.angleRange = 40;       // View-angle window in degrees, larger = more sparkles (default: 40)\r\nviewer.extras.glitter.speed = 1;             // Twinkle rate (default: 1)\r\nviewer.extras.glitter.shape = \"square\";      // \"square\" | \"circle\" (default: \"square\")\r\nviewer.extras.glitter.randomHue = false;     // Random per-cell hues, smooth style only (default: false)\r\nviewer.extras.glitter.hueRange = 0.5;        // Hue spread for randomHue, 0-1 (default: 0.5)\r\n```\r\n\r\n### Emission\r\n\r\nMakes the masked palette colors emissive. Their texels ignore shading and render fullbright. In palette style the lit shade row is claimed through the checkerboard dither gate (and the index buffer's shade row follows), so the render stays palette-pure. Smooth style blends toward the lit color instead. Combine with `bloom.maskedColors` on the same indices for a glow halo.\r\n\r\n```typescript\r\nviewer.extras.emission.enabled = true;\r\nviewer.extras.emission.maskedColors = [10];         // Emissive colors (default: [] = all)\r\nviewer.extras.emission.nodes = [\"lamp\"];          // Only within these nodes (default: [] = all nodes)\r\nviewer.extras.emission.strength = 1;                // How fully shading is ignored, 0-1 (default: 1)\r\n\r\n// Blinking (off by default)\r\nviewer.extras.emission.blinkRate = 2;               // Blinks per second, 0 = steady (default: 0)\r\nviewer.extras.emission.blinkMode = \"smooth\";        // \"smooth\" sine | hard \"pulse\" (default: \"smooth\")\r\nviewer.extras.emission.blinkMin = 0;                // Strength floor while blinking, 0-1 (default: 0)\r\n\r\n// Scrolling band waves (off by default)\r\nviewer.extras.emission.scrollGap = 2;               // World units between bands, 0 = no bands (default: 0)\r\nviewer.extras.emission.scrollWidth = 0.25;          // Band width in world units (default: 0.25)\r\nviewer.extras.emission.scrollDirection = [0, 1, 0]; // World travel direction (default: [0, 1, 0])\r\nviewer.extras.emission.scrollSpeed = 1;             // World units per second, negative reverses (default: 1)\r\n```\r\n\r\n### Projection\r\n\r\nProjects a pattern from the shared library onto the model's surfaces along a direction. The pattern is sampled on the plane perpendicular to `direction`, so it stays put while the model moves along the axis, and only faces turned toward the incoming direction receive it. `\"light\"` lifts shaded surfaces toward their lit color, `\"shadow\"` pushes them down the shade rows, and `\"tint\"` paints `color` where the pattern hits. In palette style, light and shadow step through the palette's shade rows with checkerboard dithering, so the render stays palette-pure. That also means light only shows on shaded surfaces, since lit is the palette's brightest. Smooth style blends instead.\r\n\r\n```typescript\r\nviewer.extras.projection.enabled = true;\r\nviewer.extras.projection.pattern = \"voronoi\";       // Projected field (default: \"voronoi\")\r\n// Available patterns: \"stars\" | \"dust\" | \"voronoi\" | \"lava\" | \"grid\" | \"truchet\" | \"constellations\"\r\nviewer.extras.projection.direction = [0, -1, 0];    // Travel direction of the projection (default: [0, -1, 0], straight down)\r\nviewer.extras.projection.mode = \"shadow\";           // \"light\" | \"shadow\" | \"tint\" (default: \"shadow\")\r\nviewer.extras.projection.color = [1, 1, 1];         // Tint color, snapped in palette style (default: [1, 1, 1])\r\nviewer.extras.projection.scale = 2;                 // Pattern cells per world unit (default: 2)\r\nviewer.extras.projection.speed = 0.5;               // Pattern animation speed (default: 0.5)\r\nviewer.extras.projection.seed = 0;                  // Pattern variant (default: 0)\r\nviewer.extras.projection.strength = 1;              // Intensity, 0-1 (default: 1)\r\nviewer.extras.projection.facing = 0.3;              // How squarely a face must face the direction to receive it, 0-1 (default: 0.3)\r\nviewer.extras.projection.maskedColors = [7];        // Only these colors receive it (default: [] = all)\r\nviewer.extras.projection.nodes = [\"floor\"];         // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\n### Display\r\n\r\nTurns the masked materials into screens, with the simulation the [video effects](#video-effects) post effect runs over the whole frame. Six screen types behind one `screenType` switch, the shared tone and grid controls, and the per-type settings that work on a surface. In `\"uv\"` space the surface is the screen. The virtual pixel grid lies on the texture with the texture's top row as the screen's top, scanlines run along texel rows, the subpixel structure sits inside each cell, and a `resolution` coarser than the texture shows a coarser image, since the texel lookup snaps to the cell centers. In `\"screen\"` space the structure follows the output pixels like the post effect, without resampling the image. Warps, the projector's halo and ghosting need the whole frame and stay with the post effect.\r\n\r\n```typescript\r\nviewer.extras.display.enabled = true;\r\nviewer.extras.display.space = \"uv\";                    // \"uv\" | \"screen\" (default: \"uv\")\r\nviewer.extras.display.screenType = \"crt\";              // \"crt\" | \"lcd\" | \"tn\" | \"oled\" | \"gameboy\" | \"projector\" (default: \"crt\")\r\nviewer.extras.display.resolution = 128;                // Virtual pixels along the texture or screen height, 0 = no grid (default: 128, one per texel)\r\nviewer.extras.display.brightness = 1;                  // Brightness multiplier (default: 1)\r\nviewer.extras.display.saturation = 1;                  // Saturation multiplier (default: 1)\r\nviewer.extras.display.contrastBoost = 0;               // Extra contrast (default: 0)\r\nviewer.extras.display.gridStrength = 0.5;              // Subpixel / screen-door / grille visibility (default: 0.5)\r\nviewer.extras.display.crt.scanlineIntensity = 0.3;     // Scanline opacity (default: 0.3)\r\nviewer.extras.display.crt.refreshRate = 0;             // Rolling flicker band sweeps in Hz, 0 = off (default: 0)\r\nviewer.extras.display.gameboy.palette = \"dmg\";         // \"dmg\" | \"pocket\" | \"custom\" (default: \"dmg\")\r\nviewer.extras.display.gameboy.customColors = [         // 4 shades, darkest to lightest, for \"custom\"\r\n  [0.06, 0.22, 0.06], [0.19, 0.38, 0.19], [0.55, 0.67, 0.06], [0.61, 0.74, 0.06],\r\n];\r\nviewer.extras.display.tn.angleShift = 0.5;             // Darkened top, washed-out bottom (default: 0.5)\r\nviewer.extras.display.oled.blackCrush = 0.5;           // Crush near-black to true black (default: 0.5)\r\nviewer.extras.display.oled.pentile = false;            // Alternate RG/GB subpixel layout (default: false)\r\nviewer.extras.display.projector.hotspot = 0.4;         // Radial brightness falloff from the center (default: 0.4)\r\nviewer.extras.display.maskedColors = [7];              // Only these colors become screens (default: [] = all)\r\nviewer.extras.display.nodes = [\"screen\"];              // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\nA screen's response is an RGB transform, so the display has no `style` and leaves the palette.\r\n\r\n## Geometry Effects\r\n\r\nGeometry effects reshape or grow the model's own geometry. Masks select by face color (see Color Masks), except fur's, which is per texel.\r\n\r\n### Mesh Deform\r\n\r\nStackable closed-form deforms, applied in world space after the node transform so hierarchy and animation stay correct. Applied in a fixed order ending with rounding, so voxelation quantizes the other deforms.\r\n\r\n`progress` runs the whole deform from 0 (untouched) to 1 (full), by hand or through `cycle`, and the `sweep` group (see [Sweeps](#sweeps)) decides where the front is. The warps scale by the local progress at each vertex, so a directional sweep with the cycle running turns a twist into a wave that travels up the model and unwinds. Voxelization cannot be weighted per vertex, so while the progress is partial every selected node is drawn from both its base mesh and its voxel stand-in. The cut is decided per voxel cell, so whole cubes appear and disappear as the front passes.\r\n\r\n```typescript\r\nviewer.extras.meshDeform.enabled = true;\r\nviewer.extras.meshDeform.progress = 1;             // 0 = untouched, 1 = fully deformed (default: 1)\r\nviewer.extras.meshDeform.cycle.enabled = false;    // Run progress 0 → 1 → 0 automatically (default: false)\r\nviewer.extras.meshDeform.cycle.mode = \"pingpong\";  // How the progress comes back, \"pingpong\" retraces the sweep, \"loop\" restores along the same direction (default: \"pingpong\")\r\nviewer.extras.meshDeform.cycle.duration = 4;       // Seconds per full cycle, holds included (default: 4)\r\nviewer.extras.meshDeform.cycle.hold = 0.5;         // Seconds to rest at each end (default: 0.5)\r\nviewer.extras.meshDeform.sweep.mode = \"uniform\";   // Where the front is, see Sweeps (default: \"uniform\")\r\nviewer.extras.meshDeform.voxel.enabled = true;     // Remesh into grid-aligned cubes (default: false)\r\nviewer.extras.meshDeform.voxel.gridSize = 0.25;    // Voxel edge length in world units (default: 0.25)\r\nviewer.extras.meshDeform.barrel.amount = 0.5;      // Bulge (or pinch when negative) along the axis, -1-1 (default: 0)\r\nviewer.extras.meshDeform.barrel.axis = \"y\";        // \"x\" | \"y\" | \"z\" (default: \"y\")\r\nviewer.extras.meshDeform.spherify.amount = 0.5;    // Lerp toward the bounding sphere, 0-1 (default: 0)\r\nviewer.extras.meshDeform.twist.amount = 0.5;       // Rotations across the model height (default: 0)\r\nviewer.extras.meshDeform.twist.axis = \"y\";         // \"x\" | \"y\" | \"z\" (default: \"y\")\r\nviewer.extras.meshDeform.nodes = [\"propeller\"];        // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\nMesh deform has no `maskedColors` because adjacent faces share positions, so deforming a masked face next to an unmasked face would tear their shared edge open. It does take `nodes`, whole nodes deform (or voxelize) while the rest of the model keeps its real geometry.\r\n\r\n### Triangle Flash\r\n\r\nRandom triangles blink a color for a moment. Flashing triangles keep their base palette index, so a blink does not change the masks of other effects.\r\n\r\n```typescript\r\nviewer.extras.triangleFlash.enabled = true;\r\nviewer.extras.triangleFlash.color = [1, 1, 1];     // Flash color (default: [1, 1, 1])\r\nviewer.extras.triangleFlash.rate = 8;              // Flash buckets per second (default: 8)\r\nviewer.extras.triangleFlash.density = 0.15;        // Fraction of triangles per bucket, 0-1 (default: 0.15)\r\nviewer.extras.triangleFlash.duration = 0.12;       // Seconds a flash lasts (default: 0.12)\r\nviewer.extras.triangleFlash.softness = 0;          // 0 = hard on/off, 1 = full fade (default: 0)\r\nviewer.extras.triangleFlash.mode = \"replace\";      // \"replace\" | \"add\" (add is smooth style only, default: \"replace\")\r\nviewer.extras.triangleFlash.nodes = [\"screen\"];     // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\n### Triangle Shatter\r\n\r\nBlows the model apart into its triangles. Rendering is forced double-sided and the wireframe hides while a shatter is in progress. `cycle` works like the dissolve's. While enabled it runs `progress` from 0 to 1 and back over `duration` seconds, resting `hold` seconds at each end, so the wireframe and fur return during the rest at 0. The `sweep` group (see [Sweeps](#sweeps)) decides which triangles go first.\r\n\r\n```typescript\r\nviewer.extras.triangleShatter.enabled = true;\r\nviewer.extras.triangleShatter.progress = 0.5;      // 0 = intact, 1 = fully dispersed (default: 0)\r\nviewer.extras.triangleShatter.cycle.enabled = false; // Run progress 0 → 1 → 0 automatically (default: false)\r\nviewer.extras.triangleShatter.cycle.mode = \"pingpong\"; // How the progress comes back, \"pingpong\" retraces the sweep, \"loop\" restores along the same direction (default: \"pingpong\")\r\nviewer.extras.triangleShatter.cycle.duration = 4;  // Seconds per full cycle, holds included (default: 4)\r\nviewer.extras.triangleShatter.cycle.hold = 0.5;    // Seconds to rest at each end (default: 0.5)\r\nviewer.extras.triangleShatter.sweep.mode = \"uniform\"; // Which triangles go first, see Sweeps (default: \"uniform\")\r\nviewer.extras.triangleShatter.mode = \"normal\";     // Travel direction (default: \"normal\")\r\n// Available modes: \"normal\" (face normals) | \"radial\" (away from center) | \"directional\"\r\nviewer.extras.triangleShatter.direction = [0, 1, 0]; // For \"directional\" mode (default: [0, 1, 0])\r\nviewer.extras.triangleShatter.distance = 2;        // World units traveled at progress 1 (default: 2)\r\nviewer.extras.triangleShatter.spread = 0.3;        // Random cone around the direction, 0-1 (default: 0.3)\r\nviewer.extras.triangleShatter.rotation = 1;        // Tumble revolutions at progress 1 (default: 1)\r\nviewer.extras.triangleShatter.gravity = 0;         // Downward pull scaled by distance, negative lifts (default: 0)\r\nviewer.extras.triangleShatter.shrink = 0;          // Scale toward 0 at progress 1, 0-1 (default: 0)\r\nviewer.extras.triangleShatter.maskedColors = [7];  // Only these face colors explode (default: [] = all)\r\nviewer.extras.triangleShatter.nodes = [\"wall\"];   // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\n### Vertex Glitch\r\n\r\nRhythmic mesh spikes. Time is cut into beats at `rate` per second, every beat picks a `density` fraction of units at random, and each picked unit spikes out for `duration` seconds, snapping there or easing out and back with `softness`. `unit` decides what moves, `\"triangle\"` pushes whole triangles along their face normal, which tears the mesh apart and hides the wireframe and fur while it runs, while `\"vertex\"` pushes every corner at a mesh position outward along the average normal of the faces sharing that position, so welds hold and the wireframe and fur follow. `progress`, `cycle` and the `sweep` group (see [Sweeps](#sweeps)) scale the spikes across the model the way they do for the mesh deform.\r\n\r\n```typescript\r\nviewer.extras.vertexGlitch.enabled = true;\r\nviewer.extras.vertexGlitch.unit = \"vertex\";         // \"triangle\" | \"vertex\" (default: \"vertex\")\r\nviewer.extras.vertexGlitch.strength = 0.2;          // Spike length in world units (default: 0.2)\r\nviewer.extras.vertexGlitch.rate = 8;                // Beats per second (default: 8)\r\nviewer.extras.vertexGlitch.density = 0.3;           // Fraction of units picked per beat, 0-1 (default: 0.3)\r\nviewer.extras.vertexGlitch.duration = 0.1;          // Seconds a spike lasts (default: 0.1)\r\nviewer.extras.vertexGlitch.softness = 0;            // 0 snaps out and back, 1 eases over the whole spike (default: 0)\r\nviewer.extras.vertexGlitch.progress = 1;            // 0 = still, 1 = full (default: 1)\r\nviewer.extras.vertexGlitch.cycle.enabled = false;   // Run progress 0 → 1 → 0 automatically (default: false)\r\nviewer.extras.vertexGlitch.cycle.mode = \"pingpong\"; // How the progress comes back, \"pingpong\" retraces the sweep, \"loop\" restores along the same direction (default: \"pingpong\")\r\nviewer.extras.vertexGlitch.sweep.mode = \"uniform\";  // Where the spikes are, see Sweeps (default: \"uniform\")\r\nviewer.extras.vertexGlitch.maskedColors = [7];      // Only faces of these colors spike (default: [] = all)\r\nviewer.extras.vertexGlitch.nodes = [\"antenna\"];     // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\nA face-color mask in vertex mode tears the mesh at the mask boundary, since a shared corner moves with its masked face only, and hides the wireframe, which has no face colors.\r\n\r\n### Fur\r\n\r\nShell-textured fur grown from the model's surfaces. The model is drawn again as a stack of instanced shells into strands of varying height. Strand roots darken through the palette's shade rows with checkerboard dithering. The fur stays palette-pure. Fur follows the mesh deform and hides while a triangle shatter is in progress.\r\n\r\n```typescript\r\nviewer.extras.fur.enabled = true;\r\nviewer.extras.fur.length = 0.1;            // Fur length in world units (default: 0.1)\r\nviewer.extras.fur.layers = 8;              // Shell count, 1-16 (default: 8)\r\nviewer.extras.fur.density = 40;            // Strand cells per world unit (default: 40)\r\nviewer.extras.fur.gravity = [0, -0.5, 0];  // Comb/droop vector, in fur lengths at the tip (default: [0, 0, 0])\r\nviewer.extras.fur.rootShade = 1;           // How hard roots darken through the shade rows, 0-1 (default: 1)\r\nviewer.extras.fur.maskedColors = [9];      // Fur only grows from these colors (default: [] = everywhere)\r\nviewer.extras.fur.nodes = [\"body\"];       // Only within these nodes (default: [] = all nodes)\r\n```\r\n\r\nUnlike the other geometry effects, fur's mask is per texel. The strand cutout samples the texture, so `maskedColors: [9]` grows fur exactly where the surface is painted with color 9.\r\n\r\n### Billboard\r\n\r\nTurns selected nodes toward the camera, keeping translation and scale. A node's local +Z side faces the camera, with local +X to the right and local +Y up on screen. The node's own rotation is applied on top of that, relative to the camera. Children inherit the billboarded frame. The wireframe follows automatically.\r\n\r\n```typescript\r\nviewer.extras.billboard.enabled = true;\r\nviewer.extras.billboard.nodes = [\"sign\"];  // Node names (default: [] = all top-level nodes, groups included)\r\nviewer.extras.billboard.mode = \"full\";     // \"full\" (face the camera on all axes) | \"yaw\" (spin around world Y, default: \"full\")\r\n```\r\n\r\nA node's X or Z rotation still tilts it in the camera frame, so keep those at zero for an upright sprite.\r\n\r\n## Scene Effects\r\n\r\nScene effects render additional geometry into the 3D scene, depth-tested against the model, before any post-processing.\r\n\r\n### Wireframe\r\n\r\nRenders wireframe edges over the model.\r\n\r\n```typescript\r\nviewer.extras.wireframe.enabled = true;\r\nviewer.extras.wireframe.color = [0, 1, 0];    // Wireframe color (default: [1, 1, 1])\r\n```\r\n\r\n### Particles\r\n\r\nSnow, rain, embers, sparkles or dust motes around the camera. One instanced draw of hashed, stateless, looping particles.\r\n\r\n```typescript\r\nviewer.extras.particles.enabled = true;\r\nviewer.extras.particles.count = 1000;          // Particle count, up to 10000 (default: 1000)\r\nviewer.extras.particles.shape = \"pixel\";       // \"pixel\" | \"quad\" | \"cube\" | \"triangle\" | \"line\" | \"circle\" (default: \"pixel\")\r\nviewer.extras.particles.size = 2;              // Output pixels for \"pixel\", world units otherwise: the edge of a quad, cube or circle, the height of a triangle, the length of a line (default: 2)\r\nviewer.extras.particles.sizeJitter = 0.5;      // Random per-particle shrink, 0-1 (default: 0.5)\r\nviewer.extras.particles.motion = \"drift\";      // \"drift\" | \"orbit\" | \"linear\" (default: \"drift\")\r\nviewer.extras.particles.speed = 1;             // Motion rate (default: 1)\r\nviewer.extras.particles.velocity = [0, -0.3, 0]; // Constant movement in box lengths per second, per axis (default: [0, 0, 0])\r\nviewer.extras.particles.areaScale = 8;         // Edge of the cube around the camera as a multiple of the model's largest extent (default: 8)\r\nviewer.extras.particles.twinkle = 0.3;         // Per-particle fade in and out, 0-1, dithered or blended per the viewer's transparency (default: 0.3)\r\nviewer.extras.particles.paletteIndices = [7];  // Color source: particles sample these palette colors (default: [] = white)\r\n```\r\n\r\nUnlike effect masks, `paletteIndices` is a color source, not a mask: particles are painted with the model's palette colors at those indices.\r\n\r\n### Floor\r\n\r\nA pedestal plane under the model, placed at the lowest point of its rest-pose bounds and sized from its footprint, or stretched to the horizon with `infinite`. The plate carries optional world-space grid lines, a shadow of the model cast along a direction, and the model's mirror image, and it fades out toward its edge, through an ordered dither or with alpha per the viewer's [transparency](#transparency). Shadow and reflection show through the same ordered dither by their `strength`, or blend in smooth style, and the shadow's `softness` widens its edge into a penumbra shaped the same way. Grid lines inside the shadow take it at half strength, so they read as darker lines, and a grid thins out where its cells shrink toward a pixel instead of flooding the plate. With `surface` off the plate itself is invisible and only the grid, the shadow and the reflection render. The plate is scenery, it writes the no-model palette index, so color masks, ambient occlusion and the drop shadow do not touch it, while depth fog reaches it through the depth buffer and outlines trace its edge like any content. Seen from below, the plate is opaque and shows neither shadow nor reflection.\r\n\r\n```typescript\r\nviewer.extras.floor.enabled = true;\r\nviewer.extras.floor.surface = true;                    // Draw the plate surface; off leaves only the grid, shadow and reflection (default: true)\r\nviewer.extras.floor.infinite = false;                  // Extend the plate to the horizon, ignoring size and fade (default: false)\r\nviewer.extras.floor.offset = 0;                        // Distance below the model's lowest point, in world units (default: 0)\r\nviewer.extras.floor.size = 2;                          // Plate width as a multiple of the model's larger horizontal extent (default: 2)\r\nviewer.extras.floor.color = [0.4, 0.4, 0.45];          // Plate color (default: [0.4, 0.4, 0.45])\r\nviewer.extras.floor.fade = 0.5;                        // Outer fraction of the plate that fades out, 0-1 (default: 0.5)\r\nviewer.extras.floor.grid.enabled = true;               // World-space grid lines (default: true)\r\nviewer.extras.floor.grid.spacing = 1;                  // Grid cell size in world units (default: 1)\r\nviewer.extras.floor.grid.thickness = 1;                // Line width in render pixels (default: 1)\r\nviewer.extras.floor.grid.color = [0.55, 0.55, 0.6];    // Grid line color (default: [0.55, 0.55, 0.6])\r\nviewer.extras.floor.shadow.enabled = true;             // Shadow of the model on the plate (default: true)\r\nviewer.extras.floor.shadow.direction = [0.5, -1, 0.3]; // Direction the shadow is cast along, must point down (default: [0.5, -1, 0.3])\r\nviewer.extras.floor.shadow.color = [0.2, 0.2, 0.25];   // Shadow color (default: [0.2, 0.2, 0.25])\r\nviewer.extras.floor.shadow.strength = 1;               // Shadow coverage, dithered below 1 (default: 1)\r\nviewer.extras.floor.shadow.softness = 0;               // Penumbra radius in world units, 0 = hard edge (default: 0)\r\nviewer.extras.floor.reflection.enabled = false;        // Mirror image of the model in the plate (default: false)\r\nviewer.extras.floor.reflection.strength = 0.5;         // 1 = mirror, lower = water, dithered (default: 0.5)\r\nviewer.extras.floor.style = \"palette\";                 // \"palette\" | \"dithered\" | \"smooth\" (default: \"palette\")\r\n```\r\n\r\nThe shadow and reflection each redraw the whole model, so a plate with both costs three model draws per frame.\r\n\r\n## Post-Processing Effects\r\n\r\n### Procedural Background\r\n\r\nFills background pixels with a procedural pattern, so models stop floating in flat color. Applied at the head of the chain, so fog, outlines and every other effect apply over the pattern. Does nothing over a transparent background. The pattern library is shared with the Interior material effect, both expose all seven patterns.\r\n\r\n```typescript\r\nviewer.extras.proceduralBackground.enabled = true;\r\nviewer.extras.proceduralBackground.pattern = \"stars\";        // Pattern (default: \"stars\")\r\n// Available patterns: \"voronoi\" | \"truchet\" | \"stars\" | \"constellations\" | \"lava\" | \"dust\" | \"grid\"\r\nviewer.extras.proceduralBackground.colorA = [0.02, 0.02, 0.07]; // Base color (default: [0.02, 0.02, 0.07])\r\nviewer.extras.proceduralBackground.colorB = [1, 1, 1];       // Feature color (default: [1, 1, 1])\r\nviewer.extras.proceduralBackground.scale = 12;               // Pattern cells across the viewport height (default: 12)\r\nviewer.extras.proceduralBackground.speed = 1;                // Pattern animation rate, 0 = frozen (default: 1)\r\nviewer.extras.proceduralBackground.seed = 0;                 // Selects a different slice of the pattern space (default: 0)\r\nviewer.extras.proceduralBackground.cameraParallax = 0.5;     // 0 = screen-locked, 1 = follows the orbit camera (default: 0.5)\r\nviewer.extras.proceduralBackground.dither = false;           // Checkerboard-quantize the gradients (default: false)\r\n```\r\n\r\n### Ambient Occlusion (SSAO)\r\n\r\nScreen-space ambient occlusion. Crevices, corners and contact areas darken based on the surrounding geometry, grounding the model. Runs early in the chain, so fog and color work apply over it.\r\n\r\nThe default `\"palette\"` style darkens by stepping each pixel to a deeper shade row of the model's palette, dithered with the same checkerboard the shading system uses. The occlusion looks hand-drawn instead of smeared. `\"dithered\"` darkens the RGB in the same stepped checkerboard without re-indexing, and `\"smooth\"` multiplies plain RGB instead. `maskedColors` selects which colors receive occlusion.\r\n\r\n```typescript\r\nviewer.extras.ssao.enabled = true;\r\nviewer.extras.ssao.radius = 1;             // Sampling radius in world units (default: 1)\r\nviewer.extras.ssao.intensity = 1;          // Occlusion strength (default: 1)\r\nviewer.extras.ssao.power = 1;              // Falloff exponent, higher = darkens crevices only (default: 1)\r\nviewer.extras.ssao.samples = 16;           // Samples per pixel: 8 | 16 | 32 (default: 16)\r\nviewer.extras.ssao.style = \"palette\";      // \"palette\" | \"dithered\" | \"smooth\" (default: \"palette\")\r\n```\r\n\r\n### Noise\r\n\r\nAnimated film grain overlay.\r\n\r\n```typescript\r\nviewer.extras.noise.enabled = true;\r\nviewer.extras.noise.amount = 0.05;    // Noise intensity, 0-1 (default: 0.05)\r\n```\r\n\r\n### Color Grading\r\n\r\nBrightness, contrast, saturation, and hue adjustments.\r\n\r\n```typescript\r\nviewer.extras.colorGrading.enabled = true;\r\nviewer.extras.colorGrading.brightness = 1.2;    // Brightness multiplier (default: 1.0)\r\nviewer.extras.colorGrading.contrast = 1.1;      // Contrast multiplier (default: 1.0)\r\nviewer.extras.colorGrading.saturation = 0.8;    // Saturation multiplier (default: 1.0)\r\nviewer.extras.colorGrading.hue = 30;            // Hue shift in degrees (default: 0)\r\n```\r\n\r\n### Posterization\r\n\r\nReduces color depth for a banded, stylized look.\r\n\r\n```typescript\r\nviewer.extras.posterization.enabled = true;\r\nviewer.extras.posterization.levels = 8;                   // Color levels (default: 8)\r\nviewer.extras.posterization.gamma = 1.0;                  // Gamma correction (default: 1.0)\r\nviewer.extras.posterization.colorBanding = false;         // Color banding mode (default: false)\r\nviewer.extras.posterization.channelLevels = [1, 1, 1];    // Per-channel level multiplier (default: [1, 1, 1])\r\n```\r\n\r\n### Bloom\r\n\r\nMultipass glow effect with threshold, Gaussian blur, and additive compositing.\r\n\r\n```typescript\r\nviewer.extras.bloom.enabled = true;\r\nviewer.extras.bloom.threshold = 0.8;    // Brightness threshold (default: 0.8)\r\nviewer.extras.bloom.intensity = 1.0;    // Bloom strength (default: 1.0)\r\nviewer.extras.bloom.blur = 4.0;         // Blur radius (default: 4.0)\r\n```\r\n\r\n### Dithering\r\n\r\n4x4 Bayer matrix dithering pattern.\r\n\r\n```typescript\r\nviewer.extras.dithering.enabled = true;\r\nviewer.extras.dithering.amount = 1.0;                  // Dithering intensity (default: 1.0)\r\nviewer.extras.dithering.blend = 1.0;                   // Blend with original (default: 1.0)\r\nviewer.extras.dithering.channelAmount = [1, 1, 1];    // Per-channel amount (default: [1, 1, 1])\r\n```\r\n\r\n### Video Effects\r\n\r\nWhole-display screen simulation with six screen types behind one `screenType` switch. Shared controls set up the virtual pixel grid and tone, and each screen type adds its own settings on top. The same simulation runs per material as the [display](#display) effect, with color and node masks.\r\n\r\n```typescript\r\nviewer.extras.videoEffects.enabled = true;\r\nviewer.extras.videoEffects.screenType = \"crt\";       // Screen to simulate (default: \"crt\")\r\n// Available types: \"crt\" | \"lcd\" | \"tn\" | \"oled\" | \"gameboy\" | \"projector\"\r\nviewer.extras.videoEffects.resolution = 96;          // Virtual pixels along the height, 0 = native (default: 0)\r\nviewer.extras.videoEffects.brightness = 1.0;         // Brightness multiplier (default: 1.0)\r\nviewer.extras.videoEffects.saturation = 1.0;         // Saturation multiplier (default: 1.0)\r\nviewer.extras.videoEffects.contrastBoost = 0.0;      // Extra contrast (default: 0.0)\r\nviewer.extras.videoEffects.gridStrength = 0.5;       // Subpixel / screen-door / grille visibility (default: 0.5)\r\n```\r\n\r\n`resolution` defines a virtual pixel grid, color is quantized per virtual pixel while the subpixel and grid structure renders at full output resolution, which is what makes it read as a screen instead of downscaled pixelation. At the default `0` there is no quantization and no grid structure. Because the quantization covers the same ground as pixelation, `videoEffects.resolution` supersedes `pixelation`, prefer it over stacking the two.\r\n\r\nPer-type settings:\r\n\r\n```typescript\r\n// CRT: curvature warp, scanlines, rolling flicker, phosphor ghosting\r\nviewer.extras.videoEffects.crt.curvature = 0.5;           // Barrel distortion amount (default: 0.5)\r\nviewer.extras.videoEffects.crt.scanlineIntensity = 0.3;   // Scanline opacity (default: 0.3)\r\nviewer.extras.videoEffects.crt.refreshRate = 0;           // Rolling flicker band sweeps in Hz, 0 = off (default: 0)\r\nviewer.extras.videoEffects.crt.pixelFadeTime = 0;         // Phosphor ghosting in seconds, 0 = off (default: 0)\r\n\r\n// Gameboy: 4-shade quantization with LCD smear\r\nviewer.extras.videoEffects.gameboy.palette = \"dmg\";       // \"dmg\" | \"pocket\" | \"custom\" (default: \"dmg\")\r\nviewer.extras.videoEffects.gameboy.customColors = [       // 4 shades, darkest to lightest, for \"custom\"\r\n  [0.06, 0.22, 0.06], [0.19, 0.38, 0.19], [0.55, 0.67, 0.06], [0.61, 0.74, 0.06],\r\n];\r\nviewer.extras.videoEffects.gameboy.ghosting = 0.3;        // LCD response smear, 0-1 (default: 0.3)\r\n\r\n// TN panel: viewing-angle shift\r\nviewer.extras.videoEffects.tn.angleShift = 0.5;           // Darkened top, washed-out bottom (default: 0.5)\r\n\r\n// OLED: perfect blacks and pentile layout\r\nviewer.extras.videoEffects.oled.blackCrush = 0.5;         // Crush near-black to true black (default: 0.5)\r\nviewer.extras.videoEffects.oled.pentile = false;          // Alternate RG/GB subpixel layout (default: false)\r\n\r\n// Projector: keystone, hotspot and lens glow\r\nviewer.extras.videoEffects.projector.keystone = 0.2;      // Trapezoid warp toward the top (default: 0.2)\r\nviewer.extras.videoEffects.projector.hotspot = 0.4;       // Radial brightness falloff (default: 0.4)\r\nviewer.extras.videoEffects.projector.halo = 0.3;          // Light spill around bright content (default: 0.3)\r\n```\r\n\r\nThe plain `lcd` type uses only the shared controls: set a `resolution` and the `gridStrength` draws its RGB subpixels and screen-door gaps.\r\n\r\n### Pixelation\r\n\r\nPixelates the image with configurable pixel shapes.\r\n\r\n```typescript\r\nviewer.extras.pixelation.enabled = true;\r\nviewer.extras.pixelation.pixelSize = 4;      // Pixel size in screen pixels (default: 4)\r\nviewer.extras.pixelation.blend = 1.0;        // Blend with original (default: 1.0)\r\nviewer.extras.pixelation.shape = \"square\";   // Pixel shape (default: \"square\")\r\n// Available shapes: \"square\" | \"hex\" | \"circle\" | \"diamond\" | \"triangle\" | \"cross\" | \"star\"\r\n```\r\n\r\n### Lens Distortion\r\n\r\nBarrel or pincushion lens distortion.\r\n\r\n```typescript\r\nviewer.extras.lensDistortion.enabled = true;\r\nviewer.extras.lensDistortion.strength = 0.5;    // Positive = barrel, negative = pincushion (default: 0)\r\nviewer.extras.lensDistortion.zoom = 2.0;        // Zoom compensation (default: 2.0)\r\n```\r\n\r\n### Chromatic Aberration\r\n\r\nSeparates RGB color channels with radial offset.\r\n\r\n```typescript\r\nviewer.extras.chromaticAberration.enabled = true;\r\nviewer.extras.chromaticAberration.strength = 1.0;        // Overall strength (default: 1.0)\r\nviewer.extras.chromaticAberration.redOffset = 1.0;       // Red channel offset (default: 1.0)\r\nviewer.extras.chromaticAberration.greenOffset = 0.0;     // Green channel offset (default: 0.0)\r\nviewer.extras.chromaticAberration.blueOffset = -1.0;     // Blue channel offset (default: -1.0)\r\nviewer.extras.chromaticAberration.radialFalloff = 1.5;   // Falloff exponent (default: 1.5)\r\nviewer.extras.chromaticAberration.centerX = 0.5;         // Effect center X (default: 0.5)\r\nviewer.extras.chromaticAberration.centerY = 0.5;         // Effect center Y (default: 0.5)\r\n```\r\n\r\n### Gradient Outline\r\n\r\nA gradient colored outline effect. When enabled, it automatically replaces the built-in solid outline. Like the built-in outline it fades with what it traces (see [Transparency](#transparency)). Around a dissolving surface it continues the dither or the alpha of the fade, running ahead of it so it is gone before the surface is, and it fades around twinkling particles.\r\n\r\nThe outline can grow directionally. `growthFactor` 0 (the default) grows it evenly on all sides, 1 grows it only toward `growthDirection`, with a smooth falloff to the sides. The `\"dropShadow\"` mode instead repeats the whole silhouette displaced by `shadowOffset`, for a sticker-style shadow (`size` still fattens the shadow shape; use `size = 0` for an exact copy).\r\n\r\nThe `dark` group holds a second color pair for the viewer's dark [color scheme](#color-scheme), so an outline over a transparent background can match a page with light and dark modes. It only renders while `dark.enabled` is set and the scheme resolves to `\"dark\"`, otherwise `colorFrom` and `colorTo` render in every scheme. For a single-color outline that follows the page, set `colorFrom` and `colorTo` to the same color in both groups.\r\n\r\n```typescript\r\nviewer.extras.gradientOutline.enabled = true;\r\nviewer.extras.gradientOutline.size = 1;                      // Outline radius (default: 1)\r\nviewer.extras.gradientOutline.colorFrom = [1, 0.5, 0];       // Gradient start color (default: [1, 1, 1])\r\nviewer.extras.gradientOutline.colorTo = [0, 0.5, 1];         // Gradient end color (default: [0, 0, 0])\r\nviewer.extras.gradientOutline.dark.enabled = true;           // Use the dark colors in the dark color scheme (default: false)\r\nviewer.extras.gradientOutline.dark.colorFrom = [0, 0, 0];    // Dark scheme gradient start color (default: [0, 0, 0])\r\nviewer.extras.gradientOutline.dark.colorTo = [1, 1, 1];      // Dark scheme gradient end col","readmeFilename":""}