diff --git a/examples-testing/changes.patch b/examples-testing/changes.patch
index 2db1a5162..396109599 100644
--- a/examples-testing/changes.patch
+++ b/examples-testing/changes.patch
@@ -4020,6 +4020,829 @@ index 8aa86c3..ea8662c 100644
object.rotation.x = timer * 5;
object.rotation.y = timer * 2.5;
}
+diff --git a/examples-testing/examples/webgl_geometry_colors.ts b/examples-testing/examples/webgl_geometry_colors.ts
+index 7acc60f..836e466 100644
+--- a/examples-testing/examples/webgl_geometry_colors.ts
++++ b/examples-testing/examples/webgl_geometry_colors.ts
+@@ -2,9 +2,9 @@ import * as THREE from 'three';
+
+ import Stats from 'three/addons/libs/stats.module.js';
+
+-let container, stats;
++let container: HTMLElement, stats: Stats;
+
+-let camera, scene, renderer;
++let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+
+ let mouseX = 0,
+ mouseY = 0;
+@@ -16,7 +16,7 @@ init();
+ animate();
+
+ function init() {
+- container = document.getElementById('container');
++ container = document.getElementById('container')!;
+
+ camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 10000);
+ camera.position.z = 1800;
+@@ -34,7 +34,7 @@ function init() {
+ canvas.width = 128;
+ canvas.height = 128;
+
+- const context = canvas.getContext('2d');
++ const context = canvas.getContext('2d')!;
+ const gradient = context.createRadialGradient(
+ canvas.width / 2,
+ canvas.height / 2,
+@@ -154,7 +154,7 @@ function onWindowResize() {
+ renderer.setSize(window.innerWidth, window.innerHeight);
+ }
+
+-function onDocumentMouseMove(event) {
++function onDocumentMouseMove(event: MouseEvent) {
+ mouseX = event.clientX - windowHalfX;
+ mouseY = event.clientY - windowHalfY;
+ }
+diff --git a/examples-testing/examples/webgl_geometry_colors_lookuptable.ts b/examples-testing/examples/webgl_geometry_colors_lookuptable.ts
+index 6b01385..3944e0a 100644
+--- a/examples-testing/examples/webgl_geometry_colors_lookuptable.ts
++++ b/examples-testing/examples/webgl_geometry_colors_lookuptable.ts
+@@ -5,19 +5,19 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
+ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+ import { Lut } from 'three/addons/math/Lut.js';
+
+-let container;
++let container: HTMLElement;
+
+-let perpCamera, orthoCamera, renderer, lut;
++let perpCamera: THREE.PerspectiveCamera, orthoCamera: THREE.OrthographicCamera, renderer: THREE.WebGLRenderer, lut: Lut;
+
+-let mesh, sprite;
+-let scene, uiScene;
++let mesh: THREE.Mesh, sprite: THREE.Sprite;
++let scene: THREE.Scene, uiScene: THREE.Scene;
+
+-let params;
++let params: { colorMap: 'rainbow' };
+
+ init();
+
+ function init() {
+- container = document.getElementById('container');
++ container = document.getElementById('container')!;
+
+ scene = new THREE.Scene();
+ scene.background = new THREE.Color(0xffffff);
+@@ -41,7 +41,7 @@ function init() {
+ map: new THREE.CanvasTexture(lut.createCanvas()),
+ }),
+ );
+- sprite.material.map.colorSpace = THREE.SRGBColorSpace;
++ sprite.material.map!.colorSpace = THREE.SRGBColorSpace;
+ sprite.scale.x = 0.125;
+ uiScene.add(sprite);
+
+@@ -142,7 +142,7 @@ function updateColors() {
+
+ colors.needsUpdate = true;
+
+- const map = sprite.material.map;
++ const map = sprite.material.map!;
+ lut.updateCanvas(map.image);
+ map.needsUpdate = true;
+ }
+diff --git a/examples-testing/examples/webgl_geometry_convex.ts b/examples-testing/examples/webgl_geometry_convex.ts
+index b033036..38eecb8 100644
+--- a/examples-testing/examples/webgl_geometry_convex.ts
++++ b/examples-testing/examples/webgl_geometry_convex.ts
+@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+ import { ConvexGeometry } from 'three/addons/geometries/ConvexGeometry.js';
+ import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
+
+-let group, camera, scene, renderer;
++let group: THREE.Group, camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+
+ init();
+ animate();
+@@ -54,7 +54,7 @@ function init() {
+
+ // points
+
+- let dodecahedronGeometry = new THREE.DodecahedronGeometry(10);
++ let dodecahedronGeometry: THREE.BufferGeometry = new THREE.DodecahedronGeometry(10);
+
+ // if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data
+
+diff --git a/examples-testing/examples/webgl_geometry_cube.ts b/examples-testing/examples/webgl_geometry_cube.ts
+index bf22fcb..71a3610 100644
+--- a/examples-testing/examples/webgl_geometry_cube.ts
++++ b/examples-testing/examples/webgl_geometry_cube.ts
+@@ -1,7 +1,7 @@
+ import * as THREE from 'three';
+
+-let camera, scene, renderer;
+-let mesh;
++let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
++let mesh: THREE.Mesh;
+
+ init();
+ animate();
+diff --git a/examples-testing/examples/webgl_geometry_dynamic.ts b/examples-testing/examples/webgl_geometry_dynamic.ts
+index ccbaa6b..b9307ac 100644
+--- a/examples-testing/examples/webgl_geometry_dynamic.ts
++++ b/examples-testing/examples/webgl_geometry_dynamic.ts
+@@ -4,9 +4,13 @@ import Stats from 'three/addons/libs/stats.module.js';
+
+ import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
+
+-let camera, controls, scene, renderer, stats;
++let camera: THREE.PerspectiveCamera,
++ controls: FirstPersonControls,
++ scene: THREE.Scene,
++ renderer: THREE.WebGLRenderer,
++ stats: Stats;
+
+-let mesh, geometry, material, clock;
++let mesh: THREE.Mesh, geometry: THREE.PlaneGeometry, material: THREE.MeshBasicMaterial, clock: THREE.Clock;
+
+ const worldWidth = 128,
+ worldDepth = 128;
+@@ -27,7 +31,7 @@ function init() {
+ geometry = new THREE.PlaneGeometry(20000, 20000, worldWidth - 1, worldDepth - 1);
+ geometry.rotateX(-Math.PI / 2);
+
+- const position = geometry.attributes.position;
++ const position = geometry.attributes.position as THREE.BufferAttribute;
+ position.usage = THREE.DynamicDrawUsage;
+
+ for (let i = 0; i < position.count; i++) {
+diff --git a/examples-testing/examples/webgl_geometry_extrude_shapes.ts b/examples-testing/examples/webgl_geometry_extrude_shapes.ts
+index 099b425..a2de450 100644
+--- a/examples-testing/examples/webgl_geometry_extrude_shapes.ts
++++ b/examples-testing/examples/webgl_geometry_extrude_shapes.ts
+@@ -2,7 +2,7 @@ import * as THREE from 'three';
+
+ import { TrackballControls } from 'three/addons/controls/TrackballControls.js';
+
+-let camera, scene, renderer, controls;
++let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: TrackballControls;
+
+ init();
+ animate();
+@@ -14,7 +14,7 @@ function init() {
+ info.style.width = '100%';
+ info.style.textAlign = 'center';
+ info.style.color = '#fff';
+- info.style.link = '#f80';
++ (info.style as any).link = '#f80';
+ info.innerHTML =
+ 'three.js webgl - geometry extrude shapes';
+ document.body.appendChild(info);
+diff --git a/examples-testing/examples/webgl_geometry_extrude_splines.ts b/examples-testing/examples/webgl_geometry_extrude_splines.ts
+index 370a4d9..f9810d3 100644
+--- a/examples-testing/examples/webgl_geometry_extrude_splines.ts
++++ b/examples-testing/examples/webgl_geometry_extrude_splines.ts
+@@ -6,9 +6,14 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
+ import * as Curves from 'three/addons/curves/CurveExtras.js';
+ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+
+-let container, stats;
++let container: HTMLElement, stats: Stats;
+
+-let camera, scene, renderer, splineCamera, cameraHelper, cameraEye;
++let camera: THREE.PerspectiveCamera,
++ scene: THREE.Scene,
++ renderer: THREE.WebGLRenderer,
++ splineCamera: THREE.PerspectiveCamera,
++ cameraHelper: THREE.CameraHelper,
++ cameraEye: THREE.Mesh;
+
+ const direction = new THREE.Vector3();
+ const binormal = new THREE.Vector3();
+@@ -78,10 +83,10 @@ const splines = {
+ SampleClosedSpline: sampleClosedSpline,
+ };
+
+-let parent, tubeGeometry, mesh;
++let parent: THREE.Object3D, tubeGeometry: THREE.TubeGeometry, mesh: THREE.Mesh;
+
+ const params = {
+- spline: 'GrannyKnot',
++ spline: 'GrannyKnot' as const,
+ scale: 4,
+ extrusionSegments: 100,
+ radiusSegments: 3,
+@@ -125,7 +130,7 @@ function setScale() {
+ mesh.scale.set(params.scale, params.scale, params.scale);
+ }
+
+-function addGeometry(geometry) {
++function addGeometry(geometry: THREE.BufferGeometry) {
+ // 3D shape
+
+ mesh = new THREE.Mesh(geometry, material);
+@@ -144,7 +149,7 @@ init();
+ animate();
+
+ function init() {
+- container = document.getElementById('container');
++ container = document.getElementById('container')!;
+
+ // camera
+
+diff --git a/examples-testing/examples/webgl_geometry_minecraft.ts b/examples-testing/examples/webgl_geometry_minecraft.ts
+index 537d8d5..bfa97ba 100644
+--- a/examples-testing/examples/webgl_geometry_minecraft.ts
++++ b/examples-testing/examples/webgl_geometry_minecraft.ts
+@@ -6,9 +6,9 @@ import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.j
+ import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js';
+ import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
+
+-let container, stats;
++let container: HTMLElement, stats: Stats;
+
+-let camera, controls, scene, renderer;
++let camera: THREE.PerspectiveCamera, controls: FirstPersonControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+
+ const worldWidth = 128,
+ worldDepth = 128;
+@@ -22,7 +22,7 @@ init();
+ animate();
+
+ function init() {
+- container = document.getElementById('container');
++ container = document.getElementById('container')!;
+
+ camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 20000);
+ camera.position.y = getY(worldHalfWidth, worldHalfDepth) * 100 + 100;
+@@ -143,7 +143,7 @@ function onWindowResize() {
+ controls.handleResize();
+ }
+
+-function generateHeight(width, height) {
++function generateHeight(width: number, height: number) {
+ const data = [],
+ perlin = new ImprovedNoise(),
+ size = width * height,
+@@ -166,7 +166,7 @@ function generateHeight(width, height) {
+ return data;
+ }
+
+-function getY(x, z) {
++function getY(x: number, z: number) {
+ return (data[x + z * worldWidth] * 0.15) | 0;
+ }
+
+diff --git a/examples-testing/examples/webgl_geometry_nurbs.ts b/examples-testing/examples/webgl_geometry_nurbs.ts
+index 8336ef0..d9c564d 100644
+--- a/examples-testing/examples/webgl_geometry_nurbs.ts
++++ b/examples-testing/examples/webgl_geometry_nurbs.ts
+@@ -6,10 +6,10 @@ import { NURBSCurve } from 'three/addons/curves/NURBSCurve.js';
+ import { NURBSSurface } from 'three/addons/curves/NURBSSurface.js';
+ import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js';
+
+-let container, stats;
++let container: HTMLDivElement, stats: Stats;
+
+-let camera, scene, renderer;
+-let group;
++let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
++let group: THREE.Group;
+
+ let targetRotation = 0;
+ let targetRotationOnPointerDown = 0;
+@@ -78,7 +78,7 @@ function init() {
+ group.add(nurbsLine);
+
+ const nurbsControlPointsGeometry = new THREE.BufferGeometry();
+- nurbsControlPointsGeometry.setFromPoints(nurbsCurve.controlPoints);
++ nurbsControlPointsGeometry.setFromPoints(nurbsCurve.controlPoints as THREE.Vector3[]);
+
+ const nurbsControlPointsMaterial = new THREE.LineBasicMaterial({
+ color: 0x333333,
+@@ -123,7 +123,7 @@ function init() {
+ map.anisotropy = 16;
+ map.colorSpace = THREE.SRGBColorSpace;
+
+- function getSurfacePoint(u, v, target) {
++ function getSurfacePoint(u: number, v: number, target: THREE.Vector3) {
+ return nurbsSurface.getPoint(u, v, target);
+ }
+
+@@ -163,7 +163,7 @@ function onWindowResize() {
+
+ //
+
+-function onPointerDown(event) {
++function onPointerDown(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ pointerXOnPointerDown = event.clientX - windowHalfX;
+@@ -173,7 +173,7 @@ function onPointerDown(event) {
+ document.addEventListener('pointerup', onPointerUp);
+ }
+
+-function onPointerMove(event) {
++function onPointerMove(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ pointerX = event.clientX - windowHalfX;
+@@ -181,7 +181,7 @@ function onPointerMove(event) {
+ targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02;
+ }
+
+-function onPointerUp() {
++function onPointerUp(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ document.removeEventListener('pointermove', onPointerMove);
+diff --git a/examples-testing/examples/webgl_geometry_shapes.ts b/examples-testing/examples/webgl_geometry_shapes.ts
+index c3ff3a7..ff3abca 100644
+--- a/examples-testing/examples/webgl_geometry_shapes.ts
++++ b/examples-testing/examples/webgl_geometry_shapes.ts
+@@ -2,11 +2,11 @@ import * as THREE from 'three';
+
+ import Stats from 'three/addons/libs/stats.module.js';
+
+-let container, stats;
++let container: HTMLDivElement, stats: Stats;
+
+-let camera, scene, renderer;
++let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+
+-let group;
++let group: THREE.Group;
+
+ let targetRotation = 0;
+ let targetRotationOnPointerDown = 0;
+@@ -46,11 +46,22 @@ function init() {
+ texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
+ texture.repeat.set(0.008, 0.008);
+
+- function addShape(shape, extrudeSettings, color, x, y, z, rx, ry, rz, s) {
++ function addShape(
++ shape: THREE.Shape,
++ extrudeSettings: THREE.ExtrudeGeometryOptions,
++ color: number,
++ x: number,
++ y: number,
++ z: number,
++ rx: number,
++ ry: number,
++ rz: number,
++ s: number,
++ ) {
+ // flat shape with texture
+ // note: default UVs generated by THREE.ShapeGeometry are simply the x- and y-coordinates of the vertices
+
+- let geometry = new THREE.ShapeGeometry(shape);
++ let geometry: THREE.BufferGeometry = new THREE.ShapeGeometry(shape);
+
+ let mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({ side: THREE.DoubleSide, map: texture }));
+ mesh.position.set(x, y, z - 175);
+@@ -81,7 +92,17 @@ function init() {
+ addLineShape(shape, color, x, y, z, rx, ry, rz, s);
+ }
+
+- function addLineShape(shape, color, x, y, z, rx, ry, rz, s) {
++ function addLineShape(
++ shape: THREE.Path,
++ color: number,
++ x: number,
++ y: number,
++ z: number,
++ rx: number,
++ ry: number,
++ rz: number,
++ s: number,
++ ) {
+ // lines
+
+ shape.autoClose = true;
+@@ -325,7 +346,7 @@ function onWindowResize() {
+
+ //
+
+-function onPointerDown(event) {
++function onPointerDown(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ pointerXOnPointerDown = event.clientX - windowHalfX;
+@@ -335,7 +356,7 @@ function onPointerDown(event) {
+ document.addEventListener('pointerup', onPointerUp);
+ }
+
+-function onPointerMove(event) {
++function onPointerMove(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ pointerX = event.clientX - windowHalfX;
+@@ -343,7 +364,7 @@ function onPointerMove(event) {
+ targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02;
+ }
+
+-function onPointerUp() {
++function onPointerUp(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ document.removeEventListener('pointermove', onPointerMove);
+diff --git a/examples-testing/examples/webgl_geometry_teapot.ts b/examples-testing/examples/webgl_geometry_teapot.ts
+index 4c884a5..b94b16d 100644
+--- a/examples-testing/examples/webgl_geometry_teapot.ts
++++ b/examples-testing/examples/webgl_geometry_teapot.ts
+@@ -5,22 +5,30 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
+ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+ import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js';
+
+-let camera, scene, renderer;
++let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+ let cameraControls;
+-let effectController;
++let effectController: {
++ newTess: number;
++ bottom: boolean;
++ lid: boolean;
++ body: boolean;
++ fitLid: boolean;
++ nonblinn: boolean;
++ newShading: string;
++};
+ const teapotSize = 300;
+-let ambientLight, light;
++let ambientLight: THREE.AmbientLight, light: THREE.DirectionalLight;
+
+ let tess = -1; // force initialization
+-let bBottom;
+-let bLid;
+-let bBody;
+-let bFitLid;
+-let bNonBlinn;
+-let shading;
+-
+-let teapot, textureCube;
+-const materials = {};
++let bBottom: boolean;
++let bLid: boolean;
++let bBody: boolean;
++let bFitLid: boolean;
++let bNonBlinn: boolean;
++let shading: string;
++
++let teapot: THREE.Mesh, textureCube: THREE.CubeTexture;
++const materials: Record = {};
+
+ init();
+ render();
+diff --git a/examples-testing/examples/webgl_geometry_terrain.ts b/examples-testing/examples/webgl_geometry_terrain.ts
+index b63a363..965d70a 100644
+--- a/examples-testing/examples/webgl_geometry_terrain.ts
++++ b/examples-testing/examples/webgl_geometry_terrain.ts
+@@ -5,9 +5,9 @@ import Stats from 'three/addons/libs/stats.module.js';
+ import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
+ import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js';
+
+-let container, stats;
+-let camera, controls, scene, renderer;
+-let mesh, texture;
++let container: HTMLElement, stats: Stats;
++let camera: THREE.PerspectiveCamera, controls: FirstPersonControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
++let mesh: THREE.Mesh, texture: THREE.CanvasTexture;
+
+ const worldWidth = 256,
+ worldDepth = 256;
+@@ -17,7 +17,7 @@ init();
+ animate();
+
+ function init() {
+- container = document.getElementById('container');
++ container = document.getElementById('container')!;
+
+ camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000);
+
+@@ -73,7 +73,7 @@ function onWindowResize() {
+ controls.handleResize();
+ }
+
+-function generateHeight(width, height) {
++function generateHeight(width: number, height: number) {
+ let seed = Math.PI / 4;
+ window.Math.random = function () {
+ const x = Math.sin(seed++) * 10000;
+@@ -100,7 +100,7 @@ function generateHeight(width, height) {
+ return data;
+ }
+
+-function generateTexture(data, width, height) {
++function generateTexture(data: Uint8Array, width: number, height: number) {
+ let context, image, imageData, shade;
+
+ const vector3 = new THREE.Vector3(0, 0, 0);
+@@ -112,7 +112,7 @@ function generateTexture(data, width, height) {
+ canvas.width = width;
+ canvas.height = height;
+
+- context = canvas.getContext('2d');
++ context = canvas.getContext('2d')!;
+ context.fillStyle = '#000';
+ context.fillRect(0, 0, width, height);
+
+@@ -140,7 +140,7 @@ function generateTexture(data, width, height) {
+ canvasScaled.width = width * 4;
+ canvasScaled.height = height * 4;
+
+- context = canvasScaled.getContext('2d');
++ context = canvasScaled.getContext('2d')!;
+ context.scale(4, 4);
+ context.drawImage(canvas, 0, 0);
+
+diff --git a/examples-testing/examples/webgl_geometry_terrain_raycast.ts b/examples-testing/examples/webgl_geometry_terrain_raycast.ts
+index 4e9a7d3..86071e3 100644
+--- a/examples-testing/examples/webgl_geometry_terrain_raycast.ts
++++ b/examples-testing/examples/webgl_geometry_terrain_raycast.ts
+@@ -5,18 +5,18 @@ import Stats from 'three/addons/libs/stats.module.js';
+ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+ import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js';
+
+-let container, stats;
++let container: HTMLElement, stats: Stats;
+
+-let camera, controls, scene, renderer;
++let camera: THREE.PerspectiveCamera, controls: OrbitControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+
+-let mesh, texture;
++let mesh: THREE.Mesh, texture: THREE.CanvasTexture;
+
+ const worldWidth = 256,
+ worldDepth = 256,
+ worldHalfWidth = worldWidth / 2,
+ worldHalfDepth = worldDepth / 2;
+
+-let helper;
++let helper: THREE.Mesh;
+
+ const raycaster = new THREE.Raycaster();
+ const pointer = new THREE.Vector2();
+@@ -25,7 +25,7 @@ init();
+ animate();
+
+ function init() {
+- container = document.getElementById('container');
++ container = document.getElementById('container')!;
+ container.innerHTML = '';
+
+ renderer = new THREE.WebGLRenderer({ antialias: true });
+@@ -94,7 +94,7 @@ function onWindowResize() {
+ renderer.setSize(window.innerWidth, window.innerHeight);
+ }
+
+-function generateHeight(width, height) {
++function generateHeight(width: number, height: number) {
+ const size = width * height,
+ data = new Uint8Array(size),
+ perlin = new ImprovedNoise(),
+@@ -115,7 +115,7 @@ function generateHeight(width, height) {
+ return data;
+ }
+
+-function generateTexture(data, width, height) {
++function generateTexture(data: Uint8Array, width: number, height: number) {
+ // bake lighting into texture
+
+ let context, image, imageData, shade;
+@@ -129,7 +129,7 @@ function generateTexture(data, width, height) {
+ canvas.width = width;
+ canvas.height = height;
+
+- context = canvas.getContext('2d');
++ context = canvas.getContext('2d')!;
+ context.fillStyle = '#000';
+ context.fillRect(0, 0, width, height);
+
+@@ -157,7 +157,7 @@ function generateTexture(data, width, height) {
+ canvasScaled.width = width * 4;
+ canvasScaled.height = height * 4;
+
+- context = canvasScaled.getContext('2d');
++ context = canvasScaled.getContext('2d')!;
+ context.scale(4, 4);
+ context.drawImage(canvas, 0, 0);
+
+@@ -190,7 +190,7 @@ function render() {
+ renderer.render(scene, camera);
+ }
+
+-function onPointerMove(event) {
++function onPointerMove(event: PointerEvent) {
+ pointer.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1;
+ pointer.y = -(event.clientY / renderer.domElement.clientHeight) * 2 + 1;
+ raycaster.setFromCamera(pointer, camera);
+@@ -201,7 +201,7 @@ function onPointerMove(event) {
+ // Toggle rotation bool for meshes that we clicked
+ if (intersects.length > 0) {
+ helper.position.set(0, 0, 0);
+- helper.lookAt(intersects[0].face.normal);
++ helper.lookAt(intersects[0].face!.normal);
+
+ helper.position.copy(intersects[0].point);
+ }
+diff --git a/examples-testing/examples/webgl_geometry_text.ts b/examples-testing/examples/webgl_geometry_text.ts
+index 51a639b..90087e4 100644
+--- a/examples-testing/examples/webgl_geometry_text.ts
++++ b/examples-testing/examples/webgl_geometry_text.ts
+@@ -1,23 +1,23 @@
+ import * as THREE from 'three';
+
+-import { FontLoader } from 'three/addons/loaders/FontLoader.js';
++import { Font, FontLoader } from 'three/addons/loaders/FontLoader.js';
+ import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
+
+ import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
+
+ THREE.Cache.enabled = true;
+
+-let container;
++let container: HTMLDivElement;
+
+-let camera, cameraTarget, scene, renderer;
++let camera: THREE.PerspectiveCamera, cameraTarget: THREE.Vector3, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+
+-let group, textMesh1, textMesh2, textGeo, materials;
++let group: THREE.Group, textMesh1: THREE.Mesh, textMesh2: THREE.Mesh, textGeo, materials: THREE.MeshPhongMaterial[];
+
+ let firstLetter = true;
+
+ let text = 'three.js',
+ bevelEnabled = true,
+- font = undefined,
++ font: Font | undefined = undefined,
+ fontName = 'optimer', // helvetiker, optimer, gentilis, droid sans, droid serif
+ fontWeight = 'bold'; // normal bold
+
+@@ -43,11 +43,11 @@ const weightMap = {
+ bold: 1,
+ };
+
+-const reverseFontMap = [];
+-const reverseWeightMap = [];
++const reverseFontMap: string[] = [];
++const reverseWeightMap: string[] = [];
+
+-for (const i in fontMap) reverseFontMap[fontMap[i]] = i;
+-for (const i in weightMap) reverseWeightMap[weightMap[i]] = i;
++for (const i in fontMap) reverseFontMap[fontMap[i as keyof typeof fontMap]] = i;
++for (const i in weightMap) reverseWeightMap[weightMap[i as keyof typeof weightMap]] = i;
+
+ let targetRotation = 0;
+ let targetRotationOnPointerDown = 0;
+@@ -180,7 +180,7 @@ function onWindowResize() {
+
+ //
+
+-function onDocumentKeyDown(event) {
++function onDocumentKeyDown(event: KeyboardEvent) {
+ if (firstLetter) {
+ firstLetter = false;
+ text = '';
+@@ -200,7 +200,7 @@ function onDocumentKeyDown(event) {
+ }
+ }
+
+-function onDocumentKeyPress(event) {
++function onDocumentKeyPress(event: KeyboardEvent) {
+ const keyCode = event.which;
+
+ // backspace
+@@ -226,7 +226,7 @@ function loadFont() {
+
+ function createText() {
+ textGeo = new TextGeometry(text, {
+- font: font,
++ font: font!,
+
+ size: size,
+ height: height,
+@@ -239,7 +239,7 @@ function createText() {
+
+ textGeo.computeBoundingBox();
+
+- const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x);
++ const centerOffset = -0.5 * (textGeo.boundingBox!.max.x - textGeo.boundingBox!.min.x);
+
+ textMesh1 = new THREE.Mesh(textGeo, materials);
+
+@@ -275,7 +275,7 @@ function refreshText() {
+ createText();
+ }
+
+-function onPointerDown(event) {
++function onPointerDown(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ pointerXOnPointerDown = event.clientX - windowHalfX;
+@@ -285,7 +285,7 @@ function onPointerDown(event) {
+ document.addEventListener('pointerup', onPointerUp);
+ }
+
+-function onPointerMove(event) {
++function onPointerMove(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ pointerX = event.clientX - windowHalfX;
+@@ -293,7 +293,7 @@ function onPointerMove(event) {
+ targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02;
+ }
+
+-function onPointerUp() {
++function onPointerUp(event: PointerEvent) {
+ if (event.isPrimary === false) return;
+
+ document.removeEventListener('pointermove', onPointerMove);
+diff --git a/examples-testing/examples/webgl_geometry_text_shapes.ts b/examples-testing/examples/webgl_geometry_text_shapes.ts
+index adfb600..141b618 100644
+--- a/examples-testing/examples/webgl_geometry_text_shapes.ts
++++ b/examples-testing/examples/webgl_geometry_text_shapes.ts
+@@ -3,7 +3,7 @@ import * as THREE from 'three';
+ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+ import { FontLoader } from 'three/addons/loaders/FontLoader.js';
+
+-let camera, scene, renderer;
++let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+
+ init();
+
+@@ -32,13 +32,13 @@ function init() {
+
+ const message = ' Three.js\nSimple text.';
+
+- const shapes = font.generateShapes(message, 100);
++ const shapes: THREE.Path[] = font.generateShapes(message, 100);
+
+- const geometry = new THREE.ShapeGeometry(shapes);
++ const geometry = new THREE.ShapeGeometry(shapes as THREE.Shape[]);
+
+ geometry.computeBoundingBox();
+
+- const xMid = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x);
++ const xMid = -0.5 * (geometry.boundingBox!.max.x - geometry.boundingBox!.min.x);
+
+ geometry.translate(xMid, 0, 0);
+
+@@ -50,10 +50,10 @@ function init() {
+
+ // make line shape ( N.B. edge view remains visible )
+
+- const holeShapes = [];
++ const holeShapes: THREE.Path[] = [];
+
+ for (let i = 0; i < shapes.length; i++) {
+- const shape = shapes[i];
++ const shape = shapes[i] as THREE.Shape;
+
+ if (shape.holes && shape.holes.length > 0) {
+ for (let j = 0; j < shape.holes.length; j++) {
+diff --git a/examples-testing/examples/webgl_geometry_text_stroke.ts b/examples-testing/examples/webgl_geometry_text_stroke.ts
+index 9a19832..e47d7b6 100644
+--- a/examples-testing/examples/webgl_geometry_text_stroke.ts
++++ b/examples-testing/examples/webgl_geometry_text_stroke.ts
+@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+ import { SVGLoader } from 'three/addons/loaders/SVGLoader.js';
+ import { FontLoader } from 'three/addons/loaders/FontLoader.js';
+
+-let camera, scene, renderer;
++let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
+
+ init();
+
+@@ -33,13 +33,13 @@ function init() {
+
+ const message = ' Three.js\nStroke text.';
+
+- const shapes = font.generateShapes(message, 100);
++ const shapes: THREE.Path[] = font.generateShapes(message, 100);
+
+- const geometry = new THREE.ShapeGeometry(shapes);
++ const geometry = new THREE.ShapeGeometry(shapes as THREE.Shape[]);
+
+ geometry.computeBoundingBox();
+
+- const xMid = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x);
++ const xMid = -0.5 * (geometry.boundingBox!.max.x - geometry.boundingBox!.min.x);
+
+ geometry.translate(xMid, 0, 0);
+
+@@ -51,10 +51,10 @@ function init() {
+
+ // make line shape ( N.B. edge view remains visible )
+
+- const holeShapes = [];
++ const holeShapes: THREE.Path[] = [];
+
+ for (let i = 0; i < shapes.length; i++) {
+- const shape = shapes[i];
++ const shape = shapes[i] as THREE.Shape;
+
+ if (shape.holes && shape.holes.length > 0) {
+ for (let j = 0; j < shape.holes.length; j++) {
diff --git a/examples-testing/examples/webgl_gpgpu_birds.ts b/examples-testing/examples/webgl_gpgpu_birds.ts
index ecf53eb..4f865bd 100644
--- a/examples-testing/examples/webgl_gpgpu_birds.ts
diff --git a/examples-testing/index.js b/examples-testing/index.js
index 839b65f41..ee6263665 100644
--- a/examples-testing/index.js
+++ b/examples-testing/index.js
@@ -29,24 +29,24 @@ const files = {
'webgl_framebuffer_texture',
'webgl_geometries',
'webgl_geometries_parametric',
- // 'webgl_geometry_colors',
- // 'webgl_geometry_colors_lookuptable',
- // 'webgl_geometry_convex',
+ 'webgl_geometry_colors',
+ 'webgl_geometry_colors_lookuptable',
+ 'webgl_geometry_convex',
// 'webgl_geometry_csg',
- // 'webgl_geometry_cube',
- // 'webgl_geometry_dynamic',
- // 'webgl_geometry_extrude_shapes',
- // 'webgl_geometry_extrude_splines',
- // 'webgl_geometry_minecraft',
- // 'webgl_geometry_nurbs',
- // 'webgl_geometry_shapes',
+ 'webgl_geometry_cube',
+ 'webgl_geometry_dynamic',
+ 'webgl_geometry_extrude_shapes',
+ 'webgl_geometry_extrude_splines',
+ 'webgl_geometry_minecraft',
+ 'webgl_geometry_nurbs',
+ 'webgl_geometry_shapes',
// 'webgl_geometry_spline_editor',
- // 'webgl_geometry_teapot',
- // 'webgl_geometry_terrain',
- // 'webgl_geometry_terrain_raycast',
- // 'webgl_geometry_text',
- // 'webgl_geometry_text_shapes',
- // 'webgl_geometry_text_stroke',
+ 'webgl_geometry_teapot',
+ 'webgl_geometry_terrain',
+ 'webgl_geometry_terrain_raycast',
+ 'webgl_geometry_text',
+ 'webgl_geometry_text_shapes',
+ 'webgl_geometry_text_stroke',
// 'webgl_helpers',
// 'webgl_instancing_dynamic',
// 'webgl_instancing_performance',
diff --git a/types/three/examples/jsm/curves/NURBSCurve.d.ts b/types/three/examples/jsm/curves/NURBSCurve.d.ts
index 3060b21e4..8df4a2c0b 100644
--- a/types/three/examples/jsm/curves/NURBSCurve.d.ts
+++ b/types/three/examples/jsm/curves/NURBSCurve.d.ts
@@ -1,11 +1,17 @@
import { Curve, Vector2, Vector3, Vector4 } from '../../../src/Three.js';
export class NURBSCurve extends Curve {
+ degree: number;
+ knots: number[];
+ controlPoints: Vector2[] | Vector3[] | Vector4[];
+ startKnot: number;
+ endKnot: number;
+
constructor(
degree: number,
knots: number[],
controlPoints: Vector2[] | Vector3[] | Vector4[],
- startKnot: number,
- endKnot: number,
+ startKnot?: number,
+ endKnot?: number,
);
}
diff --git a/types/three/src/extras/core/Path.d.ts b/types/three/src/extras/core/Path.d.ts
index 8a298fadf..fd6fda039 100644
--- a/types/three/src/extras/core/Path.d.ts
+++ b/types/three/src/extras/core/Path.d.ts
@@ -75,7 +75,7 @@ export class Path extends CurvePath {
aStartAngle: number,
aEndAngle: number,
aClockwise: boolean,
- aRotation: number,
+ aRotation?: number,
): this;
/**