@adatechnology/game-vegetation-three 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../game-shapes/src/color.ts","../../game-shapes/src/hash.ts","../../game-shapes/src/math.ts","../../game-shapes/src/primitives/three-generators.ts","../../game-shapes/src/primitives/difference.ts","../../game-shapes/src/primitives/earcut.ts","../../game-shapes/src/primitives/extrude.ts","../../game-shapes/src/primitives/index.ts","../../game-shapes/src/random.ts","../../game-shapes/src/registry.ts","../../game-shapes/schema/shape.schema.json","../../game-shapes/src/schema.ts","../../game-shapes/src/generate.ts","../../game-shapes/src/merge.ts","../../game-shapes/src/worker.ts","../../game-shapes-three/src/geometry.ts","../../game-shapes-three/src/namespace.ts","../../game-shapes-three/src/object.ts","../../game-shapes-three/src/merge-by-material.ts","../../game-vegetation/src/destruction.ts","../../game-vegetation/src/rng.ts","../../game-vegetation/src/math.ts","../../game-vegetation/src/color.ts","../../game-vegetation/src/geometry/builder.ts","../../game-vegetation/src/geometry/branches.ts","../../game-vegetation/src/geometry/tube.ts","../../game-vegetation/src/geometry/wood.ts","../../game-vegetation/src/geometry/ico.ts","../../game-vegetation/src/geometry/leaf.ts","../../game-vegetation/src/geometry/shell.ts","../../game-vegetation/src/geometry/flower.ts","../../game-vegetation/src/archetypes/pieces.ts","../../game-vegetation/src/archetypes/shared.ts","../../game-vegetation/src/archetypes/dead-tree.ts","../../game-vegetation/src/archetypes/tree-styles.ts","../../game-vegetation/src/archetypes/broadleaf-tree.ts","../../game-vegetation/src/archetypes/flower-plant.ts","../../game-vegetation/src/geometry/blade.ts","../../game-vegetation/src/archetypes/grass-tuft.ts","../../game-vegetation/src/archetypes/fern.ts","../../game-vegetation/src/geometry/succulent.ts","../../game-vegetation/src/archetypes/rosette.ts","../../game-vegetation/src/geometry/spines.ts","../../game-vegetation/src/archetypes/cactus-columnar.ts","../../game-vegetation/src/archetypes/cactus-paddle.ts","../../game-vegetation/src/archetypes/cactus-globe.ts","../../game-vegetation/src/geometry/fronds.ts","../../game-vegetation/src/archetypes/palm.ts","../../game-vegetation/src/archetypes/banana.ts","../../game-vegetation/src/geometry/boxshell.ts","../../game-vegetation/src/archetypes/shrub.ts","../../game-vegetation/src/archetypes/conifer.ts","../../game-vegetation/src/archetypes/vine.ts","../../game-vegetation/src/archetypes/potted.ts","../../game-vegetation/src/generate.ts","../../game-vegetation/src/lot.ts","../../game-vegetation/src/scatter.ts","../../game-vegetation/src/validate.ts","../../game-vegetation/src/three/types.ts","../../game-vegetation/src/three/materials.ts","../../game-vegetation/src/three/objects.ts","../../game-vegetation-species/data/species/trees.json","../../game-vegetation-species/data/species/palms.json","../../game-vegetation-species/data/species/shrubs.json","../../game-vegetation-species/data/species/flowers.json","../../game-vegetation-species/data/species/cacti.json","../../game-vegetation-species/data/species/succulents.json","../../game-vegetation-species/data/species/grasses.json","../../game-vegetation-species/data/species/vines.json","../../game-vegetation-species/data/species/potted.json","../../game-vegetation-species/data/locales/pt-BR.json","../../game-vegetation-species/data/locales/en.json","../../game-vegetation-species/data/regions/br.json","../../game-vegetation-species/data/regions/default.json","../../game-vegetation-species/src/rules.ts","../../game-vegetation-species/src/index.ts","../src/test-area/nursery.ts","../src/test-area/plants.ts","../src/test-area/scenarios.ts","../src/test-area/text.ts","../src/test-area/module.ts"],"sourcesContent":["export * from './test-area'\n","import type { Color } from './types'\n\n/** A colour as `0xRRGGBB`: numbers as given (floored, as three's `setHex`), `'#rrggbb'` strings parsed. */\nexport function colorHex(color: Color | undefined, fallback = 0xffffff): number {\n if (color === undefined) return fallback\n if (typeof color === 'number') return Math.floor(color)\n const match = /^#([0-9a-fA-F]{6})$/.exec(color)\n if (!match) throw new Error(`game-shapes: colour \"${color}\" is not 0xRRGGBB or #rrggbb`)\n return parseInt(match[1] as string, 16)\n}\n\n/** three's `SRGBToLinear` (r160 `ColorManagement`), the same constants. */\nexport const srgbToLinear = (c: number): number => (c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4))\n\n/**\n * The rgb floats of a hex colour as three's `Color.setHex` stores them: the channels over 255 (`'srgb'`), converted to the linear working space\n * when colour management is on (`'linear'`).\n */\nexport function colorChannels(hex: number, space: 'linear' | 'srgb'): [number, number, number] {\n const r = ((hex >> 16) & 255) / 255\n const g = ((hex >> 8) & 255) / 255\n const b = (hex & 255) / 255\n return space === 'linear' ? [srgbToLinear(r), srgbToLinear(g), srgbToLinear(b)] : [r, g, b]\n}\n","/**\n * Canonical JSON (keys sorted, `undefined` left out, `-0` kept as `-0`, typed arrays as plain lists) and a 64-bit FNV-1a of it in two 32-bit\n * lanes: the key a shape is cached and shared by.\n */\nexport function canonicalJson(value: unknown): string {\n if (value === null) return 'null'\n if (typeof value === 'number') return Object.is(value, -0) ? '-0' : Number.isFinite(value) ? String(value) : JSON.stringify(String(value))\n if (typeof value === 'string') return JSON.stringify(value)\n if (typeof value === 'boolean') return value ? 'true' : 'false'\n if (typeof value === 'function') throw new Error('game-shapes: a function cannot be part of a shape (register it as a generator)')\n if (ArrayBuffer.isView(value)) return canonicalJson(Array.from(value as unknown as ArrayLike<number>))\n if (Array.isArray(value)) return `[${value.map((item) => (item === undefined ? 'null' : canonicalJson(item))).join(',')}]`\n if (typeof value === 'object') {\n const record = value as Record<string, unknown>\n const keys = Object.keys(record).filter((key) => record[key] !== undefined).sort()\n return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(',')}}`\n }\n return 'null'\n}\n\nconst lane = (text: string, offset: number, prime: number): string => {\n let hash = offset\n for (let index = 0; index < text.length; index++) {\n hash ^= text.charCodeAt(index)\n hash = Math.imul(hash, prime)\n }\n return (hash >>> 0).toString(16).padStart(8, '0')\n}\n\n/** 64-bit FNV-1a of a text as 16 hex digits (two independent 32-bit lanes). */\nexport const hash64 = (text: string): string => lane(text, 0x811c9dc5, 0x01000193) + lane(text, 0x050c5d1f, 0x5bd1e995)\n\n/** `hash64(canonicalJson(value))`. */\nexport const hashValue = (value: unknown): string => hash64(canonicalJson(value))\n","/*\n * Matrix and quaternion arithmetic as three.js r160 does it (MIT, https://github.com/mrdoob/three.js): the same expressions in the same order, so a\n * vertex baked here has the same bits as one baked by `Matrix4.compose` / `multiplyMatrices` / `Matrix3.getNormalMatrix` / `Vector3.normalize`.\n * Matrices are column-major arrays of 16 (4 x 4) or 9 (3 x 3) numbers, the layout of three's `elements`.\n */\nimport type { Mat4, RotationOrder, Transform, Vec3 } from './types'\n\nexport type Matrix4 = number[]\nexport type Matrix3 = number[]\n\nexport const identity4 = (): Matrix4 => [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]\n\n/** `Quaternion.setFromEuler` (x, y, z, w). */\nexport function quaternionFromEuler(x: number, y: number, z: number, order: RotationOrder = 'XYZ'): [number, number, number, number] {\n const cos = Math.cos\n const sin = Math.sin\n const c1 = cos(x / 2)\n const c2 = cos(y / 2)\n const c3 = cos(z / 2)\n const s1 = sin(x / 2)\n const s2 = sin(y / 2)\n const s3 = sin(z / 2)\n switch (order) {\n case 'XYZ':\n return [s1 * c2 * c3 + c1 * s2 * s3, c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]\n case 'YXZ':\n return [s1 * c2 * c3 + c1 * s2 * s3, c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 - s1 * s2 * c3, c1 * c2 * c3 + s1 * s2 * s3]\n case 'ZXY':\n return [s1 * c2 * c3 - c1 * s2 * s3, c1 * s2 * c3 + s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]\n case 'ZYX':\n return [s1 * c2 * c3 - c1 * s2 * s3, c1 * s2 * c3 + s1 * c2 * s3, c1 * c2 * s3 - s1 * s2 * c3, c1 * c2 * c3 + s1 * s2 * s3]\n case 'YZX':\n return [s1 * c2 * c3 + c1 * s2 * s3, c1 * s2 * c3 + s1 * c2 * s3, c1 * c2 * s3 - s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]\n case 'XZY':\n return [s1 * c2 * c3 - c1 * s2 * s3, c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 + s1 * s2 * s3]\n default:\n throw new Error(`game-shapes: unknown rotation order \"${String(order)}\"`)\n }\n}\n\n/** `Matrix4.compose(position, quaternion, scale)`. */\nexport function compose(px: number, py: number, pz: number, q: readonly [number, number, number, number], sx: number, sy: number, sz: number): Matrix4 {\n const [x, y, z, w] = q\n const x2 = x + x\n const y2 = y + y\n const z2 = z + z\n const xx = x * x2\n const xy = x * y2\n const xz = x * z2\n const yy = y * y2\n const yz = y * z2\n const zz = z * z2\n const wx = w * x2\n const wy = w * y2\n const wz = w * z2\n return [\n (1 - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n (xy - wz) * sy, (1 - (xx + zz)) * sy, (yz + wx) * sy, 0,\n (xz + wy) * sz, (yz - wx) * sz, (1 - (xx + yy)) * sz, 0,\n px, py, pz, 1,\n ]\n}\n\n/** `Matrix4.makeRotationY(theta)` followed by `setPosition(x, y, z)`. */\nexport function headingMatrix(theta: number, x = 0, y = 0, z = 0): Matrix4 {\n const c = Math.cos(theta)\n const s = Math.sin(theta)\n return [c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, x, y, z, 1]\n}\n\n/** `Matrix4.multiplyMatrices(a, b)`: a x b. */\nexport function multiply(ae: readonly number[], be: readonly number[]): Matrix4 {\n const a11 = ae[0]!, a12 = ae[4]!, a13 = ae[8]!, a14 = ae[12]!\n const a21 = ae[1]!, a22 = ae[5]!, a23 = ae[9]!, a24 = ae[13]!\n const a31 = ae[2]!, a32 = ae[6]!, a33 = ae[10]!, a34 = ae[14]!\n const a41 = ae[3]!, a42 = ae[7]!, a43 = ae[11]!, a44 = ae[15]!\n const b11 = be[0]!, b12 = be[4]!, b13 = be[8]!, b14 = be[12]!\n const b21 = be[1]!, b22 = be[5]!, b23 = be[9]!, b24 = be[13]!\n const b31 = be[2]!, b32 = be[6]!, b33 = be[10]!, b34 = be[14]!\n const b41 = be[3]!, b42 = be[7]!, b43 = be[11]!, b44 = be[15]!\n return [\n a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41,\n a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41,\n a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41,\n a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41,\n a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42,\n a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42,\n a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42,\n a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42,\n a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43,\n a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43,\n a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43,\n a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43,\n a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44,\n a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44,\n a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44,\n a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44,\n ]\n}\n\n/** `Matrix3.getNormalMatrix(m)`: the inverse transpose of the upper 3 x 3 (all zeros when singular, as three). */\nexport function normalMatrix(me: readonly number[]): Matrix3 {\n // setFromMatrix4\n const n11 = me[0]!, n21 = me[1]!, n31 = me[2]!\n const n12 = me[4]!, n22 = me[5]!, n32 = me[6]!\n const n13 = me[8]!, n23 = me[9]!, n33 = me[10]!\n // invert\n const t11 = n33 * n22 - n32 * n23\n const t12 = n32 * n13 - n33 * n12\n const t13 = n23 * n12 - n22 * n13\n const det = n11 * t11 + n21 * t12 + n31 * t13\n if (det === 0) return [0, 0, 0, 0, 0, 0, 0, 0, 0]\n const detInv = 1 / det\n const te = [\n t11 * detInv,\n (n31 * n23 - n33 * n21) * detInv,\n (n32 * n21 - n31 * n22) * detInv,\n t12 * detInv,\n (n33 * n11 - n31 * n13) * detInv,\n (n31 * n12 - n32 * n11) * detInv,\n t13 * detInv,\n (n21 * n13 - n23 * n11) * detInv,\n (n22 * n11 - n21 * n12) * detInv,\n ]\n // transpose\n let tmp = te[1]!\n te[1] = te[3]!\n te[3] = tmp\n tmp = te[2]!\n te[2] = te[6]!\n te[6] = tmp\n tmp = te[5]!\n te[5] = te[7]!\n te[7] = tmp\n return te\n}\n\n/** True when the last row is (0, 0, 0, 1): `applyMatrix4`'s divide by w is then a multiply by exactly 1. */\nexport const isAffine = (e: readonly number[]): boolean => e[3] === 0 && e[7] === 0 && e[11] === 0 && e[15] === 1\n\n/** `Vector3.applyMatrix4`. */\nexport function transformPoint(e: readonly number[], x: number, y: number, z: number): [number, number, number] {\n const w = 1 / (e[3]! * x + e[7]! * y + e[11]! * z + e[15]!)\n return [(e[0]! * x + e[4]! * y + e[8]! * z + e[12]!) * w, (e[1]! * x + e[5]! * y + e[9]! * z + e[13]!) * w, (e[2]! * x + e[6]! * y + e[10]! * z + e[14]!) * w]\n}\n\nconst toVec3 = (scale: number | Vec3 | undefined): Vec3 => (scale === undefined ? [1, 1, 1] : typeof scale === 'number' ? [scale, scale, scale] : scale)\n\n/** True when the transform has no field set. */\nexport const isIdentityTransform = (t: Transform): boolean =>\n t.matrix === undefined && t.heading === undefined && t.position === undefined && t.rotation === undefined && t.scale === undefined\n\n/** The local matrix of a transform, or `null` when it has none. */\nexport function matrixOf(t: Transform): Matrix4 | null {\n if (t.matrix !== undefined) return [...t.matrix]\n if (t.heading !== undefined) {\n const p = t.position ?? [0, 0, 0]\n return headingMatrix(t.heading, p[0], p[1], p[2])\n }\n if (t.position === undefined && t.rotation === undefined && t.scale === undefined) return null\n const p = t.position ?? [0, 0, 0]\n const r = t.rotation ?? [0, 0, 0]\n const s = toVec3(t.scale)\n return compose(p[0], p[1], p[2], quaternionFromEuler(r[0], r[1], r[2], t.rotationOrder ?? 'XYZ'), s[0], s[1], s[2])\n}\n\n/** The matrix as given, as a plain array (for `ShapePart.matrix`). */\nexport const asMat4 = (m: Matrix4 | null): Mat4 => (m ? [...m] : identity4())\n","/*\n * The geometry generators of three.js r160 (MIT, https://github.com/mrdoob/three.js, src/geometries/*.js), ported line by line: the same loops,\n * the same expressions in the same order, numbers pushed into plain arrays and stored as Float32 at the end, exactly as `Float32BufferAttribute`\n * does. A test compares every array of every generator with three's, bit for bit, over a grid of parameters.\n */\nimport type { GeometryGroup, PrimitiveBuffers } from '../types'\n\nexport interface Arrays {\n vertices: number[]\n normals: number[]\n uvs: number[]\n indices: number[] | null\n groups: GeometryGroup[]\n}\n\n/** three's `arrayNeedsUint32`: 32-bit indices once any index reaches 65535. */\nexport function needsUint32(array: ArrayLike<number>): boolean {\n for (let i = array.length - 1; i >= 0; --i) if ((array[i] as number) >= 65535) return true\n return false\n}\n\nexport const indexArray = (indices: ArrayLike<number>): Uint16Array | Uint32Array => (needsUint32(indices) ? new Uint32Array(indices) : new Uint16Array(indices))\n\nexport function pack(type: string, parameters: Record<string, unknown>, a: Arrays): PrimitiveBuffers {\n return {\n type,\n parameters,\n positions: new Float32Array(a.vertices),\n normals: new Float32Array(a.normals),\n uvs: new Float32Array(a.uvs),\n ...(a.indices ? { indices: indexArray(a.indices) } : {}),\n groups: a.groups,\n }\n}\n\nconst normalize3 = (x: number, y: number, z: number): [number, number, number] => {\n const length = Math.sqrt(x * x + y * y + z * z)\n const s = 1 / (length || 1)\n return [x * s, y * s, z * s]\n}\n\nexport function box(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1): PrimitiveBuffers {\n const parameters = { width, height, depth, widthSegments, heightSegments, depthSegments }\n widthSegments = Math.floor(widthSegments)\n heightSegments = Math.floor(heightSegments)\n depthSegments = Math.floor(depthSegments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n const groups: GeometryGroup[] = []\n let numberOfVertices = 0\n let groupStart = 0\n type Axis = 'x' | 'y' | 'z'\n const buildPlane = (u: Axis, v: Axis, w: Axis, udir: number, vdir: number, width: number, height: number, depth: number, gridX: number, gridY: number, materialIndex: number): void => {\n const segmentWidth = width / gridX\n const segmentHeight = height / gridY\n const widthHalf = width / 2\n const heightHalf = height / 2\n const depthHalf = depth / 2\n const gridX1 = gridX + 1\n const gridY1 = gridY + 1\n let vertexCounter = 0\n let groupCount = 0\n const vector = { x: 0, y: 0, z: 0 }\n for (let iy = 0; iy < gridY1; iy++) {\n const y = iy * segmentHeight - heightHalf\n for (let ix = 0; ix < gridX1; ix++) {\n const x = ix * segmentWidth - widthHalf\n vector[u] = x * udir\n vector[v] = y * vdir\n vector[w] = depthHalf\n vertices.push(vector.x, vector.y, vector.z)\n vector[u] = 0\n vector[v] = 0\n vector[w] = depth > 0 ? 1 : -1\n normals.push(vector.x, vector.y, vector.z)\n uvs.push(ix / gridX)\n uvs.push(1 - iy / gridY)\n vertexCounter += 1\n }\n }\n for (let iy = 0; iy < gridY; iy++) {\n for (let ix = 0; ix < gridX; ix++) {\n const a = numberOfVertices + ix + gridX1 * iy\n const b = numberOfVertices + ix + gridX1 * (iy + 1)\n const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1)\n const d = numberOfVertices + (ix + 1) + gridX1 * iy\n indices.push(a, b, d)\n indices.push(b, c, d)\n groupCount += 6\n }\n }\n groups.push({ start: groupStart, count: groupCount, materialIndex })\n groupStart += groupCount\n numberOfVertices += vertexCounter\n }\n buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0)\n buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1)\n buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2)\n buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3)\n buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4)\n buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5)\n return pack('BoxGeometry', parameters, { vertices, normals, uvs, indices, groups })\n}\n\nfunction cylinderArrays(radiusTop: number, radiusBottom: number, height: number, radialSegments: number, heightSegments: number, openEnded: boolean, thetaStart: number, thetaLength: number): Arrays {\n radialSegments = Math.floor(radialSegments)\n heightSegments = Math.floor(heightSegments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n const groups: GeometryGroup[] = []\n let index = 0\n const indexArray: number[][] = []\n const halfHeight = height / 2\n let groupStart = 0\n\n const generateTorso = (): void => {\n let groupCount = 0\n const slope = (radiusBottom - radiusTop) / height\n for (let y = 0; y <= heightSegments; y++) {\n const indexRow: number[] = []\n const v = y / heightSegments\n const radius = v * (radiusBottom - radiusTop) + radiusTop\n for (let x = 0; x <= radialSegments; x++) {\n const u = x / radialSegments\n const theta = u * thetaLength + thetaStart\n const sinTheta = Math.sin(theta)\n const cosTheta = Math.cos(theta)\n vertices.push(radius * sinTheta, -v * height + halfHeight, radius * cosTheta)\n const n = normalize3(sinTheta, slope, cosTheta)\n normals.push(n[0], n[1], n[2])\n uvs.push(u, 1 - v)\n indexRow.push(index++)\n }\n indexArray.push(indexRow)\n }\n for (let x = 0; x < radialSegments; x++) {\n for (let y = 0; y < heightSegments; y++) {\n const a = indexArray[y]![x]!\n const b = indexArray[y + 1]![x]!\n const c = indexArray[y + 1]![x + 1]!\n const d = indexArray[y]![x + 1]!\n indices.push(a, b, d)\n indices.push(b, c, d)\n groupCount += 6\n }\n }\n groups.push({ start: groupStart, count: groupCount, materialIndex: 0 })\n groupStart += groupCount\n }\n\n const generateCap = (top: boolean): void => {\n const centerIndexStart = index\n let groupCount = 0\n const radius = top === true ? radiusTop : radiusBottom\n const sign = top === true ? 1 : -1\n for (let x = 1; x <= radialSegments; x++) {\n vertices.push(0, halfHeight * sign, 0)\n normals.push(0, sign, 0)\n uvs.push(0.5, 0.5)\n index++\n }\n const centerIndexEnd = index\n for (let x = 0; x <= radialSegments; x++) {\n const u = x / radialSegments\n const theta = u * thetaLength + thetaStart\n const cosTheta = Math.cos(theta)\n const sinTheta = Math.sin(theta)\n vertices.push(radius * sinTheta, halfHeight * sign, radius * cosTheta)\n normals.push(0, sign, 0)\n uvs.push(cosTheta * 0.5 + 0.5, sinTheta * 0.5 * sign + 0.5)\n index++\n }\n for (let x = 0; x < radialSegments; x++) {\n const c = centerIndexStart + x\n const i = centerIndexEnd + x\n if (top === true) indices.push(i, i + 1, c)\n else indices.push(i + 1, i, c)\n groupCount += 3\n }\n groups.push({ start: groupStart, count: groupCount, materialIndex: top === true ? 1 : 2 })\n groupStart += groupCount\n }\n\n generateTorso()\n if (openEnded === false) {\n if (radiusTop > 0) generateCap(true)\n if (radiusBottom > 0) generateCap(false)\n }\n return { vertices, normals, uvs, indices, groups }\n}\n\nexport function cylinder(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }\n return pack('CylinderGeometry', parameters, cylinderArrays(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))\n}\n\nexport function cone(radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }\n return pack('ConeGeometry', parameters, cylinderArrays(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))\n}\n\nexport function sphere(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI): PrimitiveBuffers {\n const parameters = { radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength }\n widthSegments = Math.max(3, Math.floor(widthSegments))\n heightSegments = Math.max(2, Math.floor(heightSegments))\n const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI)\n let index = 0\n const grid: number[][] = []\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n for (let iy = 0; iy <= heightSegments; iy++) {\n const verticesRow: number[] = []\n const v = iy / heightSegments\n let uOffset = 0\n if (iy === 0 && thetaStart === 0) uOffset = 0.5 / widthSegments\n else if (iy === heightSegments && thetaEnd === Math.PI) uOffset = -0.5 / widthSegments\n for (let ix = 0; ix <= widthSegments; ix++) {\n const u = ix / widthSegments\n const x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength)\n const y = radius * Math.cos(thetaStart + v * thetaLength)\n const z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength)\n vertices.push(x, y, z)\n const n = normalize3(x, y, z)\n normals.push(n[0], n[1], n[2])\n uvs.push(u + uOffset, 1 - v)\n verticesRow.push(index++)\n }\n grid.push(verticesRow)\n }\n for (let iy = 0; iy < heightSegments; iy++) {\n for (let ix = 0; ix < widthSegments; ix++) {\n const a = grid[iy]![ix + 1]!\n const b = grid[iy]![ix]!\n const c = grid[iy + 1]![ix]!\n const d = grid[iy + 1]![ix + 1]!\n if (iy !== 0 || thetaStart > 0) indices.push(a, b, d)\n if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d)\n }\n }\n return pack('SphereGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function plane(width = 1, height = 1, widthSegments = 1, heightSegments = 1): PrimitiveBuffers {\n const parameters = { width, height, widthSegments, heightSegments }\n const widthHalf = width / 2\n const heightHalf = height / 2\n const gridX = Math.floor(widthSegments)\n const gridY = Math.floor(heightSegments)\n const gridX1 = gridX + 1\n const gridY1 = gridY + 1\n const segmentWidth = width / gridX\n const segmentHeight = height / gridY\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n for (let iy = 0; iy < gridY1; iy++) {\n const y = iy * segmentHeight - heightHalf\n for (let ix = 0; ix < gridX1; ix++) {\n const x = ix * segmentWidth - widthHalf\n vertices.push(x, -y, 0)\n normals.push(0, 0, 1)\n uvs.push(ix / gridX)\n uvs.push(1 - iy / gridY)\n }\n }\n for (let iy = 0; iy < gridY; iy++) {\n for (let ix = 0; ix < gridX; ix++) {\n const a = ix + gridX1 * iy\n const b = ix + gridX1 * (iy + 1)\n const c = ix + 1 + gridX1 * (iy + 1)\n const d = ix + 1 + gridX1 * iy\n indices.push(a, b, d)\n indices.push(b, c, d)\n }\n }\n return pack('PlaneGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function circle(radius = 1, segments = 32, thetaStart = 0, thetaLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { radius, segments, thetaStart, thetaLength }\n segments = Math.max(3, segments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n vertices.push(0, 0, 0)\n normals.push(0, 0, 1)\n uvs.push(0.5, 0.5)\n for (let s = 0, i = 3; s <= segments; s++, i += 3) {\n const segment = thetaStart + (s / segments) * thetaLength\n // the vector's z stays 0, as three's Vector3\n vertices.push(radius * Math.cos(segment), radius * Math.sin(segment), 0)\n normals.push(0, 0, 1)\n uvs.push(((vertices[i] as number) / radius + 1) / 2, ((vertices[i + 1] as number) / radius + 1) / 2)\n }\n for (let i = 1; i <= segments; i++) indices.push(i, i + 1, 0)\n return pack('CircleGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function ring(innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength }\n thetaSegments = Math.max(3, thetaSegments)\n phiSegments = Math.max(1, phiSegments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n let radius = innerRadius\n const radiusStep = (outerRadius - innerRadius) / phiSegments\n for (let j = 0; j <= phiSegments; j++) {\n for (let i = 0; i <= thetaSegments; i++) {\n const segment = thetaStart + (i / thetaSegments) * thetaLength\n const x = radius * Math.cos(segment)\n const y = radius * Math.sin(segment)\n vertices.push(x, y, 0)\n normals.push(0, 0, 1)\n uvs.push((x / outerRadius + 1) / 2, (y / outerRadius + 1) / 2)\n }\n radius += radiusStep\n }\n for (let j = 0; j < phiSegments; j++) {\n const thetaSegmentLevel = j * (thetaSegments + 1)\n for (let i = 0; i < thetaSegments; i++) {\n const segment = i + thetaSegmentLevel\n const a = segment\n const b = segment + thetaSegments + 1\n const c = segment + thetaSegments + 2\n const d = segment + 1\n indices.push(a, b, d)\n indices.push(b, c, d)\n }\n }\n return pack('RingGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function lathe(points: ReadonlyArray<readonly [number, number]>, segments = 12, phiStart = 0, phiLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { points: points.map(([x, y]) => ({ x, y })), segments, phiStart, phiLength }\n segments = Math.floor(segments)\n phiLength = Math.max(0, Math.min(Math.PI * 2, phiLength))\n const indices: number[] = []\n const vertices: number[] = []\n const uvs: number[] = []\n const initNormals: number[] = []\n const normals: number[] = []\n const inverseSegments = 1.0 / segments\n const normal = { x: 0, y: 0, z: 0 }\n const curNormal = { x: 0, y: 0, z: 0 }\n const prevNormal = { x: 0, y: 0, z: 0 }\n let dx = 0\n let dy = 0\n const last = points.length - 1\n const px = (j: number): number => (points[j] as readonly [number, number])[0]\n const py = (j: number): number => (points[j] as readonly [number, number])[1]\n const setNormalized = (): void => {\n const n = normalize3(normal.x, normal.y, normal.z)\n normal.x = n[0]\n normal.y = n[1]\n normal.z = n[2]\n }\n for (let j = 0; j <= last; j++) {\n if (j === 0) {\n dx = px(j + 1) - px(j)\n dy = py(j + 1) - py(j)\n normal.x = dy * 1.0\n normal.y = -dx\n normal.z = dy * 0.0\n prevNormal.x = normal.x\n prevNormal.y = normal.y\n prevNormal.z = normal.z\n setNormalized()\n initNormals.push(normal.x, normal.y, normal.z)\n } else if (j === last) {\n initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z)\n } else {\n dx = px(j + 1) - px(j)\n dy = py(j + 1) - py(j)\n normal.x = dy * 1.0\n normal.y = -dx\n normal.z = dy * 0.0\n curNormal.x = normal.x\n curNormal.y = normal.y\n curNormal.z = normal.z\n normal.x += prevNormal.x\n normal.y += prevNormal.y\n normal.z += prevNormal.z\n setNormalized()\n initNormals.push(normal.x, normal.y, normal.z)\n prevNormal.x = curNormal.x\n prevNormal.y = curNormal.y\n prevNormal.z = curNormal.z\n }\n }\n for (let i = 0; i <= segments; i++) {\n const phi = phiStart + i * inverseSegments * phiLength\n const sin = Math.sin(phi)\n const cos = Math.cos(phi)\n for (let j = 0; j <= last; j++) {\n vertices.push(px(j) * sin, py(j), px(j) * cos)\n uvs.push(i / segments, j / (points.length - 1))\n const x = (initNormals[3 * j + 0] as number) * sin\n const y = initNormals[3 * j + 1] as number\n const z = (initNormals[3 * j + 0] as number) * cos\n normals.push(x, y, z)\n }\n }\n for (let i = 0; i < segments; i++) {\n for (let j = 0; j < points.length - 1; j++) {\n const base = j + i * points.length\n const a = base\n const b = base + points.length\n const c = base + points.length + 1\n const d = base + 1\n indices.push(a, b, d)\n indices.push(c, d, b)\n }\n }\n return pack('LatheGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function torus(radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2): PrimitiveBuffers {\n const parameters = { radius, tube, radialSegments, tubularSegments, arc }\n radialSegments = Math.floor(radialSegments)\n tubularSegments = Math.floor(tubularSegments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n for (let j = 0; j <= radialSegments; j++) {\n for (let i = 0; i <= tubularSegments; i++) {\n const u = (i / tubularSegments) * arc\n const v = (j / radialSegments) * Math.PI * 2\n const x = (radius + tube * Math.cos(v)) * Math.cos(u)\n const y = (radius + tube * Math.cos(v)) * Math.sin(u)\n const z = tube * Math.sin(v)\n vertices.push(x, y, z)\n const cx = radius * Math.cos(u)\n const cy = radius * Math.sin(u)\n const n = normalize3(x - cx, y - cy, z - 0)\n normals.push(n[0], n[1], n[2])\n uvs.push(i / tubularSegments)\n uvs.push(j / radialSegments)\n }\n }\n for (let j = 1; j <= radialSegments; j++) {\n for (let i = 1; i <= tubularSegments; i++) {\n const a = (tubularSegments + 1) * j + i - 1\n const b = (tubularSegments + 1) * (j - 1) + i - 1\n const c = (tubularSegments + 1) * (j - 1) + i\n const d = (tubularSegments + 1) * j + i\n indices.push(a, b, d)\n indices.push(b, c, d)\n }\n }\n return pack('TorusGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n","import type { HoleSpec, PrimitiveBuffers, Vec3 } from '../types'\nimport { indexArray } from './three-generators'\n\n/**\n * A box (centred, `size = [w, h, d]`) minus rectangular prisms that go all the way through it along z: the cheap, exact boolean (walls with\n * windows and doors). The face is cut into a grid at every hole edge; each solid cell gets its front and back quads, and every cell edge between\n * solid and empty (a hole or the outside) gets a quad over the depth facing the empty side, so the outer sides and the reveals come out of the\n * same rule. Front uvs map the face to [0, 1]; side uvs run along the edge and the depth.\n */\nexport function difference(size: Vec3, subtract: readonly HoleSpec[]): PrimitiveBuffers {\n const [w, h, d] = size\n const hw = w / 2\n const hh = h / 2\n const hd = d / 2\n const holes = subtract\n .map((hole) => ({ x0: Math.max(-hw, Math.min(hole.min[0], hole.max[0])), x1: Math.min(hw, Math.max(hole.min[0], hole.max[0])), y0: Math.max(-hh, Math.min(hole.min[1], hole.max[1])), y1: Math.min(hh, Math.max(hole.min[1], hole.max[1])) }))\n .filter((hole) => hole.x1 > hole.x0 && hole.y1 > hole.y0)\n const cuts = (lo: number, hi: number, values: number[]): number[] => [...new Set([lo, hi, ...values.filter((v) => v > lo && v < hi)])].sort((a, b) => a - b)\n const xs = cuts(-hw, hw, holes.flatMap((hole) => [hole.x0, hole.x1]))\n const ys = cuts(-hh, hh, holes.flatMap((hole) => [hole.y0, hole.y1]))\n const nx = xs.length - 1\n const ny = ys.length - 1\n const solid = (i: number, j: number): boolean => {\n if (i < 0 || j < 0 || i >= nx || j >= ny) return false\n const cx = ((xs[i] as number) + (xs[i + 1] as number)) / 2\n const cy = ((ys[j] as number) + (ys[j + 1] as number)) / 2\n return !holes.some((hole) => cx > hole.x0 && cx < hole.x1 && cy > hole.y0 && cy < hole.y1)\n }\n const positions: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n const indices: number[] = []\n const quad = (corners: readonly (readonly [number, number, number])[], normal: readonly [number, number, number], uv: readonly (readonly [number, number])[]): void => {\n const base = positions.length / 3\n for (let k = 0; k < 4; k++) {\n positions.push(...(corners[k] as [number, number, number]))\n normals.push(...normal)\n uvs.push(...(uv[k] as [number, number]))\n }\n indices.push(base, base + 1, base + 2, base, base + 2, base + 3)\n }\n const fu = (x: number): number => (x + hw) / w\n const fv = (y: number): number => (y + hh) / h\n for (let j = 0; j < ny; j++) {\n for (let i = 0; i < nx; i++) {\n if (!solid(i, j)) continue\n const x0 = xs[i] as number\n const x1 = xs[i + 1] as number\n const y0 = ys[j] as number\n const y1 = ys[j + 1] as number\n quad([[x0, y0, hd], [x1, y0, hd], [x1, y1, hd], [x0, y1, hd]], [0, 0, 1], [[fu(x0), fv(y0)], [fu(x1), fv(y0)], [fu(x1), fv(y1)], [fu(x0), fv(y1)]])\n quad([[x1, y0, -hd], [x0, y0, -hd], [x0, y1, -hd], [x1, y1, -hd]], [0, 0, -1], [[1 - fu(x1), fv(y0)], [1 - fu(x0), fv(y0)], [1 - fu(x0), fv(y1)], [1 - fu(x1), fv(y1)]])\n const zu = (z: number): number => (z + hd) / d\n if (!solid(i - 1, j)) quad([[x0, y0, -hd], [x0, y0, hd], [x0, y1, hd], [x0, y1, -hd]], [-1, 0, 0], [[zu(-hd), fv(y0)], [zu(hd), fv(y0)], [zu(hd), fv(y1)], [zu(-hd), fv(y1)]])\n if (!solid(i + 1, j)) quad([[x1, y0, hd], [x1, y0, -hd], [x1, y1, -hd], [x1, y1, hd]], [1, 0, 0], [[zu(hd), fv(y0)], [zu(-hd), fv(y0)], [zu(-hd), fv(y1)], [zu(hd), fv(y1)]])\n if (!solid(i, j - 1)) quad([[x0, y0, -hd], [x1, y0, -hd], [x1, y0, hd], [x0, y0, hd]], [0, -1, 0], [[fu(x0), zu(-hd)], [fu(x1), zu(-hd)], [fu(x1), zu(hd)], [fu(x0), zu(hd)]])\n if (!solid(i, j + 1)) quad([[x0, y1, hd], [x1, y1, hd], [x1, y1, -hd], [x0, y1, -hd]], [0, 1, 0], [[fu(x0), zu(hd)], [fu(x1), zu(hd)], [fu(x1), zu(-hd)], [fu(x0), zu(-hd)]])\n }\n }\n return {\n type: 'BufferGeometry',\n parameters: { size: [w, h, d], subtract: holes.map((hole) => ({ min: [hole.x0, hole.y0], max: [hole.x1, hole.y1] })) },\n positions: new Float32Array(positions),\n normals: new Float32Array(normals),\n uvs: new Float32Array(uvs),\n indices: indexArray(indices),\n groups: [],\n }\n}\n","/* eslint-disable */\n// @ts-nocheck -- verbatim copy of three.js r160 src/extras/Earcut.js (MIT), itself a port of mapbox/earcut v2.2.4 (ISC); kept as is so triangulation matches three\n/**\n * Port from https://github.com/mapbox/earcut (v2.2.4)\n */\n\nconst Earcut = {\n\n\ttriangulate: function ( data, holeIndices, dim = 2 ) {\n\n\t\tconst hasHoles = holeIndices && holeIndices.length;\n\t\tconst outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length;\n\t\tlet outerNode = linkedList( data, 0, outerLen, dim, true );\n\t\tconst triangles = [];\n\n\t\tif ( ! outerNode || outerNode.next === outerNode.prev ) return triangles;\n\n\t\tlet minX, minY, maxX, maxY, x, y, invSize;\n\n\t\tif ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim );\n\n\t\t// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n\t\tif ( data.length > 80 * dim ) {\n\n\t\t\tminX = maxX = data[ 0 ];\n\t\t\tminY = maxY = data[ 1 ];\n\n\t\t\tfor ( let i = dim; i < outerLen; i += dim ) {\n\n\t\t\t\tx = data[ i ];\n\t\t\t\ty = data[ i + 1 ];\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\n\t\t\t}\n\n\t\t\t// minX, minY and invSize are later used to transform coords into integers for z-order calculation\n\t\t\tinvSize = Math.max( maxX - minX, maxY - minY );\n\t\t\tinvSize = invSize !== 0 ? 32767 / invSize : 0;\n\n\t\t}\n\n\t\tearcutLinked( outerNode, triangles, dim, minX, minY, invSize, 0 );\n\n\t\treturn triangles;\n\n\t}\n\n};\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList( data, start, end, dim, clockwise ) {\n\n\tlet i, last;\n\n\tif ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) {\n\n\t\tfor ( i = start; i < end; i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );\n\n\t} else {\n\n\t\tfor ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );\n\n\t}\n\n\tif ( last && equals( last, last.next ) ) {\n\n\t\tremoveNode( last );\n\t\tlast = last.next;\n\n\t}\n\n\treturn last;\n\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints( start, end ) {\n\n\tif ( ! start ) return start;\n\tif ( ! end ) end = start;\n\n\tlet p = start,\n\t\tagain;\n\tdo {\n\n\t\tagain = false;\n\n\t\tif ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) {\n\n\t\t\tremoveNode( p );\n\t\t\tp = end = p.prev;\n\t\t\tif ( p === p.next ) break;\n\t\t\tagain = true;\n\n\t\t} else {\n\n\t\t\tp = p.next;\n\n\t\t}\n\n\t} while ( again || p !== end );\n\n\treturn end;\n\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) {\n\n\tif ( ! ear ) return;\n\n\t// interlink polygon nodes in z-order\n\tif ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize );\n\n\tlet stop = ear,\n\t\tprev, next;\n\n\t// iterate through ears, slicing them one by one\n\twhile ( ear.prev !== ear.next ) {\n\n\t\tprev = ear.prev;\n\t\tnext = ear.next;\n\n\t\tif ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) {\n\n\t\t\t// cut off the triangle\n\t\t\ttriangles.push( prev.i / dim | 0 );\n\t\t\ttriangles.push( ear.i / dim | 0 );\n\t\t\ttriangles.push( next.i / dim | 0 );\n\n\t\t\tremoveNode( ear );\n\n\t\t\t// skipping the next vertex leads to less sliver triangles\n\t\t\tear = next.next;\n\t\t\tstop = next.next;\n\n\t\t\tcontinue;\n\n\t\t}\n\n\t\tear = next;\n\n\t\t// if we looped through the whole remaining polygon and can't find any more ears\n\t\tif ( ear === stop ) {\n\n\t\t\t// try filtering points and slicing again\n\t\t\tif ( ! pass ) {\n\n\t\t\t\tearcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 );\n\n\t\t\t\t// if this didn't work, try curing all small self-intersections locally\n\n\t\t\t} else if ( pass === 1 ) {\n\n\t\t\t\tear = cureLocalIntersections( filterPoints( ear ), triangles, dim );\n\t\t\t\tearcutLinked( ear, triangles, dim, minX, minY, invSize, 2 );\n\n\t\t\t\t// as a last resort, try splitting the remaining polygon into two\n\n\t\t\t} else if ( pass === 2 ) {\n\n\t\t\t\tsplitEarcut( ear, triangles, dim, minX, minY, invSize );\n\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar( ear ) {\n\n\tconst a = ear.prev,\n\t\tb = ear,\n\t\tc = ear.next;\n\n\tif ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear\n\n\t// now make sure we don't have other points inside the potential ear\n\tconst ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;\n\n\t// triangle bbox; min & max are calculated like this for speed\n\tconst x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ),\n\t\ty0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ),\n\t\tx1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ),\n\t\ty1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy );\n\n\tlet p = c.next;\n\twhile ( p !== a ) {\n\n\t\tif ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) &&\n\t\t\tarea( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.next;\n\n\t}\n\n\treturn true;\n\n}\n\nfunction isEarHashed( ear, minX, minY, invSize ) {\n\n\tconst a = ear.prev,\n\t\tb = ear,\n\t\tc = ear.next;\n\n\tif ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear\n\n\tconst ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;\n\n\t// triangle bbox; min & max are calculated like this for speed\n\tconst x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ),\n\t\ty0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ),\n\t\tx1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ),\n\t\ty1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy );\n\n\t// z-order range for the current triangle bbox;\n\tconst minZ = zOrder( x0, y0, minX, minY, invSize ),\n\t\tmaxZ = zOrder( x1, y1, minX, minY, invSize );\n\n\tlet p = ear.prevZ,\n\t\tn = ear.nextZ;\n\n\t// look for points inside the triangle in both directions\n\twhile ( p && p.z >= minZ && n && n.z <= maxZ ) {\n\n\t\tif ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.prevZ;\n\n\t\tif ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false;\n\t\tn = n.nextZ;\n\n\t}\n\n\t// look for remaining points in decreasing z-order\n\twhile ( p && p.z >= minZ ) {\n\n\t\tif ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.prevZ;\n\n\t}\n\n\t// look for remaining points in increasing z-order\n\twhile ( n && n.z <= maxZ ) {\n\n\t\tif ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false;\n\t\tn = n.nextZ;\n\n\t}\n\n\treturn true;\n\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections( start, triangles, dim ) {\n\n\tlet p = start;\n\tdo {\n\n\t\tconst a = p.prev,\n\t\t\tb = p.next.next;\n\n\t\tif ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) {\n\n\t\t\ttriangles.push( a.i / dim | 0 );\n\t\t\ttriangles.push( p.i / dim | 0 );\n\t\t\ttriangles.push( b.i / dim | 0 );\n\n\t\t\t// remove two nodes involved\n\t\t\tremoveNode( p );\n\t\t\tremoveNode( p.next );\n\n\t\t\tp = start = b;\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\treturn filterPoints( p );\n\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut( start, triangles, dim, minX, minY, invSize ) {\n\n\t// look for a valid diagonal that divides the polygon into two\n\tlet a = start;\n\tdo {\n\n\t\tlet b = a.next.next;\n\t\twhile ( b !== a.prev ) {\n\n\t\t\tif ( a.i !== b.i && isValidDiagonal( a, b ) ) {\n\n\t\t\t\t// split the polygon in two by the diagonal\n\t\t\t\tlet c = splitPolygon( a, b );\n\n\t\t\t\t// filter colinear points around the cuts\n\t\t\t\ta = filterPoints( a, a.next );\n\t\t\t\tc = filterPoints( c, c.next );\n\n\t\t\t\t// run earcut on each half\n\t\t\t\tearcutLinked( a, triangles, dim, minX, minY, invSize, 0 );\n\t\t\t\tearcutLinked( c, triangles, dim, minX, minY, invSize, 0 );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tb = b.next;\n\n\t\t}\n\n\t\ta = a.next;\n\n\t} while ( a !== start );\n\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles( data, holeIndices, outerNode, dim ) {\n\n\tconst queue = [];\n\tlet i, len, start, end, list;\n\n\tfor ( i = 0, len = holeIndices.length; i < len; i ++ ) {\n\n\t\tstart = holeIndices[ i ] * dim;\n\t\tend = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length;\n\t\tlist = linkedList( data, start, end, dim, false );\n\t\tif ( list === list.next ) list.steiner = true;\n\t\tqueue.push( getLeftmost( list ) );\n\n\t}\n\n\tqueue.sort( compareX );\n\n\t// process holes from left to right\n\tfor ( i = 0; i < queue.length; i ++ ) {\n\n\t\touterNode = eliminateHole( queue[ i ], outerNode );\n\n\t}\n\n\treturn outerNode;\n\n}\n\nfunction compareX( a, b ) {\n\n\treturn a.x - b.x;\n\n}\n\n// find a bridge between vertices that connects hole with an outer ring and link it\nfunction eliminateHole( hole, outerNode ) {\n\n\tconst bridge = findHoleBridge( hole, outerNode );\n\tif ( ! bridge ) {\n\n\t\treturn outerNode;\n\n\t}\n\n\tconst bridgeReverse = splitPolygon( bridge, hole );\n\n\t// filter collinear points around the cuts\n\tfilterPoints( bridgeReverse, bridgeReverse.next );\n\treturn filterPoints( bridge, bridge.next );\n\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge( hole, outerNode ) {\n\n\tlet p = outerNode,\n\t\tqx = - Infinity,\n\t\tm;\n\n\tconst hx = hole.x, hy = hole.y;\n\n\t// find a segment intersected by a ray from the hole's leftmost point to the left;\n\t// segment's endpoint with lesser x will be potential connection point\n\tdo {\n\n\t\tif ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) {\n\n\t\t\tconst x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y );\n\t\t\tif ( x <= hx && x > qx ) {\n\n\t\t\t\tqx = x;\n\t\t\t\tm = p.x < p.next.x ? p : p.next;\n\t\t\t\tif ( x === hx ) return m; // hole touches outer segment; pick leftmost endpoint\n\n\t\t\t}\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== outerNode );\n\n\tif ( ! m ) return null;\n\n\t// look for points inside the triangle of hole point, segment intersection and endpoint;\n\t// if there are no points found, we have a valid connection;\n\t// otherwise choose the point of the minimum angle with the ray as connection point\n\n\tconst stop = m,\n\t\tmx = m.x,\n\t\tmy = m.y;\n\tlet tanMin = Infinity, tan;\n\n\tp = m;\n\n\tdo {\n\n\t\tif ( hx >= p.x && p.x >= mx && hx !== p.x &&\n\t\t\t\tpointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) {\n\n\t\t\ttan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential\n\n\t\t\tif ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) {\n\n\t\t\t\tm = p;\n\t\t\t\ttanMin = tan;\n\n\t\t\t}\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== stop );\n\n\treturn m;\n\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector( m, p ) {\n\n\treturn area( m.prev, m, p.prev ) < 0 && area( p.next, m, m.next ) < 0;\n\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve( start, minX, minY, invSize ) {\n\n\tlet p = start;\n\tdo {\n\n\t\tif ( p.z === 0 ) p.z = zOrder( p.x, p.y, minX, minY, invSize );\n\t\tp.prevZ = p.prev;\n\t\tp.nextZ = p.next;\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\tp.prevZ.nextZ = null;\n\tp.prevZ = null;\n\n\tsortLinked( p );\n\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked( list ) {\n\n\tlet i, p, q, e, tail, numMerges, pSize, qSize,\n\t\tinSize = 1;\n\n\tdo {\n\n\t\tp = list;\n\t\tlist = null;\n\t\ttail = null;\n\t\tnumMerges = 0;\n\n\t\twhile ( p ) {\n\n\t\t\tnumMerges ++;\n\t\t\tq = p;\n\t\t\tpSize = 0;\n\t\t\tfor ( i = 0; i < inSize; i ++ ) {\n\n\t\t\t\tpSize ++;\n\t\t\t\tq = q.nextZ;\n\t\t\t\tif ( ! q ) break;\n\n\t\t\t}\n\n\t\t\tqSize = inSize;\n\n\t\t\twhile ( pSize > 0 || ( qSize > 0 && q ) ) {\n\n\t\t\t\tif ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) {\n\n\t\t\t\t\te = p;\n\t\t\t\t\tp = p.nextZ;\n\t\t\t\t\tpSize --;\n\n\t\t\t\t} else {\n\n\t\t\t\t\te = q;\n\t\t\t\t\tq = q.nextZ;\n\t\t\t\t\tqSize --;\n\n\t\t\t\t}\n\n\t\t\t\tif ( tail ) tail.nextZ = e;\n\t\t\t\telse list = e;\n\n\t\t\t\te.prevZ = tail;\n\t\t\t\ttail = e;\n\n\t\t\t}\n\n\t\t\tp = q;\n\n\t\t}\n\n\t\ttail.nextZ = null;\n\t\tinSize *= 2;\n\n\t} while ( numMerges > 1 );\n\n\treturn list;\n\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder( x, y, minX, minY, invSize ) {\n\n\t// coords are transformed into non-negative 15-bit integer range\n\tx = ( x - minX ) * invSize | 0;\n\ty = ( y - minY ) * invSize | 0;\n\n\tx = ( x | ( x << 8 ) ) & 0x00FF00FF;\n\tx = ( x | ( x << 4 ) ) & 0x0F0F0F0F;\n\tx = ( x | ( x << 2 ) ) & 0x33333333;\n\tx = ( x | ( x << 1 ) ) & 0x55555555;\n\n\ty = ( y | ( y << 8 ) ) & 0x00FF00FF;\n\ty = ( y | ( y << 4 ) ) & 0x0F0F0F0F;\n\ty = ( y | ( y << 2 ) ) & 0x33333333;\n\ty = ( y | ( y << 1 ) ) & 0x55555555;\n\n\treturn x | ( y << 1 );\n\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost( start ) {\n\n\tlet p = start,\n\t\tleftmost = start;\n\tdo {\n\n\t\tif ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p;\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\treturn leftmost;\n\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) {\n\n\treturn ( cx - px ) * ( ay - py ) >= ( ax - px ) * ( cy - py ) &&\n ( ax - px ) * ( by - py ) >= ( bx - px ) * ( ay - py ) &&\n ( bx - px ) * ( cy - py ) >= ( cx - px ) * ( by - py );\n\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal( a, b ) {\n\n\treturn a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // dones't intersect other edges\n ( locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ) && // locally visible\n ( area( a.prev, a, b.prev ) || area( a, b.prev, b ) ) || // does not create opposite-facing sectors\n equals( a, b ) && area( a.prev, a, a.next ) > 0 && area( b.prev, b, b.next ) > 0 ); // special zero-length case\n\n}\n\n// signed area of a triangle\nfunction area( p, q, r ) {\n\n\treturn ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y );\n\n}\n\n// check if two points are equal\nfunction equals( p1, p2 ) {\n\n\treturn p1.x === p2.x && p1.y === p2.y;\n\n}\n\n// check if two segments intersect\nfunction intersects( p1, q1, p2, q2 ) {\n\n\tconst o1 = sign( area( p1, q1, p2 ) );\n\tconst o2 = sign( area( p1, q1, q2 ) );\n\tconst o3 = sign( area( p2, q2, p1 ) );\n\tconst o4 = sign( area( p2, q2, q1 ) );\n\n\tif ( o1 !== o2 && o3 !== o4 ) return true; // general case\n\n\tif ( o1 === 0 && onSegment( p1, p2, q1 ) ) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n\tif ( o2 === 0 && onSegment( p1, q2, q1 ) ) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n\tif ( o3 === 0 && onSegment( p2, p1, q2 ) ) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n\tif ( o4 === 0 && onSegment( p2, q1, q2 ) ) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n\treturn false;\n\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment( p, q, r ) {\n\n\treturn q.x <= Math.max( p.x, r.x ) && q.x >= Math.min( p.x, r.x ) && q.y <= Math.max( p.y, r.y ) && q.y >= Math.min( p.y, r.y );\n\n}\n\nfunction sign( num ) {\n\n\treturn num > 0 ? 1 : num < 0 ? - 1 : 0;\n\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon( a, b ) {\n\n\tlet p = a;\n\tdo {\n\n\t\tif ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n\t\t\tintersects( p, p.next, a, b ) ) return true;\n\t\tp = p.next;\n\n\t} while ( p !== a );\n\n\treturn false;\n\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside( a, b ) {\n\n\treturn area( a.prev, a, a.next ) < 0 ?\n\t\tarea( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 :\n\t\tarea( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0;\n\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside( a, b ) {\n\n\tlet p = a,\n\t\tinside = false;\n\tconst px = ( a.x + b.x ) / 2,\n\t\tpy = ( a.y + b.y ) / 2;\n\tdo {\n\n\t\tif ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y &&\n\t\t\t( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) )\n\t\t\tinside = ! inside;\n\t\tp = p.next;\n\n\t} while ( p !== a );\n\n\treturn inside;\n\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon( a, b ) {\n\n\tconst a2 = new Node( a.i, a.x, a.y ),\n\t\tb2 = new Node( b.i, b.x, b.y ),\n\t\tan = a.next,\n\t\tbp = b.prev;\n\n\ta.next = b;\n\tb.prev = a;\n\n\ta2.next = an;\n\tan.prev = a2;\n\n\tb2.next = a2;\n\ta2.prev = b2;\n\n\tbp.next = b2;\n\tb2.prev = bp;\n\n\treturn b2;\n\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode( i, x, y, last ) {\n\n\tconst p = new Node( i, x, y );\n\n\tif ( ! last ) {\n\n\t\tp.prev = p;\n\t\tp.next = p;\n\n\t} else {\n\n\t\tp.next = last.next;\n\t\tp.prev = last;\n\t\tlast.next.prev = p;\n\t\tlast.next = p;\n\n\t}\n\n\treturn p;\n\n}\n\nfunction removeNode( p ) {\n\n\tp.next.prev = p.prev;\n\tp.prev.next = p.next;\n\n\tif ( p.prevZ ) p.prevZ.nextZ = p.nextZ;\n\tif ( p.nextZ ) p.nextZ.prevZ = p.prevZ;\n\n}\n\nfunction Node( i, x, y ) {\n\n\t// vertex index in coordinates array\n\tthis.i = i;\n\n\t// vertex coordinates\n\tthis.x = x;\n\tthis.y = y;\n\n\t// previous and next vertex nodes in a polygon ring\n\tthis.prev = null;\n\tthis.next = null;\n\n\t// z-order curve value\n\tthis.z = 0;\n\n\t// previous and next nodes in z-order\n\tthis.prevZ = null;\n\tthis.nextZ = null;\n\n\t// indicates whether this is a steiner point\n\tthis.steiner = false;\n\n}\n\nfunction signedArea( data, start, end, dim ) {\n\n\tlet sum = 0;\n\tfor ( let i = start, j = end - dim; i < end; i += dim ) {\n\n\t\tsum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] );\n\t\tj = i;\n\n\t}\n\n\treturn sum;\n\n}\n\nexport { Earcut };\n","/*\n * three.js r160 `ExtrudeGeometry` (MIT) for straight-edged shapes, ported line by line: the outline is sampled as `Shape.extractPoints` samples a\n * path of `LineCurve`s, triangulated by three's `ShapeUtils.triangulateShape` (Earcut), bevelled and walled in the same order, with the\n * `WorldUVGenerator` uvs and `computeVertexNormals` on the Float32 positions. Path extrusion (`extrudePath`) is not supported.\n */\nimport type { BevelSpec, GeometryGroup, PrimitiveBuffers, ShapeOutline, Vec2 } from '../types'\nimport { Earcut } from './earcut'\n\ninterface P {\n x: number\n y: number\n}\n\nconst equals = (a: P, b: P): boolean => a.x === b.x && a.y === b.y\n\n/** `LineCurve.getPoint(t)`. */\nconst linePoint = (v1: P, v2: P, t: number): P => (t === 1 ? { x: v2.x, y: v2.y } : { x: (v2.x - v1.x) * t + v1.x, y: (v2.y - v1.y) * t + v1.y })\n\n/** `Path.setFromPoints(points).getPoints()`: one `LineCurve` per edge, resolution 1, consecutive duplicates dropped, not closed. */\nfunction pathPoints(points: readonly Vec2[]): P[] {\n const out: P[] = []\n let last: P | undefined\n for (let i = 1; i < points.length; i++) {\n const v1 = { x: (points[i - 1] as Vec2)[0], y: (points[i - 1] as Vec2)[1] }\n const v2 = { x: (points[i] as Vec2)[0], y: (points[i] as Vec2)[1] }\n for (let d = 0; d <= 1; d++) {\n const point = linePoint(v1, v2, d / 1)\n if (last && equals(last, point)) continue\n out.push(point)\n last = point\n }\n }\n return out\n}\n\nfunction area(contour: readonly P[]): number {\n const n = contour.length\n let a = 0.0\n for (let p = n - 1, q = 0; q < n; p = q++) a += (contour[p] as P).x * (contour[q] as P).y - (contour[q] as P).x * (contour[p] as P).y\n return a * 0.5\n}\nconst isClockWise = (pts: readonly P[]): boolean => area(pts) < 0\n\nfunction removeDupEndPts(points: P[]): void {\n const l = points.length\n if (l > 2 && equals(points[l - 1] as P, points[0] as P)) points.pop()\n}\n\nfunction triangulateShape(contour: P[], holes: P[][]): number[][] {\n const vertices: number[] = []\n const holeIndices: number[] = []\n const faces: number[][] = []\n removeDupEndPts(contour)\n for (const p of contour) vertices.push(p.x, p.y)\n let holeIndex = contour.length\n holes.forEach(removeDupEndPts)\n for (let i = 0; i < holes.length; i++) {\n holeIndices.push(holeIndex)\n holeIndex += (holes[i] as P[]).length\n for (const p of holes[i] as P[]) vertices.push(p.x, p.y)\n }\n const triangles: number[] = Earcut.triangulate(vertices, holeIndices)\n for (let i = 0; i < triangles.length; i += 3) faces.push(triangles.slice(i, i + 3))\n return faces\n}\n\n/** `BufferGeometry.computeVertexNormals` for non-indexed Float32 positions, then `normalizeNormals`, both stored as Float32. */\nexport function computeVertexNormals(positions: Float32Array, indices?: ArrayLike<number>): Float32Array {\n const normals = new Float32Array(positions.length)\n const get = (array: Float32Array, i: number): [number, number, number] => [array[i * 3] as number, array[i * 3 + 1] as number, array[i * 3 + 2] as number]\n const face = (vA: number, vB: number, vC: number): [number, number, number] => {\n const pA = get(positions, vA)\n const pB = get(positions, vB)\n const pC = get(positions, vC)\n const cb = [pC[0] - pB[0], pC[1] - pB[1], pC[2] - pB[2]] as const\n const ab = [pA[0] - pB[0], pA[1] - pB[1], pA[2] - pB[2]] as const\n // Vector3.cross\n return [cb[1] * ab[2] - cb[2] * ab[1], cb[2] * ab[0] - cb[0] * ab[2], cb[0] * ab[1] - cb[1] * ab[0]]\n }\n const set = (i: number, x: number, y: number, z: number): void => {\n normals[i * 3] = x\n normals[i * 3 + 1] = y\n normals[i * 3 + 2] = z\n }\n if (indices) {\n for (let i = 0; i < indices.length; i += 3) {\n const vA = indices[i] as number\n const vB = indices[i + 1] as number\n const vC = indices[i + 2] as number\n const cb = face(vA, vB, vC)\n for (const v of [vA, vB, vC]) {\n const n = get(normals, v)\n set(v, n[0] + cb[0], n[1] + cb[1], n[2] + cb[2])\n }\n }\n } else {\n for (let i = 0; i < positions.length / 3; i += 3) {\n const cb = face(i, i + 1, i + 2)\n set(i, cb[0], cb[1], cb[2])\n set(i + 1, cb[0], cb[1], cb[2])\n set(i + 2, cb[0], cb[1], cb[2])\n }\n }\n for (let i = 0; i < normals.length / 3; i++) {\n const [x, y, z] = get(normals, i)\n const s = 1 / (Math.sqrt(x * x + y * y + z * z) || 1)\n set(i, x * s, y * s, z * s)\n }\n return normals\n}\n\nexport function extrude(outline: ShapeOutline, depth = 1, steps = 1, bevel: false | BevelSpec | undefined = undefined): PrimitiveBuffers {\n const parameters = { shape: outline, depth, steps, bevel: bevel ?? {} }\n const verticesArray: number[] = []\n const uvArray: number[] = []\n const groups: GeometryGroup[] = []\n const placeholder: number[] = []\n\n const bevelEnabled = bevel !== false\n const spec: BevelSpec = bevel === false || bevel === undefined ? {} : bevel\n let bevelThickness = spec.thickness !== undefined ? spec.thickness : 0.2\n let bevelSize = spec.size !== undefined ? spec.size : bevelThickness - 0.1\n let bevelOffset = spec.offset !== undefined ? spec.offset : 0\n let bevelSegments = spec.segments !== undefined ? spec.segments : 3\n if (!bevelEnabled) {\n bevelSegments = 0\n bevelThickness = 0\n bevelSize = 0\n bevelOffset = 0\n }\n\n let vertices = pathPoints(outline.outer)\n const holes = (outline.holes ?? []).map(pathPoints)\n const reverse = !isClockWise(vertices)\n if (reverse) {\n vertices = vertices.reverse()\n for (let h = 0; h < holes.length; h++) {\n const ahole = holes[h] as P[]\n if (isClockWise(ahole)) holes[h] = ahole.reverse()\n }\n }\n const faces = triangulateShape(vertices, holes)\n const contour = vertices\n for (const ahole of holes) vertices = vertices.concat(ahole)\n\n const scalePt2 = (pt: P, vec: P, size: number): P => ({ x: pt.x + vec.x * size, y: pt.y + vec.y * size })\n const vlen = vertices.length\n const flen = faces.length\n\n const getBevelVec = (inPt: P, inPrev: P, inNext: P): P => {\n let vTransX: number\n let vTransY: number\n let shrinkBy: number\n const vPrevX = inPt.x - inPrev.x\n const vPrevY = inPt.y - inPrev.y\n const vNextX = inNext.x - inPt.x\n const vNextY = inNext.y - inPt.y\n const vPrevLensq = vPrevX * vPrevX + vPrevY * vPrevY\n const collinear0 = vPrevX * vNextY - vPrevY * vNextX\n if (Math.abs(collinear0) > Number.EPSILON) {\n const vPrevLen = Math.sqrt(vPrevLensq)\n const vNextLen = Math.sqrt(vNextX * vNextX + vNextY * vNextY)\n const ptPrevShiftX = inPrev.x - vPrevY / vPrevLen\n const ptPrevShiftY = inPrev.y + vPrevX / vPrevLen\n const ptNextShiftX = inNext.x - vNextY / vNextLen\n const ptNextShiftY = inNext.y + vNextX / vNextLen\n const sf = ((ptNextShiftX - ptPrevShiftX) * vNextY - (ptNextShiftY - ptPrevShiftY) * vNextX) / (vPrevX * vNextY - vPrevY * vNextX)\n vTransX = ptPrevShiftX + vPrevX * sf - inPt.x\n vTransY = ptPrevShiftY + vPrevY * sf - inPt.y\n const vTransLensq = vTransX * vTransX + vTransY * vTransY\n if (vTransLensq <= 2) return { x: vTransX, y: vTransY }\n shrinkBy = Math.sqrt(vTransLensq / 2)\n } else {\n let directionEq = false\n if (vPrevX > Number.EPSILON) {\n if (vNextX > Number.EPSILON) directionEq = true\n } else if (vPrevX < -Number.EPSILON) {\n if (vNextX < -Number.EPSILON) directionEq = true\n } else if (Math.sign(vPrevY) === Math.sign(vNextY)) {\n directionEq = true\n }\n if (directionEq) {\n vTransX = -vPrevY\n vTransY = vPrevX\n shrinkBy = Math.sqrt(vPrevLensq)\n } else {\n vTransX = vPrevX\n vTransY = vPrevY\n shrinkBy = Math.sqrt(vPrevLensq / 2)\n }\n }\n return { x: vTransX / shrinkBy, y: vTransY / shrinkBy }\n }\n\n const movements = (ring: readonly P[]): P[] => {\n const out: P[] = []\n for (let i = 0, il = ring.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) {\n if (j === il) j = 0\n if (k === il) k = 0\n out[i] = getBevelVec(ring[i] as P, ring[j] as P, ring[k] as P)\n }\n return out\n }\n const contourMovements = movements(contour)\n const holesMovements: P[][] = []\n let verticesMovements = contourMovements.concat()\n for (const ahole of holes) {\n const oneHoleMovements = movements(ahole)\n holesMovements.push(oneHoleMovements)\n verticesMovements = verticesMovements.concat(oneHoleMovements)\n }\n\n const v = (x: number, y: number, z: number): void => {\n placeholder.push(x)\n placeholder.push(y)\n placeholder.push(z)\n }\n const bevelLayer = (b: number, zOf: (z: number) => number): void => {\n const t = b / bevelSegments\n const z = bevelThickness * Math.cos((t * Math.PI) / 2)\n const bs = bevelSize * Math.sin((t * Math.PI) / 2) + bevelOffset\n for (let i = 0; i < contour.length; i++) {\n const vert = scalePt2(contour[i] as P, contourMovements[i] as P, bs)\n v(vert.x, vert.y, zOf(z))\n }\n for (let h = 0; h < holes.length; h++) {\n const ahole = holes[h] as P[]\n const oneHoleMovements = holesMovements[h] as P[]\n for (let i = 0; i < ahole.length; i++) {\n const vert = scalePt2(ahole[i] as P, oneHoleMovements[i] as P, bs)\n v(vert.x, vert.y, zOf(z))\n }\n }\n }\n for (let b = 0; b < bevelSegments; b++) bevelLayer(b, (z) => -z)\n const bs = bevelSize + bevelOffset\n for (let i = 0; i < vlen; i++) {\n const vert = bevelEnabled ? scalePt2(vertices[i] as P, verticesMovements[i] as P, bs) : (vertices[i] as P)\n v(vert.x, vert.y, 0)\n }\n for (let s = 1; s <= steps; s++) {\n for (let i = 0; i < vlen; i++) {\n const vert = bevelEnabled ? scalePt2(vertices[i] as P, verticesMovements[i] as P, bs) : (vertices[i] as P)\n v(vert.x, vert.y, (depth / steps) * s)\n }\n }\n for (let b = bevelSegments - 1; b >= 0; b--) bevelLayer(b, (z) => depth + z)\n\n const addVertex = (index: number): void => {\n verticesArray.push(placeholder[index * 3 + 0] as number)\n verticesArray.push(placeholder[index * 3 + 1] as number)\n verticesArray.push(placeholder[index * 3 + 2] as number)\n }\n const addUV = (x: number, y: number): void => {\n uvArray.push(x)\n uvArray.push(y)\n }\n const at = (index: number, axis: number): number => verticesArray[index * 3 + axis] as number\n const f3 = (a: number, b: number, c: number): void => {\n addVertex(a)\n addVertex(b)\n addVertex(c)\n const nextIndex = verticesArray.length / 3\n for (const index of [nextIndex - 3, nextIndex - 2, nextIndex - 1]) addUV(at(index, 0), at(index, 1))\n }\n const f4 = (a: number, b: number, c: number, d: number): void => {\n addVertex(a)\n addVertex(b)\n addVertex(d)\n addVertex(b)\n addVertex(c)\n addVertex(d)\n const nextIndex = verticesArray.length / 3\n const iA = nextIndex - 6\n const iB = nextIndex - 3\n const iC = nextIndex - 2\n const iD = nextIndex - 1\n const byX = Math.abs(at(iA, 1) - at(iB, 1)) < Math.abs(at(iA, 0) - at(iB, 0))\n const uv = (index: number): [number, number] => [byX ? at(index, 0) : at(index, 1), 1 - at(index, 2)]\n const uvs = [uv(iA), uv(iB), uv(iC), uv(iD)]\n for (const k of [0, 1, 3, 1, 2, 3]) addUV(...(uvs[k] as [number, number]))\n }\n\n // lid faces\n let start = verticesArray.length / 3\n if (bevelEnabled) {\n let offset = 0\n for (let i = 0; i < flen; i++) {\n const face = faces[i] as number[]\n f3((face[2] as number) + offset, (face[1] as number) + offset, (face[0] as number) + offset)\n }\n const layer = steps + bevelSegments * 2\n offset = vlen * layer\n for (let i = 0; i < flen; i++) {\n const face = faces[i] as number[]\n f3((face[0] as number) + offset, (face[1] as number) + offset, (face[2] as number) + offset)\n }\n } else {\n for (let i = 0; i < flen; i++) {\n const face = faces[i] as number[]\n f3(face[2] as number, face[1] as number, face[0] as number)\n }\n for (let i = 0; i < flen; i++) {\n const face = faces[i] as number[]\n f3((face[0] as number) + vlen * steps, (face[1] as number) + vlen * steps, (face[2] as number) + vlen * steps)\n }\n }\n groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 0 })\n\n // side faces\n start = verticesArray.length / 3\n const sidewalls = (ring: readonly P[], layeroffset: number): void => {\n let i = ring.length\n while (--i >= 0) {\n const j = i\n let k = i - 1\n if (k < 0) k = ring.length - 1\n for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) {\n const slen1 = vlen * s\n const slen2 = vlen * (s + 1)\n f4(layeroffset + j + slen1, layeroffset + k + slen1, layeroffset + k + slen2, layeroffset + j + slen2)\n }\n }\n }\n let layeroffset = 0\n sidewalls(contour, layeroffset)\n layeroffset += contour.length\n for (const ahole of holes) {\n sidewalls(ahole, layeroffset)\n layeroffset += ahole.length\n }\n groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 1 })\n\n const positions = new Float32Array(verticesArray)\n return { type: 'ExtrudeGeometry', parameters, positions, normals: computeVertexNormals(positions), uvs: new Float32Array(uvArray), groups }\n}\n","import { canonicalJson } from '../hash'\nimport type { PrimitiveBuffers, PrimitiveNode } from '../types'\nimport { difference } from './difference'\nimport { computeVertexNormals, extrude } from './extrude'\nimport { box, circle, cone, cylinder, indexArray, lathe, plane, ring, sphere, torus } from './three-generators'\n\nexport { box, circle, cone, cylinder, lathe, plane, ring, sphere, torus } from './three-generators'\nexport { computeVertexNormals, extrude } from './extrude'\nexport { difference } from './difference'\n\n/** How a level of detail changes a primitive. */\nexport interface DetailOptions {\n /** Multiplies the segment counts of round primitives (1 leaves them as given). */\n readonly detail?: number\n /** Floor of the scaled segment counts (default 3). */\n readonly minSegments?: number\n}\n\nconst PARAMETER_KEYS: Readonly<Record<PrimitiveNode['kind'], readonly string[]>> = {\n box: ['size', 'segments'],\n cylinder: ['radiusTop', 'radiusBottom', 'height', 'radialSegments', 'heightSegments', 'openEnded', 'thetaStart', 'thetaLength'],\n cone: ['radius', 'height', 'radialSegments', 'heightSegments', 'openEnded', 'thetaStart', 'thetaLength'],\n sphere: ['radius', 'widthSegments', 'heightSegments', 'phiStart', 'phiLength', 'thetaStart', 'thetaLength'],\n plane: ['width', 'height', 'widthSegments', 'heightSegments'],\n circle: ['radius', 'segments', 'thetaStart', 'thetaLength'],\n ring: ['innerRadius', 'outerRadius', 'thetaSegments', 'phiSegments', 'thetaStart', 'thetaLength'],\n lathe: ['points', 'segments', 'phiStart', 'phiLength'],\n torus: ['radius', 'tube', 'radialSegments', 'tubularSegments', 'arc'],\n extrude: ['shape', 'depth', 'steps', 'bevel'],\n difference: ['size', 'subtract'],\n mesh: ['positions', 'normals', 'uvs', 'indices'],\n}\n\n/** The segment fields `detail` scales, per kind. */\nconst SEGMENT_KEYS: Readonly<Partial<Record<PrimitiveNode['kind'], readonly string[]>>> = {\n cylinder: ['radialSegments'],\n cone: ['radialSegments'],\n sphere: ['widthSegments', 'heightSegments'],\n circle: ['segments'],\n ring: ['thetaSegments'],\n lathe: ['segments'],\n torus: ['radialSegments', 'tubularSegments'],\n}\n/** three's defaults of the segment fields, so a scaled default is scaled from the right number. */\nconst SEGMENT_DEFAULTS: Readonly<Record<string, number>> = { radialSegments: 32, widthSegments: 32, heightSegments: 16, segments: 12, thetaSegments: 32, tubularSegments: 48 }\nconst segmentDefault = (kind: string, key: string): number => (kind === 'circle' && key === 'segments' ? 32 : kind === 'torus' && key === 'radialSegments' ? 12 : (SEGMENT_DEFAULTS[key] as number))\n\n/** The parameters of a primitive node (no transform, colour or name), with the level of detail applied: what its geometry depends on. */\nexport function primitiveParameters(node: PrimitiveNode, options: DetailOptions = {}): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const source = node as unknown as Record<string, unknown>\n for (const key of PARAMETER_KEYS[node.kind]) if (source[key] !== undefined) out[key] = source[key]\n const detail = options.detail ?? 1\n if (detail !== 1) {\n const floor = options.minSegments ?? 3\n for (const key of SEGMENT_KEYS[node.kind] ?? []) {\n const given = (out[key] as number | undefined) ?? segmentDefault(node.kind, key)\n out[key] = Math.max(floor, Math.round(given * detail))\n }\n }\n return out\n}\n\nfunction mesh(p: Record<string, unknown>): PrimitiveBuffers {\n const positions = new Float32Array(p.positions as number[])\n const indices = p.indices ? indexArray(p.indices as number[]) : undefined\n return {\n type: 'BufferGeometry',\n parameters: {},\n positions,\n normals: p.normals ? new Float32Array(p.normals as number[]) : computeVertexNormals(positions, indices),\n uvs: p.uvs ? new Float32Array(p.uvs as number[]) : new Float32Array((positions.length / 3) * 2),\n ...(indices ? { indices } : {}),\n groups: [],\n }\n}\n\nfunction make(kind: PrimitiveNode['kind'], p: Record<string, any>): PrimitiveBuffers {\n switch (kind) {\n case 'box': {\n const size = (p.size ?? [1, 1, 1]) as number[]\n const segments = (p.segments ?? [1, 1, 1]) as number[]\n return box(size[0], size[1], size[2], segments[0], segments[1], segments[2])\n }\n case 'cylinder':\n return cylinder(p.radiusTop, p.radiusBottom, p.height, p.radialSegments, p.heightSegments, p.openEnded, p.thetaStart, p.thetaLength)\n case 'cone':\n return cone(p.radius, p.height, p.radialSegments, p.heightSegments, p.openEnded, p.thetaStart, p.thetaLength)\n case 'sphere':\n return sphere(p.radius, p.widthSegments, p.heightSegments, p.phiStart, p.phiLength, p.thetaStart, p.thetaLength)\n case 'plane':\n return plane(p.width, p.height, p.widthSegments, p.heightSegments)\n case 'circle':\n return circle(p.radius, p.segments, p.thetaStart, p.thetaLength)\n case 'ring':\n return ring(p.innerRadius, p.outerRadius, p.thetaSegments, p.phiSegments, p.thetaStart, p.thetaLength)\n case 'lathe':\n return lathe(p.points, p.segments, p.phiStart, p.phiLength)\n case 'torus':\n return torus(p.radius, p.tube, p.radialSegments, p.tubularSegments, p.arc)\n case 'extrude':\n return extrude(p.shape, p.depth, p.steps, p.bevel)\n case 'difference':\n return difference(p.size, p.subtract ?? [])\n case 'mesh':\n return mesh(p)\n default:\n throw new Error(`game-shapes: unknown primitive kind \"${String(kind)}\"`)\n }\n}\n\n/** Templates by their parameter text: the same cylinder is generated once per process. Read-only by contract. */\nconst templates = new Map<string, PrimitiveBuffers>()\nlet templateLimit = 4096\nconst stats = { hits: 0, misses: 0 }\n\n/** Sets how many primitive templates are kept (least recently used out; 0 turns the cache off). */\nexport function setTemplateCacheSize(size: number): void {\n templateLimit = Math.max(0, Math.floor(size))\n while (templates.size > templateLimit) templates.delete(templates.keys().next().value as string)\n}\nexport function clearTemplateCache(): void {\n templates.clear()\n stats.hits = 0\n stats.misses = 0\n}\nexport const templateCacheStats = (): { size: number; hits: number; misses: number } => ({ size: templates.size, ...stats })\n\n/**\n * The geometry of one primitive on its own, not baked: the arrays three's generator of the same kind builds, bit for bit (meshes and differences\n * are `BufferGeometry`). The result comes from a shared template cache and must not be written to (copy it with `clonePrimitive`).\n */\nexport function buildPrimitive(node: PrimitiveNode, options: DetailOptions = {}): PrimitiveBuffers {\n const parameters = primitiveParameters(node, options)\n // raw meshes are not worth a key of their whole arrays; they are cheap to wrap\n if (node.kind === 'mesh' || templateLimit === 0) return make(node.kind, parameters)\n const key = `${node.kind}:${canonicalJson(parameters)}`\n const cached = templates.get(key)\n if (cached) {\n stats.hits++\n templates.delete(key)\n templates.set(key, cached)\n return cached\n }\n stats.misses++\n const built = make(node.kind, parameters)\n templates.set(key, built)\n if (templates.size > templateLimit) templates.delete(templates.keys().next().value as string)\n return built\n}\n\n/** A copy that owns its arrays. */\nexport function clonePrimitive(p: PrimitiveBuffers): PrimitiveBuffers {\n return {\n type: p.type,\n parameters: p.parameters,\n positions: p.positions.slice(),\n normals: p.normals.slice(),\n uvs: p.uvs.slice(),\n ...(p.indices ? { indices: p.indices.slice() } : {}),\n groups: p.groups.map((group) => ({ ...group })),\n }\n}\n","import { hash64 } from './hash'\n\n/** mulberry32: a small, fast 32-bit seeded stream in [0, 1). */\nexport function mulberry32(seed: number): () => number {\n let state = seed >>> 0\n return () => {\n state = (state + 0x6d2b79f5) >>> 0\n let t = state\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** The stream of one node: its own per (seed, generator, path), so adding a node never shifts another node's draws. */\nexport const streamFor = (seed: number | string, generator: string, path: string): (() => number) =>\n mulberry32(parseInt(hash64(`${String(seed)}\\u0000${generator}\\u0000${path}`).slice(0, 8), 16))\n","import type { ShapeGenerator } from './types'\n\nconst generators = new Map<string, ShapeGenerator>()\n\n/**\n * Registers a generator for `{ kind: 'custom', generator: name, params }` nodes: a pure function of its params and a seeded stream that returns a\n * node. A worker that generates shapes with custom nodes must register the same generators (import the same module in the worker script).\n */\nexport function registerGenerator(name: string, generator: ShapeGenerator): void {\n if (!/^[a-zA-Z][\\w.:-]*$/.test(name)) throw new Error(`game-shapes: generator name \"${name}\" must start with a letter and use letters, digits, \".\", \":\", \"-\" or \"_\"`)\n generators.set(name, generator)\n}\nexport const unregisterGenerator = (name: string): boolean => generators.delete(name)\nexport const getGenerator = (name: string): ShapeGenerator | undefined => generators.get(name)\nexport const listGenerators = (): string[] => [...generators.keys()].sort()\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://github.com/Andersonfrfilho/adatechnology-game-kit/packages/game-shapes/schema/shape.schema.json\",\n \"title\": \"game-shapes shape\",\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"root\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"version\": {\n \"const\": 1\n },\n \"name\": {\n \"type\": \"string\"\n },\n \"materials\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/material\"\n }\n },\n \"root\": {\n \"$ref\": \"#/$defs/node\"\n },\n \"lod\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/lodLevel\"\n }\n },\n \"cullDistance\": {\n \"type\": \"number\",\n \"exclusiveMinimum\": 0\n }\n },\n \"$defs\": {\n \"number\": {\n \"type\": \"number\"\n },\n \"count\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"vec2\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n },\n \"minItems\": 2,\n \"maxItems\": 2\n },\n \"vec3\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n },\n \"minItems\": 3,\n \"maxItems\": 3\n },\n \"mat4\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n },\n \"minItems\": 16,\n \"maxItems\": 16\n },\n \"color\": {\n \"oneOf\": [\n {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 16777215\n },\n {\n \"type\": \"string\",\n \"pattern\": \"^#[0-9a-fA-F]{6}$\"\n }\n ]\n },\n \"uvRect\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"u0\",\n \"v0\",\n \"u1\",\n \"v1\"\n ],\n \"properties\": {\n \"u0\": {\n \"type\": \"number\"\n },\n \"v0\": {\n \"type\": \"number\"\n },\n \"u1\": {\n \"type\": \"number\"\n },\n \"v1\": {\n \"type\": \"number\"\n }\n }\n },\n \"rotationOrder\": {\n \"enum\": [\n \"XYZ\",\n \"YXZ\",\n \"ZXY\",\n \"ZYX\",\n \"YZX\",\n \"XZY\"\n ]\n },\n \"transform\": {\n \"type\": \"object\",\n \"properties\": {\n \"position\": {\n \"$ref\": \"#/$defs/vec3\"\n },\n \"rotation\": {\n \"$ref\": \"#/$defs/vec3\"\n },\n \"rotationOrder\": {\n \"$ref\": \"#/$defs/rotationOrder\"\n },\n \"scale\": {\n \"oneOf\": [\n {\n \"type\": \"number\"\n },\n {\n \"$ref\": \"#/$defs/vec3\"\n }\n ]\n },\n \"heading\": {\n \"type\": \"number\"\n },\n \"matrix\": {\n \"$ref\": \"#/$defs/mat4\"\n }\n }\n },\n \"instance\": {\n \"allOf\": [\n {\n \"$ref\": \"#/$defs/transform\"\n }\n ],\n \"properties\": {\n \"position\": true,\n \"rotation\": true,\n \"rotationOrder\": true,\n \"scale\": true,\n \"heading\": true,\n \"matrix\": true,\n \"color\": {\n \"$ref\": \"#/$defs/color\"\n }\n },\n \"unevaluatedProperties\": false\n },\n \"material\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"color\": {\n \"$ref\": \"#/$defs/color\"\n },\n \"roughness\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"metalness\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"opacity\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"transparent\": {\n \"type\": \"boolean\"\n },\n \"emissive\": {\n \"$ref\": \"#/$defs/color\"\n },\n \"emissiveIntensity\": {\n \"type\": \"number\",\n \"minimum\": 0\n },\n \"side\": {\n \"enum\": [\n \"front\",\n \"back\",\n \"double\"\n ]\n },\n \"flatShading\": {\n \"type\": \"boolean\"\n },\n \"vertexColors\": {\n \"type\": \"boolean\"\n },\n \"depthWrite\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"lodLevel\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"distance\",\n \"detail\"\n ],\n \"properties\": {\n \"distance\": {\n \"type\": \"number\",\n \"minimum\": 0\n },\n \"detail\": {\n \"type\": \"number\",\n \"exclusiveMinimum\": 0,\n \"maximum\": 1\n },\n \"minSize\": {\n \"type\": \"number\",\n \"minimum\": 0\n },\n \"minSegments\": {\n \"type\": \"integer\",\n \"minimum\": 3\n }\n }\n },\n \"common\": {\n \"allOf\": [\n {\n \"$ref\": \"#/$defs/transform\"\n }\n ],\n \"properties\": {\n \"kind\": {\n \"type\": \"string\"\n },\n \"name\": {\n \"type\": \"string\"\n },\n \"part\": {\n \"type\": \"string\"\n },\n \"material\": {\n \"type\": \"string\"\n },\n \"color\": {\n \"$ref\": \"#/$defs/color\"\n },\n \"uv\": {\n \"$ref\": \"#/$defs/uvRect\"\n },\n \"instances\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/instance\"\n }\n },\n \"minDetail\": {\n \"type\": \"number\",\n \"exclusiveMinimum\": 0,\n \"maximum\": 1\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"node\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"allOf\": [\n {\n \"$ref\": \"#/$defs/common\"\n }\n ],\n \"oneOf\": [\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"group\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/node\"\n }\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"box\"\n },\n \"size\": {\n \"$ref\": \"#/$defs/vec3\"\n },\n \"segments\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"minItems\": 3,\n \"maxItems\": 3\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"cylinder\"\n },\n \"radiusTop\": {\n \"type\": \"number\"\n },\n \"radiusBottom\": {\n \"type\": \"number\"\n },\n \"height\": {\n \"type\": \"number\"\n },\n \"radialSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"heightSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"openEnded\": {\n \"type\": \"boolean\"\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"cone\"\n },\n \"radius\": {\n \"type\": \"number\"\n },\n \"height\": {\n \"type\": \"number\"\n },\n \"radialSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"heightSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"openEnded\": {\n \"type\": \"boolean\"\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"sphere\"\n },\n \"radius\": {\n \"type\": \"number\"\n },\n \"widthSegments\": {\n \"type\": \"integer\",\n \"minimum\": 3\n },\n \"heightSegments\": {\n \"type\": \"integer\",\n \"minimum\": 2\n },\n \"phiStart\": {\n \"type\": \"number\"\n },\n \"phiLength\": {\n \"type\": \"number\"\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"plane\"\n },\n \"width\": {\n \"type\": \"number\"\n },\n \"height\": {\n \"type\": \"number\"\n },\n \"widthSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"heightSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"circle\"\n },\n \"radius\": {\n \"type\": \"number\"\n },\n \"segments\": {\n \"type\": \"integer\",\n \"minimum\": 3\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"ring\"\n },\n \"innerRadius\": {\n \"type\": \"number\"\n },\n \"outerRadius\": {\n \"type\": \"number\"\n },\n \"thetaSegments\": {\n \"type\": \"integer\",\n \"minimum\": 3\n },\n \"phiSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"required\": [\n \"points\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"lathe\"\n },\n \"points\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/vec2\"\n },\n \"minItems\": 2\n },\n \"segments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"phiStart\": {\n \"type\": \"number\"\n },\n \"phiLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"torus\"\n },\n \"radius\": {\n \"type\": \"number\"\n },\n \"tube\": {\n \"type\": \"number\"\n },\n \"radialSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"tubularSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"arc\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"required\": [\n \"shape\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"extrude\"\n },\n \"shape\": {\n \"type\": \"object\",\n \"required\": [\n \"outer\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"outer\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/vec2\"\n },\n \"minItems\": 3\n },\n \"holes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/vec2\"\n },\n \"minItems\": 3\n }\n }\n }\n },\n \"depth\": {\n \"type\": \"number\"\n },\n \"steps\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"bevel\": {\n \"oneOf\": [\n {\n \"const\": false\n },\n {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"thickness\": {\n \"type\": \"number\"\n },\n \"size\": {\n \"type\": \"number\"\n },\n \"offset\": {\n \"type\": \"number\"\n },\n \"segments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n }\n }\n }\n ]\n }\n }\n },\n {\n \"required\": [\n \"size\",\n \"subtract\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"difference\"\n },\n \"size\": {\n \"$ref\": \"#/$defs/vec3\"\n },\n \"subtract\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"min\",\n \"max\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"min\": {\n \"$ref\": \"#/$defs/vec2\"\n },\n \"max\": {\n \"$ref\": \"#/$defs/vec2\"\n }\n }\n }\n }\n }\n },\n {\n \"required\": [\n \"positions\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"mesh\"\n },\n \"positions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n }\n },\n \"normals\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n }\n },\n \"uvs\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n }\n },\n \"indices\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/count\"\n }\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"point\"\n },\n \"data\": {}\n }\n },\n {\n \"required\": [\n \"generator\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"custom\"\n },\n \"generator\": {\n \"type\": \"string\"\n },\n \"params\": {}\n }\n }\n ]\n }\n }\n}\n","import schemaJson from '../schema/shape.schema.json'\nimport type { ShapeSchema } from './types'\n\n/** The JSON Schema (draft 2020-12) of a shape document; the same file ships as `@adatechnology/game-shapes/schema.json`. */\nexport const SHAPE_SCHEMA: Readonly<Record<string, unknown>> = schemaJson\n\ntype Check = (value: unknown) => string | null\n\nconst num: Check = (v) => (typeof v === 'number' && Number.isFinite(v) ? null : 'expected a finite number')\nconst bool: Check = (v) => (typeof v === 'boolean' ? null : 'expected a boolean')\nconst str: Check = (v) => (typeof v === 'string' ? null : 'expected a string')\nconst int = (min: number): Check => (v) => (typeof v === 'number' && Number.isInteger(v) && v >= min ? null : `expected an integer >= ${min}`)\nconst range = (lo: number, hi: number, loOpen = false): Check => (v) =>\n typeof v === 'number' && (loOpen ? v > lo : v >= lo) && v <= hi ? null : `expected a number in ${loOpen ? '(' : '['}${lo}, ${hi}]`\nconst tuple = (n: number, item: Check = num): Check => (v) => {\n if (!Array.isArray(v) || v.length !== n) return `expected an array of ${n}`\n for (const x of v) if (item(x)) return `expected an array of ${n} numbers`\n return null\n}\nconst list = (item: Check, min = 0): Check => (v) => {\n if (!Array.isArray(v)) return 'expected an array'\n if (v.length < min) return `expected at least ${min} items`\n for (let i = 0; i < v.length; i++) {\n const e = item(v[i])\n if (e) return `[${i}]: ${e}`\n }\n return null\n}\nconst color: Check = (v) =>\n (typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 0xffffff) || (typeof v === 'string' && /^#[0-9a-fA-F]{6}$/.test(v)) ? null : 'expected 0xRRGGBB or \"#rrggbb\"'\nconst oneOf = (values: readonly unknown[]): Check => (v) => (values.includes(v) ? null : `expected one of ${values.map((x) => JSON.stringify(x)).join(', ')}`)\nconst object = (fields: Readonly<Record<string, Check>>, required: readonly string[] = []): Check => (v) => {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return 'expected an object'\n const record = v as Record<string, unknown>\n for (const key of required) if (record[key] === undefined) return `${key}: required`\n for (const key of Object.keys(record)) {\n if (record[key] === undefined) continue\n const check = fields[key]\n if (!check) return `${key}: unknown field`\n const e = check(record[key])\n if (e) return `${key}: ${e}`\n }\n return null\n}\n\nconst ORDERS = ['XYZ', 'YXZ', 'ZXY', 'ZYX', 'YZX', 'XZY'] as const\nconst TRANSFORM: Record<string, Check> = {\n position: tuple(3),\n rotation: tuple(3),\n rotationOrder: oneOf(ORDERS),\n scale: (v) => (typeof v === 'number' ? num(v) : tuple(3)(v)),\n heading: num,\n matrix: tuple(16),\n}\nconst UV = object({ u0: num, v0: num, u1: num, v1: num }, ['u0', 'v0', 'u1', 'v1'])\nconst INSTANCE = object({ ...TRANSFORM, color })\nconst COMMON: Record<string, Check> = {\n ...TRANSFORM,\n kind: str,\n name: str,\n part: str,\n material: str,\n color,\n uv: UV,\n instances: list(INSTANCE),\n minDetail: range(0, 1, true),\n tags: list(str),\n}\nconst vec2 = tuple(2)\nconst BEVEL: Check = (v) => (v === false ? null : object({ thickness: num, size: num, offset: num, segments: int(1) })(v))\nconst KINDS: Readonly<Record<string, { fields: Record<string, Check>; required?: string[] }>> = {\n group: { fields: {} },\n box: { fields: { size: tuple(3), segments: tuple(3, int(1)) } },\n cylinder: { fields: { radiusTop: num, radiusBottom: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },\n cone: { fields: { radius: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },\n sphere: { fields: { radius: num, widthSegments: int(3), heightSegments: int(2), phiStart: num, phiLength: num, thetaStart: num, thetaLength: num } },\n plane: { fields: { width: num, height: num, widthSegments: int(1), heightSegments: int(1) } },\n circle: { fields: { radius: num, segments: int(3), thetaStart: num, thetaLength: num } },\n ring: { fields: { innerRadius: num, outerRadius: num, thetaSegments: int(3), phiSegments: int(1), thetaStart: num, thetaLength: num } },\n lathe: { fields: { points: list(vec2, 2), segments: int(1), phiStart: num, phiLength: num }, required: ['points'] },\n torus: { fields: { radius: num, tube: num, radialSegments: int(1), tubularSegments: int(1), arc: num } },\n extrude: {\n fields: { shape: object({ outer: list(vec2, 3), holes: list(list(vec2, 3)) }, ['outer']), depth: num, steps: int(1), bevel: BEVEL },\n required: ['shape'],\n },\n difference: { fields: { size: tuple(3), subtract: list(object({ min: vec2, max: vec2 }, ['min', 'max'])) }, required: ['size', 'subtract'] },\n mesh: {\n fields: {\n positions: (v) => list(num)(v) ?? ((v as unknown[]).length % 3 === 0 ? null : 'expected a multiple of 3 numbers'),\n normals: list(num),\n uvs: list(num),\n indices: list(int(0)),\n },\n required: ['positions'],\n },\n point: { fields: { data: () => null } },\n custom: { fields: { generator: str, params: () => null }, required: ['generator'] },\n}\n\nfunction validateNode(node: unknown, path: string, errors: string[]): void {\n if (!node || typeof node !== 'object' || Array.isArray(node)) {\n errors.push(`${path}: expected a node object`)\n return\n }\n const record = node as Record<string, unknown>\n const spec = typeof record.kind === 'string' ? KINDS[record.kind] : undefined\n if (!spec) {\n errors.push(`${path}.kind: expected one of ${Object.keys(KINDS).join(', ')}`)\n return\n }\n for (const key of spec.required ?? []) if (record[key] === undefined) errors.push(`${path}.${key}: required`)\n for (const key of Object.keys(record)) {\n if (record[key] === undefined || key === 'children') continue\n const check = spec.fields[key] ?? COMMON[key]\n if (!check) {\n errors.push(`${path}.${key}: unknown field for a ${String(record.kind)}`)\n continue\n }\n const e = check(record[key])\n if (e) errors.push(`${path}.${key}: ${e}`)\n }\n const exclusive = ['matrix', 'heading'].filter((key) => record[key] !== undefined)\n if (record.matrix !== undefined && (record.position !== undefined || record.rotation !== undefined || record.scale !== undefined || record.heading !== undefined))\n errors.push(`${path}.matrix: cannot be combined with position, rotation, scale or heading`)\n else if (exclusive.includes('heading') && (record.rotation !== undefined || record.scale !== undefined)) errors.push(`${path}.heading: cannot be combined with rotation or scale`)\n if (record.children !== undefined) {\n if (record.kind !== 'group') errors.push(`${path}.children: only a group has children`)\n else if (!Array.isArray(record.children)) errors.push(`${path}.children: expected an array`)\n else record.children.forEach((child, index) => validateNode(child, `${path}.children[${index}]`, errors))\n }\n}\n\n/** Every rule of the JSON Schema, checked without a schema engine: one message per problem, with its path (`root.children[3].radialSegments: ...`). */\nexport function validateShape(schema: unknown): string[] {\n const errors: string[] = []\n if (!schema || typeof schema !== 'object' || Array.isArray(schema)) return ['expected a shape object']\n const record = schema as Record<string, unknown>\n for (const key of Object.keys(record)) if (!['version', 'name', 'materials', 'root', 'lod', 'cullDistance'].includes(key) && record[key] !== undefined) errors.push(`${key}: unknown field`)\n if (record.version !== 1) errors.push('version: expected 1')\n if (record.name !== undefined && typeof record.name !== 'string') errors.push('name: expected a string')\n if (record.materials !== undefined) {\n if (!record.materials || typeof record.materials !== 'object' || Array.isArray(record.materials)) errors.push('materials: expected an object')\n else {\n const material = object({\n color,\n roughness: range(0, 1),\n metalness: range(0, 1),\n opacity: range(0, 1),\n transparent: bool,\n emissive: color,\n emissiveIntensity: (v) => (typeof v === 'number' && v >= 0 ? null : 'expected a number >= 0'),\n side: oneOf(['front', 'back', 'double']),\n flatShading: bool,\n vertexColors: bool,\n depthWrite: bool,\n })\n for (const [id, hint] of Object.entries(record.materials)) {\n const e = material(hint)\n if (e) errors.push(`materials.${id}: ${e}`)\n }\n }\n }\n if (record.lod !== undefined) {\n const e = list(object({ distance: (v) => (typeof v === 'number' && v >= 0 ? null : 'expected a number >= 0'), detail: range(0, 1, true), minSize: (v) => (typeof v === 'number' && v >= 0 ? null : 'expected a number >= 0'), minSegments: int(3) }, ['distance', 'detail']))(record.lod)\n if (e) errors.push(`lod${e.startsWith('[') ? '' : ': '}${e}`)\n }\n if (record.cullDistance !== undefined && !(typeof record.cullDistance === 'number' && record.cullDistance > 0)) errors.push('cullDistance: expected a number > 0')\n if (record.root === undefined) errors.push('root: required')\n else validateNode(record.root, 'root', errors)\n return errors\n}\n\n/** Throws with every problem when the schema is not valid. */\nexport function assertValidShape(schema: unknown): asserts schema is ShapeSchema {\n const errors = validateShape(schema)\n if (errors.length) throw new Error(`game-shapes: invalid shape\\n ${errors.slice(0, 20).join('\\n ')}${errors.length > 20 ? `\\n ... ${errors.length - 20} more` : ''}`)\n}\n","import { colorChannels, colorHex } from './color'\nimport { hashValue } from './hash'\nimport { asMat4, identity4, isAffine, matrixOf, multiply, normalMatrix, transformPoint } from './math'\nimport type { Matrix4 } from './math'\nimport { buildPrimitive, primitiveParameters } from './primitives'\nimport { canonicalJson } from './hash'\nimport { streamFor } from './random'\nimport { getGenerator } from './registry'\nimport { assertValidShape } from './schema'\nimport type {\n Bounds,\n GenerateOptions,\n InstancedBatch,\n NamedRange,\n PrimitiveBuffers,\n PrimitiveNode,\n ShapeBatch,\n ShapeBuffers,\n ShapeLevel,\n ShapeNode,\n ShapePart,\n ShapePoint,\n ShapeSchema,\n UvRect,\n} from './types'\n\nconst PRIMITIVE_KINDS = new Set(['box', 'cylinder', 'cone', 'sphere', 'plane', 'circle', 'ring', 'lathe', 'torus', 'extrude', 'difference', 'mesh'])\nexport const isPrimitiveNode = (node: ShapeNode): node is PrimitiveNode => PRIMITIVE_KINDS.has(node.kind)\n\n/** The options that change the output, as they enter the cache key. */\nexport function keyOptions(options: GenerateOptions = {}): Record<string, unknown> {\n return {\n seed: options.seed ?? 0,\n colors: options.colors ?? 'linear',\n indexed: options.indexed ?? true,\n materials: options.materials,\n fallbackMaterial: options.fallbackMaterial,\n materialAlias: options.materialAlias,\n instancing: options.instancing,\n levels: options.levels,\n }\n}\n\n/** The cache key of a shape under some options: 64-bit FNV-1a of the canonical schema text and the options that change the output. */\nexport const shapeKey = (schema: ShapeSchema, options: GenerateOptions = {}): string => hashValue({ schema, options: keyOptions(options) })\n\nconst IDENTITY_UV: UvRect = { u0: 0, v0: 0, u1: 1, v1: 1 }\n\nclass FloatList {\n array: Float32Array\n length = 0\n constructor(capacity = 256) {\n this.array = new Float32Array(capacity)\n }\n reserve(extra: number): void {\n if (this.length + extra <= this.array.length) return\n let capacity = this.array.length * 2\n while (capacity < this.length + extra) capacity *= 2\n const next = new Float32Array(capacity)\n next.set(this.array.subarray(0, this.length))\n this.array = next\n }\n done(): Float32Array {\n return this.array.slice(0, this.length)\n }\n}\nclass IndexList {\n array: Uint32Array\n length = 0\n constructor(capacity = 256) {\n this.array = new Uint32Array(capacity)\n }\n reserve(extra: number): void {\n if (this.length + extra <= this.array.length) return\n let capacity = this.array.length * 2\n while (capacity < this.length + extra) capacity *= 2\n const next = new Uint32Array(capacity)\n next.set(this.array.subarray(0, this.length))\n this.array = next\n }\n}\n\n/** Growing buffers of one (target, material). */\nclass Accumulator {\n readonly positions = new FloatList()\n readonly normals = new FloatList()\n readonly uvs = new FloatList(170)\n readonly colors = new FloatList()\n readonly indices = new IndexList()\n readonly ranges: NamedRange[] = []\n vertices = 0\n constructor(\n readonly material: string,\n readonly part: string | null,\n ) {}\n}\n\ninterface Target {\n readonly part: string | null\n readonly accs: Map<string, Accumulator>\n}\n\ninterface Settings {\n readonly colors: 'linear' | 'srgb' | 'none'\n readonly indexed: boolean\n readonly materials?: ReadonlySet<string>\n readonly fallback?: string\n readonly alias?: Readonly<Record<string, string>>\n readonly seed: number | string\n readonly generators?: GenerateOptions['generators']\n readonly autoMin?: number\n}\n\ninterface LevelSpec {\n readonly distance: number\n readonly detail: number\n readonly minSize?: number\n readonly minSegments?: number\n readonly index: number\n}\n\ninterface Inherited {\n readonly material: string\n readonly color: number\n readonly uv: UvRect\n readonly target: Target\n}\n\n/**\n * Bakes a template into an accumulator: positions by the world matrix, normals by its normal matrix and normalised, uvs into the atlas cell,\n * one colour for all, indices offset. The arithmetic is three's (`createMeshApi`, `BufferGeometry.applyMatrix4`), so the bits match.\n */\nfunction bake(acc: Accumulator, t: PrimitiveBuffers, world: readonly number[], rgb: readonly number[] | null, u: UvRect, indexed: boolean): void {\n const e = world\n const nm = normalMatrix(world)\n const affine = isAffine(world)\n const source = t.positions\n const count = source.length / 3\n const order: ArrayLike<number> | null = indexed ? null : t.indices ?? null\n const emitted = order ? order.length : count\n acc.positions.reserve(emitted * 3)\n acc.normals.reserve(emitted * 3)\n acc.uvs.reserve(emitted * 2)\n if (rgb) acc.colors.reserve(emitted * 3)\n const P = acc.positions.array\n const N = acc.normals.array\n const U = acc.uvs.array\n const C = acc.colors.array\n let pi = acc.positions.length\n let ni = acc.normals.length\n let ui = acc.uvs.length\n let ci = acc.colors.length\n const du = u.u1 - u.u0\n const dv = u.v1 - u.v0\n const tn = t.normals\n const tu = t.uvs\n for (let k = 0; k < emitted; k++) {\n const i = order ? (order[k] as number) : k\n const x = source[i * 3] as number\n const y = source[i * 3 + 1] as number\n const z = source[i * 3 + 2] as number\n if (affine) {\n P[pi++] = e[0]! * x + e[4]! * y + e[8]! * z + e[12]!\n P[pi++] = e[1]! * x + e[5]! * y + e[9]! * z + e[13]!\n P[pi++] = e[2]! * x + e[6]! * y + e[10]! * z + e[14]!\n } else {\n const p = transformPoint(e, x, y, z)\n P[pi++] = p[0]\n P[pi++] = p[1]\n P[pi++] = p[2]\n }\n const nx = tn[i * 3] as number\n const ny = tn[i * 3 + 1] as number\n const nz = tn[i * 3 + 2] as number\n const vx = nm[0]! * nx + nm[3]! * ny + nm[6]! * nz\n const vy = nm[1]! * nx + nm[4]! * ny + nm[7]! * nz\n const vz = nm[2]! * nx + nm[5]! * ny + nm[8]! * nz\n const s = 1 / (Math.sqrt(vx * vx + vy * vy + vz * vz) || 1)\n N[ni++] = vx * s\n N[ni++] = vy * s\n N[ni++] = vz * s\n U[ui++] = u.u0 + (tu[i * 2] as number) * du\n U[ui++] = u.v0 + (tu[i * 2 + 1] as number) * dv\n if (rgb) {\n C[ci++] = rgb[0]!\n C[ci++] = rgb[1]!\n C[ci++] = rgb[2]!\n }\n }\n acc.positions.length = pi\n acc.normals.length = ni\n acc.uvs.length = ui\n acc.colors.length = ci\n if (indexed) {\n const base = acc.vertices\n const idx = t.indices\n const n = idx ? idx.length : count\n acc.indices.reserve(n)\n const I = acc.indices.array\n let ii = acc.indices.length\n for (let k = 0; k < n; k++) I[ii++] = base + (idx ? (idx[k] as number) : k)\n acc.indices.length = ii\n }\n acc.vertices += emitted\n}\n\nfunction boundsOf(positions: Float32Array): Bounds {\n const min: [number, number, number] = [Infinity, Infinity, Infinity]\n const max: [number, number, number] = [-Infinity, -Infinity, -Infinity]\n for (let i = 0; i < positions.length; i += 3) {\n for (let axis = 0; axis < 3; axis++) {\n const v = positions[i + axis] as number\n if (v < min[axis]!) min[axis] = v\n if (v > max[axis]!) max[axis] = v\n }\n }\n return { min, max }\n}\n\nfunction finish(acc: Accumulator, indexed: boolean, withColors: boolean): ShapeBatch {\n const positions = acc.positions.done()\n const indices = indexed ? (acc.vertices > 65535 ? acc.indices.array.slice(0, acc.indices.length) : Uint16Array.from(acc.indices.array.subarray(0, acc.indices.length))) : undefined\n return {\n material: acc.material,\n part: acc.part,\n positions,\n normals: acc.normals.done(),\n uvs: acc.uvs.done(),\n ...(withColors ? { colors: acc.colors.done() } : {}),\n ...(indices ? { indices } : {}),\n ranges: acc.ranges,\n bounds: boundsOf(positions),\n }\n}\n\nconst radiusOf = (t: PrimitiveBuffers, world: readonly number[]): number => {\n let r = 0\n const p = t.positions\n for (let i = 0; i < p.length; i += 3) r = Math.max(r, Math.hypot(p[i] as number, p[i + 1] as number, p[i + 2] as number))\n const sx = Math.hypot(world[0]!, world[1]!, world[2]!)\n const sy = Math.hypot(world[4]!, world[5]!, world[6]!)\n const sz = Math.hypot(world[8]!, world[9]!, world[10]!)\n return r * Math.max(sx, sy, sz)\n}\n\ninterface LevelResult {\n readonly level: ShapeLevel\n readonly parts: ShapePart[]\n readonly points: ShapePoint[]\n readonly primitives: number\n}\n\n/** Expands a custom node into the node its generator returns (wrapped so that the custom node's own fields still apply). */\nfunction expandCustom(node: Extract<ShapeNode, { kind: 'custom' }>, settings: Settings, detail: number, path: string): ShapeNode {\n const generator = settings.generators?.[node.generator] ?? getGenerator(node.generator)\n if (!generator) throw new Error(`game-shapes: no generator \"${node.generator}\" (register it with registerGenerator, in the worker too) at ${path}`)\n const generated = generator(node.params, { random: streamFor(settings.seed, node.generator, path), seed: settings.seed, detail, path })\n const { kind: _kind, generator: _generator, params: _params, ...common } = node\n return { ...common, kind: 'group', children: [generated] }\n}\n\n/** The key two leaf primitives share when one can stand for the other as an instance. */\nconst leafKey = (node: PrimitiveNode, material: string, color: number, uv: UvRect, level: LevelSpec): string =>\n `${node.kind}|${canonicalJson(primitiveParameters(node, level))}|${material}|${color}|${uv.u0},${uv.v0},${uv.u1},${uv.v1}`\n\nfunction runLevel(schema: ShapeSchema, settings: Settings, level: LevelSpec): LevelResult {\n const bakeParts = level.index > 0\n const root: Target = { part: null, accs: new Map() }\n const targets: Target[] = [root]\n const partTargets = new Map<string, Target>()\n const parts: ShapePart[] = []\n const points: ShapePoint[] = []\n const instanced: InstancedBatch[] = []\n let primitives = 0\n const space = settings.colors === 'none' ? null : settings.colors\n const channels = new Map<number, readonly number[]>()\n const rgbOf = (hex: number): readonly number[] | null => {\n if (!space) return null\n let c = channels.get(hex)\n if (!c) {\n c = colorChannels(hex, space)\n channels.set(hex, c)\n }\n return c\n }\n const resolveMaterial = (id: string): string => {\n let out = id\n if (settings.materials && !settings.materials.has(out)) out = settings.fallback ?? out\n return settings.alias?.[out] ?? out\n }\n const accOf = (target: Target, material: string): Accumulator => {\n let acc = target.accs.get(material)\n if (!acc) {\n acc = new Accumulator(material, target.part)\n target.accs.set(material, acc)\n }\n return acc\n }\n\n // automatic instancing: count the leaves first\n const autoCounts = new Map<string, number>()\n const autoGroups = new Map<string, { node: PrimitiveNode; material: string; color: number; part: string | null; matrices: number[] }>()\n\n const count = (node: ShapeNode, inherited: { material: string; color: number; uv: UvRect; inPart: boolean }, path: string): void => {\n if (node.minDetail !== undefined && level.detail < node.minDetail) return\n if (node.kind === 'custom') return count(expandCustom(node, settings, level.detail, path), inherited, path)\n const next = {\n material: node.material !== undefined ? resolveMaterial(node.material) : inherited.material,\n color: node.color !== undefined ? colorHex(node.color) : inherited.color,\n uv: node.uv ?? inherited.uv,\n inPart: inherited.inPart || (node.part !== undefined && !bakeParts),\n }\n if (node.instances) return\n if (node.kind === 'group') {\n node.children?.forEach((child, index) => count(child, next, `${path}/${index}`))\n return\n }\n if (isPrimitiveNode(node) && node.name === undefined && !next.inPart) {\n const key = leafKey(node, next.material, next.color, next.uv, level)\n autoCounts.set(key, (autoCounts.get(key) ?? 0) + 1)\n }\n }\n const rootMaterial = resolveMaterial('default')\n if (settings.autoMin !== undefined) count(schema.root, { material: rootMaterial, color: 0xffffff, uv: IDENTITY_UV, inPart: false }, 'root')\n\n /** Draws a subtree into `collector` (a target) under `parent` (null: identity). */\n const visit = (node: ShapeNode, parent: Matrix4 | null, inherited: Inherited, path: string): void => {\n if (node.minDetail !== undefined && level.detail < node.minDetail) return\n if (node.kind === 'custom') return visit(expandCustom(node, settings, level.detail, path), parent, inherited, path)\n let target = inherited.target\n let parentWorld = parent\n if (node.part !== undefined) {\n if (bakeParts) {\n // far levels freeze the parts at rest: the part's pivot is relative to the root\n parentWorld = null\n } else {\n let partTarget = partTargets.get(node.part)\n if (!partTarget) {\n partTarget = { part: node.part, accs: new Map() }\n partTargets.set(node.part, partTarget)\n targets.push(partTarget)\n const { position, rotation, rotationOrder, scale, heading, matrix } = node\n parts.push({\n id: node.part,\n ...(position ? { position } : {}),\n ...(rotation ? { rotation } : {}),\n ...(rotationOrder ? { rotationOrder } : {}),\n ...(scale !== undefined ? { scale } : {}),\n ...(heading !== undefined ? { heading } : {}),\n ...(matrix ? { matrix } : { matrix: asMat4(matrixOf(node)) }),\n })\n }\n target = partTarget\n }\n }\n const isPart = node.part !== undefined && !bakeParts\n const local = isPart ? null : matrixOf(node)\n const world = isPart ? null : local ? (parentWorld ? multiply(parentWorld, local) : local) : parentWorld\n const next: Inherited = {\n material: node.material !== undefined ? resolveMaterial(node.material) : inherited.material,\n color: node.color !== undefined ? colorHex(node.color) : inherited.color,\n uv: node.uv ?? inherited.uv,\n target,\n }\n\n if (node.instances) {\n drawInstanced(node, parentWorld, next, path)\n return\n }\n\n const snapshot = node.name !== undefined ? new Map([...target.accs].map(([m, a]) => [m, { v: a.vertices, i: a.indices.length }])) : null\n\n if (node.kind === 'group') {\n node.children?.forEach((child, index) => visit(child, world, next, `${path}/${index}`))\n } else if (node.kind === 'point') {\n const p = node.position ?? [0, 0, 0]\n points.push({\n ...(node.name !== undefined ? { name: node.name } : {}),\n part: target.part,\n position: parent ? transformPoint(parent, p[0], p[1], p[2]) : [p[0], p[1], p[2]],\n ...(node.data !== undefined ? { data: node.data } : {}),\n ...(node.tags ? { tags: node.tags } : {}),\n })\n } else if (isPrimitiveNode(node)) {\n const template = buildPrimitive(node, level)\n const m = world ?? identity4()\n if (level.minSize !== undefined && radiusOf(template, m) < level.minSize) return\n primitives++\n if (settings.autoMin !== undefined && node.name === undefined && target.part === null) {\n const key = leafKey(node, next.material, next.color, next.uv, level)\n if ((autoCounts.get(key) ?? 0) >= settings.autoMin) {\n let group = autoGroups.get(key)\n if (!group) {\n group = { node, material: next.material, color: next.color, part: null, matrices: [] }\n autoGroups.set(key, group)\n }\n group.matrices.push(...m)\n return\n }\n }\n bake(accOf(target, next.material), template, m, rgbOf(next.color), next.uv, settings.indexed)\n }\n\n if (snapshot) {\n for (const [material, acc] of target.accs) {\n const before = snapshot.get(material) ?? { v: 0, i: 0 }\n if (acc.vertices === before.v) continue\n acc.ranges.push({\n name: node.name as string,\n ...(node.tags ? { tags: node.tags } : {}),\n vertexStart: before.v,\n vertexCount: acc.vertices - before.v,\n indexStart: before.i,\n indexCount: acc.indices.length - before.i,\n })\n }\n }\n }\n\n const drawInstanced = (node: ShapeNode, parentWorld: Matrix4 | null, inherited: Inherited, path: string): void => {\n const collector: Target = { part: inherited.target.part, accs: new Map() }\n const { instances, ...single } = node as ShapeNode & { instances: NonNullable<ShapeNode['instances']> }\n const before = parts.length\n visit(single as ShapeNode, null, { ...inherited, target: collector }, path)\n if (parts.length !== before) throw new Error(`game-shapes: an instanced node cannot hold parts (${path})`)\n const matrices = new Float32Array(instances.length * 16)\n const hasColors = instances.some((instance) => instance.color !== undefined)\n const colors = hasColors ? new Float32Array(instances.length * 3) : undefined\n instances.forEach((instance, index) => {\n const local = matrixOf(instance)\n const m = local ? (parentWorld ? multiply(parentWorld, local) : local) : parentWorld ?? identity4()\n matrices.set(m, index * 16)\n if (colors) colors.set(colorChannels(colorHex(instance.color), space ?? 'srgb'), index * 3)\n })\n for (const acc of collector.accs.values()) {\n const batch = finish(acc, settings.indexed, false)\n instanced.push({\n material: acc.material,\n part: collector.part,\n ...(node.name !== undefined ? { name: node.name } : {}),\n geometry: { type: 'BufferGeometry', parameters: {}, positions: batch.positions, normals: batch.normals, uvs: batch.uvs, ...(batch.indices ? { indices: batch.indices } : {}), groups: [] },\n matrices: matrices.slice(),\n ...(colors ? { colors: colors.slice() } : {}),\n count: instances.length,\n })\n }\n }\n\n visit(schema.root, null, { material: rootMaterial, color: 0xffffff, uv: IDENTITY_UV, target: root }, 'root')\n\n for (const group of autoGroups.values()) {\n const template = buildPrimitive(group.node, level)\n const n = group.matrices.length / 16\n const rgb = colorChannels(group.color, space ?? 'srgb')\n const colors = new Float32Array(n * 3)\n for (let i = 0; i < n; i++) colors.set(rgb, i * 3)\n instanced.push({\n material: group.material,\n part: null,\n geometry: { type: template.type, parameters: template.parameters, positions: template.positions.slice(), normals: template.normals.slice(), uvs: template.uvs.slice(), ...(template.indices ? { indices: template.indices.slice() } : {}), groups: template.groups.map((g) => ({ ...g })) },\n matrices: new Float32Array(group.matrices),\n ...(space ? { colors } : {}),\n count: n,\n })\n }\n\n const batches: ShapeBatch[] = []\n for (const target of targets) for (const acc of target.accs.values()) if (acc.vertices > 0 && (!settings.indexed || acc.indices.length > 0)) batches.push(finish(acc, settings.indexed, space !== null))\n return { level: { distance: level.distance, detail: level.detail, batches, instanced }, parts, points, primitives }\n}\n\n/**\n * Turns a shape into buffers: one batch per (part, material) per level, baked; instanced nodes as instance batches; parts with their pivots;\n * points. Pure: the same schema and options give the same bytes, here or in a worker.\n */\nexport function generate(schema: ShapeSchema, options: GenerateOptions = {}): ShapeBuffers {\n if (options.validate !== false) assertValidShape(schema)\n const settings: Settings = {\n colors: options.colors ?? 'linear',\n indexed: options.indexed ?? true,\n ...(options.materials ? { materials: new Set(options.materials) } : {}),\n ...(options.fallbackMaterial !== undefined ? { fallback: options.fallbackMaterial } : {}),\n ...(options.materialAlias ? { alias: options.materialAlias } : {}),\n seed: options.seed ?? 0,\n ...(options.generators ? { generators: options.generators } : {}),\n ...(options.instancing ? { autoMin: Math.max(2, options.instancing.minCount) } : {}),\n }\n const specs: LevelSpec[] = [{ distance: 0, detail: 1, index: 0 }, ...(schema.lod ?? []).map((rule, index) => ({ ...rule, index: index + 1 }))]\n const wanted = options.levels ? specs.filter((spec) => options.levels!.includes(spec.index)) : specs\n let parts: ShapePart[] = []\n let points: ShapePoint[] = []\n let primitives = 0\n const levels: ShapeLevel[] = []\n for (const spec of wanted) {\n const result = runLevel(schema, settings, spec)\n if (spec.index === 0 || levels.length === 0) {\n parts = result.parts\n points = result.points\n primitives = result.primitives\n }\n levels.push(result.level)\n }\n const first = levels[0]\n const vertices = first ? first.batches.reduce((sum, batch) => sum + batch.positions.length / 3, 0) : 0\n const triangles = first\n ? first.batches.reduce((sum, batch) => sum + (batch.indices ? batch.indices.length : batch.positions.length / 3) / 3, 0) +\n first.instanced.reduce((sum, batch) => sum + ((batch.geometry.indices ? batch.geometry.indices.length : batch.geometry.positions.length / 3) / 3) * batch.count, 0)\n : 0\n return {\n key: options.key === false ? '' : options.key ?? shapeKey(schema, options),\n ...(schema.name !== undefined ? { name: schema.name } : {}),\n levels,\n parts,\n points,\n ...(schema.materials ? { materials: schema.materials } : {}),\n ...(schema.cullDistance !== undefined ? { cullDistance: schema.cullDistance } : {}),\n stats: { vertices, triangles, batches: first ? first.batches.length : 0, instances: first ? first.instanced.reduce((sum, batch) => sum + batch.count, 0) : 0, primitives },\n }\n}\n","import { normalMatrix, transformPoint } from './math'\nimport type { InstancedBatch, PrimitiveBuffers, ShapeBatch, ShapeBuffers } from './types'\n\n/** One piece for `mergeTransformed`: arrays (any may be missing) and the matrix that takes them into the merged space. */\nexport interface TransformedPiece {\n readonly positions: ArrayLike<number>\n readonly normals?: ArrayLike<number>\n readonly uvs?: ArrayLike<number>\n readonly indices?: ArrayLike<number> | null\n /** Column-major 4 x 4. */\n readonly matrix: readonly number[]\n}\n\nexport interface MergedArrays {\n readonly positions: Float32Array\n readonly normals: Float32Array\n readonly uvs: Float32Array\n}\n\n/**\n * Joins pieces into one non-indexed set of arrays, each piece de-indexed, its missing normals and uvs zero-filled, its positions by\n * `Vector3.applyMatrix4` and its normals by the normal matrix and normalised: what three's `toNonIndexed` + `applyMatrix4` + a join do,\n * bit for bit (the port of `mergeByMaterial`).\n */\nexport function mergeTransformed(pieces: readonly TransformedPiece[]): MergedArrays {\n let total = 0\n for (const piece of pieces) total += piece.indices ? piece.indices.length : piece.positions.length / 3\n const positions = new Float32Array(total * 3)\n const normals = new Float32Array(total * 3)\n const uvs = new Float32Array(total * 2)\n let at = 0\n for (const piece of pieces) {\n const e = piece.matrix\n const nm = normalMatrix(e)\n const count = piece.indices ? piece.indices.length : piece.positions.length / 3\n // de-index into Float32 first, as toNonIndexed does, then transform the stored values\n const p = new Float32Array(count * 3)\n const n = new Float32Array(count * 3)\n for (let k = 0; k < count; k++) {\n const i = piece.indices ? (piece.indices[k] as number) : k\n for (let c = 0; c < 3; c++) {\n p[k * 3 + c] = piece.positions[i * 3 + c] as number\n if (piece.normals) n[k * 3 + c] = piece.normals[i * 3 + c] as number\n }\n if (piece.uvs) {\n uvs[(at + k) * 2] = piece.uvs[i * 2] as number\n uvs[(at + k) * 2 + 1] = piece.uvs[i * 2 + 1] as number\n }\n }\n for (let k = 0; k < count; k++) {\n const q = transformPoint(e, p[k * 3] as number, p[k * 3 + 1] as number, p[k * 3 + 2] as number)\n positions[(at + k) * 3] = q[0]\n positions[(at + k) * 3 + 1] = q[1]\n positions[(at + k) * 3 + 2] = q[2]\n const x = n[k * 3] as number\n const y = n[k * 3 + 1] as number\n const z = n[k * 3 + 2] as number\n const vx = nm[0]! * x + nm[3]! * y + nm[6]! * z\n const vy = nm[1]! * x + nm[4]! * y + nm[7]! * z\n const vz = nm[2]! * x + nm[5]! * y + nm[8]! * z\n const s = 1 / (Math.sqrt(vx * vx + vy * vy + vz * vz) || 1)\n normals[(at + k) * 3] = vx * s\n normals[(at + k) * 3 + 1] = vy * s\n normals[(at + k) * 3 + 2] = vz * s\n }\n at += count\n }\n return { positions, normals, uvs }\n}\n\nconst primitiveArrays = (p: PrimitiveBuffers): ArrayBuffer[] => [p.positions, p.normals, p.uvs, ...(p.indices ? [p.indices] : [])].map((a) => a.buffer as ArrayBuffer)\nconst batchArrays = (b: ShapeBatch): ArrayBuffer[] => [b.positions, b.normals, b.uvs, ...(b.colors ? [b.colors] : []), ...(b.indices ? [b.indices] : [])].map((a) => a.buffer as ArrayBuffer)\nconst instancedArrays = (b: InstancedBatch): ArrayBuffer[] => [...primitiveArrays(b.geometry), b.matrices.buffer as ArrayBuffer, ...(b.colors ? [b.colors.buffer as ArrayBuffer] : [])]\n\n/** Every `ArrayBuffer` of a result, for `postMessage(buffers, transferablesOf(buffers))`. */\nexport function transferablesOf(buffers: ShapeBuffers): ArrayBuffer[] {\n const out = new Set<ArrayBuffer>()\n for (const level of buffers.levels) {\n for (const batch of level.batches) for (const a of batchArrays(batch)) out.add(a)\n for (const batch of level.instanced) for (const a of instancedArrays(batch)) out.add(a)\n }\n return [...out]\n}\n\nconst copyPrimitive = (p: PrimitiveBuffers): PrimitiveBuffers => ({\n ...p,\n positions: p.positions.slice(),\n normals: p.normals.slice(),\n uvs: p.uvs.slice(),\n ...(p.indices ? { indices: p.indices.slice() } : {}),\n groups: p.groups.map((g) => ({ ...g })),\n})\n\n/** A deep copy whose arrays are its own (cached results are shared and read-only; copy before deforming). */\nexport function cloneBuffers(buffers: ShapeBuffers): ShapeBuffers {\n return {\n ...buffers,\n levels: buffers.levels.map((level) => ({\n ...level,\n batches: level.batches.map((b) => ({\n ...b,\n positions: b.positions.slice(),\n normals: b.normals.slice(),\n uvs: b.uvs.slice(),\n ...(b.colors ? { colors: b.colors.slice() } : {}),\n ...(b.indices ? { indices: b.indices.slice() } : {}),\n ranges: b.ranges.map((r) => ({ ...r })),\n bounds: { min: [...b.bounds.min], max: [...b.bounds.max] },\n })),\n instanced: level.instanced.map((b) => ({ ...b, geometry: copyPrimitive(b.geometry), matrices: b.matrices.slice(), ...(b.colors ? { colors: b.colors.slice() } : {}) })),\n })),\n }\n}\n\n/** Bytes held by the arrays of a result (what the cache counts). */\nexport function byteSizeOf(buffers: ShapeBuffers): number {\n return transferablesOf(buffers).reduce((sum, buffer) => sum + buffer.byteLength, 0)\n}\n","import { generate } from './generate'\nimport { transferablesOf } from './merge'\nimport type { GenerateOptions, ShapeBuffers, ShapeGenerator, ShapeSchema } from './types'\n\n/** A job the pool posts: `options` without `generators` (functions do not cross threads; register them in the worker script). */\nexport interface ShapeJob {\n readonly id: number\n readonly schema: ShapeSchema\n readonly options?: Omit<GenerateOptions, 'generators'>\n}\n\nexport type ShapeReply = { readonly id: number; readonly ok: true; readonly buffers: ShapeBuffers } | { readonly id: number; readonly ok: false; readonly error: string }\n\n/** What a worker scope looks like: `self` in a browser worker, a `worker_threads` `parentPort` wrapper in Node, or an in-thread fake. */\nexport interface WorkerScopeLike {\n onmessage: ((event: { data: unknown }) => void) | null\n postMessage(message: unknown, transfer?: ArrayBuffer[]): void\n}\n\nexport interface ShapeWorkerOptions {\n /** Generators of the `custom` nodes, the same ones the main thread registers. */\n readonly generators?: Readonly<Record<string, ShapeGenerator>>\n /** Transfer the arrays back (default true: zero copy, the worker keeps nothing). */\n readonly transfer?: boolean\n}\n\n/**\n * The worker side of `createShapePool`: answers each job with `generate(schema, options)`, transferring every array.\n *\n * ```ts\n * // shape-worker.ts\n * import { installShapeWorker } from '@adatechnology/game-shapes/worker'\n * installShapeWorker(self as never, { generators: myGenerators })\n * ```\n */\nexport function installShapeWorker(scope: WorkerScopeLike, options: ShapeWorkerOptions = {}): void {\n const transfer = options.transfer !== false\n scope.onmessage = (event) => {\n const job = event.data as ShapeJob\n try {\n const buffers = generate(job.schema, { ...(job.options ?? {}), ...(options.generators ? { generators: options.generators } : {}) })\n const reply: ShapeReply = { id: job.id, ok: true, buffers }\n scope.postMessage(reply, transfer ? transferablesOf(buffers) : [])\n } catch (error) {\n const reply: ShapeReply = { id: job.id, ok: false, error: error instanceof Error ? error.message : String(error) }\n scope.postMessage(reply)\n }\n }\n}\n","import type { PrimitiveBuffers, ShapeBatch } from '@adatechnology/game-shapes'\nimport type * as THREE_NS from 'three'\n\nexport type Three = typeof THREE_NS\n\nexport interface ToGeometryOptions {\n /** Copy the arrays into the attributes (default true). Without a copy the geometry shares the buffers (a cached result is read-only: do not deform it). */\n readonly copy?: boolean\n}\n\n/** The order in which three's generator of each type sets its attributes (toJSON and attribute iteration keep it). */\nconst UV_BEFORE_NORMAL = new Set(['LatheGeometry', 'ExtrudeGeometry'])\n/** Types whose constructor sets the index before the attributes. */\nconst INDEX_FIRST = new Set(['BoxGeometry', 'CylinderGeometry', 'ConeGeometry', 'SphereGeometry', 'PlaneGeometry', 'CircleGeometry', 'RingGeometry', 'LatheGeometry', 'TorusGeometry'])\n\nconst isPrimitive = (value: PrimitiveBuffers | ShapeBatch): value is PrimitiveBuffers => typeof (value as PrimitiveBuffers).type === 'string'\n\n/** Three's own parameters object for a type (lathe points as `Vector2`). */\nfunction threeParameters(THREE: Three, p: PrimitiveBuffers): Record<string, unknown> {\n if (p.type === 'LatheGeometry') {\n const points = (p.parameters.points as Array<{ x: number; y: number }>).map(({ x, y }) => new THREE.Vector2(x, y))\n return { ...p.parameters, points }\n }\n return { ...p.parameters }\n}\n\n/**\n * A `BufferGeometry` from game-shapes buffers. A primitive becomes an instance of the three class it reproduces (`type`, `parameters`, prototype:\n * `instanceof THREE.CylinderGeometry`, `clone()` and `toJSON()` behave as three's), with the same attributes, index and groups. A batch gets\n * `position`, `normal`, `uv`, `color` (when present) and its index.\n */\nexport function toGeometry(THREE: Three, source: PrimitiveBuffers | ShapeBatch, options: ToGeometryOptions = {}): THREE_NS.BufferGeometry {\n const copy = options.copy !== false\n const primitive = isPrimitive(source) ? source : null\n const ThreeClass = primitive && primitive.type !== 'BufferGeometry' ? ((THREE as unknown as Record<string, unknown>)[primitive.type] as (new () => THREE_NS.BufferGeometry) | undefined) : undefined\n // the BufferGeometry constructor only, with the prototype of the class it stands for\n const geometry = (ThreeClass ? Reflect.construct(THREE.BufferGeometry, [], ThreeClass) : new THREE.BufferGeometry()) as THREE_NS.BufferGeometry & { parameters?: Record<string, unknown> }\n if (primitive && ThreeClass) {\n Object.assign(geometry, { type: primitive.type, parameters: threeParameters(THREE, primitive) })\n }\n const attribute = (array: Float32Array, size: number): THREE_NS.BufferAttribute => (copy ? new THREE.Float32BufferAttribute(array, size) : new THREE.BufferAttribute(array, size))\n const index = source.indices\n const setIndex = (): void => {\n if (!index) return\n geometry.setIndex(copy ? (index instanceof Uint32Array ? new THREE.Uint32BufferAttribute(index, 1) : new THREE.Uint16BufferAttribute(index, 1)) : new THREE.BufferAttribute(index, 1))\n }\n const type = primitive?.type ?? 'BufferGeometry'\n if (INDEX_FIRST.has(type)) setIndex()\n geometry.setAttribute('position', attribute(source.positions, 3))\n if (UV_BEFORE_NORMAL.has(type)) {\n geometry.setAttribute('uv', attribute(source.uvs, 2))\n geometry.setAttribute('normal', attribute(source.normals, 3))\n } else {\n geometry.setAttribute('normal', attribute(source.normals, 3))\n geometry.setAttribute('uv', attribute(source.uvs, 2))\n }\n if (!primitive && (source as ShapeBatch).colors) geometry.setAttribute('color', attribute((source as ShapeBatch).colors as Float32Array, 3))\n if (!INDEX_FIRST.has(type)) setIndex()\n if (primitive) for (const group of primitive.groups) geometry.addGroup(group.start, group.count, group.materialIndex)\n return geometry\n}\n","import { box, circle, cone, cylinder, extrude, lathe, plane, ring, sphere, torus } from '@adatechnology/game-shapes'\nimport type { BevelSpec, PrimitiveBuffers, PrimitiveNode, ShapeOutline, Vec2 } from '@adatechnology/game-shapes'\nimport { buildPrimitive } from '@adatechnology/game-shapes'\nimport type * as THREE_NS from 'three'\n\nimport { toGeometry } from './geometry'\nimport type { Three } from './geometry'\n\n/** The geometry constructors `shapeGeometries` replaces. */\nexport const SHAPE_GEOMETRY_TYPES = ['BoxGeometry', 'CylinderGeometry', 'ConeGeometry', 'SphereGeometry', 'PlaneGeometry', 'CircleGeometry', 'RingGeometry', 'LatheGeometry', 'TorusGeometry', 'ExtrudeGeometry'] as const\n\ntype Curve = { isLineCurve?: boolean; v1?: { x: number; y: number }; v2?: { x: number; y: number } }\ntype PathLike = { curves: Curve[]; autoClose?: boolean; holes?: PathLike[] }\n\n/** The point list of a path made only of contiguous `LineCurve`s (what `moveTo` + `lineTo` builds), or null. */\nfunction linePoints(path: PathLike): Vec2[] | null {\n if (path.autoClose || path.curves.length === 0) return null\n const points: Vec2[] = []\n for (const [index, curve] of path.curves.entries()) {\n if (!curve.isLineCurve || !curve.v1 || !curve.v2) return null\n if (index === 0) points.push([curve.v1.x, curve.v1.y])\n else {\n const last = points[points.length - 1] as Vec2\n if (last[0] !== curve.v1.x || last[1] !== curve.v1.y) return null\n }\n points.push([curve.v2.x, curve.v2.y])\n }\n return points\n}\n\ntype ExtrudeOptions = { depth?: number; steps?: number; bevelEnabled?: boolean; bevelThickness?: number; bevelSize?: number; bevelOffset?: number; bevelSegments?: number; extrudePath?: unknown; UVGenerator?: unknown; curveSegments?: number }\n\n/** An extrusion game-shapes can make exactly: one straight-edged shape, no path, the world uvs. */\nfunction extrudeOf(shapes: unknown, options: ExtrudeOptions = {}): PrimitiveBuffers | null {\n if (Array.isArray(shapes) || !shapes || options.extrudePath !== undefined || options.UVGenerator !== undefined) return null\n const shape = shapes as PathLike\n const outer = linePoints(shape)\n if (!outer) return null\n const holes: Vec2[][] = []\n for (const hole of shape.holes ?? []) {\n const points = linePoints(hole)\n if (!points) return null\n holes.push(points)\n }\n const outline: ShapeOutline = holes.length ? { outer, holes } : { outer }\n const bevel: false | BevelSpec =\n options.bevelEnabled === false\n ? false\n : {\n ...(options.bevelThickness !== undefined ? { thickness: options.bevelThickness } : {}),\n ...(options.bevelSize !== undefined ? { size: options.bevelSize } : {}),\n ...(options.bevelOffset !== undefined ? { offset: options.bevelOffset } : {}),\n ...(options.bevelSegments !== undefined ? { segments: options.bevelSegments } : {}),\n }\n return extrude(outline, options.depth, options.steps, bevel)\n}\n\nexport interface ShapeGeometriesOptions {\n /** Go through the template cache of game-shapes (default true): the same primitive is generated once per process. */\n readonly cache?: boolean\n}\n\nconst namespaces = new WeakMap<object, Map<string, Three>>()\n/** The namespaces this module made: wrapping one again gives it back (a package handing its `T` to another). */\nconst shims = new WeakSet<object>()\n\n/**\n * A three namespace whose `BoxGeometry`, `CylinderGeometry`, `ConeGeometry`, `SphereGeometry`, `PlaneGeometry`, `CircleGeometry`, `RingGeometry`,\n * `LatheGeometry`, `TorusGeometry` and (straight-edged) `ExtrudeGeometry` are made by game-shapes, bit-identical to three's and instances of three's\n * classes; everything else is three's own. Hand it to code ported from the teams as `T`, so it keeps reading `new T.CylinderGeometry(...)`.\n * An extrusion with curves, several shapes, a path or a custom uv generator falls back to three.\n */\nexport function shapeGeometries(THREE: Three, options: ShapeGeometriesOptions = {}): Three {\n if (shims.has(THREE)) return THREE\n const cache = options.cache !== false\n const key = cache ? 'cache' : 'nocache'\n let byKey = namespaces.get(THREE)\n if (!byKey) {\n byKey = new Map()\n namespaces.set(THREE, byKey)\n }\n const existing = byKey.get(key)\n if (existing) return existing\n const made = (p: PrimitiveBuffers): THREE_NS.BufferGeometry => toGeometry(THREE, p)\n const viaCache = (node: PrimitiveNode, direct: () => PrimitiveBuffers): PrimitiveBuffers => (cache ? buildPrimitive(node) : direct())\n const defined = <T extends object>(o: T): T => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined)) as T\n const constructors: Record<(typeof SHAPE_GEOMETRY_TYPES)[number], (...args: any[]) => THREE_NS.BufferGeometry> = {\n BoxGeometry: (width?: number, height?: number, depth?: number, ws = 1, hs = 1, ds = 1) =>\n made(viaCache({ kind: 'box', size: [width ?? 1, height ?? 1, depth ?? 1], segments: [ws, hs, ds] }, () => box(width, height, depth, ws, hs, ds))),\n CylinderGeometry: (radiusTop?: number, radiusBottom?: number, height?: number, radialSegments?: number, heightSegments?: number, openEnded?: boolean, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'cylinder', ...defined({ radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }) }, () => cylinder(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))),\n ConeGeometry: (radius?: number, height?: number, radialSegments?: number, heightSegments?: number, openEnded?: boolean, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'cone', ...defined({ radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }) }, () => cone(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))),\n SphereGeometry: (radius?: number, widthSegments?: number, heightSegments?: number, phiStart?: number, phiLength?: number, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'sphere', ...defined({ radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength }) }, () => sphere(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength))),\n PlaneGeometry: (width?: number, height?: number, widthSegments?: number, heightSegments?: number) =>\n made(viaCache({ kind: 'plane', ...defined({ width, height, widthSegments, heightSegments }) }, () => plane(width, height, widthSegments, heightSegments))),\n CircleGeometry: (radius?: number, segments?: number, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'circle', ...defined({ radius, segments, thetaStart, thetaLength }) }, () => circle(radius, segments, thetaStart, thetaLength))),\n RingGeometry: (innerRadius?: number, outerRadius?: number, thetaSegments?: number, phiSegments?: number, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'ring', ...defined({ innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength }) }, () => ring(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength))),\n LatheGeometry: (points?: Array<{ x: number; y: number }>, segments?: number, phiStart?: number, phiLength?: number) => {\n if (!points) return new THREE.LatheGeometry(undefined, segments, phiStart, phiLength)\n const profile = points.map((p) => [p.x, p.y] as const)\n return made(viaCache({ kind: 'lathe', points: profile, ...defined({ segments, phiStart, phiLength }) }, () => lathe(profile, segments, phiStart, phiLength)))\n },\n TorusGeometry: (radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, arc?: number) =>\n made(viaCache({ kind: 'torus', ...defined({ radius, tube, radialSegments, tubularSegments, arc }) }, () => torus(radius, tube, radialSegments, tubularSegments, arc))),\n ExtrudeGeometry: (shapes?: unknown, extrudeOptions?: ExtrudeOptions) => {\n const buffers = shapes === undefined ? null : extrudeOf(shapes, extrudeOptions)\n if (!buffers) return new THREE.ExtrudeGeometry(shapes as THREE_NS.Shape, extrudeOptions as THREE_NS.ExtrudeGeometryOptions)\n const geometry = toGeometry(THREE, buffers) as THREE_NS.BufferGeometry & { parameters: unknown }\n geometry.parameters = { shapes, options: extrudeOptions ?? {} }\n return geometry\n },\n }\n const namespace: Record<string, unknown> = { ...(THREE as unknown as Record<string, unknown>) }\n for (const type of SHAPE_GEOMETRY_TYPES) {\n const make = constructors[type]\n // callable with `new` (the returned object wins), and `instanceof` checks three's prototype\n const Constructor = function (this: unknown, ...args: unknown[]) {\n return make(...args)\n } as unknown as { prototype: unknown }\n Constructor.prototype = (THREE as unknown as Record<string, { prototype: unknown }>)[type]!.prototype\n Object.defineProperty(Constructor, 'name', { value: type })\n namespace[type] = Constructor\n }\n const result = namespace as unknown as Three\n byKey.set(key, result)\n shims.add(result)\n return result\n}\n","import { colorHex } from '@adatechnology/game-shapes'\nimport type { MaterialHint, ShapeBuffers, ShapeLevel, ShapePart, ShapePoint } from '@adatechnology/game-shapes'\nimport type * as THREE_NS from 'three'\n\nimport { toGeometry } from './geometry'\nimport type { Three } from './geometry'\n\n/** A `MeshStandardMaterial` per material id from the schema's hints (vertex colours on unless the hint says otherwise). */\nexport function createMaterials(THREE: Three, hints: Readonly<Record<string, MaterialHint>> = {}, ids: Iterable<string> = []): Record<string, THREE_NS.Material> {\n const out: Record<string, THREE_NS.Material> = {}\n const all = new Set([...Object.keys(hints), ...ids])\n for (const id of all) {\n const hint = hints[id] ?? {}\n const parameters: THREE_NS.MeshStandardMaterialParameters = { vertexColors: hint.vertexColors ?? true }\n if (hint.color !== undefined) parameters.color = colorHex(hint.color)\n if (hint.roughness !== undefined) parameters.roughness = hint.roughness\n if (hint.metalness !== undefined) parameters.metalness = hint.metalness\n if (hint.opacity !== undefined) parameters.opacity = hint.opacity\n if (hint.transparent !== undefined) parameters.transparent = hint.transparent\n if (hint.emissive !== undefined) parameters.emissive = colorHex(hint.emissive)\n if (hint.emissiveIntensity !== undefined) parameters.emissiveIntensity = hint.emissiveIntensity\n if (hint.flatShading !== undefined) parameters.flatShading = hint.flatShading\n if (hint.depthWrite !== undefined) parameters.depthWrite = hint.depthWrite\n if (hint.side !== undefined) parameters.side = hint.side === 'double' ? THREE.DoubleSide : hint.side === 'back' ? THREE.BackSide : THREE.FrontSide\n const material = new THREE.MeshStandardMaterial(parameters)\n material.name = id\n out[id] = material\n }\n return out\n}\n\nexport interface ToObjectOptions {\n /** Materials by id; missing ids get one from the schema hints (`createMaterials`). */\n readonly materials?: Readonly<Record<string, THREE_NS.Material>>\n /** The material of one draw (wins over `materials`): per material id and part (`null` for the static body). */\n readonly materialFor?: (material: string, part: string | null) => THREE_NS.Material | undefined\n /** Cast and receive shadows (default true). */\n readonly shadows?: boolean\n /** Copy the arrays into the attributes (default true; false shares them, read-only). */\n readonly copy?: boolean\n /** Name of the root. */\n readonly name?: string\n}\n\nexport interface ShapeObject {\n /** A `Group`, or a `LOD` when the shape has levels or a cull distance. */\n readonly object: THREE_NS.Object3D\n /** The level 0 group (the root itself without LOD). */\n readonly near: THREE_NS.Group\n /** Part groups of level 0 by id, at their pivots; animate these. */\n readonly parts: Record<string, THREE_NS.Group>\n readonly meshes: THREE_NS.Mesh[]\n readonly instanced: THREE_NS.InstancedMesh[]\n readonly points: readonly ShapePoint[]\n readonly materials: Record<string, THREE_NS.Material>\n}\n\nfunction placePart(THREE: Three, group: THREE_NS.Group, part: ShapePart): void {\n if (part.matrix && part.position === undefined && part.rotation === undefined && part.scale === undefined && part.heading === undefined) {\n new THREE.Matrix4().fromArray(part.matrix as number[]).decompose(group.position, group.quaternion, group.scale)\n return\n }\n if (part.position) group.position.set(part.position[0], part.position[1], part.position[2])\n if (part.heading !== undefined) group.rotation.y = part.heading\n else if (part.rotation) group.rotation.set(part.rotation[0], part.rotation[1], part.rotation[2], part.rotationOrder ?? 'XYZ')\n if (part.scale !== undefined) {\n if (typeof part.scale === 'number') group.scale.setScalar(part.scale)\n else group.scale.set(part.scale[0], part.scale[1], part.scale[2])\n }\n group.updateMatrix()\n}\n\n/**\n * The three objects of a shape: one mesh per batch (`static:<material>` or `part:<id>`, `userData.material`, `userData.part`), part groups at their\n * pivots, an `InstancedMesh` per instanced batch, and a `LOD` (levels at their distances, nothing from `cullDistance`) when there are levels.\n */\nexport function toObject3D(THREE: Three, buffers: ShapeBuffers, options: ToObjectOptions = {}): ShapeObject {\n const shadows = options.shadows !== false\n const ids = new Set<string>()\n for (const level of buffers.levels) {\n for (const b of level.batches) ids.add(b.material)\n for (const b of level.instanced) ids.add(b.material)\n }\n const made = createMaterials(THREE, buffers.materials, [...ids].filter((id) => !options.materials?.[id]))\n const materials: Record<string, THREE_NS.Material> = { ...made, ...(options.materials ?? {}) }\n const materialOf = (id: string, part: string | null): THREE_NS.Material => options.materialFor?.(id, part) ?? (materials[id] as THREE_NS.Material)\n const meshes: THREE_NS.Mesh[] = []\n const instanced: THREE_NS.InstancedMesh[] = []\n\n const build = (level: ShapeLevel, withParts: boolean): { group: THREE_NS.Group; parts: Record<string, THREE_NS.Group> } => {\n const group = new THREE.Group()\n group.name = options.name ?? buffers.name ?? 'shape'\n const parts: Record<string, THREE_NS.Group> = {}\n if (withParts) {\n for (const part of buffers.parts) {\n const g = new THREE.Group()\n g.name = `part:${part.id}`\n g.userData.part = part.id\n placePart(THREE, g, part)\n parts[part.id] = g\n }\n }\n const into = (part: string | null): THREE_NS.Object3D => (part !== null && parts[part]) || group\n for (const batch of level.batches) {\n const mesh = new THREE.Mesh(toGeometry(THREE, batch, { copy: options.copy !== false }), materialOf(batch.material, batch.part))\n mesh.geometry.computeBoundingSphere()\n mesh.geometry.computeBoundingBox()\n mesh.name = batch.part === null ? `static:${batch.material}` : `part:${batch.part}`\n if (batch.part !== null) mesh.userData.part = batch.part\n mesh.userData.material = batch.material\n if (batch.ranges.length) mesh.userData.ranges = batch.ranges\n mesh.castShadow = shadows\n mesh.receiveShadow = shadows\n into(batch.part).add(mesh)\n meshes.push(mesh)\n }\n for (const batch of level.instanced) {\n const mesh = new THREE.InstancedMesh(toGeometry(THREE, batch.geometry, { copy: options.copy !== false }), materialOf(batch.material, batch.part), batch.count)\n mesh.instanceMatrix.array.set(batch.matrices)\n mesh.instanceMatrix.needsUpdate = true\n if (batch.colors) mesh.instanceColor = new THREE.InstancedBufferAttribute(batch.colors.slice(), 3)\n mesh.name = `instanced:${batch.name ?? batch.material}`\n mesh.userData.material = batch.material\n if (batch.part !== null) mesh.userData.part = batch.part\n mesh.castShadow = shadows\n mesh.receiveShadow = shadows\n mesh.computeBoundingSphere()\n into(batch.part).add(mesh)\n instanced.push(mesh)\n }\n for (const part of Object.values(parts)) group.add(part)\n return { group, parts }\n }\n\n const levels = buffers.levels\n const first = build(levels[0] ?? { distance: 0, detail: 1, batches: [], instanced: [] }, true)\n let object: THREE_NS.Object3D = first.group\n if (levels.length > 1 || buffers.cullDistance !== undefined) {\n const lod = new THREE.LOD()\n lod.name = first.group.name\n lod.addLevel(first.group, 0)\n for (const level of levels.slice(1)) lod.addLevel(build(level, false).group, level.distance)\n if (buffers.cullDistance !== undefined) lod.addLevel(new THREE.Group(), buffers.cullDistance)\n object = lod\n }\n object.userData.points = buffers.points\n return { object, near: first.group, parts: first.parts, meshes, instanced, points: buffers.points, materials }\n}\n","import { mergeTransformed } from '@adatechnology/game-shapes'\nimport type { TransformedPiece } from '@adatechnology/game-shapes'\nimport type * as THREE_NS from 'three'\n\nimport type { Three } from './geometry'\n\nconst isVisible = (object: THREE_NS.Object3D): boolean => {\n for (let node: THREE_NS.Object3D | null = object; node; node = node.parent) if (!node.visible) return false\n return true\n}\n\n/** A plain, non-interleaved, not normalised Float32 attribute: what the core merge reads directly. */\nconst plain = (attribute: THREE_NS.BufferAttribute | THREE_NS.InterleavedBufferAttribute | undefined): attribute is THREE_NS.BufferAttribute =>\n attribute !== undefined && !(attribute as THREE_NS.InterleavedBufferAttribute).isInterleavedBufferAttribute && attribute.array instanceof Float32Array && !attribute.normalized\n\n/** Arrays of a geometry the core merge can take as they are; for anything else, the arrays three's own `toNonIndexed` makes (then not indexed). */\nfunction piece(geometry: THREE_NS.BufferGeometry, matrix: THREE_NS.Matrix4): TransformedPiece {\n const position = geometry.getAttribute('position')\n const normal = geometry.getAttribute('normal')\n const uv = geometry.getAttribute('uv')\n const ok = plain(position) && (normal === undefined || plain(normal)) && (uv === undefined || plain(uv)) && position.itemSize === 3 && (uv === undefined || uv.itemSize === 2)\n if (ok) {\n return { positions: position.array, ...(normal ? { normals: normal.array } : {}), ...(uv ? { uvs: uv.array } : {}), indices: geometry.index ? geometry.index.array : null, matrix: matrix.elements }\n }\n const flat = geometry.index ? geometry.toNonIndexed() : geometry\n const read = (name: string, size: number): Float32Array | undefined => {\n const attribute = flat.getAttribute(name)\n if (!attribute) return undefined\n const out = new Float32Array(attribute.count * size)\n for (let i = 0; i < attribute.count; i++) for (let c = 0; c < size; c++) out[i * size + c] = c === 0 ? attribute.getX(i) : c === 1 ? attribute.getY(i) : attribute.getZ(i)\n return out\n }\n const positions = read('position', 3) as Float32Array\n const normals = read('normal', 3)\n const uvs = read('uv', 2)\n if (flat !== geometry) flat.dispose()\n return { positions, ...(normals ? { normals } : {}), ...(uvs ? { uvs } : {}), indices: null, matrix: matrix.elements }\n}\n\n/**\n * Every visible mesh under `root` (whose world matrix must be up to date), baked into the space of `space` and joined by material: one non-indexed\n * mesh per material (position, normal, uv), no shadow cast. The bake is game-shapes' `mergeTransformed`, bit-identical to three's\n * `toNonIndexed` + `applyMatrix4` + join, so the result is the one `game-props3d`'s `mergeByMaterial` always gave.\n */\nexport function mergeByMaterial(THREE: Three, root: THREE_NS.Object3D, space: THREE_NS.Object3D): THREE_NS.Mesh[] {\n const toSpace = space.matrixWorld.clone().invert()\n const byMaterial = new Map<THREE_NS.Material, TransformedPiece[]>()\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh || Array.isArray(mesh.material) || !isVisible(mesh)) return\n const list = byMaterial.get(mesh.material) ?? []\n list.push(piece(mesh.geometry, new THREE.Matrix4().multiplyMatrices(toSpace, mesh.matrixWorld)))\n byMaterial.set(mesh.material, list)\n })\n return [...byMaterial].map(([material, pieces]) => {\n const merged = mergeTransformed(pieces)\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(merged.positions, 3))\n geometry.setAttribute('normal', new THREE.BufferAttribute(merged.normals, 3))\n geometry.setAttribute('uv', new THREE.BufferAttribute(merged.uvs, 2))\n const mesh = new THREE.Mesh(geometry, material)\n mesh.castShadow = false\n mesh.receiveShadow = true\n return mesh\n })\n}\n","import type { Condition, DamageMaterial, PartKind } from './types'\n\n/** Keys of the material table. A piece / mesh refers to a key; `MaterialIds` maps it to a destruction SDK material id. */\nexport type MaterialKey = 'wood' | 'woodDry' | 'foliage' | 'flowers' | 'fruit' | 'pot' | 'soil' | 'cactus'\nexport type MaterialIds = Record<MaterialKey, string>\n\n/**\n * Default mapping to the common destruction SDK material ids (snake_case `MaterialId` strings, see game-destruction).\n * Nothing is imported from that package: these are plain strings, override any of them with the `materialIds` option.\n */\nexport const DEFAULT_MATERIAL_IDS: Readonly<MaterialIds> = Object.freeze({\n wood: 'green_wood',\n woodDry: 'wood_soft',\n foliage: 'foliage',\n flowers: 'foliage',\n fruit: 'flesh_fruit',\n pot: 'ceramic',\n soil: 'soil',\n cactus: 'cactus',\n})\n\nexport function resolveMaterialIds(overrides?: Partial<MaterialIds>): MaterialIds {\n return { ...DEFAULT_MATERIAL_IDS, ...(overrides ?? {}) }\n}\n\n/** Material key of a whole mesh part (wood of a dry / dead plant is dry wood; the cactus body and spines are 'cactus'). */\nexport function materialKeyForPart(part: PartKind, meshMaterial: DamageMaterial, condition: Condition = 'healthy'): MaterialKey {\n switch (part) {\n case 'wood':\n return condition === 'dry' || condition === 'dead' ? 'woodDry' : 'wood'\n case 'foliage':\n return meshMaterial === 'cactus' ? 'cactus' : 'foliage'\n case 'flowers':\n return 'flowers'\n case 'fruit':\n return 'fruit'\n default:\n return 'cactus'\n }\n}\n","/** FNV-1a 32-bit string hash. */\nexport function hashString(s: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n}\n\n/** Mix two uint32 values into one. */\nexport function hashMix(a: number, b: number): number {\n let h = (a ^ Math.imul(b, 0x9e3779b1)) >>> 0\n h = Math.imul(h ^ (h >>> 16), 0x85ebca6b)\n h = Math.imul(h ^ (h >>> 13), 0xc2b2ae35)\n return (h ^ (h >>> 16)) >>> 0\n}\n\nexport function toSeed(seed: number | string | undefined): number {\n if (seed === undefined) return 1\n if (typeof seed === 'string') return hashString(seed)\n return seed >>> 0 || 1\n}\n\n/** mulberry32 PRNG with small helpers. Never uses Math.random. */\nexport class Rng {\n private s: number\n constructor(seed: number) {\n this.s = seed >>> 0\n }\n next(): number {\n this.s = (this.s + 0x6d2b79f5) >>> 0\n let t = this.s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n range(a: number, b: number): number {\n return a + (b - a) * this.next()\n }\n int(a: number, b: number): number {\n return Math.floor(this.range(a, b + 1))\n }\n chance(p: number): boolean {\n return this.next() < p\n }\n sign(): number {\n return this.next() < 0.5 ? -1 : 1\n }\n pick<T>(arr: readonly T[]): T {\n return arr[Math.min(arr.length - 1, Math.floor(this.next() * arr.length))]\n }\n /** approx gaussian (sum of 3 uniforms), mean 0, roughly -1..1 */\n gauss(): number {\n return (this.next() + this.next() + this.next()) / 1.5 - 1\n }\n /** independent child generator derived from this one's seed and a label / index */\n fork(label: number | string): Rng {\n return new Rng(hashMix(this.s, typeof label === 'string' ? hashString(label) : label + 1))\n }\n /** a fresh uint32 derived without advancing structure-dependent streams */\n seed(): number {\n return Math.floor(this.next() * 4294967296) >>> 0\n }\n}\n\nexport function createRng(seed: number | string | undefined): Rng {\n return new Rng(toSeed(seed))\n}\n","import type { Vec3 } from './types'\n\nexport const TAU = Math.PI * 2\nexport const add = (a: Vec3, b: Vec3): Vec3 => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]\nexport const sub = (a: Vec3, b: Vec3): Vec3 => [a[0] - b[0], a[1] - b[1], a[2] - b[2]]\nexport const mul = (a: Vec3, s: number): Vec3 => [a[0] * s, a[1] * s, a[2] * s]\nexport const dot = (a: Vec3, b: Vec3): number => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\nexport const cross = (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]\nexport const len = (a: Vec3): number => Math.hypot(a[0], a[1], a[2])\nexport const dist = (a: Vec3, b: Vec3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2])\nexport const norm = (a: Vec3): Vec3 => {\n const l = len(a)\n return l < 1e-9 ? [0, 1, 0] : [a[0] / l, a[1] / l, a[2] / l]\n}\nexport const lerp = (a: number, b: number, t: number): number => a + (b - a) * t\nexport const lerp3 = (a: Vec3, b: Vec3, t: number): Vec3 => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t]\nexport const clamp = (v: number, a: number, b: number): number => (v < a ? a : v > b ? b : v)\nexport const smooth = (t: number): number => t * t * (3 - 2 * t)\n\n/** Rotate v around a unit axis by angle (Rodrigues). */\nexport function rotAxis(v: Vec3, axis: Vec3, ang: number): Vec3 {\n const c = Math.cos(ang)\n const s = Math.sin(ang)\n const k = cross(axis, v)\n const d = dot(axis, v) * (1 - c)\n return [v[0] * c + k[0] * s + axis[0] * d, v[1] * c + k[1] * s + axis[1] * d, v[2] * c + k[2] * s + axis[2] * d]\n}\nexport const rotY = (v: Vec3, a: number): Vec3 => {\n const c = Math.cos(a)\n const s = Math.sin(a)\n return [v[0] * c + v[2] * s, v[1], -v[0] * s + v[2] * c]\n}\n\n/** Any unit vector perpendicular to n. */\nexport function perp(n: Vec3): Vec3 {\n const a: Vec3 = Math.abs(n[1]) < 0.95 ? [0, 1, 0] : [1, 0, 0]\n return norm(cross(a, n))\n}\n\n/** Direction from azimuth (around +y, 0 = +x) and elevation (0 = horizontal, pi/2 = up). */\nexport function dirFromAngles(az: number, el: number): Vec3 {\n const c = Math.cos(el)\n return [Math.cos(az) * c, Math.sin(el), Math.sin(az) * c]\n}\n\n/** Local frame: world = o + x*lx + y*ly + z*lz. y is the \"axis\" direction. */\nexport interface Frame {\n o: Vec3\n x: Vec3\n y: Vec3\n z: Vec3\n}\nexport function frameFromAxis(o: Vec3, axis: Vec3, twist = 0): Frame {\n const y = norm(axis)\n let x = perp(y)\n if (twist) x = rotAxis(x, y, twist)\n const z = norm(cross(x, y))\n return { o, x, y, z }\n}\nexport function toWorld(f: Frame, l: Vec3): Vec3 {\n return [\n f.o[0] + f.x[0] * l[0] + f.y[0] * l[1] + f.z[0] * l[2],\n f.o[1] + f.x[1] * l[0] + f.y[1] * l[1] + f.z[1] * l[2],\n f.o[2] + f.x[2] * l[0] + f.y[2] * l[1] + f.z[2] * l[2],\n ]\n}\nexport function dirToWorld(f: Frame, l: Vec3): Vec3 {\n return [\n f.x[0] * l[0] + f.y[0] * l[1] + f.z[0] * l[2],\n f.x[1] * l[0] + f.y[1] * l[1] + f.z[1] * l[2],\n f.x[2] * l[0] + f.y[2] * l[1] + f.z[2] * l[2],\n ]\n}\n\n/** Catmull-Rom through points, `n` samples per span (including end points). */\nexport function catmull(pts: Vec3[], perSpan: number): Vec3[] {\n if (pts.length < 3 || perSpan <= 1) return pts.slice()\n const out: Vec3[] = []\n for (let i = 0; i < pts.length - 1; i++) {\n const p0 = pts[Math.max(0, i - 1)]\n const p1 = pts[i]\n const p2 = pts[i + 1]\n const p3 = pts[Math.min(pts.length - 1, i + 2)]\n for (let k = 0; k < perSpan; k++) {\n const t = k / perSpan\n const t2 = t * t\n const t3 = t2 * t\n const p: Vec3 = [0, 0, 0]\n for (let c = 0; c < 3; c++) {\n p[c] = 0.5 * (2 * p1[c] + (-p0[c] + p2[c]) * t + (2 * p0[c] - 5 * p1[c] + 4 * p2[c] - p3[c]) * t2 + (-p0[c] + 3 * p1[c] - 3 * p2[c] + p3[c]) * t3)\n }\n out.push(p)\n }\n }\n out.push(pts[pts.length - 1])\n return out\n}\n\n/** Point and tangent on a polyline at t in 0..1 (by index fraction). */\nexport function sampleLine(pts: Vec3[], t: number): { p: Vec3; d: Vec3 } {\n const f = clamp(t, 0, 1) * (pts.length - 1)\n const i = Math.min(pts.length - 2, Math.floor(f))\n const u = f - i\n return { p: lerp3(pts[i], pts[i + 1], u), d: norm(sub(pts[i + 1], pts[i])) }\n}\n","import type { Vec3, Condition } from './types'\nimport type { Rng } from './rng'\nimport { clamp, lerp3 } from './math'\n\n/** 0xRRGGBB -> sRGB triplet 0..1. All colors in this package are handled as sRGB triplets until MeshData is built (then linear). */\nexport function rgb(hex: number): Vec3 {\n return [((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255]\n}\n\nexport function toHsv(c: Vec3): Vec3 {\n const [r, g, b] = c\n const mx = Math.max(r, g, b)\n const mn = Math.min(r, g, b)\n const d = mx - mn\n let h = 0\n if (d > 1e-6) {\n if (mx === r) h = ((g - b) / d) % 6\n else if (mx === g) h = (b - r) / d + 2\n else h = (r - g) / d + 4\n h /= 6\n if (h < 0) h += 1\n }\n return [h, mx < 1e-6 ? 0 : d / mx, mx]\n}\n\nexport function fromHsv(h: number, s: number, v: number): Vec3 {\n h = ((h % 1) + 1) % 1\n const i = Math.floor(h * 6)\n const f = h * 6 - i\n const p = v * (1 - s)\n const q = v * (1 - f * s)\n const t = v * (1 - (1 - f) * s)\n switch (i % 6) {\n case 0:\n return [v, t, p]\n case 1:\n return [q, v, p]\n case 2:\n return [p, v, t]\n case 3:\n return [p, q, v]\n case 4:\n return [t, p, v]\n default:\n return [v, p, q]\n }\n}\n\nexport const shade = (c: Vec3, f: number): Vec3 => [clamp(c[0] * f, 0, 1), clamp(c[1] * f, 0, 1), clamp(c[2] * f, 0, 1)]\nexport const mix = (a: Vec3, b: Vec3, t: number): Vec3 => lerp3(a, b, t)\n\n/** Hue / value / saturation jitter (amounts are max deltas). */\nexport function jitter(c: Vec3, rng: Rng, hue = 0.02, val = 0.08, sat = 0.06): Vec3 {\n const [h, s, v] = toHsv(c)\n return fromHsv(h + rng.gauss() * hue, clamp(s + rng.gauss() * sat, 0, 1), clamp(v * (1 + rng.gauss() * val), 0, 1))\n}\n\n/** Warm the hue toward yellow and darken the top (used for lit tips). */\nexport function lighten(c: Vec3, amt: number): Vec3 {\n const [h, s, v] = toHsv(c)\n return fromHsv(h - amt * 0.03, clamp(s - amt * 0.12, 0, 1), clamp(v + amt * 0.35, 0, 1))\n}\n\nexport function srgbToLinear(v: number): number {\n return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4)\n}\n\nexport function linearToSrgb(v: number): number {\n return v <= 0.0031308 ? v * 12.92 : 1.055 * Math.pow(v, 1 / 2.4) - 0.055\n}\n\nconst DRY: Vec3 = [0.66, 0.56, 0.22]\nconst DEAD: Vec3 = [0.4, 0.35, 0.27]\nconst PALE: Vec3 = [0.74, 0.7, 0.5]\n\n/** Tint a leaf / green-tissue color by condition. */\nexport function tintGreen(c: Vec3, condition: Condition): Vec3 {\n switch (condition) {\n case 'dry':\n return mix(c, DRY, 0.55)\n case 'dead':\n return mix(c, DEAD, 0.85)\n case 'overgrown': {\n const [h, s, v] = toHsv(c)\n return fromHsv(h - 0.004, clamp(s * 1.08, 0, 1), v * 0.9)\n }\n default:\n return c\n }\n}\n\n/** Tint a succulent / cactus body color by condition (dead = pale and bleached). */\nexport function tintFlesh(c: Vec3, condition: Condition): Vec3 {\n switch (condition) {\n case 'dry':\n return mix(c, [0.62, 0.6, 0.34], 0.4)\n case 'dead':\n return mix(c, PALE, 0.8)\n case 'overgrown':\n return shade(c, 0.95)\n default:\n return c\n }\n}\n","import type { DamageMaterial, MeshData, PartKind, Vec3 } from '../types'\nimport { linearToSrgb, srgbToLinear } from '../color'\n\ntype ColorArg = Vec3\n\n/** Accumulates triangles with per-vertex color / sway. Colors are given as sRGB and converted to linear in `build`. */\nexport class MeshBuilder {\n pos: number[] = []\n nor: number[] = []\n col: number[] = []\n sway: number[] = []\n idx: number[] = []\n /** piece tag of every triangle (see Ctx.piece); '' = untagged */\n triTag: string[] = []\n /** tag given to the triangles emitted from now on */\n tag = ''\n /** centerlines of the tubes drawn so far with the piece tag they were drawn under (see `tube`), for piece geometry */\n tubes: { tag: string; path: Vec3[]; radii: number[] }[] = []\n /** after `build`: contiguous triangle-index ranges per tag, in index units (3 per triangle) */\n ranges: { tag: string; indexStart: number; indexCount: number }[] = []\n\n get triangleCount(): number {\n return this.idx.length / 3\n }\n get vertexCount(): number {\n return this.pos.length / 3\n }\n\n vert(p: Vec3, n: Vec3, c: ColorArg, s: number): number {\n const i = this.pos.length / 3\n this.pos.push(p[0], p[1], p[2])\n this.nor.push(n[0], n[1], n[2])\n this.col.push(c[0], c[1], c[2])\n this.sway.push(s < 0 ? 0 : s > 1 ? 1 : s)\n return i\n }\n tri(a: number, b: number, c: number): void {\n this.idx.push(a, b, c)\n this.triTag.push(this.tag)\n }\n\n /**\n * Flat shaded triangle. If `hint` is given the face is wound so that its normal faces that direction.\n * Colors / sway are per vertex (gradients across the face are kept).\n */\n flatTri(p0: Vec3, p1: Vec3, p2: Vec3, c0: ColorArg, c1: ColorArg, c2: ColorArg, s0: number, s1: number, s2: number, hint?: Vec3): void {\n const ux = p1[0] - p0[0]\n const uy = p1[1] - p0[1]\n const uz = p1[2] - p0[2]\n const vx = p2[0] - p0[0]\n const vy = p2[1] - p0[1]\n const vz = p2[2] - p0[2]\n let nx = uy * vz - uz * vy\n let ny = uz * vx - ux * vz\n let nz = ux * vy - uy * vx\n const l = Math.hypot(nx, ny, nz)\n if (l < 1e-12) return\n nx /= l\n ny /= l\n nz /= l\n if (hint && nx * hint[0] + ny * hint[1] + nz * hint[2] < 0) {\n // flip winding\n const n: Vec3 = [-nx, -ny, -nz]\n const a = this.vert(p0, n, c0, s0)\n const b = this.vert(p2, n, c2, s2)\n const c = this.vert(p1, n, c1, s1)\n this.tri(a, b, c)\n return\n }\n const n: Vec3 = [nx, ny, nz]\n const a = this.vert(p0, n, c0, s0)\n const b = this.vert(p1, n, c1, s1)\n const c = this.vert(p2, n, c2, s2)\n this.tri(a, b, c)\n }\n\n /** Flat triangle with a single color and sway. */\n flat(p0: Vec3, p1: Vec3, p2: Vec3, c: ColorArg, s: number, hint?: Vec3): void {\n this.flatTri(p0, p1, p2, c, c, c, s, s, s, hint)\n }\n\n /** Flat quad split along p0-p2. */\n flatQuad(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, c0: ColorArg, c1: ColorArg, c2: ColorArg, c3: ColorArg, s0: number, s1: number, s2: number, s3: number, hint?: Vec3): void {\n this.flatTri(p0, p1, p2, c0, c1, c2, s0, s1, s2, hint)\n this.flatTri(p0, p2, p3, c0, c2, c3, s0, s2, s3, hint)\n }\n\n /** Append already-built (linear) mesh data with a y-rotation, scale and translation. */\n appendMesh(m: MeshData, tx: number, ty: number, tz: number, ry = 0, scale = 1, tagOf?: (triangle: number) => string): void {\n const base = this.pos.length / 3\n const c = Math.cos(ry)\n const s = Math.sin(ry)\n const n = m.positions.length / 3\n for (let i = 0; i < n; i++) {\n const x = m.positions[i * 3] * scale\n const y = m.positions[i * 3 + 1] * scale\n const z = m.positions[i * 3 + 2] * scale\n this.pos.push(x * c + z * s + tx, y + ty, -x * s + z * c + tz)\n const nx = m.normals[i * 3]\n const nz = m.normals[i * 3 + 2]\n this.nor.push(nx * c + nz * s, m.normals[i * 3 + 1], -nx * s + nz * c)\n this.col.push(linearToSrgb(m.colors[i * 3]), linearToSrgb(m.colors[i * 3 + 1]), linearToSrgb(m.colors[i * 3 + 2]))\n this.sway.push(m.sway[i])\n }\n for (let i = 0; i < m.indices.length; i++) this.idx.push(m.indices[i] + base)\n for (let t = 0; t < m.indices.length / 3; t++) this.triTag.push(tagOf ? tagOf(t) : this.tag)\n }\n\n /** Make the triangles of every tag contiguous (stable, tags ordered by first appearance) and fill `ranges`. */\n private groupTriangles(): void {\n const nTri = this.idx.length / 3\n const order: string[] = []\n const count = new Map<string, number>()\n for (let t = 0; t < nTri; t++) {\n const tg = this.triTag[t]\n const c = count.get(tg)\n if (c === undefined) {\n order.push(tg)\n count.set(tg, 1)\n } else count.set(tg, c + 1)\n }\n // already contiguous?\n let contiguous = true\n const seen = new Set<string>()\n for (let t = 0; t < nTri && contiguous; t++) {\n const tg = this.triTag[t]\n if (t > 0 && tg === this.triTag[t - 1]) continue\n if (seen.has(tg)) contiguous = false\n seen.add(tg)\n }\n if (!contiguous) {\n const start = new Map<string, number>()\n let acc = 0\n for (const tg of order) {\n start.set(tg, acc)\n acc += count.get(tg)!\n }\n const idx = new Array<number>(this.idx.length)\n const tags = new Array<string>(nTri)\n for (let t = 0; t < nTri; t++) {\n const tg = this.triTag[t]\n const o = start.get(tg)!\n start.set(tg, o + 1)\n idx[o * 3] = this.idx[t * 3]\n idx[o * 3 + 1] = this.idx[t * 3 + 1]\n idx[o * 3 + 2] = this.idx[t * 3 + 2]\n tags[o] = tg\n }\n this.idx = idx\n this.triTag = tags\n }\n this.ranges = []\n let acc = 0\n for (const tg of order) {\n const c = count.get(tg)!\n this.ranges.push({ tag: tg, indexStart: acc * 3, indexCount: c * 3 })\n acc += c\n }\n }\n\n build(kind: PartKind, material: DamageMaterial): MeshData | undefined {\n if (this.idx.length === 0) return undefined\n this.groupTriangles()\n const n = this.pos.length / 3\n const colors = new Float32Array(n * 3)\n for (let i = 0; i < n * 3; i++) colors[i] = srgbToLinear(this.col[i])\n return {\n positions: new Float32Array(this.pos),\n normals: new Float32Array(this.nor),\n colors,\n sway: new Float32Array(this.sway),\n indices: new Uint32Array(this.idx),\n triangleCount: this.idx.length / 3,\n kind,\n material,\n }\n }\n}\n","import type { CrownShape, Vec3 } from '../types'\nimport type { Rng } from '../rng'\nimport { add, catmull, clamp, dirFromAngles, lerp, mul, norm, perp, rotAxis, cross, sub, TAU } from '../math'\n\nexport interface Branch {\n /** control points (smooth with catmull for rendering) */\n pts: Vec3[]\n radii: number[]\n level: number\n broken?: boolean\n}\nexport interface Tip {\n p: Vec3\n dir: Vec3\n /** relative size 0.7..1.3 */\n size: number\n level: number\n seed: number\n /** random 0..1 used to decide whether the tip keeps its leaves in dry / winter conditions */\n keep: number\n /** extra random 0..1 */\n roll: number\n}\nexport interface TreeShape {\n trunk: Branch\n branches: Branch[]\n tips: Tip[]\n /** center of the crown (for shading) */\n crown: Vec3\n trunkTopY: number\n}\n\nexport interface GrowParams {\n height: number\n trunkRadius: number\n crownRadius: number\n shape: CrownShape\n levels: number\n trunkFraction: number\n gnarl: number\n /** number of primary branches */\n primary: number\n lean: number\n /** 'bare' trees show twisted limbs, with broken stubs */\n bare?: boolean\n}\n\nfunction jitterDir(rng: Rng, d: Vec3, amt: number): Vec3 {\n return norm([d[0] + rng.gauss() * amt, d[1] + rng.gauss() * amt * 0.6, d[2] + rng.gauss() * amt])\n}\n\nfunction branchPath(rng: Rng, start: Vec3, dir0: Vec3, length: number, steps: number, upBias: number, droop: number, gnarl: number): Vec3[] {\n const pts: Vec3[] = [start]\n let d = dir0\n let p = start\n for (let i = 0; i < steps; i++) {\n const f = (i + 1) / steps\n d = norm(add(jitterDir(rng, d, gnarl), [0, upBias / steps - droop * f * f * 0.9, 0]))\n p = add(p, mul(d, length / steps))\n pts.push(p)\n }\n return pts\n}\n\nfunction taper(n: number, r0: number, r1: number): number[] {\n const out: number[] = []\n for (let i = 0; i < n; i++) out.push(lerp(r0, r1, Math.pow(i / (n - 1), 0.85)))\n return out\n}\n\n/** Grow the skeleton of a tree: trunk, nested branches and leaf-clump anchors. Consumes the same random numbers at every LOD. */\nexport function growTree(rng: Rng, p: GrowParams): TreeShape {\n const H = p.height\n const trunkTop = H * (p.shape === 'columnar' ? 0.97 : 0.93)\n const clearY = H * p.trunkFraction\n // trunk centerline\n const n = 7\n const ctrl: Vec3[] = []\n let ox = 0\n let oz = 0\n const lx = Math.cos(rng.range(0, TAU))\n const lz = Math.sin(rng.range(0, TAU))\n for (let i = 0; i < n; i++) {\n const f = i / (n - 1)\n if (i > 0) {\n ox += rng.gauss() * p.gnarl * H * 0.025\n oz += rng.gauss() * p.gnarl * H * 0.025\n }\n ctrl.push([ox + lx * p.lean * H * f * f, trunkTop * f, oz + lz * p.lean * H * f * f])\n }\n const tpts = catmull(ctrl, 3)\n const tr: number[] = []\n for (let i = 0; i < tpts.length; i++) {\n const f = i / (tpts.length - 1)\n tr.push(p.trunkRadius * (1 - 0.62 * f) * (1 + 0.5 * Math.exp(-f * 22)) * (f > 0.9 ? 0.85 : 1))\n }\n const trunk: Branch = { pts: tpts, radii: tr, level: 0 }\n const trunkAt = (y: number): { pos: Vec3; r: number } => {\n const f = Math.min(1, Math.max(0, y / trunkTop)) * (tpts.length - 1)\n const i = Math.min(tpts.length - 2, Math.floor(f))\n const u = f - i\n return { pos: [lerp(tpts[i][0], tpts[i + 1][0], u), lerp(tpts[i][1], tpts[i + 1][1], u), lerp(tpts[i][2], tpts[i + 1][2], u)], r: lerp(tr[i], tr[i + 1], u) }\n }\n\n const branches: Branch[] = []\n const tips: Tip[] = []\n const baseAz = rng.range(0, TAU)\n const golden = 2.399963\n const pushTip = (pos: Vec3, dir: Vec3, level: number, size: number): void => {\n tips.push({ p: pos, dir, size, level, seed: rng.seed(), keep: rng.next(), roll: rng.next() })\n }\n\n const grow = (start: Vec3, dir: Vec3, length: number, r0: number, level: number, fracStart: number, shapeUp: number, droop: number): void => {\n const steps = level === 1 ? 5 : 4\n const pts = branchPath(rng, start, dir, length, steps, shapeUp, droop, p.gnarl * 0.18)\n let radii = taper(pts.length, r0, Math.max(r0 * 0.22, 0.006))\n let broken = false\n if (p.bare && level >= 2 && rng.chance(0.3)) {\n // broken stub: cut short, blunt end\n pts.length = Math.max(2, Math.ceil(pts.length * rng.range(0.45, 0.7)))\n radii = radii.slice(0, pts.length)\n radii[radii.length - 1] = radii[radii.length - 2] * 0.7\n broken = true\n }\n branches.push({ pts: catmull(pts, 2), radii: catmull(radii.map((r) => [r, 0, 0] as Vec3), 2).map((v) => v[0]), level, broken })\n const last = pts[pts.length - 1]\n const lastDir = norm(sub(last, pts[pts.length - 2]))\n if (level >= p.levels || broken) {\n if (!broken) pushTip(last, lastDir, level, rng.range(0.85, 1.2))\n else rng.next()\n } else {\n // continue the branch with a tip and spawn children\n const kids = level === 1 ? rng.int(2, 3) : 2\n for (let k = 0; k < kids; k++) {\n const t = rng.range(0.4, 0.92) * (kids === 1 ? 1 : 1)\n const idx = Math.min(pts.length - 2, Math.floor(t * (pts.length - 1)))\n const u = t * (pts.length - 1) - idx\n const pos: Vec3 = [lerp(pts[idx][0], pts[idx + 1][0], u), lerp(pts[idx][1], pts[idx + 1][1], u), lerp(pts[idx][2], pts[idx + 1][2], u)]\n const pd = norm(sub(pts[idx + 1], pts[idx]))\n const axis = norm(cross(pd, perp(pd)))\n const rot = rotAxis(pd, rotAxis(axis, pd, rng.range(0, TAU)), rng.range(0.45, 0.95) * rng.sign())\n const cdir = norm(add(rot, [0, 0.25, 0]))\n grow(pos, cdir, length * rng.range(0.5, 0.68) * (1 - t * 0.35), radii[idx] * 0.62, level + 1, fracStart, shapeUp, droop)\n }\n if (!p.bare) pushTip(last, lastDir, level, rng.range(0.9, 1.2))\n else rng.next()\n }\n }\n\n for (let i = 0; i < p.primary; i++) {\n const f = p.primary === 1 ? 0 : i / (p.primary - 1)\n const y = lerp(clearY, trunkTop * 0.82, Math.pow(f, 0.9)) + rng.range(-0.04, 0.04) * H\n const { pos, r } = trunkAt(y)\n const az = baseAz + i * golden + rng.range(-0.25, 0.25)\n const hf = clamp((y - clearY) / Math.max(0.01, trunkTop - clearY), 0, 1)\n let el: number\n let lenK: number\n let up: number\n let droop = 0\n switch (p.shape) {\n case 'spreading':\n el = lerp(0.5, 0.18, 1 - hf) * (0.9 + rng.next() * 0.3)\n lenK = lerp(1.15, 0.75, hf)\n up = 0.25\n break\n case 'columnar':\n el = lerp(1.15, 1.35, hf)\n lenK = lerp(0.85, 0.5, hf)\n up = 0.25\n break\n case 'weeping':\n el = lerp(0.95, 0.6, 1 - hf)\n lenK = lerp(1.15, 0.7, hf)\n up = 0.5\n droop = 1.8\n break\n default:\n el = lerp(1.05, 0.62, 1 - hf) + rng.range(-0.1, 0.1)\n lenK = lerp(1.1, 0.7, Math.pow(hf, 1.3))\n up = 0.35\n }\n const dir = dirFromAngles(az, el)\n const start = add(pos, mul(norm([dir[0], 0, dir[2]]), r * 0.5))\n grow(start, dir, p.crownRadius * lenK * rng.range(0.85, 1.1), r * rng.range(0.4, 0.55), 1, f, up, droop)\n }\n // leader clump at the top\n const topPos = tpts[tpts.length - 1]\n pushTip(add(topPos, [0, H * 0.02, 0]), [0, 1, 0], 0, p.shape === 'columnar' ? 1.1 : 1.0)\n\n // crown center\n let cx = 0\n let cy = 0\n let cz = 0\n for (const t of tips) {\n cx += t.p[0]\n cy += t.p[1]\n cz += t.p[2]\n }\n const m = Math.max(1, tips.length)\n return { trunk, branches, tips, crown: [cx / m, cy / m - H * 0.04, cz / m], trunkTopY: trunkTop }\n}\n\n/**\n * Rescale branches and tips (not the trunk) so the crown reaches `height` and `reach` once clumps of radius `clumpR` sit on the tips.\n * Keeps the proportions honest whatever the random growth did.\n */\nexport function fitTree(tree: TreeShape, height: number, reach: number, clumpR: number, clearY: number, tipFilter?: (t: Tip) => boolean): void {\n let maxY = clearY + 0.01\n let maxR = 0.01\n for (const t of tree.tips) {\n if (tipFilter && !tipFilter(t)) continue\n maxY = Math.max(maxY, t.p[1])\n maxR = Math.max(maxR, Math.hypot(t.p[0], t.p[2]))\n }\n const sx = clamp((reach - clumpR * 0.7) / Math.max(0.1, maxR), 0.35, 1.8)\n const sy = clamp((height - clumpR * 0.55 - clearY) / Math.max(0.1, maxY - clearY), 0.4, 1.6)\n const f = (p: Vec3): void => {\n p[0] *= sx\n p[2] *= sx\n if (p[1] > clearY) p[1] = clearY + (p[1] - clearY) * sy\n }\n for (const b of tree.branches) for (const p of b.pts) f(p)\n for (const t of tree.tips) f(t.p)\n tree.crown = [tree.crown[0] * sx, clearY + (tree.crown[1] - clearY) * sy, tree.crown[2] * sx]\n}\n","import type { Vec3 } from '../types'\nimport { add, cross, mul, norm, perp, sub, TAU, dot } from '../math'\nimport type { MeshBuilder } from './builder'\n\nexport interface TubeOptions {\n sides: number\n /** radius per path point */\n radii: number[]\n /** color by position along the path (0..1) and angle fraction around (0..1) */\n color: (t: number, a: number) => Vec3\n /** wind sway by position along the path */\n sway: (t: number) => number\n /** close the far end: 'point' adds a short rounded tip, 'flat' a flat cap, 'none' leaves it open */\n end?: 'point' | 'flat' | 'none'\n /** smooth radial normals (default true) or flat faces */\n smooth?: boolean\n /** radius jitter per ring vertex for a hand-cut look, 0..0.3 */\n rough?: (ring: number, i: number) => number\n}\n\n/** Frames along a polyline by parallel transport. */\nexport function pathFrames(path: Vec3[]): { t: Vec3; n: Vec3; b: Vec3 }[] {\n const out: { t: Vec3; n: Vec3; b: Vec3 }[] = []\n let n: Vec3 | undefined\n for (let i = 0; i < path.length; i++) {\n const a = path[Math.max(0, i - 1)]\n const c = path[Math.min(path.length - 1, i + 1)]\n const tan = norm(sub(c, a))\n if (!n) n = perp(tan)\n else {\n // project previous normal onto the plane perpendicular to the new tangent\n n = sub(n, mul(tan, dot(n, tan)))\n n = norm(n)\n }\n out.push({ t: tan, n, b: norm(cross(tan, n)) })\n }\n return out\n}\n\n/** Tapered tube along a polyline. Returns the ring start indices so callers can attach things. */\nexport function tube(b: MeshBuilder, path: Vec3[], o: TubeOptions): void {\n const n = path.length\n if (n < 2) return\n b.tubes.push({ tag: b.tag, path, radii: o.radii })\n const frames = pathFrames(path)\n const S = o.sides\n const smooth = o.smooth !== false\n const rings: { p: Vec3; nr: Vec3; c: Vec3 }[][] = []\n for (let k = 0; k < n; k++) {\n const f = frames[k]\n const r = o.radii[k]\n const t = k / (n - 1)\n const ring: { p: Vec3; nr: Vec3; c: Vec3 }[] = []\n for (let i = 0; i < S; i++) {\n const a = (i / S) * TAU\n const ca = Math.cos(a)\n const sa = Math.sin(a)\n const dir: Vec3 = [f.n[0] * ca + f.b[0] * sa, f.n[1] * ca + f.b[1] * sa, f.n[2] * ca + f.b[2] * sa]\n const rr = r * (1 + (o.rough ? o.rough(k, i) : 0))\n ring.push({ p: add(path[k], mul(dir, rr)), nr: dir, c: o.color(t, i / S) })\n }\n rings.push(ring)\n }\n const sw = (k: number): number => o.sway(k / (n - 1))\n if (smooth) {\n const base: number[] = []\n for (let k = 0; k < n; k++) {\n base.push(b.vertexCount)\n for (let i = 0; i < S; i++) b.vert(rings[k][i].p, rings[k][i].nr, rings[k][i].c, sw(k))\n }\n for (let k = 0; k < n - 1; k++) {\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n const a0 = base[k] + i\n const a1 = base[k] + j\n const b0 = base[k + 1] + i\n const b1 = base[k + 1] + j\n b.tri(a0, a1, b0)\n b.tri(a1, b1, b0)\n }\n }\n } else {\n for (let k = 0; k < n - 1; k++) {\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n const hint = add(rings[k][i].nr, rings[k][j].nr)\n b.flatQuad(\n rings[k][i].p, rings[k + 1][i].p, rings[k + 1][j].p, rings[k][j].p,\n rings[k][i].c, rings[k + 1][i].c, rings[k + 1][j].c, rings[k][j].c,\n sw(k), sw(k + 1), sw(k + 1), sw(k), hint,\n )\n }\n }\n }\n const end = o.end ?? 'point'\n const last = n - 1\n if (end === 'point') {\n const tip = add(path[last], mul(frames[last].t, Math.max(o.radii[last] * 1.2, 0.005)))\n const tc = rings[last][0].c\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n b.flatTri(rings[last][i].p, rings[last][j].p, tip, rings[last][i].c, rings[last][j].c, tc, sw(last), sw(last), sw(last), add(rings[last][i].nr, frames[last].t))\n }\n } else if (end === 'flat') {\n const tc = rings[last][0].c\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n b.flatTri(rings[last][i].p, rings[last][j].p, path[last], rings[last][i].c, rings[last][j].c, tc, sw(last), sw(last), sw(last), frames[last].t)\n }\n }\n}\n\nexport interface RibbedOptions {\n ribs: number\n /** ridge radius per path point */\n radii: number[]\n /** valley radius as a fraction of the ridge radius */\n valley: number\n color: (t: number, ridge: boolean, rib: number) => Vec3\n sway: (t: number) => number\n /** extra rings that round off the end (dome) */\n dome?: number\n /** wobble of ridge radius for organic look (per ring, per rib) */\n rough?: (ring: number, rib: number) => number\n}\n\nexport interface RibbedInfo {\n /** ridge world positions per ring and rib (for attaching spines) */\n ridges: { p: Vec3; n: Vec3; t: number; rib: number; ring: number }[]\n end: Vec3\n}\n\n/** Ribbed column (cactus): 2*ribs vertices per ring alternating ridge and valley, flat shaded. */\nexport function ribbedTube(b: MeshBuilder, path: Vec3[], o: RibbedOptions): RibbedInfo {\n b.tubes.push({ tag: b.tag, path, radii: o.radii })\n const frames = pathFrames(path)\n const pts = path.slice()\n const radii = o.radii.slice()\n const fr = frames.slice()\n const domeN = o.dome ?? 0\n const lastR = o.radii[o.radii.length - 1]\n const lastF = frames[frames.length - 1]\n const lastP = path[path.length - 1]\n for (let j = 1; j <= domeN; j++) {\n const a = (j / (domeN + 1)) * (Math.PI / 2)\n pts.push(add(lastP, mul(lastF.t, lastR * Math.sin(a) * 0.9)))\n radii.push(lastR * Math.cos(a))\n fr.push(lastF)\n }\n const apex = add(lastP, mul(lastF.t, lastR * (domeN > 0 ? 0.95 : 0.2)))\n const S = o.ribs * 2\n const N = pts.length\n const rings: { p: Vec3; nr: Vec3; c: Vec3 }[][] = []\n const info: RibbedInfo = { ridges: [], end: apex }\n const swayAt = (k: number): number => o.sway(k / (N - 1))\n for (let k = 0; k < N; k++) {\n const f = fr[k]\n const ring: { p: Vec3; nr: Vec3; c: Vec3 }[] = []\n for (let i = 0; i < S; i++) {\n const ridge = i % 2 === 0\n const rib = i >> 1\n const a = (i / S) * TAU\n const dir: Vec3 = [f.n[0] * Math.cos(a) + f.b[0] * Math.sin(a), f.n[1] * Math.cos(a) + f.b[1] * Math.sin(a), f.n[2] * Math.cos(a) + f.b[2] * Math.sin(a)]\n const wob = o.rough ? o.rough(k, rib) : 0\n const rr = radii[k] * (ridge ? 1 + wob : o.valley)\n const p = add(pts[k], mul(dir, rr))\n const c = o.color(Math.min(1, k / (path.length - 1)), ridge, rib)\n ring.push({ p, nr: dir, c })\n if (ridge && k < path.length) info.ridges.push({ p, n: dir, t: k / (path.length - 1), rib, ring: k })\n }\n rings.push(ring)\n }\n for (let k = 0; k < N - 1; k++) {\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n const hint = add(rings[k][i].nr, rings[k][j].nr)\n b.flatQuad(\n rings[k][i].p, rings[k + 1][i].p, rings[k + 1][j].p, rings[k][j].p,\n rings[k][i].c, rings[k + 1][i].c, rings[k + 1][j].c, rings[k][j].c,\n swayAt(k), swayAt(k + 1), swayAt(k + 1), swayAt(k), hint,\n )\n }\n }\n const lastRing = rings[N - 1]\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n b.flatTri(lastRing[i].p, lastRing[j].p, apex, lastRing[i].c, lastRing[j].c, lastRing[0].c, swayAt(N - 1), swayAt(N - 1), swayAt(N - 1), add(lastRing[i].nr, lastF.t))\n }\n return info\n}\n","import type { Lod, Vec3 } from '../types'\nimport { clamp } from '../math'\nimport { shade, mix } from '../color'\nimport type { MeshBuilder } from './builder'\nimport { tube } from './tube'\nimport type { Branch } from './branches'\n\n/** Bark color function: vertical bands, angular ribs, darker toward the ground, lighter young tips. */\nexport function barkColor(base: Vec3, level: number, seed = 0): (t: number, a: number) => Vec3 {\n const lightTip: Vec3 = shade(base, 1.18)\n return (t, a) => {\n const band = 0.93 + 0.07 * Math.sin(t * (level === 0 ? 38 : 16) + seed)\n const rib = 0.92 + 0.08 * Math.cos(a * Math.PI * 2 * 3 + seed * 1.7 + t * 2.2)\n let k = band * rib\n if (level === 0) k *= 0.8 + 0.2 * clamp(t * 7, 0, 1)\n const c = shade(base, k * 1.5)\n return level === 0 ? c : mix(c, lightTip, clamp(t * 0.8, 0, 1) * 0.5)\n }\n}\n\n/** Draw a branch / trunk as a tapered tube, thinning the path by lod. */\nexport function drawBranch(b: MeshBuilder, br: Branch, bark: Vec3, lod: Lod, seed = 0): void {\n const maxLevel = lod === 0 ? 99 : lod === 1 ? 2 : 1\n if (br.level > maxLevel) return\n const stride = lod === 0 ? (br.level >= 1 ? 2 : 1) : lod === 1 ? (br.level >= 1 ? 3 : 2) : br.level === 0 ? 4 : 3\n const pts: Vec3[] = []\n const radii: number[] = []\n for (let i = 0; i < br.pts.length; i += stride) {\n pts.push(br.pts[i])\n radii.push(br.radii[i])\n }\n if ((br.pts.length - 1) % stride !== 0) {\n pts.push(br.pts[br.pts.length - 1])\n radii.push(br.radii[br.radii.length - 1])\n }\n if (pts.length < 2) return\n const sides = br.level === 0 ? (lod === 0 ? 8 : lod === 1 ? 6 : 4) : br.level === 1 ? (lod === 0 ? 5 : 3) : lod === 0 ? 4 : 3\n const lv = br.level\n tube(b, pts, {\n sides,\n radii,\n color: barkColor(bark, lv, seed),\n sway: (t) => (lv === 0 ? 0.03 * t : clamp(0.06 * lv + 0.22 * t, 0, 0.5)),\n end: br.broken ? 'flat' : 'point',\n })\n}\n","import type { Vec3 } from '../types'\nimport { norm } from '../math'\n\nexport interface IcoTemplate {\n verts: Vec3[]\n faces: [number, number, number][]\n}\n\nconst cache = new Map<number, IcoTemplate>()\n\n/** Unit icosphere template: detail 0 = 20 faces, 1 = 80, 2 = 320. */\nexport function icoTemplate(detail: number): IcoTemplate {\n const hit = cache.get(detail)\n if (hit) return hit\n const t = (1 + Math.sqrt(5)) / 2\n const verts: Vec3[] = [\n [-1, t, 0], [1, t, 0], [-1, -t, 0], [1, -t, 0],\n [0, -1, t], [0, 1, t], [0, -1, -t], [0, 1, -t],\n [t, 0, -1], [t, 0, 1], [-t, 0, -1], [-t, 0, 1],\n ].map((v) => norm(v as Vec3))\n let faces: [number, number, number][] = [\n [0, 11, 5], [0, 5, 1], [0, 1, 7], [0, 7, 10], [0, 10, 11],\n [1, 5, 9], [5, 11, 4], [11, 10, 2], [10, 7, 6], [7, 1, 8],\n [3, 9, 4], [3, 4, 2], [3, 2, 6], [3, 6, 8], [3, 8, 9],\n [4, 9, 5], [2, 4, 11], [6, 2, 10], [8, 6, 7], [9, 8, 1],\n ]\n for (let d = 0; d < detail; d++) {\n const mid = new Map<string, number>()\n const midpoint = (a: number, b: number): number => {\n const key = a < b ? a + '_' + b : b + '_' + a\n const h = mid.get(key)\n if (h !== undefined) return h\n const va = verts[a]\n const vb = verts[b]\n verts.push(norm([(va[0] + vb[0]) / 2, (va[1] + vb[1]) / 2, (va[2] + vb[2]) / 2]))\n mid.set(key, verts.length - 1)\n return verts.length - 1\n }\n const next: [number, number, number][] = []\n for (const [a, b, c] of faces) {\n const ab = midpoint(a, b)\n const bc = midpoint(b, c)\n const ca = midpoint(c, a)\n next.push([a, ab, ca], [b, bc, ab], [c, ca, bc], [ab, bc, ca])\n }\n faces = next\n }\n const res = { verts, faces }\n cache.set(detail, res)\n return res\n}\n","import type { Vec3 } from '../types'\nimport { add, cross, mul, norm, dot } from '../math'\nimport { mix, shade } from '../color'\nimport type { MeshBuilder } from './builder'\n\nexport interface LeafOptions {\n /** tip droop as a fraction of length, along -up (default 0.18) */\n curl?: number\n /** midrib lift as a fraction of half-width (default 0.5): leaves are folded, never flat cards */\n fold?: number\n /** rows along the length; 2 = 4 triangles, 3 = 8, ... (default 2) */\n rows?: number\n /** width at the base as a fraction of the max width (default 0) */\n baseWidth?: number\n /** sway at the base and at the tip */\n swayBase: number\n swayTip: number\n /** peak of the width profile along the length 0..1 (default 0.38) */\n peak?: number\n /** rounder tip: profile exponent (default 1) */\n round?: number\n /** edge darkening factor for the leaf edges (default 0.92) */\n edge?: number\n /** width multiplier of the edge vertices per row and side (tears / notches); <1 pulls the edge in */\n tear?: (row: number, side: -1 | 1) => number\n}\n\n/**\n * Folded, slightly drooping leaf (bent strip with a midrib). `up` is the direction the upper face looks to.\n * 4 triangles with rows = 2.\n */\nexport function leaf(b: MeshBuilder, base: Vec3, dir: Vec3, up: Vec3, length: number, width: number, c0: Vec3, c1: Vec3, o: LeafOptions): void {\n const d = norm(dir)\n let right = cross(d, up)\n if (dot(right, right) < 1e-6) right = cross(d, [1, 0, 0])\n right = norm(right)\n const n2 = norm(cross(right, d))\n const rows = o.rows ?? 2\n const curl = o.curl ?? 0.18\n const fold = o.fold ?? 0.5\n const peak = o.peak ?? 0.38\n const round = o.round ?? 1\n const edgeK = o.edge ?? 0.92\n const bw = o.baseWidth ?? 0\n type Row = { c: Vec3; w: number; col: Vec3; s: number }\n const rr: Row[] = []\n for (let i = 0; i <= rows; i++) {\n const t = i / rows\n let w: number\n if (t < peak) w = bw + (1 - bw) * Math.sin((t / peak) * Math.PI * 0.5)\n else w = Math.pow(Math.cos(((t - peak) / (1 - peak)) * Math.PI * 0.5), round)\n w *= width * 0.5\n const centre = add(add(base, mul(d, length * t)), mul(n2, -length * curl * t * t))\n rr.push({ c: centre, w: i === rows ? 0 : w, col: mix(c0, c1, t), s: o.swayBase + (o.swayTip - o.swayBase) * t })\n }\n const verts = rr.map((r, i) => {\n const hasWidth = r.w > 1e-6\n const edgeC = shade(r.col, edgeK)\n const lift = r.w * fold\n const mid = add(r.c, mul(n2, hasWidth ? lift : 0))\n const tl = o.tear ? o.tear(i, -1) : 1\n const tr = o.tear ? o.tear(i, 1) : 1\n const L = hasWidth ? add(add(r.c, mul(right, -r.w * tl)), mul(n2, -r.w * 0.12)) : r.c\n const R = hasWidth ? add(add(r.c, mul(right, r.w * tr)), mul(n2, -r.w * 0.12)) : r.c\n return { L, M: mid, R, c: r.col, e: edgeC, s: r.s, w: r.w, i }\n })\n for (let i = 0; i < rows; i++) {\n const a = verts[i]\n const z = verts[i + 1]\n const aw = a.w > 1e-6\n const zw = z.w > 1e-6\n if (!aw && zw) {\n b.flatTri(a.M, z.L, z.M, a.c, z.e, z.c, a.s, z.s, z.s, n2)\n b.flatTri(a.M, z.M, z.R, a.c, z.c, z.e, a.s, z.s, z.s, n2)\n } else if (aw && !zw) {\n b.flatTri(a.L, z.M, a.M, a.e, z.c, a.c, a.s, z.s, a.s, n2)\n b.flatTri(a.M, z.M, a.R, a.c, z.c, a.e, a.s, z.s, a.s, n2)\n } else if (aw && zw) {\n b.flatQuad(a.L, z.L, z.M, a.M, a.e, z.e, z.c, a.c, a.s, z.s, z.s, a.s, n2)\n b.flatQuad(a.M, z.M, z.R, a.R, a.c, z.c, z.e, a.e, a.s, z.s, z.s, a.s, n2)\n }\n }\n}\n\n\n/** Cheap leaflet / pinna: 2 triangles with a slight fold. */\nexport function kite(b: MeshBuilder, base: Vec3, dir: Vec3, up: Vec3, length: number, width: number, c0: Vec3, c1: Vec3, sway0: number, sway1: number, lift = 0.35): void {\n const d = norm(dir)\n let right = cross(d, up)\n if (dot(right, right) < 1e-6) right = cross(d, [1, 0, 0])\n right = norm(right)\n const n2 = norm(cross(right, d))\n const m = add(base, mul(d, length * 0.4))\n const hw = width * 0.5\n const L = add(add(m, mul(right, -hw)), mul(n2, hw * lift))\n const R = add(add(m, mul(right, hw)), mul(n2, hw * lift))\n const T = add(add(base, mul(d, length)), mul(n2, -length * 0.08))\n const cm = mix(c0, c1, 0.4)\n b.flatTri(base, L, R, c0, cm, cm, sway0, sway0 + (sway1 - sway0) * 0.4, sway0 + (sway1 - sway0) * 0.4, n2)\n b.flatTri(L, T, R, cm, c1, cm, sway0 + (sway1 - sway0) * 0.4, sway1, sway0 + (sway1 - sway0) * 0.4, n2)\n}\n","import type { Vec3 } from '../types'\nimport { add, mul, norm, sub, dot, clamp, smooth, lerp, dist, type Frame, toWorld } from '../math'\nimport { jitter, lighten, mix, shade } from '../color'\nimport { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\nimport { icoTemplate } from './ico'\nimport { leaf } from './leaf'\n\nexport interface ShellVertex {\n p: Vec3\n /** unit direction from the shell center (local space) */\n dir: Vec3\n /** 0 at the bottom, 1 at the top */\n h: number\n}\n\nexport interface ShellOptions {\n center: Vec3\n /** radii along local x / y / z */\n radii: Vec3\n frame?: Frame\n detail: 0 | 1 | 2\n rng?: Rng\n /** radial noise amplitude (fraction of radius) */\n noise: number\n /** squash of the lower part (0 none .. 1 flat bottom) */\n flatBottom?: number\n color: (v: ShellVertex) => Vec3\n sway: (v: ShellVertex) => number\n}\n\n/** Faceted, noisy, flat shaded ellipsoid shell. Returns the displaced vertices. */\nexport function icoShell(b: MeshBuilder, o: ShellOptions): ShellVertex[] {\n const tpl = icoTemplate(o.detail)\n const verts: ShellVertex[] = tpl.verts.map((u) => {\n let r = 1 + (o.rng && o.noise ? o.rng.gauss() * o.noise : 0)\n let y = u[1]\n if (o.flatBottom && y < 0) y *= 1 - o.flatBottom * 0.7 * Math.min(1, -y * 1.4)\n r = Math.max(0.5, r)\n const l: Vec3 = [u[0] * o.radii[0] * r, y * o.radii[1] * r, u[2] * o.radii[2] * r]\n const p = o.frame ? toWorld(o.frame, l) : add(o.center, l)\n return { p, dir: u, h: clamp((u[1] + 1) / 2, 0, 1) }\n })\n const origin = o.frame ? o.frame.o : o.center\n const colors = verts.map((v) => o.color(v))\n const sways = verts.map((v) => o.sway(v))\n for (const [a, bb, c] of tpl.faces) {\n const hint = sub(add(add(verts[a].p, verts[bb].p), verts[c].p), mul(origin, 3))\n b.flatTri(verts[a].p, verts[bb].p, verts[c].p, colors[a], colors[bb], colors[c], sways[a], sways[bb], sways[c], hint)\n }\n return verts\n}\n\nexport interface ClumpOptions {\n center: Vec3\n radius: number\n /** vertical radius ratio (default 0.78) */\n squash?: number\n detail: 0 | 1 | 2\n seed: number\n /** base leaf color (sRGB) */\n base: Vec3\n /** crown center: vertices facing away from it are brighter, facing it darker */\n crown?: Vec3\n /** accent color mixed on top (flowers / new growth), 0..1 amount */\n accent?: { color: Vec3; amount: number }\n /** leaves poking out of the surface: count (LOD0 only) and length */\n leaves?: { count: number; length: number; width?: number }\n /** sway multiplier (trees move little, shrubs more) */\n swayK: number\n noise?: number\n flatBottom?: number\n /** minimum brightness at the bottom (default 0.5) */\n ao?: number\n}\n\n/** Leaf clump: deformed low poly shell with gradient colors and optional small leaves on the surface. */\nexport function clump(b: MeshBuilder, o: ClumpOptions): void {\n const rng = new Rng(o.seed)\n const base = jitter(o.base, rng, 0.015, 0.07, 0.05)\n const crown = o.crown\n const ao = o.ao ?? 0.5\n const accent = o.accent\n const sq = o.squash ?? 0.78\n icoShell(b, {\n center: o.center,\n radii: [o.radius, o.radius * sq, o.radius],\n detail: o.detail,\n rng,\n noise: o.noise ?? 0.2,\n flatBottom: o.flatBottom ?? 0.5,\n color: (v) => {\n const tHeight = smooth(v.h)\n let k = lerp(ao, 1.04, tHeight)\n if (crown) {\n const out = norm(sub(v.p, crown))\n const f = dot(out, norm(sub(v.p, o.center)))\n k *= lerp(0.8, 1.06, clamp((f + 1) / 2, 0, 1))\n }\n let c = shade(base, k)\n if (v.h > 0.62) c = mix(c, lighten(base, 1), clamp((v.h - 0.62) * 1.7, 0, 0.6))\n c = shade(c, 0.94 + ((Math.sin(v.p[0] * 91.7 + v.p[1] * 53.3 + v.p[2] * 37.1) + 1) / 2) * 0.12)\n if (accent && accent.amount > 0) {\n const m = clamp(accent.amount * (0.35 + v.h * 0.9), 0, 1)\n c = mix(c, shade(accent.color, 0.7 + 0.35 * tHeight), m)\n }\n return c\n },\n sway: (v) => o.swayK * (0.45 + 0.55 * v.h),\n })\n}\n\n/** Surface leaves for a clump, emitted separately so callers can skip them at lower LODs. */\nexport function clumpLeaves(b: MeshBuilder, o: ClumpOptions): void {\n if (!o.leaves || o.leaves.count <= 0) return\n const rng = new Rng(o.seed ^ 0x9e3779b9)\n const base = jitter(o.base, new Rng(o.seed), 0.015, 0.07, 0.05)\n const sq = o.squash ?? 0.78\n for (let i = 0; i < o.leaves.count; i++) {\n // direction biased to the upper / outer half\n const a = rng.range(0, Math.PI * 2)\n const y = rng.range(-0.25, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [o.center[0] + d[0] * o.radius * 0.92, o.center[1] + d[1] * o.radius * sq * 0.92, o.center[2] + d[2] * o.radius * 0.92]\n let out = d\n if (o.crown) out = norm(add(d, mul(norm(sub(p, o.crown)), 0.6)))\n // leaves lie on the surface like shingles, pointing up-and-out, with the tips lifted off the shell\n let t: Vec3 = sub([0, 1, 0], mul(out, out[1]))\n if (dot(t, t) < 0.05) t = [Math.cos(a + 1.3), 0, Math.sin(a + 1.3)]\n const dir = norm(add(mul(norm(t), 0.8), mul(out, 0.22)))\n const k = lerp(o.ao ?? 0.5, 1.1, clamp((y + 0.4) / 1.4, 0, 1))\n const c0 = shade(base, Math.max(0.6, k * 0.9))\n const c1 = lighten(shade(base, Math.min(1.1, k)), 0.9)\n const len = o.leaves.length * rng.range(0.8, 1.25)\n const start = sub(p, mul(out, len * 0.05))\n leaf(b, start, dir, out, len, o.leaves.width ?? len * 0.8, c0, c1, { swayBase: o.swayK * 0.8, swayTip: Math.min(1, o.swayK * 1.4), curl: 0.06, fold: 0.12, round: 0.8, peak: 0.45 })\n }\n}\n\n/** Greedily merge points with radii into at most k groups (used by the far LOD). */\nexport function mergeAnchors<T extends { p: Vec3; r: number }>(items: T[], k: number): { p: Vec3; r: number; members: T[] }[] {\n if (items.length <= k) return items.map((i) => ({ p: i.p, r: i.r, members: [i] }))\n const seeds: T[] = [items.reduce((a, b2) => (b2.r > a.r ? b2 : a), items[0])]\n while (seeds.length < k) {\n let best: T | undefined\n let bd = -1\n for (const it of items) {\n let md = Infinity\n for (const s of seeds) md = Math.min(md, dist(it.p, s.p))\n if (md > bd) {\n bd = md\n best = it\n }\n }\n seeds.push(best as T)\n }\n const groups = seeds.map((s) => ({ s, members: [] as T[] }))\n for (const it of items) {\n let bi = 0\n let bd = Infinity\n for (let i = 0; i < seeds.length; i++) {\n const d = dist(it.p, seeds[i].p)\n if (d < bd) {\n bd = d\n bi = i\n }\n }\n groups[bi].members.push(it)\n }\n return groups\n .filter((g) => g.members.length > 0)\n .map((g) => {\n let cx = 0\n let cy = 0\n let cz = 0\n let w = 0\n for (const m of g.members) {\n cx += m.p[0] * m.r\n cy += m.p[1] * m.r\n cz += m.p[2] * m.r\n w += m.r\n }\n const p: Vec3 = [cx / w, cy / w, cz / w]\n let r = 0\n for (const m of g.members) r = Math.max(r, dist(p, m.p) + m.r * 0.85)\n return { p, r, members: g.members }\n })\n}\n\n/** Tiny faceted blob (8 triangles) for small fruit / buds. */\nexport function octa(b: MeshBuilder, center: Vec3, radii: Vec3, color: (h: number) => Vec3, sway: number): void {\n const pts: Vec3[] = [\n [radii[0], 0, 0], [0, 0, radii[2]], [-radii[0], 0, 0], [0, 0, -radii[2]],\n ].map((p) => add(center, [p[0], p[1] + 0.0, p[2]] as Vec3))\n const top: Vec3 = add(center, [0, radii[1], 0])\n const bot: Vec3 = add(center, [0, -radii[1], 0])\n for (let i = 0; i < 4; i++) {\n const a = pts[i]\n const c = pts[(i + 1) % 4]\n const out = sub(add(a, c), mul(center, 2))\n b.flatTri(a, c, top, color(0.5), color(0.5), color(1), sway, sway, sway, add(out, [0, 1, 0]))\n b.flatTri(c, a, bot, color(0.5), color(0.5), color(0), sway, sway, sway, add(out, [0, -1, 0]))\n }\n}\n","import type { Lod, Vec3 } from '../types'\nimport { add, frameFromAxis, mul, norm, TAU, toWorld, dirToWorld, type Frame, lerp } from '../math'\nimport { shade, lighten, mix, jitter } from '../color'\nimport type { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\nimport { leaf } from './leaf'\nimport { icoShell } from './shell'\nimport { tube } from './tube'\n\n/** Small flat flower (default 5 petals) lying on a surface, normal pointing out. */\nexport function blossom(b: MeshBuilder, center: Vec3, normal: Vec3, size: number, color: Vec3, heart: Vec3, sway: number, petals = 5, twist = 0): void {\n const f = frameFromAxis(center, normal, twist)\n const peak = toWorld(f, [0, size * 0.3, 0])\n for (let i = 0; i < petals; i++) {\n const a0 = (i / petals) * TAU\n const a1 = ((i + 1) / petals) * TAU\n const am = (a0 + a1) / 2\n const p0 = toWorld(f, [Math.cos(a0) * size * 0.75, 0, Math.sin(a0) * size * 0.75])\n const p1 = toWorld(f, [Math.cos(a1) * size * 0.75, 0, Math.sin(a1) * size * 0.75])\n const pm = toWorld(f, [Math.cos(am) * size * 1.1, size * 0.08, Math.sin(am) * size * 1.1])\n const c = i % 2 ? shade(color, 0.93) : color\n b.flatTri(peak, p0, pm, heart, c, lighten(c, 0.4), sway, sway, sway, normal)\n b.flatTri(peak, pm, p1, heart, lighten(c, 0.4), c, sway, sway, sway, normal)\n }\n}\n\nexport type FlowerKind = 'daisy' | 'sunflower' | 'rose' | 'tulip' | 'hibiscus' | 'cluster' | 'lily' | 'bird_of_paradise' | 'trumpet' | 'passion' | 'bract' | 'bell' | 'pompom' | 'florets'\n\nexport interface HeadOptions {\n kind: FlowerKind\n center: Vec3\n /** direction the flower faces (stem tip direction) */\n axis: Vec3\n /** head radius in meters */\n size: number\n colors: Vec3[]\n centerColor: Vec3\n rng: Rng\n lod: Lod\n sway: number\n twist?: number\n}\n\ninterface PetalOpts {\n angle: number\n r0: number\n elev: number\n length: number\n width: number\n c0: Vec3\n c1: Vec3\n curl: number\n rows?: number\n face?: 'axis' | 'radial'\n fold?: number\n peak?: number\n round?: number\n swayK: number\n}\n\nfunction petal(b: MeshBuilder, f: Frame, o: PetalOpts): void {\n const ca = Math.cos(o.angle)\n const sa = Math.sin(o.angle)\n const ce = Math.cos(o.elev)\n const se = Math.sin(o.elev)\n const baseL: Vec3 = [ca * o.r0, 0, sa * o.r0]\n const dirL: Vec3 = [ca * ce, se, sa * ce]\n const faceL: Vec3 = o.face === 'radial' ? [ca, 0, sa] : [0, 1, 0]\n leaf(b, toWorld(f, baseL), dirToWorld(f, dirL), dirToWorld(f, faceL), o.length, o.width, o.c0, o.c1, {\n rows: o.rows ?? 2,\n curl: o.curl,\n fold: o.fold ?? 0.25,\n swayBase: o.swayK,\n swayTip: o.swayK,\n peak: o.peak ?? 0.55,\n round: o.round ?? 0.8,\n edge: 0.96,\n })\n}\n\nfunction dome(b: MeshBuilder, f: Frame, radius: number, height: number, c0: Vec3, c1: Vec3, sway: number, detail: 0 | 1 = 0): void {\n icoShell(b, {\n center: f.o,\n frame: f,\n radii: [radius, height, radius],\n detail,\n noise: 0,\n color: (v) => mix(c0, c1, Math.max(0, v.h - 0.2) * 1.2),\n sway: () => sway,\n })\n}\n\n/** A flower head built from folded petals (no flat cards). Sizes are in meters. */\nexport function flowerHead(b: MeshBuilder, o: HeadOptions): void {\n const f = frameFromAxis(o.center, o.axis, o.twist ?? o.rng.range(0, TAU))\n const s = o.size\n const rng = o.rng\n const col = (i: number): Vec3 => o.colors[i % o.colors.length]\n const sw = o.sway\n const heart = o.centerColor\n if (o.lod === 2 && o.kind !== 'cluster' && o.kind !== 'bird_of_paradise') {\n blossom(b, o.center, o.axis, s * 1.2, col(0), heart, sw, 4, o.twist ?? 0)\n return\n }\n switch (o.kind) {\n case 'daisy': {\n const n = o.lod === 0 ? 12 : o.lod === 1 ? 8 : 5\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.005, 0.03, 0.02)\n petal(b, f, { angle: (i / n) * TAU + rng.range(-0.05, 0.05), r0: s * 0.18, elev: 0.12 + rng.range(-0.05, 0.08), length: s * 0.95, width: s * 0.42 * (12 / n) ** 0.5, c0: shade(c, 0.88), c1: lighten(c, 0.2), curl: -0.08, swayK: sw })\n }\n dome(b, f, s * 0.3, s * 0.2, shade(heart, 0.75), lighten(heart, 0.5), sw)\n break\n }\n case 'sunflower': {\n const n = o.lod === 0 ? 14 : o.lod === 1 ? 10 : 6\n for (let layer = 0; layer < 2; layer++) {\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.006, 0.04, 0.03)\n petal(b, f, { angle: ((i + layer * 0.5) / n) * TAU, r0: s * 0.5, elev: layer ? 0.02 : 0.2, length: s * 0.62, width: s * 0.3, c0: shade(c, 0.85), c1: lighten(c, 0.18), curl: -0.1 + layer * 0.12, swayK: sw, peak: 0.45 })\n }\n if (o.lod > 0) break\n }\n dome(b, f, s * 0.58, s * 0.2, shade(heart, 0.6), shade(mix(heart, [0.55, 0.38, 0.12], 0.5), 1.2), sw, o.lod === 0 ? 1 : 0)\n break\n }\n case 'rose': {\n const layers = o.lod === 0 ? [{ n: 5, r: 0.55, e: 0.5, k: 1 }, { n: 5, r: 0.38, e: 0.85, k: 0.82 }, { n: 4, r: 0.22, e: 1.15, k: 0.62 }, { n: 3, r: 0.1, e: 1.4, k: 0.42 }] : [{ n: 5, r: 0.5, e: 0.7, k: 1 }, { n: 4, r: 0.25, e: 1.2, k: 0.6 }]\n layers.forEach((L, li) => {\n for (let i = 0; i < L.n; i++) {\n const base = col(i)\n const c = jitter(base, rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / L.n) * TAU + li * 0.9 + rng.range(-0.1, 0.1), r0: s * L.r * 0.5, elev: L.e, length: s * (0.75 + L.r * 0.5), width: s * (0.85 - li * 0.1), c0: shade(c, 0.5 * L.k + 0.35), c1: lighten(shade(c, 0.95), 0.3), curl: 0.12, face: 'radial', swayK: sw, peak: 0.6, rows: 2, fold: 0.1 })\n }\n })\n break\n }\n case 'tulip': {\n const n = o.lod === 2 ? 4 : 6\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n const inner = i % 2\n petal(b, f, { angle: (i / n) * TAU + (inner ? 0.5 : 0), r0: s * (inner ? 0.2 : 0.35), elev: inner ? 1.35 : 1.15, length: s * (inner ? 1.7 : 1.9), width: s * 1.05, c0: shade(c, 0.78), c1: lighten(c, 0.22), curl: 0.28, face: 'radial', rows: o.lod === 0 ? 3 : 2, swayK: sw, peak: 0.45 })\n }\n break\n }\n case 'hibiscus': {\n const n = 5\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / n) * TAU + rng.range(-0.08, 0.08), r0: s * 0.04, elev: 0.5, length: s * 1.2, width: s * 1.15, c0: shade(mix(c, [0.35, 0.02, 0.05], 0.7), 0.9), c1: lighten(c, 0.2), curl: -0.05, rows: o.lod === 0 ? 3 : 2, swayK: sw, peak: 0.55, round: 0.6, fold: 0.15 })\n }\n if (o.lod < 2) {\n const tip = toWorld(f, [0, s * 1.0, 0])\n tube(b, [f.o, add(f.o, mul(f.y, s * 0.5)), tip], { sides: 3, radii: [s * 0.05, s * 0.04, s * 0.03], color: () => [0.95, 0.75, 0.3], sway: () => sw, end: 'none' })\n if (o.lod === 0) {\n dome(b, { ...f, o: tip }, s * 0.14, s * 0.08, [0.95, 0.78, 0.2], [1, 0.9, 0.4], sw)\n for (let i = 0; i < 3; i++) {\n const a = (i / 3) * TAU\n dome(b, { ...f, o: toWorld(f, [Math.cos(a) * s * 0.2, s * 0.85, Math.sin(a) * s * 0.2]) }, s * 0.06, s * 0.05, [0.95, 0.5, 0.15], [1, 0.8, 0.3], sw)\n }\n }\n }\n break\n }\n case 'cluster': {\n const detail: 0 | 1 = o.lod === 0 ? 1 : 0\n icoShell(b, {\n center: o.center,\n radii: [s, s * 0.85, s],\n detail,\n rng,\n noise: 0.12,\n color: (v) => {\n const h = (Math.sin(v.p[0] * 131 + v.p[1] * 71 + v.p[2] * 97) + 1) / 2\n const c = mix(col(0), col(1 % o.colors.length), h)\n return shade(c, lerp(0.7, 1.1, v.h))\n },\n sway: () => sw,\n })\n break\n }\n case 'lily': {\n const n = 6\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / n) * TAU + (i % 2 ? 0.2 : 0), r0: s * 0.06, elev: 0.55, length: s * 1.25, width: s * 0.55, c0: shade(mix(c, [0.2, 0.4, 0.1], 0.35), 0.85), c1: lighten(c, 0.2), curl: -0.28, rows: o.lod === 0 ? 3 : 2, swayK: sw, peak: 0.5, fold: 0.3 })\n }\n if (o.lod === 0) {\n for (let i = 0; i < 3; i++) {\n const a = (i / 3) * TAU + 0.4\n const p1 = toWorld(f, [Math.cos(a) * s * 0.25, s * 0.55, Math.sin(a) * s * 0.25])\n tube(b, [f.o, p1], { sides: 3, radii: [s * 0.02, s * 0.015], color: () => [0.9, 0.9, 0.7], sway: () => sw, end: 'none' })\n dome(b, { ...f, o: p1 }, s * 0.06, s * 0.04, [0.8, 0.35, 0.1], [0.95, 0.55, 0.15], sw)\n }\n }\n break\n }\n case 'bird_of_paradise': {\n const green: Vec3 = [0.3, 0.5, 0.25]\n const red: Vec3 = [0.7, 0.15, 0.15]\n // boat shaped bract, then the orange and blue petals standing from it\n leaf(b, o.center, norm(add(f.x, mul(f.y, 0.5))), f.y, s * 1.5, s * 0.5, shade(green, 0.7), red, { rows: 2, curl: -0.15, fold: 0.6, swayBase: sw, swayTip: sw, peak: 0.45 })\n for (let i = 0; i < (o.lod === 2 ? 2 : 3); i++) {\n const c = col(0)\n const a = (i - 1) * 0.35\n const dir = norm(add(mul(f.y, 0.75), add(mul(f.x, 0.55 + Math.abs(a) * 0.1), mul(f.z, a))))\n leaf(b, add(o.center, mul(f.y, s * 0.15)), dir, f.z, s * 1.2, s * 0.32, shade(c, 0.85), lighten(c, 0.2), { rows: 2, curl: 0.2, fold: 0.35, swayBase: sw, swayTip: sw, peak: 0.4 })\n }\n if (o.lod < 2) {\n const c2 = col(1 % o.colors.length)\n for (let i = 0; i < 2; i++) {\n const dir = norm(add(mul(f.y, 0.4), add(mul(f.x, 0.8), mul(f.z, i ? 0.2 : -0.2))))\n leaf(b, add(o.center, mul(f.y, s * 0.1)), dir, f.z, s * 1.1, s * 0.22, shade(c2, 0.8), c2, { rows: 2, curl: 0.1, fold: 0.35, swayBase: sw, swayTip: sw, peak: 0.4 })\n }\n }\n break\n }\n case 'trumpet': {\n const n = o.lod === 0 ? 8 : 6\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / n) * TAU, r0: s * 0.08, elev: 0.75, length: s * 1.3, width: s * 0.38, c0: shade(c, 0.85), c1: c, curl: -0.1, rows: 2, swayK: sw, peak: 0.45 })\n }\n dome(b, f, s * 0.2, s * 0.15, shade(heart, 0.8), heart, sw)\n break\n }\n case 'passion': {\n const n = o.lod === 0 ? 10 : 6\n for (let i = 0; i < n; i++) {\n const c = col(i % 2)\n petal(b, f, { angle: (i / n) * TAU, r0: s * 0.1, elev: 0.1, length: s * 0.95, width: s * 0.4, c0: shade(c, 0.9), c1: lighten(c, 0.1), curl: -0.05, rows: 2, swayK: sw, peak: 0.5 })\n }\n if (o.lod < 2) {\n const cor = o.colors[o.colors.length - 1]\n for (let i = 0; i < (o.lod === 0 ? 12 : 6); i++) {\n petal(b, f, { angle: (i / (o.lod === 0 ? 12 : 6)) * TAU, r0: s * 0.12, elev: 0.5, length: s * 0.45, width: s * 0.1, c0: shade(cor, 0.7), c1: lighten(cor, 0.3), curl: -0.2, rows: 2, swayK: sw })\n }\n dome(b, { ...f, o: add(f.o, mul(f.y, s * 0.25)) }, s * 0.12, s * 0.12, [0.45, 0.55, 0.2], [0.7, 0.8, 0.35], sw)\n }\n break\n }\n case 'bract': {\n // bougainvillea: three papery heart-shaped bracts around a tiny white flower\n const n = 3\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.008, 0.06, 0.03)\n petal(b, f, { angle: (i / n) * TAU + rng.range(0, 0.5), r0: s * 0.05, elev: 0.5, length: s * 1.1, width: s * 1.0, c0: shade(c, 0.85), c1: lighten(c, 0.2), curl: -0.1, rows: 2, swayK: sw, peak: 0.55, round: 0.6 })\n }\n break\n }\n case 'pompom': {\n // marigold: ruffled little ball, faceted, orange with yellow streaks, on a green calyx\n const c0 = col(0)\n const c1 = col(1 % o.colors.length)\n const ctr = add(o.center, mul(o.axis, s * 0.55))\n icoShell(b, {\n center: ctr,\n radii: [s, s * 0.82, s],\n detail: 0,\n rng,\n noise: 0.13,\n color: (v) => {\n const h = (Math.sin(v.p[0] * 311 + v.p[1] * 177 + v.p[2] * 233) + 1) / 2\n return shade(mix(c0, c1, h), lerp(0.72, 1.12, v.h))\n },\n sway: () => sw,\n })\n dome(b, { ...f, o: add(o.center, mul(o.axis, s * 0.05)) }, s * 0.5, s * 0.35, [0.2, 0.4, 0.15], [0.3, 0.5, 0.2], sw)\n break\n }\n case 'florets': {\n // hydrangea: a ball of many small four-petal florets over a dark core\n const n = o.lod === 0 ? 34 : 20\n const R = s\n const ctr = add(o.center, mul(o.axis, R * 0.75))\n icoShell(b, { center: ctr, radii: [R * 0.84, R * 0.8, R * 0.84], detail: 0, noise: 0, color: (v) => shade(mix(col(0), [0.15, 0.3, 0.2], 0.55), 0.65 + v.h * 0.3), sway: () => sw })\n const w = R * 0.34 * Math.sqrt(34 / n)\n for (let i = 0; i < n; i++) {\n const y = 1 - (i + 0.5) * (2 / n)\n const r = Math.sqrt(Math.max(0, 1 - y * y))\n const a = i * 2.399963\n const d: Vec3 = norm([Math.cos(a) * r, y, Math.sin(a) * r])\n const fr = frameFromAxis(add(ctr, mul(d, R * 0.97)), d, a)\n const c = jitter(col(i), rng, 0.01, 0.07, 0.05)\n const base = shade(c, lerp(0.7, 1.08, (y + 1) / 2))\n const tip = lighten(base, 0.35)\n const pk = toWorld(fr, [0, w * 0.35, 0])\n const ps: Vec3[] = [toWorld(fr, [w, 0, 0]), toWorld(fr, [0, 0, w]), toWorld(fr, [-w, 0, 0]), toWorld(fr, [0, 0, -w])]\n for (let k = 0; k < 4; k++) {\n const q = ps[k]\n const q2 = ps[(k + 1) % 4]\n b.flatTri(pk, q, q2, tip, base, base, sw, sw, sw, d)\n }\n }\n break\n }\n case 'bell': {\n // drooping bell (fuchsia / abutilon like): 5 petals hanging, narrow at the stem\n for (let i = 0; i < 5; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / 5) * TAU, r0: s * 0.05, elev: 0.5, length: s * 1.1, width: s * 0.8, c0: shade(c, 0.8), c1: lighten(c, 0.15), curl: 0.2, rows: 2, face: 'radial', swayK: sw, peak: 0.6 })\n }\n break\n }\n }\n}\n","import type { Vec3 } from '../types'\nimport type { Ctx } from '../ctx'\nimport type { Branch } from '../geometry/branches'\n\n/** Maximum number of separate main branches a tree is split into (more are merged into the last). */\nexport const MAX_MAIN_BRANCHES = 6\n\nexport interface CrownAnchor {\n /** crown piece id that the foliage near `points` goes to */\n crownId: string\n branchId: string\n points: Vec3[]\n}\n\n/**\n * Draw the trunk and every branch as separate wood pieces: 'trunk', then 'branch0'..'branch5' (a main branch, i.e. level 1, with all\n * the branches that grow from it). `draw(branch, index)` draws one branch (index -1 is the trunk).\n * Returns the anchors that `splitCrown` uses to hand foliage to the nearest main branch.\n */\nexport function drawTreeWood(ctx: Ctx, tree: { trunk: Branch; branches: Branch[] }, draw: (br: Branch, index: number) => void): CrownAnchor[] {\n ctx.piece('trunk', 'trunk')\n draw(tree.trunk, -1)\n const top = tree.trunk.pts[tree.trunk.pts.length - 1]\n const anchors: CrownAnchor[] = [{ crownId: 'crown', branchId: 'trunk', points: [top] }]\n let main = -1\n let current: CrownAnchor | undefined\n for (let i = 0; i < tree.branches.length; i++) {\n const br = tree.branches[i]\n if (br.level <= 1) {\n main++\n const k = Math.min(main, MAX_MAIN_BRANCHES - 1)\n const id = `branch${k}`\n ctx.piece(id, 'branch', 'trunk', br.pts[0])\n current = anchors.find((a) => a.branchId === id)\n if (!current) {\n current = { crownId: `crown${k}`, branchId: id, points: [] }\n anchors.push(current)\n }\n }\n if (current) current.points.push(br.pts[br.pts.length - 1])\n draw(br, i)\n }\n ctx.piece('trunk', 'trunk')\n return anchors\n}\n\n/**\n * Relabel the foliage / flower triangles tagged 'crown' so each goes to the crown of the nearest main branch (by triangle center\n * to the nearest branch end). Call after the crown geometry was emitted.\n */\nexport function splitCrown(ctx: Ctx, anchors: CrownAnchor[]): void {\n if (anchors.length <= 1) {\n return\n }\n for (const b of [ctx.foliage, ctx.flowers, ctx.wood]) {\n const nTri = b.idx.length / 3\n for (let t = 0; t < nTri; t++) {\n if (b.triTag[t] !== 'crown') continue\n let cx = 0\n let cy = 0\n let cz = 0\n for (let k = 0; k < 3; k++) {\n const v = b.idx[t * 3 + k] * 3\n cx += b.pos[v]\n cy += b.pos[v + 1]\n cz += b.pos[v + 2]\n }\n cx /= 3\n cy /= 3\n cz /= 3\n let best = anchors[0]\n let bd = Infinity\n for (const a of anchors) {\n for (const p of a.points) {\n const d = (p[0] - cx) ** 2 + (p[1] - cy) ** 2 + (p[2] - cz) ** 2\n if (d < bd) {\n bd = d\n best = a\n }\n }\n }\n b.triTag[t] = best.crownId\n if (!ctx.pieceMeta.has(best.crownId)) ctx.pieceMeta.set(best.crownId, { kind: 'crown', parent: best.branchId })\n }\n }\n}\n","import type { Vec3 } from '../types'\nimport type { Ctx } from '../ctx'\nimport { mix, tintGreen } from '../color'\nimport { clamp } from '../math'\n\nconst AUTUMN: Vec3[] = [\n [0.86, 0.56, 0.12],\n [0.8, 0.32, 0.1],\n [0.92, 0.76, 0.2],\n [0.66, 0.3, 0.1],\n]\nconst WINTER_LEAF: Vec3 = [0.45, 0.34, 0.2]\n\n/** Condition + season tint for leaf-like green tissue. `roll` (0..1) varies the autumn color per clump. */\nexport function leafTint(ctx: Ctx, c: Vec3, deciduous: boolean, roll: number): Vec3 {\n let out = tintGreen(c, ctx.condition)\n if (deciduous) {\n if (ctx.season === 'autumn') out = mix(out, AUTUMN[Math.floor(roll * AUTUMN.length) % AUTUMN.length], 0.8)\n else if (ctx.season === 'winter') out = mix(out, WINTER_LEAF, 0.8)\n }\n return out\n}\n\n/** Share of leaf tips kept (0..1+) by condition and season. */\nexport function leafAmount(ctx: Ctx, deciduous: boolean): number {\n let a = 1\n switch (ctx.condition) {\n case 'dry':\n a = 0.72\n break\n case 'dead':\n a = 0\n break\n case 'overgrown':\n a = 1.15\n break\n }\n if (deciduous) {\n if (ctx.season === 'winter') a *= 0.1\n else if (ctx.season === 'autumn') a *= 0.85\n }\n return clamp(a, 0, 1.3)\n}\n\nexport function inSeason(ctx: Ctx, seasons: readonly string[] | undefined): boolean {\n return (seasons ?? ['spring', 'summer']).includes(ctx.season)\n}\n","import type { DeadTreeSpec } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { rgb, shade, mix } from '../color'\nimport { growTree } from '../geometry/branches'\nimport { drawBranch } from '../geometry/wood'\nimport { drawTreeWood } from './pieces'\n\n/** Bare, twisted tree with broken stubs. Also used for the `dead` condition of broadleaf trees. */\nexport function generateDeadTree(spec: DeadTreeSpec, ctx: Ctx, fromTree = false): ArchResult {\n const height = spec.height ?? 5\n const trunkRadius = spec.trunkRadius ?? 0.2\n const crownRadius = spec.crownRadius ?? height * 0.38\n const base = fromTree ? mix(rgb(spec.barkColor ?? 0x6b4b34), [0.42, 0.39, 0.34], 0.7) : rgb(spec.barkColor ?? 0x6c6458)\n const bark = shade(base, 0.95)\n const tree = growTree(ctx.rng, {\n height,\n trunkRadius,\n crownRadius,\n shape: 'spreading',\n levels: spec.branchLevels ?? 3,\n trunkFraction: 0.33,\n gnarl: 1.1,\n primary: 5,\n lean: 0.1,\n bare: true,\n })\n drawTreeWood(ctx, tree, (br, i) => drawBranch(ctx.wood, br, bark, ctx.lod, i < 0 ? 1 : i * 0.5))\n return { collider: { kind: 'cylinder', radius: trunkRadius * 1.1, height: height * 0.5 }, bendable: false }\n}\n","import type { BroadleafTreeSpec, CrownStyle, Vec3 } from '../types'\nimport type { Ctx } from '../ctx'\nimport { Rng } from '../rng'\nimport { add, clamp, dist, lerp, mul, norm, TAU } from '../math'\nimport { mix, shade } from '../color'\nimport { clump, clumpLeaves } from '../geometry/shell'\nimport { tube } from '../geometry/tube'\nimport { barkColor } from '../geometry/wood'\nimport { leaf } from '../geometry/leaf'\nimport { growTree, type Branch, type GrowParams, type Tip, type TreeShape } from '../geometry/branches'\nimport { catmull } from '../math'\n\nexport interface StyleGroup {\n p: Vec3\n r: number\n sq: number\n}\n\nexport interface StyleEnv {\n ctx: Ctx\n spec: BroadleafTreeSpec\n tree: TreeShape\n vis: Tip[]\n H: number\n R: number\n clearY: number\n /** leaf / bloom color of a clump */\n colorFor: (tip: Tip) => { base: Vec3; accent?: { color: Vec3; amount: number } }\n grow: number\n bark: Vec3\n keep: number\n bloomOn: boolean\n}\n\ninterface Anchor {\n p: Vec3\n r: number\n sq: number\n tip: Tip\n tone: number\n}\n\n/** Weeping willow skeleton: short trunk forking into arching limbs that rise, then fall toward the ground. */\nexport function willowTree(rng: Rng, p: GrowParams): TreeShape {\n const base = growTree(rng, { ...p, height: p.height * 0.56, primary: 1, levels: 1, shape: 'round' })\n const H = p.height\n const trunk = base.trunk\n const top = trunk.pts[trunk.pts.length - 1]\n const branches: Branch[] = []\n const tips: Tip[] = []\n const n = 8\n for (let i = 0; i < n; i++) {\n const az = (i / n) * TAU + rng.range(-0.25, 0.25)\n const y0 = top[1] * rng.range(0.72, 0.98)\n // the trunk position at that height (trunk pts are dense and monotonic in y)\n let tp = top\n for (const q of trunk.pts) if (q[1] >= y0) { tp = q; break }\n const L = p.crownRadius * rng.range(0.85, 1.1)\n const G = H * rng.range(0.15, 0.22)\n const k2 = 6.25 * G\n const pts: Vec3[] = []\n for (let k = 0; k <= 7; k++) {\n const t = k / 7\n const d = L * Math.pow(t, 0.85)\n const wob = Math.sin(t * 5 + i) * 0.12\n pts.push([tp[0] + Math.cos(az + wob) * d, y0 + 0.8 * k2 * t - k2 * t * t, tp[2] + Math.sin(az + wob) * d])\n }\n const sm = catmull(pts, 2)\n const r0 = trunk.radii[Math.floor(trunk.radii.length * 0.85)] * rng.range(0.4, 0.5)\n const radii = sm.map((_, k) => Math.max(0.012, r0 * (1 - 0.85 * (k / (sm.length - 1)))))\n branches.push({ pts: sm, radii, level: 1 })\n // twig forks\n for (let q = 0; q < 2; q++) {\n const t = rng.range(0.4, 0.7)\n const bi = Math.floor(t * (sm.length - 1))\n const s0 = sm[bi]\n const az2 = az + rng.range(0.5, 1) * (q ? 1 : -1)\n const pp: Vec3[] = [s0]\n for (let k = 1; k <= 4; k++) pp.push([s0[0] + Math.cos(az2) * L * 0.12 * k, s0[1] + (k < 2 ? 0.1 : -0.25 * k) * H * 0.04 - k * 0.15, s0[2] + Math.sin(az2) * L * 0.12 * k])\n branches.push({ pts: catmull(pp, 2), radii: catmull(pp.map((_, k) => [r0 * 0.4 * (1 - k * 0.2), 0, 0] as Vec3), 2).map((v) => Math.max(0.008, v[0])), level: 2 })\n }\n for (const t of [0.3, 0.55, 0.8]) {\n const q = sm[Math.floor(t * (sm.length - 1))]\n tips.push({ p: q, dir: [0, 1, 0], size: rng.range(0.8, 1.2), level: 1, seed: rng.seed(), keep: rng.next(), roll: rng.next() })\n }\n }\n tips.push({ p: [top[0], top[1] + 0.4, top[2]], dir: [0, 1, 0], size: 1, level: 0, seed: rng.seed(), keep: 0, roll: 0.5 })\n return { trunk, branches, tips, crown: [top[0], top[1] + G0(H), top[2]], trunkTopY: top[1] }\n}\nconst G0 = (H: number): number => H * 0.12\n\n/** Skeleton parameters per style: how the branches grow under the crown. */\nexport function styleSkeleton(style: CrownStyle): { shape: 'round' | 'spreading' | 'weeping'; primary: number; trunkFraction: number; levels: number; gnarl: number; lean: number } {\n switch (style) {\n case 'dome':\n return { shape: 'spreading', primary: 6, trunkFraction: 0.34, levels: 3, gnarl: 0.5, lean: 0.02 }\n case 'umbrella':\n return { shape: 'spreading', primary: 7, trunkFraction: 0.46, levels: 2, gnarl: 0.55, lean: 0.03 }\n case 'lumpy':\n return { shape: 'round', primary: 5, trunkFraction: 0.3, levels: 3, gnarl: 0.95, lean: 0.05 }\n case 'sphere':\n return { shape: 'round', primary: 4, trunkFraction: 0.5, levels: 2, gnarl: 0.3, lean: 0.01 }\n case 'willow':\n return { shape: 'weeping', primary: 7, trunkFraction: 0.28, levels: 2, gnarl: 0.5, lean: 0.03 }\n case 'sparse_high':\n return { shape: 'round', primary: 4, trunkFraction: 0.58, levels: 3, gnarl: 0.9, lean: 0.07 }\n default:\n return { shape: 'round', primary: 5, trunkFraction: 0.32, levels: 3, gnarl: 0.55, lean: 0.03 }\n }\n}\n\nconst fakeTip = (r: Rng, level = 1): Tip => ({ p: [0, 0, 0], dir: [0, 1, 0], size: 1, level, seed: r.seed(), keep: r.next(), roll: r.next() })\n\nfunction pickSpread(tips: Tip[], rad: number, max: number, minY: number): Tip[] {\n const out: Tip[] = []\n const sorted = tips.filter((t) => t.p[1] >= minY).sort((a, b) => b.level - a.level || a.keep - b.keep)\n for (const t of sorted) {\n if (out.length >= max) break\n if (out.every((o) => dist(o.p, t.p) > rad * 1.05)) out.push(t)\n }\n return out\n}\n\nfunction buildAnchors(style: CrownStyle, env: StyleEnv, rng: Rng): Anchor[] {\n const { H, R, tree, vis } = env\n const size = env.spec.clumpSize ?? 1\n const top = tree.trunk.pts[tree.trunk.pts.length - 1]\n const cx = tree.crown[0] * 0.3 + top[0] * 0.7\n const cz = tree.crown[2] * 0.3 + top[2] * 0.7\n const out: Anchor[] = []\n const add1 = (p: Vec3, r: number, sq: number, tip?: Tip, tone = 1): void => {\n out.push({ p, r, sq, tip: tip ?? fakeTip(rng), tone })\n }\n switch (style) {\n case 'sphere': {\n // clipped ball made of lumps (never one smooth sphere)\n const rs = Math.min(R, (H - env.clearY) * 0.5)\n const cy = H - rs\n add1([top[0], cy, top[2]], rs * 0.66, 1, vis[0])\n const ringN = 7\n for (let i = 0; i < ringN; i++) {\n const a = (i / ringN) * TAU + rng.range(0, 0.4)\n const lift = i % 2 ? 0.22 : -0.1\n add1([top[0] + Math.cos(a) * rs * 0.52, cy + rs * lift, top[2] + Math.sin(a) * rs * 0.52], rs * 0.5, 0.95, undefined, 1 - (i % 3) * 0.05)\n }\n add1([top[0] + rs * 0.12, cy + rs * 0.5, top[2]], rs * 0.46, 0.95, undefined, 1.05)\n add1([top[0], cy - rs * 0.45, top[2]], rs * 0.44, 0.85, undefined, 0.92)\n break\n }\n case 'dome':\n case 'cloud': {\n const cloud = style === 'cloud'\n const y0 = cloud ? Math.min(env.clearY * 0.7, Math.max(0.7, H * 0.2)) : env.clearY * 0.66\n const n = cloud ? 9 : 11\n const rr = R * (cloud ? 0.5 : 0.4) * size\n for (let i = 0; i < n; i++) {\n const u = (i + 0.5) / n\n const ang = i * 2.399963\n const rad = Math.min(R - rr * 0.95, Math.sqrt(u) * R * (cloud ? 0.78 : 0.9))\n const hh = Math.pow(Math.max(0.04, 1 - (rad / R) ** 2), cloud ? 0.6 : 0.42)\n const r = rr * (1.12 - 0.3 * u) * rng.range(0.9, 1.08)\n const sq = cloud ? 0.92 : 0.7\n const depth = cloud ? (i % 3 === 0 ? 1 : 0.35 + 0.65 * ((i * 0.618034) % 1)) : 0.3 + 0.7 * ((i * 0.618034) % 1)\n const y = y0 + r * sq + hh * (H - y0 - r * sq * 2) * (cloud ? 0.95 : 0.96) * depth\n add1([cx + Math.cos(ang) * rad, y, cz + Math.sin(ang) * rad], r, sq, undefined, 1 - u * 0.1)\n }\n break\n }\n case 'umbrella': {\n const sq = 0.36\n const r0 = R * 0.4 * size\n const yTop = H - r0 * sq\n add1([cx, yTop, cz], r0 * 0.95, sq)\n const rings: [number, number][] = [[6, 0.36], [10, 0.7], [12, 1.0]]\n for (const [cnt, f] of rings) {\n for (let i = 0; i < cnt; i++) {\n const ang = (i / cnt) * TAU + f * 2 + rng.range(-0.15, 0.15)\n const rad = Math.min(R - r0 * 0.7, R * f) * rng.range(0.92, 1.05)\n const r = r0 * rng.range(0.85, 1.1) * (1 - f * 0.12)\n add1([cx + Math.cos(ang) * rad, yTop - (rad / R) * H * 0.07 - rng.range(0, 0.25), cz + Math.sin(ang) * rad], r, sq, undefined, 1)\n }\n }\n break\n }\n case 'lumpy': {\n const r = R * 0.3 * size\n const picks = pickSpread(vis, r * 1.5, 15, env.clearY + 0.05 * H)\n for (const t of picks) add1(add(t.p, [0, r * 0.45, 0]), r * t.size * rng.range(0.85, 1.15), 0.7, t, rng.range(0.9, 1.1))\n break\n }\n case 'sparse_high': {\n const r = R * 0.3 * size\n const picks = pickSpread(vis, r * 0.9, 8, env.clearY)\n for (const t of picks) add1(add(t.p, [0, r * 0.25, 0]), r * t.size * rng.range(0.75, 1.15), 0.68, t, 1)\n // irregular fill around the upper trunk\n const yTop = H - r * 0.5\n for (let i = 0; i < 9; i++) {\n const ang = rng.range(0, TAU)\n const rad = R * rng.range(0.2, 1.0)\n const y = lerp(env.clearY + (H - env.clearY) * 0.2, yTop, rng.next())\n add1([cx + Math.cos(ang) * rad, y, cz + Math.sin(ang) * rad], r * rng.range(0.55, 0.9), 0.66, undefined, rng.range(0.9, 1.05))\n }\n break\n }\n case 'willow': {\n const r = R * 0.24 * size\n const picks = pickSpread(vis, r * 1.2, 9, env.clearY)\n for (const t of picks) add1(add(t.p, [0, r * 0.2, 0]), r * t.size, 0.5, t, 1)\n break\n }\n default:\n break\n }\n return out\n}\n\n/** Hanging curtain strips (willow / eucalyptus) from points along the branches. */\nfunction hangStrips(env: StyleEnv, rng: Rng, base: Vec3, opts: { perBranch: number; minLen: number; maxLen: number; toGround: boolean; width: number; light: Vec3 }): void {\n const { ctx, tree } = env\n const lodK = ctx.pick(1, 0.45, 0.18)\n for (const br of tree.branches) {\n if (br.level < 1) continue\n const n = Math.max(1, Math.round(opts.perBranch * lodK * (br.level === 1 ? 1 : 0.8)))\n for (let k = 0; k < n; k++) {\n const t = lerp(0.45, 1, (k + rng.next() * 0.7) / n)\n const idx = Math.min(br.pts.length - 2, Math.floor(t * (br.pts.length - 1)))\n const u = t * (br.pts.length - 1) - idx\n const p: Vec3 = [lerp(br.pts[idx][0], br.pts[idx + 1][0], u), lerp(br.pts[idx][1], br.pts[idx + 1][1], u), lerp(br.pts[idx][2], br.pts[idx + 1][2], u)]\n const len = opts.toGround ? Math.max(opts.minLen, (p[1] - 0.2 - rng.range(0, 0.9)) * rng.range(0.85, 1)) : rng.range(opts.minLen, opts.maxLen)\n const out = norm([p[0], 0, p[2]])\n const w = opts.width * (ctx.lod === 2 ? 2.2 : 1) * rng.range(0.8, 1.2)\n const g0 = shade(base, 0.78)\n const g1 = mix(base, opts.light, 0.55)\n const reps = ctx.lod === 0 ? 2 : 1\n for (let q = 0; q < reps; q++) {\n const off: Vec3 = [-out[2] * w * q * 0.9, 0, out[0] * w * q * 0.9]\n leaf(ctx.foliage, add(p, off), [out[0] * 0.12, -1, out[2] * 0.12], out, len * rng.range(0.9, 1), w, g0, g1, { rows: ctx.lod === 0 ? 3 : 2, curl: 0.04, fold: 0.2, baseWidth: 0.7, swayBase: 0.35, swayTip: 1, peak: 0.2, round: 1.4 })\n }\n }\n }\n}\n\n/** Foliage of a styled crown; returns the clump list so blossoms / fruit can sit on it. */\nexport function styledCrown(style: CrownStyle, env: StyleEnv): StyleGroup[] {\n const { ctx } = env\n const rng = new Rng((env.vis[0]?.seed ?? 1) ^ 0x51ed27)\n let anchors = buildAnchors(style, env, rng)\n const overgrown = ctx.condition === 'overgrown' ? 1.14 : 1\n // condition / season: drop some clumps (dry, bare), never the first\n anchors = anchors.filter((a, i) => i === 0 || a.tip.keep < env.keep)\n if (ctx.lod === 2 && anchors.length > 7) anchors = anchors.filter((_, i) => i % 2 === 0 || i === 1)\n if (ctx.lod === 1 && anchors.length > 6 && style !== 'sphere') anchors = anchors.filter((_, i) => i % 3 !== 2)\n const groups: StyleGroup[] = []\n const bigSphere = false\n for (const a of anchors) {\n const { base: b0, accent } = env.colorFor(a.tip)\n const base = shade(b0, clamp(a.tone * (0.9 + a.tip.roll * 0.2), 0.7, 1.15))\n const r = a.r * overgrown\n const detail = (ctx.lod === 0 ? (bigSphere ? 2 : 1) : ctx.lod === 1 ? (bigSphere ? 1 : 0) : 0) as 0 | 1 | 2\n const leaves =\n ctx.lod === 0 && !bigSphere && style !== 'willow' && style !== 'umbrella' && style !== 'sparse_high' ? { count: Math.round((4 + r * 2) * (ctx.condition === 'dry' ? 0.5 : 1)), length: r * 0.4, width: r * 0.32 } : undefined\n const o = {\n center: a.p,\n radius: r,\n squash: a.sq,\n detail,\n seed: a.tip.seed,\n base,\n crown: env.tree.crown,\n accent,\n leaves,\n swayK: 0.3,\n noise: bigSphere ? 0.015 : style === 'lumpy' || style === 'sparse_high' ? 0.2 : 0.13,\n flatBottom: style === 'umbrella' || style === 'dome' ? 0.75 : 0.5,\n ao: env.bloomOn && env.spec.bloom?.replacesLeaves ? 0.78 : style === 'dome' ? 0.45 : 0.55,\n }\n if (ctx.lod >= 1 && style !== 'willow') {\n // mid LOD: several small low-subdivision lumps per clump instead of one big faceted icosahedron\n const sr = new Rng(a.tip.seed ^ 0x2545f491)\n const subs = 2\n for (let k = 0; k < subs; k++) {\n const ang = (k / subs) * TAU + sr.range(0, 1)\n const off = r * (ctx.lod === 2 ? 0.42 : 0.5)\n const sub = { ...o, radius: r * (ctx.lod === 2 ? 0.74 : 0.62), seed: a.tip.seed + k * 977, center: [a.p[0] + Math.cos(ang) * off, a.p[1] + r * a.sq * sr.range(0, 0.35), a.p[2] + Math.sin(ang) * off] as Vec3 }\n clump(ctx.foliage, sub)\n }\n } else {\n clump(ctx.foliage, o)\n }\n if (ctx.lod === 0) clumpLeaves(ctx.foliage, o)\n groups.push({ p: a.p, r, sq: a.sq })\n if (style === 'sparse_high' && a.tip.p[0] === 0 && a.tip.p[1] === 0 && ctx.lod < 2) {\n // twig linking a free clump to the trunk\n const tp = env.tree.trunk.pts\n let q = tp[tp.length - 1]\n for (const pt of tp) if (pt[1] >= a.p[1] - r * 1.4) { q = pt; break }\n const mid: Vec3 = [(q[0] + a.p[0]) / 2, (q[1] + a.p[1]) / 2 - r * 0.2 + 0.15, (q[2] + a.p[2]) / 2]\n const end: Vec3 = [a.p[0], a.p[1] - r * a.sq * 0.4, a.p[2]]\n tube(ctx.wood, catmull([q, mid, end], 2), { sides: 4, radii: [0.07, 0.06, 0.05, 0.04, 0.03, 0.02, 0.012].slice(0, 5), color: barkColor(env.bark, 1), sway: (t) => 0.1 + 0.3 * t, end: 'point' })\n }\n }\n if (style === 'willow' && ctx.lod < 3) {\n const base = env.colorFor(env.vis[0] ?? fakeTip(rng)).base\n hangStrips(env, rng, base, { perBranch: 7, minLen: 1.2, maxLen: 9, toGround: true, width: env.R * 0.07, light: [0.78, 0.84, 0.4] })\n } else if (style === 'sparse_high') {\n const base = env.colorFor(env.vis[0] ?? fakeTip(rng)).base\n hangStrips(env, rng, base, { perBranch: 2, minLen: env.H * 0.07, maxLen: env.H * 0.13, toGround: false, width: env.R * 0.06, light: [0.7, 0.78, 0.55] })\n }\n void mul\n return groups\n}\n","import type { BroadleafTreeSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { Rng } from '../rng'\nimport { add, clamp, dist, lerp, mul, norm, TAU } from '../math'\nimport { jitter, mix, rgb, shade } from '../color'\nimport { fitTree, growTree, type Tip } from '../geometry/branches'\nimport { drawBranch } from '../geometry/wood'\nimport { clump, clumpLeaves, mergeAnchors, icoShell, octa } from '../geometry/shell'\nimport { blossom } from '../geometry/flower'\nimport { leaf } from '../geometry/leaf'\nimport { tube } from '../geometry/tube'\nimport { drawTreeWood, splitCrown } from './pieces'\nimport { inSeason, leafAmount, leafTint } from './shared'\nimport { generateDeadTree } from './dead-tree'\nimport { styleSkeleton, styledCrown, willowTree, type StyleGroup } from './tree-styles'\n\nconst DEFAULT_LEAF = [0x4d9a43, 0x5aa84a, 0x428a3e]\n\nexport function generateBroadleafTree(spec: BroadleafTreeSpec, ctx: Ctx): ArchResult {\n const height = spec.height ?? 6\n const trunkRadius = spec.trunkRadius ?? height * 0.04\n const crownRadius = spec.crownRadius ?? height * 0.42\n const shape = spec.crownShape ?? 'round'\n const bark = rgb(spec.barkColor ?? 0x8a6a4c)\n if (ctx.condition === 'dead') {\n return generateDeadTree({ archetype: 'dead_tree', height, trunkRadius, crownRadius, barkColor: spec.barkColor, branchLevels: spec.branchLevels }, ctx, true)\n }\n const style = spec.crownStyle\n const sk = style ? styleSkeleton(style) : undefined\n const trunkFraction = spec.trunkFraction ?? sk?.trunkFraction ?? (shape === 'spreading' ? 0.36 : shape === 'columnar' ? 0.22 : shape === 'weeping' ? 0.3 : 0.4)\n const levels = spec.branchLevels ?? sk?.levels ?? 3\n const rng = ctx.rng\n const growFn = style === 'willow' ? willowTree : growTree\n const tree = growFn(rng, {\n height,\n trunkRadius,\n crownRadius,\n shape: sk?.shape ?? shape,\n levels,\n trunkFraction,\n gnarl: sk?.gnarl ?? (spec.leafShape === 'sparse' ? 0.9 : 0.55),\n primary: sk?.primary ?? (shape === 'columnar' ? 5 : shape === 'spreading' ? 5 : 4),\n lean: sk?.lean ?? (spec.leafShape === 'sparse' ? 0.08 : 0.03),\n })\n const deciduous = spec.deciduous ?? false\n const bloom = spec.bloom\n const bloomOn = !!bloom && inSeason(ctx, bloom.seasons)\n const replaces = bloomOn && !!bloom?.replacesLeaves\n const palette = (spec.leafColor ?? DEFAULT_LEAF).map(rgb)\n const amount = leafAmount(ctx, deciduous && !replaces)\n const baseKeep = spec.density ?? 1\n\n\n // visible tips\n const keepThreshold = clamp(amount * baseKeep, 0, 1.3)\n const visible: Tip[] = tree.tips.filter((t, i) => i === 0 || t.keep < keepThreshold || t.level === 0)\n const sparse = spec.leafShape === 'sparse'\n const nT = Math.max(1, visible.length)\n const rK = clamp(2.3 / Math.sqrt(nT), 0.36, 0.8) * (sparse ? 0.62 : 1) * (spec.clipped ? 1.1 : 1)\n const grow = ctx.condition === 'overgrown' ? 1.14 : 1\n const reachK = shape === 'spreading' ? 1.08 : shape === 'columnar' ? 0.62 : 1\n const styleReach = style === 'dome' || style === 'umbrella' ? 0.95 : style === 'sphere' ? 0.5 : style === 'sparse_high' ? 0.85 : style === 'willow' ? 1 : 0.9\n const styleClumpR = style ? crownRadius * 0.28 : crownRadius * rK * grow\n if (style !== 'willow') fitTree(tree, height, style ? crownRadius * styleReach : crownRadius * reachK, styleClumpR, height * trunkFraction * 0.95)\n if (style && style !== 'sparse_high' && style !== 'willow') {\n // the leader must not poke out of the crown\n const yMax = style === 'sphere' ? height * 0.62 : height * 0.8\n const tpts = tree.trunk.pts\n let keepN = tpts.findIndex((q) => q[1] > yMax)\n if (keepN < 0) keepN = tpts.length\n keepN = Math.max(3, keepN)\n tree.trunk = { ...tree.trunk, pts: tpts.slice(0, keepN), radii: tree.trunk.radii.slice(0, keepN) }\n }\n // wood\n const anchors = drawTreeWood(ctx, tree, (br, i) => drawBranch(ctx.wood, br, bark, ctx.lod, i < 0 ? 0 : i * 0.37))\n ctx.piece('crown', 'crown', 'trunk')\n const colorFor = (tip: Tip): { base: Vec3; accent?: { color: Vec3; amount: number } } => {\n const pc = palette[Math.floor(tip.roll * palette.length) % palette.length]\n let base = leafTint(ctx, pc, deciduous, tip.roll)\n if (bloomOn && bloom) {\n const bc = rgb(bloom.colors[Math.floor(((tip.seed >>> 8) % 1000) / 1000 * bloom.colors.length)])\n const density = bloom.density ?? (replaces ? 1 : 0.85)\n if (replaces && tip.roll > density) return { base }\n if (replaces) base = mix(bc, shade(bc, 0.8), tip.roll * 0.5)\n else return { base, accent: { color: bc, amount: density * 0.8 } }\n }\n return { base }\n }\n\n let groups: { p: Vec3; r: number; sq?: number }[]\n const squash = shape === 'spreading' ? 0.55 : shape === 'weeping' ? 1.35 : shape === 'columnar' ? 1.05 : 0.78\n if (style) {\n groups = styledCrown(style, { ctx, spec, tree, vis: visible, H: height, R: crownRadius, clearY: height * trunkFraction * 0.95, colorFor, grow, bark, keep: keepThreshold, bloomOn }) as StyleGroup[]\n } else {\n const anchors = visible.map((t) => {\n const r = crownRadius * rK * t.size * grow\n const lift = shape === 'weeping' ? -0.1 : 0.35\n const center = add(add(t.p, mul(t.dir, r * 0.25)), [0, r * lift, 0])\n return { p: center, r, tip: t }\n })\n // inner fill clumps halfway along the main limbs so the crown reads as one mass\n if (!sparse) {\n for (let bi = 0; bi < tree.branches.length; bi++) {\n const br = tree.branches[bi]\n if (br.level !== 1) continue\n const r2 = new Rng(Math.floor(br.radii[0] * 1e6) ^ (bi * 7919))\n const mid = br.pts[Math.floor(br.pts.length * 0.55)]\n const roll = r2.next()\n if (roll > keepThreshold) continue\n const r = crownRadius * rK * 0.95 * grow\n anchors.push({ p: add(mid, [0, r * 0.35, 0]), r, tip: { p: mid, dir: [0, 1, 0], size: 1, level: 1, seed: r2.seed(), keep: roll, roll: r2.next() } })\n }\n }\n\n const crown = tree.crown\n const kGroups = ctx.pick(clamp(Math.round(anchors.length * 0.26), 5, 7), clamp(Math.round(anchors.length * 0.26), 5, 7), 6)\n const lg = (sparse && ctx.lod < 2) || anchors.length <= kGroups ? anchors.map((an) => ({ p: an.p, r: an.r, members: [an] })) : mergeAnchors(anchors, kGroups)\n groups = lg\n for (const g of lg) {\n const t0 = g.members[0].tip\n const { base, accent } = colorFor(t0)\n const rMain = ctx.lod === 2 ? g.r : g.members.length > 1 ? g.r * 0.95 : g.r\n const leaves = ctx.lod === 0 && !sparse ? { count: Math.round((6 + rMain * 3) * (ctx.condition === 'dry' ? 0.5 : 1)), length: rMain * 0.34, width: rMain * 0.28 } : undefined\n const o = {\n center: g.p,\n radius: rMain,\n squash,\n detail: (ctx.lod === 0 ? (sparse ? 1 : 2) : ctx.lod === 1 ? 1 : 0) as 0 | 1 | 2,\n seed: t0.seed,\n base,\n crown,\n accent,\n leaves,\n swayK: 0.3,\n noise: ctx.lod === 0 ? (sparse ? 0.3 : 0.17) : 0.14,\n flatBottom: shape === 'weeping' ? 0.1 : 0.5,\n ao: 0.5,\n }\n clump(ctx.foliage, o)\n if (ctx.lod === 0) clumpLeaves(ctx.foliage, o)\n if (ctx.lod < 2 && g.members.length > 1) {\n // satellites on the members that are farthest from the group center: lumpy, layered silhouette\n const sorted = g.members.slice().sort((m1, m2) => dist(m2.p, g.p) - dist(m1.p, g.p)).slice(0, ctx.condition === 'dry' ? 1 : 2)\n for (const m of sorted) {\n const so = { ...o, center: m.p, radius: m.r * 0.78, seed: m.tip.seed, detail: (ctx.lod === 0 ? 1 : 0) as 0 | 1, leaves: ctx.lod === 0 && !sparse ? { count: 3, length: m.r * 0.3, width: m.r * 0.25 } : undefined }\n clump(ctx.foliage, so)\n if (ctx.lod === 0) clumpLeaves(ctx.foliage, so)\n }\n }\n if (ctx.condition === 'overgrown' && ctx.lod < 2) {\n const r2 = new Rng(t0.seed ^ 0x1234)\n clump(ctx.foliage, { ...o, center: add(g.p, [r2.range(-0.4, 0.4) * g.r, g.r * r2.range(0.2, 0.5), r2.range(-0.4, 0.4) * g.r]), radius: g.r * 0.7, seed: t0.seed ^ 0x77, leaves: undefined, detail: 1 })\n }\n if ((shape === 'weeping' || sparse) && ctx.lod < 2) {\n const r2 = new Rng(t0.seed ^ 0x5151)\n const n = ctx.lod === 0 ? (sparse ? 7 : 10) : sparse ? 3 : 4\n for (let i = 0; i < n; i++) {\n const ang = r2.range(0, TAU)\n const rr = g.r * r2.range(0.3, 0.95)\n const top: Vec3 = [g.p[0] + Math.cos(ang) * rr, g.p[1] - g.r * 0.2, g.p[2] + Math.sin(ang) * rr]\n const hang = g.r * r2.range(1.4, 2.4) * (sparse ? 1.3 : 1)\n const g0 = shade(base, 0.75)\n const g1 = mix(base, [0.78, 0.82, 0.4], 0.35)\n leaf(ctx.foliage, top, [0.1 * Math.cos(ang), -1, 0.1 * Math.sin(ang)], [Math.cos(ang), 0.2, Math.sin(ang)], hang, g.r * 0.3, g0, g1, { rows: 2, curl: 0.05, fold: 0.3, swayBase: 0.4, swayTip: 1, peak: 0.25 })\n }\n }\n }\n\n }\n\n // blossoms scattered on the crown surface (LOD0 only)\n if (bloomOn && bloom && ctx.lod === 0) {\n const r2 = new Rng(Math.floor(height * 1000) + 77)\n for (const a of groups) {\n const n = replaces ? 6 : 5\n for (let i = 0; i < n; i++) {\n const ang = r2.range(0, TAU)\n const y = r2.range(0.1, 1)\n const rr = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(ang) * rr, y, Math.sin(ang) * rr]\n const p: Vec3 = [a.p[0] + d[0] * a.r * 1.0, a.p[1] + d[1] * a.r * (a.sq ?? squash) * 1.0, a.p[2] + d[2] * a.r * 1.0]\n const bc = rgb(r2.pick(bloom.colors))\n blossom(ctx.flowers, p, norm(d), a.r * 0.2, shade(bc, 1.05), jitter(bc, r2, 0.01, 0.05), 0.5, 4, r2.range(0, TAU))\n }\n }\n }\n\n splitCrown(ctx, anchors)\n\n // fruit\n if (spec.fruit && ctx.condition !== 'dry') {\n const f = spec.fruit\n const count = Math.round(f.count * ctx.pick(1, 0.3, 0))\n const r2 = new Rng(Math.floor(height * 733) + 5)\n const fr = f.radius ?? 0.07\n if (f.onTrunk) {\n const mains = tree.branches.filter((b2) => b2.level === 1)\n for (let i = 0; i < count; i++) {\n // ~45% on the trunk, the rest on the main limbs\n const onBranch = mains.length > 0 && r2.next() > 0.45\n const br = onBranch ? mains[r2.int(0, mains.length - 1)] : tree.trunk\n const tpts = br.pts\n const u = onBranch ? r2.range(0.05, 0.75) : r2.range(0.03, Math.min(0.7, (trunkFraction * 1.05) / 0.93))\n const idx = Math.min(tpts.length - 2, Math.floor(u * (tpts.length - 1)))\n const k = u * (tpts.length - 1) - idx\n const pos: Vec3 = [lerp(tpts[idx][0], tpts[idx + 1][0], k), lerp(tpts[idx][1], tpts[idx + 1][1], k), lerp(tpts[idx][2], tpts[idx + 1][2], k)]\n const rad = lerp(br.radii[idx], br.radii[idx + 1], k)\n const ang = r2.range(0, TAU)\n const c = rgb(r2.pick(f.colors))\n const out: Vec3 = [Math.cos(ang), r2.range(-0.3, 0.5), Math.sin(ang)]\n const center = add(pos, mul(norm(out), rad + fr * 0.4))\n const rr = fr * r2.range(0.8, 1.2)\n ctx.fruitItem(() => octa(ctx.fruit, center, [rr, rr, rr], (h) => shade(c, 0.75 + h * 0.6), 0))\n }\n } else {\n for (let i = 0; i < count; i++) {\n const a = groups[i % groups.length]\n const ang = r2.range(0, TAU)\n const rr = a.r * r2.range(0.45, 0.9)\n const depth = Math.sqrt(Math.max(0, 1 - (rr / a.r) ** 2)) * 0.8\n const top: Vec3 = [a.p[0] + Math.cos(ang) * rr, a.p[1] - a.r * (a.sq ?? squash) * depth * 0.9, a.p[2] + Math.sin(ang) * rr]\n const c = rgb(r2.pick(f.colors))\n const s = fr * r2.range(0.9, 1.15)\n const drop = s * 3.2\n const centre: Vec3 = [top[0], top[1] - drop - s * 0.6, top[2]]\n ctx.fruitItem(() => {\n tube(ctx.wood, [top, [top[0], top[1] - drop * 0.8, top[2]]], { sides: 3, radii: [0.008, 0.008], color: () => [0.3, 0.4, 0.2], sway: () => 0.5, end: 'none' })\n if (s < 0.06) octa(ctx.fruit, centre, [s * 0.85, s * 1.2, s * 0.85], (h) => shade(c, 0.7 + h * 0.45), 0.4)\n else icoShell(ctx.fruit, { center: centre, radii: [s * 0.85, s * 1.2, s * 0.85], detail: 0, rng: r2, noise: 0.04, color: (v) => shade(c, 0.7 + v.h * 0.45), sway: () => 0.4 })\n })\n }\n }\n }\n\n return {\n collider: { kind: 'cylinder', radius: trunkRadius * 1.1, height: height * Math.max(0.35, trunkFraction) },\n bendable: false,\n }\n}\n","import type { FlowerPlantSpec, FlowerType, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { add, catmull, dirFromAngles, mul, norm, sampleLine, TAU, lerp } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen } from '../color'\nimport { tube } from '../geometry/tube'\nimport { leaf } from '../geometry/leaf'\nimport { blossom, flowerHead, type FlowerKind } from '../geometry/flower'\nimport { clump } from '../geometry/shell'\n\ninterface TypeDef {\n height: number\n size: number\n stems: number\n colors: number[]\n center: number\n kind: FlowerKind\n leaf: { style: 'lance' | 'heart' | 'strap' | 'compound' | 'broad'; len: number; width: number; along: number; basal: number }\n woody?: boolean\n tilt?: number\n /** upright, nearly vertical stems */\n straight?: boolean\n /** flower heads per stem (default 1) */\n heads?: number\n bushy?: boolean\n hmin?: number\n /** leafy mound the flowers sit on instead of free stems (radius / height as multiples of the plant height) */\n mound?: { r: number; h: number; heads: number; leaf: number }\n}\n\nconst TYPES: Record<FlowerType, TypeDef> = {\n daisy: { height: 0.38, size: 0.05, stems: 6, colors: [0xfbfaf2], center: 0xf0b820, kind: 'daisy', leaf: { style: 'lance', len: 0.16, width: 0.05, along: 2, basal: 4 } },\n sunflower: { height: 1.7, size: 0.2, stems: 3, colors: [0xf4c21a], center: 0x4a2c14, kind: 'sunflower', leaf: { style: 'heart', len: 0.3, width: 0.24, along: 5, basal: 3 }, tilt: 0.5 },\n rose: { height: 0.85, size: 0.062, stems: 7, colors: [0xd0243a], center: 0xe8c040, kind: 'rose', leaf: { style: 'compound', len: 0.12, width: 0.07, along: 4, basal: 2 }, woody: true },\n tulip: { height: 0.42, size: 0.042, stems: 7, colors: [0xe03a52], center: 0x303030, kind: 'tulip', leaf: { style: 'strap', len: 0.3, width: 0.085, along: 0, basal: 3 }, straight: true },\n pompom: { height: 0.34, size: 0.019, stems: 8, colors: [0xf08a1a, 0xf5b020], center: 0x305020, kind: 'pompom', leaf: { style: 'lance', len: 0.11, width: 0.04, along: 5, basal: 3 }, bushy: true, heads: 2 },\n hydrangea: { height: 0.95, size: 0.07, stems: 5, mound: { r: 0.46, h: 0.78, heads: 5, leaf: 0.15 }, colors: [0x5a84d8, 0x8aa8e8, 0x9a90e0], center: 0x405080, kind: 'florets', leaf: { style: 'broad', len: 0.26, width: 0.19, along: 9, basal: 4 }, bushy: true },\n hibiscus: { height: 0.9, size: 0.1, stems: 3, colors: [0xe02a3a], center: 0xe8c040, kind: 'hibiscus', leaf: { style: 'heart', len: 0.18, width: 0.12, along: 4, basal: 2 }, woody: true },\n cluster: { height: 0.8, size: 0.15, stems: 4, colors: [0x5a84d8, 0x8aa8e8], center: 0x405080, kind: 'cluster', leaf: { style: 'broad', len: 0.26, width: 0.2, along: 4, basal: 2 } },\n lily: { height: 0.85, size: 0.09, stems: 3, colors: [0xfffaf0], center: 0xe08a20, kind: 'lily', leaf: { style: 'lance', len: 0.22, width: 0.04, along: 5, basal: 2 } },\n bird_of_paradise: { height: 1.3, size: 0.14, stems: 3, colors: [0xf08a20, 0x4a5ad0], center: 0x303030, kind: 'bird_of_paradise', leaf: { style: 'broad', len: 0.55, width: 0.2, along: 0, basal: 6 } },\n}\n\nexport function generateFlowerPlant(spec: FlowerPlantSpec, ctx: Ctx): ArchResult {\n const type = spec.flowerType ?? 'daisy'\n const def = TYPES[type]\n const rng = ctx.rng\n const over = ctx.condition === 'overgrown'\n const height = (spec.height ?? def.height) * (over ? 1.15 : 1)\n const stemCount = Math.max(ctx.lod === 2 ? 2 : 1, Math.round((spec.stemCount ?? def.stems) * (over ? 1.4 : 1) * (ctx.lod === 2 ? 0.45 : 1)))\n const colors = (spec.petalColors ?? def.colors).map(rgb)\n const heart = rgb(spec.centerColor ?? def.center)\n const leafBase = tintGreen(rgb(spec.leafColor ?? 0x3f8a3a), ctx.condition)\n const stemBase = tintGreen(rgb(spec.leafColor ? spec.leafColor : 0x4a8a3a), ctx.condition)\n const size = (spec.flowerSize ?? def.size) * 1.25\n const spreading = !!spec.spreading\n const mnd = spreading ? { r: 1.15, h: 0.62, heads: 0, leaf: 0.075 } : def.mound\n const isMound = !!mnd\n const bushy = !!spec.bushy || def.woody === true || def.bushy === true\n const dead = ctx.condition === 'dead'\n const dry = ctx.condition === 'dry'\n const bloomShare = dead ? 0 : (ctx.season === 'winter' ? 0.35 : 1) * (dry ? 0.5 : 1)\n const stemBuilder = def.woody ? ctx.wood : ctx.foliage\n const stemColor: Vec3 = def.woody ? mix(rgb(0x5a6a30), tintGreen(rgb(0x6b5030), ctx.condition), 0.4) : shade(stemBase, 0.9)\n const sides = ctx.pick(4, 3, 3)\n const leafRows = ctx.pick(2, 2, 2)\n const swayHead = 0.85\n\n const stemsData: { base: Vec3; tip: Vec3; path: Vec3[]; ang: number }[] = []\n for (let i = 0; i < stemCount; i++) {\n const ang = (i / stemCount) * TAU + rng.range(-0.4, 0.4)\n const r0 = spreading ? rng.range(0.02, 0.06) : rng.range(0.0, 0.09) * Math.sqrt(height)\n const base: Vec3 = [Math.cos(ang) * r0, 0, Math.sin(ang) * r0]\n const h = height * (def.hmin ? rng.range(def.hmin, 1.0) : rng.range(0.72, 1.08))\n const lean = spreading ? height * 1.1 * rng.range(0.7, 1.25) : def.straight ? h * rng.range(0.0, 0.05) : h * rng.range(0.08, bushy ? 0.4 : 0.22)\n const la = ang + rng.range(-0.5, 0.5)\n let tip: Vec3 = spreading ? [base[0] + Math.cos(la) * lean, h * 0.5, base[2] + Math.sin(la) * lean] : [base[0] + Math.cos(la) * lean, h, base[2] + Math.sin(la) * lean]\n if (dry) tip = [tip[0] * 1.4, tip[1] * 0.8, tip[2] * 1.4]\n if (dead) tip = [tip[0] * 2.2, tip[1] * 0.45, tip[2] * 2.2]\n const mid: Vec3 = spreading ? [lerp(base[0], tip[0], 0.5), h * 1.0, lerp(base[2], tip[2], 0.5)] : [lerp(base[0], tip[0], 0.3), tip[1] * 0.55, lerp(base[2], tip[2], 0.3)]\n const ctrl: Vec3[] = [base, mid, tip]\n const path = ctx.lod === 2 ? [base, tip] : catmull(ctrl, ctx.pick(3, 2, 1))\n stemsData.push({ base, tip, path, ang })\n }\n\n const moundR = height * (mnd?.r ?? 1)\n const moundH = height * (mnd?.h ?? 1)\n const mLeaf = mnd?.leaf ?? 0.08\n const mLeafC = dead ? mix(leafBase, [0.42, 0.32, 0.2], 0.8) : dry ? mix(leafBase, [0.55, 0.48, 0.22], 0.5) : leafBase\n const blobs: { c: Vec3; r: number; sq: number }[] = []\n if (isMound) {\n if (spreading) blobs.push({ c: [0, moundH * 0.42, 0], r: moundR, sq: (moundH / moundR) * 0.95 })\n else {\n // leafy bush: a ring of rounded leaf clumps around a taller one\n const nb = ctx.pick(6, 5, 4)\n for (let i = 0; i < nb; i++) {\n const a = i * 2.2 + 0.4\n const ring = i === 0 ? 0 : moundR * 0.5\n blobs.push({ c: [Math.cos(a) * ring, moundH * (i === 0 ? 0.55 : 0.28 + 0.07 * (i % 3)), Math.sin(a) * ring], r: moundR * (i === 0 ? 0.62 : 0.52), sq: 0.95 })\n }\n }\n for (const bl of blobs) clump(ctx.foliage, { center: bl.c, radius: bl.r, squash: bl.sq, detail: ctx.pick(1, 1, 0) as 0 | 1, seed: rng.seed(), base: dead ? mix(leafBase, [0.42, 0.32, 0.2], 0.7) : dry ? mix(leafBase, [0.55, 0.48, 0.22], 0.45) : mix(leafBase, [0.25, 0.55, 0.22], 0.25), swayK: 0.3, noise: 0.16, flatBottom: 0.8, ao: 0.5 })\n const nl = ctx.pick(spreading ? 60 : 66, spreading ? 26 : 30, 0)\n for (let i = 0; i < nl; i++) {\n const bl = blobs[i % blobs.length]\n const a = rng.range(0, TAU)\n const y = rng.range(0.05, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [bl.c[0] + d[0] * bl.r * 0.92, bl.c[1] + d[1] * bl.r * bl.sq * 0.92, bl.c[2] + d[2] * bl.r * 0.92]\n const out = norm([d[0], d[1] * 0.8 + 0.3, d[2]])\n leaf(ctx.foliage, p, norm([-d[2] * 0.3 + out[0], out[1] * 0.4 + 0.2, d[0] * 0.3 + out[2]]), out, mLeaf, mLeaf * 0.68, shade(mLeafC, 0.7), mix(mLeafC, [0.6, 0.8, 0.3], dead ? 0 : 0.2), { rows: 2, curl: 0.2, fold: 0.4, swayBase: 0.2, swayTip: 0.6, peak: 0.45, round: 0.7 })\n }\n }\n const radius = isMound ? 0.0001 : Math.max(0.004, height * 0.014) * (def.woody ? 1.2 : 1)\n for (const st of isMound ? [] : stemsData) {\n const n = st.path.length\n tube(stemBuilder, st.path, {\n sides,\n radii: st.path.map((_, k) => radius * (1 - 0.35 * (k / (n - 1)))),\n color: (t) => mix(shade(stemColor, 0.8), stemColor, t),\n sway: (t) => 0.15 + 0.8 * t * t,\n end: 'none',\n smooth: true,\n })\n }\n\n const leafC0 = shade(leafBase, 0.68)\n const leafC1 = mix(leafBase, [0.55, 0.75, 0.25], 0.25)\n const L = def.leaf\n const lscale = height / def.height\n const makeLeaf = (pos: Vec3, azimuth: number, elev: number, lenK: number): void => {\n let len = L.len * lscale * lenK * (over ? 1.2 : 1)\n let wid = L.width * lscale * lenK\n if (spreading) {\n len = 0.07 * lenK * (over ? 1.2 : 1)\n wid = 0.045 * lenK\n }\n const dir = dirFromAngles(azimuth, elev)\n const c0 = jitter(leafC0, rng, 0.01, 0.06, 0.04)\n const c1 = jitter(leafC1, rng, 0.01, 0.06, 0.04)\n switch (L.style) {\n case 'strap':\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len * 1.2, wid, c0, c1, { rows: ctx.pick(3, 2, 2), curl: 0.35, fold: 0.5, swayBase: 0.2, swayTip: 0.9, peak: 0.3, round: 1.4 })\n break\n case 'heart':\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len, wid, c0, c1, { rows: leafRows, curl: 0.3, fold: 0.4, swayBase: 0.3, swayTip: 0.9, peak: 0.3, round: 0.55, baseWidth: 0.25 })\n break\n case 'broad':\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len, wid, c0, c1, { rows: ctx.pick(3, 2, 2), curl: 0.25, fold: 0.5, swayBase: 0.3, swayTip: 0.9, peak: 0.45, round: 0.7 })\n break\n case 'compound': {\n const side = ctx.lod === 2 ? 0 : 2\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len, wid, c0, c1, { rows: 2, curl: 0.2, fold: 0.4, swayBase: 0.3, swayTip: 0.9, peak: 0.45 })\n for (let k = 0; k < side; k++) {\n const d2 = dirFromAngles(azimuth + (k ? 0.7 : -0.7), elev * 0.8)\n leaf(ctx.foliage, add(pos, mul(dir, len * 0.4)), d2, [0, 1, 0], len * 0.8, wid * 0.9, c0, c1, { rows: 2, curl: 0.2, fold: 0.4, swayBase: 0.3, swayTip: 0.9, peak: 0.45 })\n }\n break\n }\n default:\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len, wid, c0, c1, { rows: leafRows, curl: 0.25, fold: 0.5, swayBase: 0.25, swayTip: 0.9, peak: 0.4 })\n }\n }\n // basal leaves\n const basal = Math.round(L.basal * (bushy ? 1.5 : 1) * ctx.pick(1, 0.6, 0.35) * (over ? 1.4 : 1) * (dead ? 0.4 : 1))\n const basalN = isMound ? 0 : basal * Math.max(1, Math.round(stemCount / 3))\n for (let i = 0; i < basalN; i++) {\n const a = rng.range(0, TAU)\n const rr = spreading ? rng.range(0.02, 0.5) : rng.range(0, 0.07)\n const pos: Vec3 = [Math.cos(a) * rr, 0.01, Math.sin(a) * rr]\n makeLeaf(pos, a, spreading ? rng.range(0.15, 0.5) : rng.range(0.5, 1.0), rng.range(0.7, 1.2))\n }\n // leaves along the stems\n if (L.along > 0 && !dead && !isMound) {\n const per = Math.max(1, Math.round(L.along * ctx.pick(1, 0.5, 0)))\n for (const st of stemsData) {\n for (let k = 0; k < per; k++) {\n const t = lerp(0.15, 0.75, (k + rng.range(0, 0.6)) / per)\n const s = sampleLine(st.path, t)\n makeLeaf(s.p, st.ang + k * 2.4 + rng.range(-0.4, 0.4), rng.range(0.2, 0.9), lerp(1.05, 0.65, t) * rng.range(0.85, 1.15))\n }\n }\n }\n\n // flower heads\n const multi = colors.length > 1 && type !== 'cluster' && type !== 'bird_of_paradise'\n for (let i = 0; i < stemsData.length; i++) {\n const st = stemsData[i]\n if (rng.next() > bloomShare) {\n rng.next()\n continue\n }\n const tipDir = norm([st.tip[0] - st.path[st.path.length - 2][0], st.tip[1] - st.path[st.path.length - 2][1], st.tip[2] - st.path[st.path.length - 2][2]])\n let axis = tipDir\n if (def.tilt) axis = norm(add(tipDir, [Math.cos(st.ang) * def.tilt, -0.1, Math.sin(st.ang) * def.tilt]))\n if (type === 'tulip' || type === 'rose' || type === 'lily') axis = norm(add(axis, [0, 0.8, 0]))\n let hc = multi ? [colors[i % colors.length]] : colors\n if (dry) hc = hc.map((c) => mix(c, [0.55, 0.42, 0.25], 0.5))\n const sz = size * rng.range(0.85, 1.15)\n if (def.mound) {\n // heads sitting on the leafy mound\n if (i >= def.mound.heads) continue\n const a = i * 2.4 + rng.range(-0.3, 0.3)\n const bl = blobs[i % blobs.length]\n const y = i === 0 ? 1 : rng.range(0.6, 0.95)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [bl.c[0] + d[0] * bl.r * 0.9, bl.c[1] + d[1] * bl.r * bl.sq * 0.95, bl.c[2] + d[2] * bl.r * 0.9]\n flowerHead(ctx.flowers, { kind: def.kind, center: p, axis: norm([d[0] * 0.5, 1, d[2] * 0.5]), size: sz * rng.range(0.9, 1.1), colors: hc, centerColor: heart, rng: rng.fork(i), lod: ctx.lod, sway: swayHead })\n } else if (spreading) {\n // five-petal flowers sitting on top of the mound\n const nb = ctx.pick(2, 1, 1) + (i % 3 === 0 ? 1 : 0)\n for (let k = 0; k < nb; k++) {\n const a = rng.range(0, TAU)\n const y = rng.range(0.35, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [d[0] * moundR * 0.9, moundH * 0.42 + d[1] * moundH * 0.9, d[2] * moundR * 0.9]\n const nrm = norm([d[0] * 0.5, 0.9 + d[1] * 0.3, d[2] * 0.5])\n blossom(ctx.flowers, add(p, mul(nrm, 0.012)), nrm, sz * rng.range(0.85, 1.1), hc[0], heart, 0.7, ctx.pick(5, 5, 4), rng.range(0, TAU))\n }\n } else if (def.heads && def.heads > 1) {\n const nh = Math.max(1, Math.round(def.heads * ctx.pick(1, 0.7, 0.4)))\n for (let k = 0; k < nh; k++) {\n const s = sampleLine(st.path, k === 0 ? 1 : rng.range(0.55, 0.92))\n const ax = norm([Math.cos(st.ang + k) * 0.5 * (k ? 1 : 0.3), 1, Math.sin(st.ang + k) * 0.5 * (k ? 1 : 0.3)])\n flowerHead(ctx.flowers, { kind: def.kind, center: s.p, axis: ax, size: sz * (k === 0 ? 1 : 0.85), colors: hc, centerColor: heart, rng: rng.fork(i * 7 + k), lod: k === 0 ? ctx.lod : (Math.max(ctx.lod, 1) as 0 | 1 | 2), sway: swayHead })\n }\n } else {\n flowerHead(ctx.flowers, { kind: def.kind, center: add(st.tip, mul(axis, def.kind === 'rose' ? 0 : 0.0)), axis, size: sz, colors: hc, centerColor: heart, rng: rng.fork(i), lod: ctx.lod, sway: swayHead })\n }\n }\n\n return { collider: null, bendable: true }\n}\n\n","import type { Vec3 } from '../types'\nimport { add, mul } from '../math'\nimport { mix } from '../color'\nimport type { MeshBuilder } from './builder'\n\nexport interface BladeOptions {\n /** segments (tris = 2 * segs - 1) */\n segs: number\n /** horizontal lean 0..1.2 (fraction of height the tip is displaced) */\n lean: number\n /** curvature exponent of the lean (higher = straighter at the base) */\n bend?: number\n swayMax: number\n /** twist of the ribbon around the blade axis in radians */\n twist?: number\n}\n\n/** Curved tapered grass blade (a ribbon facing outward, not crossed planes). `az` is the direction the blade leans toward. */\nexport function blade(b: MeshBuilder, base: Vec3, az: number, height: number, width: number, c0: Vec3, c1: Vec3, o: BladeOptions): Vec3 {\n const dx = Math.cos(az)\n const dz = Math.sin(az)\n const bend = o.bend ?? 1.7\n const tw = o.twist ?? 0\n const side: Vec3 = [-dz * Math.cos(tw), Math.sin(tw), dx * Math.cos(tw)]\n const pts: Vec3[] = []\n for (let i = 0; i <= o.segs; i++) {\n const t = i / o.segs\n const h = height * (1 - 0.18 * t * t)\n const off = o.lean * height * Math.pow(t, bend)\n pts.push([base[0] + dx * off, base[1] + h * t, base[2] + dz * off])\n }\n const nrm: Vec3 = [dx, 0.2, dz]\n for (let i = 0; i < o.segs; i++) {\n const t0 = i / o.segs\n const t1 = (i + 1) / o.segs\n const w0 = width * 0.5 * (1 - Math.pow(t0, 1.3) * 0.9)\n const w1 = width * 0.5 * (1 - Math.pow(t1, 1.3) * 0.9) * (i + 1 === o.segs ? 0 : 1)\n const a = add(pts[i], mul(side, -w0))\n const bb = add(pts[i], mul(side, w0))\n const cA = mix(c0, c1, t0)\n const cB = mix(c0, c1, t1)\n const s0 = o.swayMax * Math.pow(t0, 1.4)\n const s1 = o.swayMax * Math.pow(t1, 1.4)\n if (i + 1 === o.segs) {\n b.flatTri(a, bb, pts[i + 1], cA, cA, cB, s0, s0, s1, nrm)\n } else {\n const c = add(pts[i + 1], mul(side, w1))\n const d = add(pts[i + 1], mul(side, -w1))\n b.flatQuad(a, bb, c, d, cA, cA, cB, cB, s0, s0, s1, s1, nrm)\n }\n }\n return pts[pts.length - 1]\n}\n","import type { GrassTuftSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, mul, dirFromAngles } from '../math'\nimport { jitter, rgb, shade, tintGreen, mix, lighten } from '../color'\nimport { blade } from '../geometry/blade'\nimport { tube } from '../geometry/tube'\nimport { icoShell } from '../geometry/shell'\n\nexport function generateGrassTuft(spec: GrassTuftSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const over = ctx.condition === 'overgrown'\n const count = Math.round((spec.count ?? 34) * (spec.seedHeads ? 0.75 : 1) * (spec.umbrellaHeads ? 0.2 : 1) * (over ? 1.4 : 1) * ctx.pick(1, 0.55, 0.22))\n const height = (spec.height ?? 0.35) * (over ? 1.3 : 1)\n const bladeH = spec.umbrellaHeads ? height * 0.35 : height\n const radius = spec.radius ?? height * 0.45\n let base = rgb(spec.color ?? 0x6aa646)\n base = tintGreen(base, ctx.condition)\n const dry = ctx.condition === 'dry' || ctx.condition === 'dead'\n const c0 = shade(base, 0.5)\n const c1 = mix(lighten(base, 0.8), [0.85, 0.85, 0.45], dry ? 0.2 : 0.18)\n const segs = ctx.pick(3, 2, 1)\n const wid = Math.max(0.018, height * ctx.pick(0.13, 0.16, 0.2))\n for (let i = 0; i < count; i++) {\n const a = rng.range(0, TAU)\n const d0 = rng.range(0, radius * 0.35)\n const p: Vec3 = [Math.cos(a) * d0, 0, Math.sin(a) * d0]\n const h = bladeH * rng.range(0.55, 1.15) * (1 - d0 / (radius * 1.8))\n // colour variation: some blades yellower, some darker\n const v = rng.next()\n const tone = v < 0.2 ? mix(c1, [0.78, 0.78, 0.32], 0.45) : v > 0.8 ? shade(c1, 0.8) : c1\n const col0 = jitter(v > 0.8 ? shade(c0, 0.85) : c0, rng, 0.012, 0.12, 0.06)\n const col1 = jitter(tone, rng, 0.02, 0.12, 0.07)\n blade(ctx.foliage, p, a + rng.range(-0.3, 0.3), h, wid * rng.range(0.8, 1.35), col0, col1, { segs, lean: rng.range(0.22, 0.7), swayMax: 1, twist: rng.range(-0.4, 0.4) })\n }\n if (spec.umbrellaHeads) {\n // papyrus: bare triangular stems, each topped by an umbrella of thin arching rays\n const ns = Math.max(3, Math.round((spec.count ?? 18) * 0.36 * ctx.pick(1, 0.6, 0.35)))\n const ray = ctx.pick(11, 7, 4)\n const gc = shade(base, 0.9)\n for (let i = 0; i < ns; i++) {\n const a = rng.range(0, TAU)\n const d0 = rng.range(0, radius * 0.6)\n const b0: Vec3 = [Math.cos(a) * d0, 0, Math.sin(a) * d0]\n const h = height * rng.range(0.85, 1.2)\n const la = rng.range(0, TAU)\n const lean = h * rng.range(0.03, 0.12) * (1 + d0 / radius)\n const top: Vec3 = [b0[0] + Math.cos(la) * lean, h, b0[2] + Math.sin(la) * lean]\n const mid: Vec3 = [b0[0] + Math.cos(la) * lean * 0.3, h * 0.5, b0[2] + Math.sin(la) * lean * 0.3]\n tube(ctx.foliage, [b0, mid, top], { sides: 3, radii: [height * 0.011, height * 0.009, height * 0.007], color: (t) => mix(shade(gc, 0.75), lighten(gc, 0.5), t), sway: (t) => 0.3 + 0.7 * t * t, end: 'none' })\n for (let k = 0; k < ray; k++) {\n const ra = (k / ray) * TAU + rng.range(-0.2, 0.2)\n const len = height * rng.range(0.2, 0.3)\n const dx = Math.cos(ra)\n const dz = Math.sin(ra)\n const p1: Vec3 = [top[0] + dx * len * 0.5, top[1] + len * 0.22, top[2] + dz * len * 0.5]\n const p2: Vec3 = [top[0] + dx * len, top[1] - len * 0.18, top[2] + dz * len]\n tube(ctx.foliage, [top, p1, p2], { sides: 3, radii: [height * 0.005, height * 0.004, height * 0.0025], color: (t) => mix(shade(gc, 1.05), lighten(gc, 0.9), t), sway: (t) => 0.6 + 0.4 * t, end: 'none' })\n }\n if (ctx.lod < 2) {\n // tuft of bracts under the umbrella\n icoShell(ctx.foliage, { center: [top[0], top[1] - 0.01, top[2]], radii: [height * 0.025, height * 0.018, height * 0.025], detail: 0, rng, noise: 0.1, color: (v) => shade(lighten(gc, 0.6), 0.8 + v.h * 0.3), sway: () => 0.9 })\n }\n }\n }\n if (spec.seedHeads && ctx.condition !== 'dead') {\n const seed = rgb(spec.seedColor ?? 0xd8c98a)\n const n = Math.max(2, Math.round(count / 7))\n for (let i = 0; i < n; i++) {\n const a = rng.range(0, TAU)\n const d0 = rng.range(0, radius * 0.3)\n const base0: Vec3 = [Math.cos(a) * d0, 0, Math.sin(a) * d0]\n const h = height * rng.range(1.5, 2.0)\n const lean = rng.range(0.1, 0.3)\n const dir = dirFromAngles(a, 1.3)\n const mid = add(base0, add(mul([dir[0], 0, dir[2]], h * lean * 0.5), [0, h * 0.55, 0]))\n const tip = add(base0, add(mul([dir[0], 0, dir[2]], h * lean), [0, h, 0]))\n tube(ctx.foliage, [base0, mid, tip], { sides: 3, radii: [height * 0.012, height * 0.009, height * 0.007], color: (t) => mix(c0, seed, t * 0.9), sway: (t) => 0.4 + 0.6 * t, end: 'none' })\n if (ctx.lod < 2) {\n const head = h * 0.22\n const hc = jitter(seed, rng, 0.01, 0.08, 0.05)\n icoShell(ctx.flowers, { center: add(tip, [dir[0] * head * 0.2, head * 0.35, dir[2] * head * 0.2]), radii: [height * 0.035, head * 0.55, height * 0.035], detail: 0, rng, noise: 0.1, color: (v) => shade(hc, 0.8 + v.h * 0.4), sway: () => 1 })\n }\n }\n }\n return { collider: null, bendable: true }\n}\n","import type { FernSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, cross, dirFromAngles, mul, norm, lerp } from '../math'\nimport { jitter, rgb, shade, tintGreen, mix } from '../color'\nimport { leaf, kite } from '../geometry/leaf'\n\nexport function generateFern(spec: FernSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const over = ctx.condition === 'overgrown'\n const n = Math.round((spec.frondCount ?? 11) * (ctx.condition === 'dead' ? 0.6 : 1) * (over ? 1.3 : 1) * ctx.pick(1, 0.7, 0.35))\n const L0 = (spec.frondLength ?? 0.7) * (over ? 1.15 : 1)\n const base = tintGreen(rgb(spec.color ?? 0x468f3c), ctx.condition)\n const c0 = shade(base, 0.62)\n const c1 = mix(shade(base, 1.12), [0.7, 0.85, 0.3], 0.15)\n const pairs = ctx.pick(11, 6, 0)\n for (let i = 0; i < n; i++) {\n const az = (i / n) * TAU + rng.range(-0.3, 0.3)\n const L = L0 * rng.range(0.7, 1.1) * (i % 3 === 0 ? 1.1 : 0.85)\n const e0 = rng.range(0.5, 1.15) * (i % 2 ? 0.8 : 1.1)\n const droop = rng.range(0.45, 0.9) * (ctx.condition === 'dry' ? 1.3 : 1)\n const horiz = dirFromAngles(az, 0)\n const pts: Vec3[] = []\n const segs = 6\n for (let k = 0; k <= segs; k++) {\n const t = k / segs\n pts.push([horiz[0] * L * t * Math.cos(e0) * 0.9 + 0.0, 0.04 + L * t * Math.sin(e0) - L * t * t * droop, horiz[2] * L * t * Math.cos(e0) * 0.9])\n }\n if (ctx.lod === 2) {\n leaf(ctx.foliage, pts[0], norm([pts[4][0] - pts[0][0], pts[4][1] - pts[0][1], pts[4][2] - pts[0][2]]), [0, 1, 0], L * 1.0, L * 0.34, c0, c1, { rows: 3, curl: 0.5, fold: 0.2, swayBase: 0.2, swayTip: 1, peak: 0.4, round: 1.3 })\n continue\n }\n // rachis as a thin ribbon\n for (let k = 0; k < segs; k++) {\n const a = pts[k]\n const bq = pts[k + 1]\n const d = norm([bq[0] - a[0], bq[1] - a[1], bq[2] - a[2]])\n const side = norm(cross(d, [0, 1, 0]))\n const w = L * 0.012 * (1 - k / segs)\n const t0 = k / segs\n const t1 = (k + 1) / segs\n const rc0 = shade(c0, 0.8 + 0.2 * t0)\n const rc1 = shade(c0, 0.8 + 0.2 * t1)\n ctx.foliage.flatQuad(add(a, mul(side, -w)), add(a, mul(side, w)), add(bq, mul(side, w * 0.8)), add(bq, mul(side, -w * 0.8)), rc0, rc0, rc1, rc1, 0.2 + 0.7 * t0, 0.2 + 0.7 * t0, 0.2 + 0.7 * t1, 0.2 + 0.7 * t1, [0, 1, 0])\n }\n if (pairs === 0) continue\n for (let k = 0; k < pairs; k++) {\n const t = lerp(0.1, 0.97, k / (pairs - 1))\n const f = t * segs\n const idx = Math.min(segs - 1, Math.floor(f))\n const u = f - idx\n const p: Vec3 = [lerp(pts[idx][0], pts[idx + 1][0], u), lerp(pts[idx][1], pts[idx + 1][1], u), lerp(pts[idx][2], pts[idx + 1][2], u)]\n const d = norm([pts[idx + 1][0] - pts[idx][0], pts[idx + 1][1] - pts[idx][1], pts[idx + 1][2] - pts[idx][2]])\n const side = norm(cross(d, [0, 1, 0]))\n const len = L * 0.2 * Math.sin(Math.PI * Math.min(1, t * 0.9 + 0.12)) * (0.8 + rng.next() * 0.3)\n const col0 = jitter(c0, rng, 0.01, 0.06, 0.04)\n const col1 = jitter(c1, rng, 0.01, 0.06, 0.04)\n for (const s of [-1, 1]) {\n const dir = norm(add(add(mul(side, s * 0.95), mul(d, 0.6)), [0, -0.28, 0]))\n kite(ctx.foliage, p, dir, [0, 1, 0], len, len * 0.5, col0, col1, 0.3 + 0.6 * t, 0.4 + 0.6 * t)\n }\n }\n }\n return { collider: null, bendable: true }\n}\n","import type { Vec3 } from '../types'\nimport { add, cross, dot, mul, norm } from '../math'\nimport { shade } from '../color'\nimport type { MeshBuilder } from './builder'\n\nexport interface FleshyLeafOptions {\n rows: number\n profile: 'blade' | 'sword' | 'aloe' | 'spoon'\n /** half thickness as a fraction of the half width at the ridge */\n thick: number\n /** tip droop as a fraction of length (along -up) */\n curl: number\n /** emit the underside (keel) as well */\n lower: boolean\n swayBase: number\n swayTip: number\n /** per row color: t along the length -> ridge color; edges use `edge` */\n color: (t: number) => Vec3\n edge: (t: number) => Vec3\n /** teeth along the edges: count per side, color, size as fraction of width */\n teeth?: { count: number; color: Vec3; size: number }\n /** terminal spine color */\n spine?: Vec3\n}\n\nfunction widthAt(profile: FleshyLeafOptions['profile'], t: number): number {\n switch (profile) {\n case 'blade': // agave: widest near 30%, long taper\n return t < 0.3 ? Math.pow(Math.sin((t / 0.3) * Math.PI * 0.5), 0.6) : Math.pow(1 - (t - 0.3) / 0.7, 0.85)\n case 'sword': // sansevieria: parallel sides, pointed tip\n return Math.min(1, Math.sin(Math.min(1, t * 6 + 0.15) * Math.PI * 0.5)) * (t > 0.82 ? Math.pow(1 - (t - 0.82) / 0.18, 0.8) : 1)\n case 'aloe': // triangular\n return t < 0.08 ? 0.75 + t * 3 : Math.pow(1 - (t - 0.08) / 0.92, 0.8)\n case 'spoon': // echeveria\n return Math.pow(Math.sin(Math.PI * Math.pow(Math.min(1, t * 0.97 + 0.03), 0.65)), 0.75)\n }\n}\n\n/** Thick leaf with a ridge on top and a keel below (ridge / edges / keel per row). Tip points along `dir`. */\nexport function fleshyLeaf(b: MeshBuilder, base: Vec3, dir: Vec3, up: Vec3, length: number, width: number, o: FleshyLeafOptions): void {\n const d = norm(dir)\n let right = cross(d, up)\n if (dot(right, right) < 1e-6) right = cross(d, [1, 0, 0])\n right = norm(right)\n const n2 = norm(cross(right, d))\n const R = o.rows\n type Row = { L: Vec3; T: Vec3; R: Vec3; K: Vec3; c: Vec3; e: Vec3; s: number; w: number; ctr: Vec3 }\n const rows: Row[] = []\n for (let i = 0; i <= R; i++) {\n const t = i / R\n const w = (i === R ? 0 : widthAt(o.profile, t)) * width * 0.5\n const centre = add(add(base, mul(d, length * t)), mul(n2, -length * o.curl * t * t))\n const th = w * o.thick\n const ridge = add(centre, mul(n2, th))\n const c = o.color(t)\n const e = o.edge(t)\n const sw = o.swayBase + (o.swayTip - o.swayBase) * t\n rows.push({\n L: add(centre, mul(right, -w)),\n T: ridge,\n R: add(centre, mul(right, w)),\n K: add(centre, mul(n2, -th * 0.8)),\n c,\n e,\n s: sw,\n w,\n ctr: centre,\n })\n }\n for (let i = 0; i < R; i++) {\n const a = rows[i]\n const z = rows[i + 1]\n const aw = a.w > 1e-6\n const zw = z.w > 1e-6\n if (!aw && zw) {\n b.flatTri(a.T, z.L, z.T, a.c, z.e, z.c, a.s, z.s, z.s, n2)\n b.flatTri(a.T, z.T, z.R, a.c, z.c, z.e, a.s, z.s, z.s, n2)\n if (o.lower) {\n b.flatTri(a.T, z.K, z.L, shade(a.c, 0.7), shade(z.c, 0.6), shade(z.e, 0.7), a.s, z.s, z.s, mul(n2, -1))\n b.flatTri(a.T, z.R, z.K, shade(a.c, 0.7), shade(z.e, 0.7), shade(z.c, 0.6), a.s, z.s, z.s, mul(n2, -1))\n }\n } else if (aw && !zw) {\n b.flatTri(a.L, z.T, a.T, a.e, z.c, a.c, a.s, z.s, a.s, n2)\n b.flatTri(a.T, z.T, a.R, a.c, z.c, a.e, a.s, z.s, a.s, n2)\n if (o.lower) {\n b.flatTri(a.L, a.K, z.T, shade(a.e, 0.7), shade(a.c, 0.6), z.c, a.s, a.s, z.s, mul(n2, -1))\n b.flatTri(a.K, a.R, z.T, shade(a.c, 0.6), shade(a.e, 0.7), z.c, a.s, a.s, z.s, mul(n2, -1))\n }\n } else if (aw && zw) {\n b.flatQuad(a.L, z.L, z.T, a.T, a.e, z.e, z.c, a.c, a.s, z.s, z.s, a.s, n2)\n b.flatQuad(a.T, z.T, z.R, a.R, a.c, z.c, z.e, a.e, a.s, z.s, z.s, a.s, n2)\n if (o.lower) {\n b.flatQuad(a.L, a.K, z.K, z.L, shade(a.e, 0.7), shade(a.c, 0.55), shade(z.c, 0.55), shade(z.e, 0.7), a.s, a.s, z.s, z.s, mul(n2, -1))\n b.flatQuad(a.K, a.R, z.R, z.K, shade(a.c, 0.55), shade(a.e, 0.7), shade(z.e, 0.7), shade(z.c, 0.55), a.s, a.s, z.s, z.s, mul(n2, -1))\n }\n }\n }\n if (o.teeth && o.teeth.count > 0) {\n const { count, color, size } = o.teeth\n for (let k = 0; k < count; k++) {\n const t0 = 0.12 + (0.7 * k) / count\n const t1 = t0 + 0.05\n const i0 = Math.min(R, Math.round(t0 * R))\n const i1 = Math.min(R, Math.max(i0 + 1, Math.round(t1 * R)))\n for (const sd of [-1, 1]) {\n const e0 = sd < 0 ? rows[i0].L : rows[i0].R\n const e1 = sd < 0 ? rows[i1].L : rows[i1].R\n const out = mul(right, sd * width * size)\n const tip = add(add(mul(add(e0, e1), 0.5), out), mul(d, length * 0.02))\n b.flatTri(e0, tip, e1, color, shade(color, 1.3), color, rows[i0].s, rows[i0].s, rows[i1].s, add(out, n2))\n }\n }\n }\n if (o.spine) {\n const last = rows[R]\n const prev = rows[R - 1]\n const tip = add(last.ctr, mul(d, length * 0.06))\n const hw = Math.max(prev.w * 0.12, width * 0.02)\n b.flatTri(add(prev.ctr, mul(right, -hw)), add(prev.ctr, mul(right, hw)), tip, o.spine, o.spine, shade(o.spine, 1.4), last.s, last.s, last.s, n2)\n b.flatTri(add(prev.ctr, mul(right, -hw)), tip, add(prev.ctr, mul(right, hw)), o.spine, shade(o.spine, 1.4), o.spine, last.s, last.s, last.s, mul(n2, -1))\n }\n}\n\n","import type { RosetteSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, dirFromAngles, lerp, mul } from '../math'\nimport { jitter, mix, rgb, shade, tintFlesh, lighten } from '../color'\nimport { fleshyLeaf } from '../geometry/succulent'\nimport { tube } from '../geometry/tube'\nimport { icoShell } from '../geometry/shell'\n\nexport function generateRosette(spec: RosetteSpec, ctx: Ctx): ArchResult {\n const form = spec.form ?? 'agave'\n const rng = ctx.rng\n const over = ctx.condition === 'overgrown'\n switch (form) {\n case 'sword': {\n const h = (spec.height ?? 0.8) * (over ? 1.2 : 1)\n const n = Math.round((spec.leafCount ?? 9) * (over ? 1.3 : 1) * ctx.pick(1, 0.7, 0.55))\n const base = tintFlesh(rgb(spec.color ?? 0x3f7a45), ctx.condition)\n const edgeC = tintFlesh(rgb(spec.edgeColor ?? 0xc9c24a), ctx.condition)\n const dark = shade(base, 0.6)\n const light = mix(base, [0.62, 0.78, 0.6], 0.45)\n for (let i = 0; i < n; i++) {\n const az = (i / n) * TAU * 1.0 + rng.range(-0.3, 0.3)\n const el = rng.range(1.2, 1.5)\n const len = h * rng.range(0.55, 1.0) * (ctx.condition === 'dead' ? 0.6 : 1)\n const ring = rng.range(0, 0.08)\n const base0: Vec3 = [Math.cos(az) * ring, 0.0, Math.sin(az) * ring]\n const band = rng.range(0, TAU)\n fleshyLeaf(ctx.foliage, base0, dirFromAngles(az, el), dirFromAngles(az + Math.PI, 0.2), len, h * 0.16 * rng.range(0.85, 1.15), {\n rows: ctx.pick(7, 4, 2),\n profile: 'sword',\n thick: 0.25,\n curl: rng.range(0.03, ctx.condition === 'dry' ? 0.3 : 0.12),\n lower: false,\n swayBase: 0,\n swayTip: 0.5,\n color: (t) => mix(dark, light, 0.5 + 0.5 * Math.sin(t * 22 + band)),\n edge: (t) => mix(edgeC, shade(edgeC, 0.8), 0.5 + 0.5 * Math.sin(t * 22 + band)),\n })\n }\n break\n }\n case 'aloe': {\n const h = (spec.height ?? 0.55) * (over ? 1.2 : 1)\n const n = Math.round((spec.leafCount ?? 12) * ctx.pick(1, 0.7, 0.5))\n const base = tintFlesh(rgb(spec.color ?? 0x6f9f6a), ctx.condition)\n const edge = rgb(spec.edgeColor ?? 0xe8e0c8)\n for (let i = 0; i < n; i++) {\n const ring = i < n * 0.4 ? 0 : i < n * 0.75 ? 1 : 2\n const az = i * 2.4 + rng.range(-0.2, 0.2)\n const el = [1.15, 0.85, 0.55][ring] + rng.range(-0.1, 0.1)\n const len = h * [0.75, 0.95, 0.85][ring] * rng.range(0.9, 1.1)\n const c = jitter(base, rng, 0.01, 0.06, 0.04)\n fleshyLeaf(ctx.foliage, [0, 0.02, 0], dirFromAngles(az, el), [0, 1, 0], len, h * 0.26, {\n rows: ctx.pick(3, 2, 2),\n profile: 'aloe',\n thick: 0.45,\n curl: 0.28,\n lower: ctx.lod === 0,\n swayBase: 0,\n swayTip: 0.5,\n color: (t) => mix(shade(c, 0.62), lighten(c, 0.5), t),\n edge: (t) => mix(shade(c, 0.5), shade(c, 0.95), t),\n teeth: ctx.lod === 0 ? { count: 5, color: edge, size: 0.07 } : undefined,\n })\n }\n if (spec.bloom && ctx.condition !== 'dead' && ctx.lod < 2) {\n const bc = rgb(spec.bloom.color)\n const stalkH = h * 1.5\n const tip: Vec3 = [0.04, stalkH, 0.02]\n tube(ctx.foliage, [[0, 0.1, 0], [0.02, stalkH * 0.5, 0.0], tip], { sides: 4, radii: [0.012, 0.01, 0.007], color: () => [0.45, 0.55, 0.3], sway: (t) => 0.3 + 0.6 * t, end: 'point' })\n for (let k = 0; k < 9; k++) {\n const t = 0.62 + (0.38 * k) / 9\n const y = lerp(0.1, stalkH, t)\n const a = k * 2.3\n const p: Vec3 = [lerp(0, 0.04, t) + Math.cos(a) * 0.012, y, lerp(0, 0.02, t) + Math.sin(a) * 0.012]\n const dir = dirFromAngles(a, -0.8)\n icoShell(ctx.flowers, { center: add(p, mul(dir, 0.03)), radii: [0.014, 0.04, 0.014], detail: 0, noise: 0, rng, color: (v) => mix(shade(bc, 0.8), lighten(bc, 0.4), v.h), sway: () => 0.9 })\n }\n }\n break\n }\n case 'echeveria': {\n const h = spec.height ?? 0.14\n const base = tintFlesh(rgb(spec.color ?? 0x8fb0a0), ctx.condition)\n const tipC = rgb(spec.edgeColor ?? 0xd88aa0)\n const rings = ctx.pick([5, 7, 9, 11], [5, 8, 10], [6, 9])\n rings.forEach((cnt, r) => {\n for (let i = 0; i < cnt; i++) {\n const az = (i / cnt) * TAU + r * 0.45 + rng.range(-0.1, 0.1)\n const el = [1.35, 1.0, 0.65, 0.35][Math.min(r, 3)]\n const len = h * [0.5, 0.65, 0.8, 0.9][Math.min(r, 3)]\n const c = jitter(base, rng, 0.008, 0.05, 0.04)\n fleshyLeaf(ctx.foliage, [0, 0.01 + r * 0.004, 0], dirFromAngles(az, el), [0, 1, 0], len, h * 0.42, {\n rows: ctx.pick(3, 2, 2),\n profile: 'spoon',\n thick: 0.6,\n curl: 0.25,\n lower: ctx.lod === 0,\n swayBase: 0,\n swayTip: 0.15,\n color: (t) => mix(shade(c, 0.7), mix(lighten(c, 0.4), tipC, 0.5), Math.pow(t, 2)),\n edge: (t) => mix(shade(c, 0.6), tipC, Math.pow(t, 1.5) * 0.9),\n })\n }\n })\n break\n }\n default: {\n // agave\n const h = (spec.height ?? 0.9) * (over ? 1.15 : 1)\n const n = Math.round((spec.leafCount ?? 20) * ctx.pick(1, 0.7, 0.55))\n const base = tintFlesh(rgb(spec.color ?? 0x5f9a8a), ctx.condition)\n const tooth = rgb(spec.edgeColor ?? 0x5a3a2a)\n for (let i = 0; i < n; i++) {\n const f = i / n\n const az = i * 2.399963 + rng.range(-0.15, 0.15)\n const el = lerp(1.35, 0.3, Math.pow(f, 0.8)) + rng.range(-0.06, 0.06)\n const len = h * lerp(0.55, 1, Math.pow(f, 0.6)) * rng.range(0.92, 1.08)\n const c = jitter(base, rng, 0.012, 0.06, 0.04)\n fleshyLeaf(ctx.foliage, [0, 0.03, 0], dirFromAngles(az, el), [0, 1, 0], len, len * 0.3, {\n rows: ctx.pick(3, 2, 2),\n profile: 'blade',\n thick: 0.5,\n curl: lerp(0.12, 0.3, f),\n lower: ctx.lod === 0,\n swayBase: 0,\n swayTip: 0.25,\n color: (t) => mix(shade(c, 0.6), mix(lighten(c, 0.6), [0.7, 0.8, 0.6], 0.25), Math.pow(t, 0.9)),\n edge: (t) => mix(shade(c, 0.5), shade(c, 1.0), t * 0.8),\n teeth: ctx.lod === 0 && f > 0.35 ? { count: 4, color: tooth, size: 0.05 } : undefined,\n spine: ctx.lod < 2 ? tooth : undefined,\n })\n }\n break\n }\n }\n return { collider: null, bendable: true }\n}\n","import type { Vec3 } from '../types'\nimport { add, cross, mul, norm, perp } from '../math'\nimport { shade } from '../color'\nimport type { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\n\n/** Tuft of thin radial spines at an areole: each spine is one thin triangle. */\nexport function spineTuft(b: MeshBuilder, p: Vec3, n: Vec3, count: number, length: number, color: Vec3, rng: Rng, sway = 0): void {\n const nn = norm(n)\n const t1 = perp(nn)\n const t2 = norm(cross(nn, t1))\n const w = length * 0.07\n for (let i = 0; i < count; i++) {\n const a = (i / count) * Math.PI * 2 + rng.range(0, 0.6)\n const spread = i === 0 ? 0 : 0.55\n const dir = norm(add(mul(nn, 1), add(mul(t1, Math.cos(a) * spread), mul(t2, Math.sin(a) * spread))))\n const tip = add(p, mul(dir, length * rng.range(0.75, 1.1)))\n const side = mul(norm(cross(dir, nn)), w)\n const left = add(p, side)\n const right = add(p, mul(side, -1))\n b.flatTri(left, right, tip, shade(color, 0.8), shade(color, 0.8), color, sway, sway, sway, nn)\n }\n}\n\n/** Tiny dark areole base under a tuft (single triangle). */\nexport function areole(b: MeshBuilder, p: Vec3, n: Vec3, size: number, color: Vec3, sway = 0): void {\n const nn = norm(n)\n const t1 = mul(perp(nn), size)\n const t2 = mul(norm(cross(nn, perp(nn))), size)\n const c = add(p, mul(nn, size * 0.1))\n b.flatTri(add(c, t1), add(c, add(mul(t1, -0.5), t2)), add(c, add(mul(t1, -0.5), mul(t2, -1))), color, color, color, sway, sway, sway, nn)\n}\n","import type { ColumnarCactusSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, catmull, dirFromAngles, lerp, mul, norm } from '../math'\nimport { mix, rgb, shade, tintFlesh, lighten } from '../color'\nimport { ribbedTube } from '../geometry/tube'\nimport { spineTuft, areole } from '../geometry/spines'\nimport { flowerHead } from '../geometry/flower'\n\nexport function generateColumnarCactus(spec: ColumnarCactusSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const srng = rng.fork('spines')\n const dead = ctx.condition === 'dead'\n const dry = ctx.condition === 'dry'\n const over = ctx.condition === 'overgrown'\n const H = (spec.height ?? 3.2) * (over ? 1.1 : 1)\n const R = spec.radius ?? H * 0.055\n const ribsFull = spec.ribs ?? 10\n const ribs = ctx.pick(ribsFull, Math.max(6, Math.round(ribsFull * 0.7)), Math.min(5, ribsFull))\n const style = spec.armStyle ?? 'candelabra'\n const armsSpec = spec.arms ?? [2, 4]\n const arms = (Array.isArray(armsSpec) ? rng.int(armsSpec[0], armsSpec[1]) : armsSpec) + (over ? 1 : 0)\n const base = tintFlesh(rgb(spec.color ?? 0x5f9a78), ctx.condition)\n const spineC = rgb(spec.spineColor ?? 0xe6dcb4)\n const slump = dead ? 0.22 : dry ? 0.05 : 0\n const rings = ctx.pick(1, 0.7, 0.45)\n const domeSteps = ctx.pick(2, 1, 1)\n const spineOn = ctx.lod === 0 && ctx.condition !== 'dead' ? 1 : ctx.lod === 0 ? 0.5 : 0\n\n const bodyColor = (t: number, ridge: boolean, rib: number): Vec3 => {\n let k = ridge ? 1.05 : 0.7\n if (rib % 2 === 0) k *= 1.04\n const c = shade(base, k * (0.78 + 0.28 * Math.min(1, t * 1.4)))\n return mix(c, lighten(base, 0.8), Math.max(0, t - 0.8) * 1.4 * (ridge ? 1 : 0.5))\n }\n const info: { tipPos: Vec3; tipDir: Vec3; r: number }[] = []\n\n const column = (path: Vec3[], radiusAt: (t: number) => number, seedK: number, withSpines: boolean): void => {\n const radii = path.map((_, i) => radiusAt(i / (path.length - 1)))\n const res = ribbedTube(ctx.foliage, path, {\n ribs,\n radii,\n valley: 0.74,\n dome: domeSteps,\n color: (t, ridge, rib) => bodyColor(t, ridge, rib + seedK),\n sway: () => 0,\n rough: (ring, rib) => Math.sin(ring * 1.7 + rib * 2.3 + seedK) * 0.03,\n })\n const last = path[path.length - 1]\n const prev = path[path.length - 2]\n info.push({ tipPos: add(last, mul(norm([last[0] - prev[0], last[1] - prev[1], last[2] - prev[2]]), radii[radii.length - 1] * 0.9)), tipDir: norm([last[0] - prev[0], last[1] - prev[1], last[2] - prev[2]]), r: radii[radii.length - 1] })\n if (withSpines && spineOn > 0) {\n for (const rd of res.ridges) {\n if (rd.ring === 0 || rd.ring % 3 !== 1) continue\n if (srng.next() > spineOn) continue\n areole(ctx.spines, rd.p, rd.n, R * 0.09, [0.25, 0.2, 0.15])\n spineTuft(ctx.spines, rd.p, add(rd.n, [0, 0.15, 0]), 3, R * 0.55, spineC, srng)\n }\n }\n }\n\n // main trunk (slightly sinuous, slumped when dead)\n const nCtrl = 5\n const ctrl: Vec3[] = []\n const lean = rng.range(-0.04, 0.04) * H\n for (let i = 0; i < nCtrl; i++) {\n const t = i / (nCtrl - 1)\n ctrl.push([lean * t + slump * H * t * t, H * t, Math.sin(t * 3 + rng.range(0, 1)) * 0.015 * H])\n }\n const mainPath = catmull(ctrl, Math.max(1, Math.round(2 * rings)))\n const mainR = (t: number): number => R * (1 + 0.35 * Math.exp(-t * 18)) * (1 - 0.08 * t) * (t > 0.92 ? 1 - (t - 0.92) * 1.5 : 1)\n column(mainPath, mainR, 0, true)\n const at = (t: number): { p: Vec3; r: number } => {\n const f = t * (mainPath.length - 1)\n const i = Math.min(mainPath.length - 2, Math.floor(f))\n const u = f - i\n return { p: [lerp(mainPath[i][0], mainPath[i + 1][0], u), lerp(mainPath[i][1], mainPath[i + 1][1], u), lerp(mainPath[i][2], mainPath[i + 1][2], u)], r: mainR(t) }\n }\n\n // arms\n for (let a = 0; a < arms; a++) {\n const az = (a / arms) * TAU + rng.range(-0.5, 0.5)\n const out = dirFromAngles(az, 0)\n let t0: number\n let outLen: number\n let upLen: number\n let rise: number\n switch (style) {\n case 'saguaro':\n t0 = rng.range(0.35, 0.6)\n outLen = H * rng.range(0.12, 0.2)\n upLen = H * rng.range(0.25, 0.4)\n rise = 0.1\n break\n case 'sprawl':\n t0 = rng.range(0.02, 0.2)\n outLen = H * rng.range(0.3, 0.6)\n upLen = H * rng.range(0.25, 0.5)\n rise = 0.35\n break\n default:\n t0 = rng.range(0.45, 0.75)\n outLen = H * rng.range(0.08, 0.15)\n upLen = H * rng.range(0.28, 0.42)\n rise = 0.25\n }\n const s = at(t0)\n const start = add(s.p, mul(out, s.r * 0.3))\n const p1 = add(start, add(mul(out, outLen * 0.7), [0, outLen * rise, 0]))\n const p2 = add(start, add(mul(out, outLen), [0, outLen * rise + upLen * 0.18, 0]))\n let p3 = add(p2, add(mul(out, outLen * 0.15), [0, upLen, 0]))\n if (dead) p3 = add(p2, add(mul(out, upLen * 0.7), [0, upLen * 0.25, 0]))\n ctx.piece(`arm${a}`, 'arm', 'stem', start)\n const armPath = catmull([start, p1, p2, p3], Math.max(1, Math.round(2 * rings)))\n const ar = s.r * (style === 'sprawl' ? 0.9 : 0.72)\n column(armPath, (t) => ar * (t > 0.9 ? 1 - (t - 0.9) * 1.6 : 1) * (t < 0.12 ? 0.85 + t * 1.2 : 1), a + 1, true)\n }\n\n ctx.piece('stem', 'stem')\n const frng = rng.fork('flowers')\n // flowers (night bloom, white trumpets) at the tips\n if (spec.flowers && !dead && ctx.lod < 2) {\n const fc = rgb(spec.flowers.color)\n const count = spec.flowers.count ?? 1\n for (let i = 0; i < info.length; i++) {\n for (let k = 0; k < count; k++) {\n if (frng.next() > 0.8) continue\n const tip = info[i]\n const ax = norm(add(tip.tipDir, [rng.range(-0.5, 0.5), 0.2, rng.range(-0.5, 0.5)]))\n flowerHead(ctx.flowers, { kind: 'trumpet', center: add(tip.tipPos, mul(tip.tipDir, -tip.r * 0.3)), axis: ax, size: R * 1.5, colors: [fc, shade(fc, 0.92)], centerColor: [0.95, 0.85, 0.4], rng: rng.fork(i * 7 + k), lod: ctx.lod, sway: 0 })\n }\n }\n }\n return { collider: { kind: 'cylinder', radius: R * 1.1, height: H * 0.9 }, bendable: false, thorny: true, foliageMaterial: 'cactus' }\n}\n","import type { PaddleCactusSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { add, mul, norm, rotAxis, TAU } from '../math'\nimport { jitter, mix, rgb, shade, tintFlesh, lighten } from '../color'\nimport { icoShell } from '../geometry/shell'\nimport { spineTuft } from '../geometry/spines'\nimport { blossom } from '../geometry/flower'\nimport { frameFromAxis, type Frame } from '../math'\n\ninterface Pad {\n center: Vec3\n dir: Vec3\n /** width axis */\n x: Vec3\n /** thickness axis */\n z: Vec3\n w: number\n l: number\n gen: number\n index: number\n parent?: number\n start: Vec3\n}\n\nexport function generatePaddleCactus(spec: PaddleCactusSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const dead = ctx.condition === 'dead'\n const over = ctx.condition === 'overgrown'\n const gens = (spec.generations ?? 3) + (over ? 1 : 0)\n const padL = (spec.padSize ?? 0.34) * (over ? 1.1 : 1)\n const base = tintFlesh(rgb(spec.color ?? 0x6c9f62), ctx.condition)\n const spineC = rgb(0xe9dfb8)\n const pads: Pad[] = []\n const frng = rng.fork('decor')\n\n const mkFrame = (dir: Vec3, twist: number): { x: Vec3; z: Vec3 } => {\n const f = frameFromAxis([0, 0, 0], dir, twist)\n return { x: f.x, z: f.z }\n }\n const addPad = (start: Vec3, dir: Vec3, scale: number, gen: number, twist: number, parent?: Pad): Pad => {\n const l = padL * scale * rng.range(0.9, 1.1)\n const w = l * rng.range(0.62, 0.78)\n const d = norm(dir)\n const { x, z } = mkFrame(d, twist)\n const p: Pad = { center: add(start, mul(d, l * 0.46)), dir: d, x, z, w, l, gen, index: pads.length, parent: parent?.index, start }\n pads.push(p)\n return p\n }\n const root = addPad([0, 0, 0], [rng.range(-0.15, 0.15), 1, rng.range(-0.15, 0.15)], 1.15, 0, rng.range(0, TAU))\n let frontier: Pad[] = [root]\n for (let g = 1; g < gens; g++) {\n const next: Pad[] = []\n for (const p of frontier) {\n const kids = g === 1 ? rng.int(2, 3) : rng.int(1, 3)\n for (let k = 0; k < kids; k++) {\n // attach near the upper edge; tilt sideways around the pad's thickness axis, with a little twist\n const side = kids === 1 ? rng.sign() : (k / (kids - 1)) * 2 - 1\n const ang = side * rng.range(0.5, 0.95)\n let nd = rotAxis(p.dir, p.z, ang)\n nd = rotAxis(nd, p.dir, rng.range(-0.4, 0.4))\n nd = norm(add(nd, [0, 0.25, 0]))\n if (dead) nd = norm(add(nd, [0, -0.7, 0]))\n const start = add(add(p.center, mul(p.dir, p.l * 0.42)), mul(p.x, side * p.w * 0.28))\n next.push(addPad(start, nd, 0.86 - g * 0.04, g, rng.range(0, TAU), p))\n }\n }\n frontier = next\n }\n const maxGen = ctx.lod === 2 ? 1 : 99\n const detail = (ctx.lod === 0 ? 1 : 0) as 0 | 1\n for (const p of pads) {\n if (p.gen > maxGen) continue\n ctx.piece(`pad${p.index}`, 'pad', p.parent === undefined ? undefined : `pad${p.parent}`, p.start)\n ctx.pieceGeom(`pad${p.index}`, { radius: p.l * 0.085, length: p.l, axis: p.dir, base: p.start })\n const frame: Frame = { o: p.center, x: p.x, y: p.dir, z: p.z }\n const c = jitter(base, rng.fork(p.gen * 31 + Math.floor(p.l * 1000)), 0.012, 0.05, 0.04)\n icoShell(ctx.foliage, {\n center: p.center,\n frame,\n radii: [p.w * 0.5, p.l * 0.5, p.l * 0.085],\n detail,\n rng: rng.fork(Math.floor(p.l * 997) + p.gen),\n noise: 0.04,\n color: (v) => {\n const edge = 1 - Math.abs(v.dir[2])\n let k = 0.72 + 0.34 * v.h\n k *= 0.9 + 0.2 * edge\n const col = shade(c, k)\n return p.gen === 0 ? mix(col, shade(c, 0.6), Math.max(0, 0.5 - v.h) * 0.8) : mix(col, lighten(c, 0.5), Math.max(0, v.h - 0.8))\n },\n sway: () => 0,\n })\n if (ctx.lod === 0 && ctx.condition !== 'dead') {\n // areole tufts on both faces\n const n = 12\n for (let i = 0; i < n; i++) {\n const u = ((i % 4) + 0.5 + (Math.floor(i / 4) % 2) * 0.5) / 4.2 - 0.5\n const v = (Math.floor(i / 4) + 0.5) / 3 - 0.5\n const face = i % 2 ? 1 : -1\n const px = u * p.w * 0.78\n const py = v * p.l * 0.8\n const pz = face * p.l * 0.085 * Math.sqrt(Math.max(0, 1 - (px / (p.w * 0.5)) ** 2 - (py / (p.l * 0.5)) ** 2)) * 1.04\n const pos = add(add(add(p.center, mul(p.x, px)), mul(p.dir, py)), mul(p.z, pz))\n const nrm = add(mul(p.z, face), [0, 0.1, 0])\n spineTuft(ctx.spines, pos, nrm, 3, p.l * 0.1, spineC, frng)\n }\n }\n }\n // fruit and flowers on the rim of the outer pads\n const outer = pads.filter((p) => p.gen >= gens - 1 || p.gen >= 2)\n if (spec.fruit && !dead && ctx.lod < 2) {\n const fc = rgb(spec.fruit.color)\n for (let i = 0; i < spec.fruit.count; i++) {\n const p = outer[i % Math.max(1, outer.length)] ?? root\n const side = frng.sign()\n const pos = add(add(p.center, mul(p.dir, p.l * 0.5 * 0.92)), mul(p.x, side * p.w * frng.range(0, 0.28)))\n const r = padL * 0.1\n ctx.fruitItem(() => icoShell(ctx.fruit, { center: add(pos, mul(p.z, r * 0.2)), radii: [r * 0.8, r * 1.15, r * 0.8], detail: 0, rng: frng, noise: 0.05, color: (v) => mix(shade(fc, 0.7), lighten(fc, 0.4), v.h), sway: () => 0 }))\n }\n }\n if (spec.flowers && !dead && ctx.lod === 0) {\n const fc = rgb(spec.flowers.color)\n for (let i = 0; i < spec.flowers.count; i++) {\n const p = outer[(i * 3 + 1) % Math.max(1, outer.length)] ?? root\n ctx.piece(`pad${p.index}`, 'pad', p.parent === undefined ? undefined : `pad${p.parent}`, p.start)\n const pos = add(add(p.center, mul(p.dir, p.l * 0.5 * 0.9)), mul(p.x, frng.range(-0.25, 0.25) * p.w))\n blossom(ctx.flowers, add(pos, mul(p.z, p.l * 0.04)), norm(add(p.dir, mul(p.z, 0.5))), padL * 0.16, fc, [0.9, 0.5, 0.2], 0, 6, frng.range(0, TAU))\n }\n }\n return { collider: { kind: 'cylinder', radius: padL * 0.12, height: padL * 1.2 }, bendable: false, thorny: true, foliageMaterial: 'cactus' }\n}\n","import type { GlobeCactusSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, norm } from '../math'\nimport { mix, rgb, shade, tintFlesh, lighten } from '../color'\nimport { ribbedTube } from '../geometry/tube'\nimport { spineTuft, areole } from '../geometry/spines'\nimport { icoShell } from '../geometry/shell'\nimport { blossom } from '../geometry/flower'\n\nexport function generateGlobeCactus(spec: GlobeCactusSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const srng = rng.fork('spines')\n const R = (spec.radius ?? 0.28) * (ctx.condition === 'overgrown' ? 1.1 : 1)\n const H = spec.height ?? R * 2.0\n const ribs = spec.ribs ?? 13\n const base = tintFlesh(rgb(spec.color ?? 0x5c9a58), ctx.condition)\n const spineC = rgb(spec.spineColor ?? 0xf0d890)\n const rings = ctx.pick(7, 5, 3)\n const path: Vec3[] = []\n const radii: number[] = []\n for (let i = 0; i < rings; i++) {\n const t = i / (rings - 1)\n path.push([0, H * 0.9 * t, 0])\n // barrel profile: narrow at the soil line, full at 45%, rounding in at the top\n radii.push(R * (0.55 + 0.45 * Math.sin(Math.min(1, t * 1.2 + 0.1) * Math.PI * 0.62) ** 0.7) * (t > 0.85 ? 1 - (t - 0.85) * 1.2 : 1))\n }\n const res = ribbedTube(ctx.foliage, path, {\n ribs,\n radii,\n valley: 0.7,\n dome: ctx.pick(2, 1, 1),\n color: (t, ridge, rib) => {\n const k = (ridge ? 1.08 : 0.68) * (0.75 + 0.3 * t) * (rib % 2 ? 0.97 : 1.03)\n return shade(base, k)\n },\n sway: () => 0,\n rough: (ring, rib) => Math.sin(ring * 2.1 + rib * 1.3) * 0.02,\n })\n if (ctx.lod === 0) {\n for (const rd of res.ridges) {\n if (rd.ring === 0 || rd.t > 0.9) continue\n areole(ctx.spines, rd.p, rd.n, R * 0.08, [0.3, 0.25, 0.18])\n spineTuft(ctx.spines, rd.p, add(rd.n, [0, 0.1, 0]), 5, R * 0.42, spineC, srng)\n }\n }\n const topY = H * 0.9 + R * 0.2\n if (spec.cephalium && ctx.lod < 2) {\n // cap of the crown cactus: red hairy dome with white bristles\n const cc = rgb(spec.cephalium.color)\n const capR = radii[radii.length - 1] * 0.95 + R * 0.12\n icoShell(ctx.fruit, {\n center: [0, H * 0.9 + R * 0.02, 0],\n radii: [capR, R * 0.45, capR],\n detail: ctx.pick(1, 0, 0) as 0 | 1,\n rng: srng,\n noise: 0.08,\n color: (v) => mix(shade(cc, 0.7), mix(lighten(cc, 0.3), [0.95, 0.9, 0.85], 0.35), v.h),\n sway: () => 0,\n })\n if (ctx.lod === 0) {\n for (let i = 0; i < 14; i++) {\n const a = srng.range(0, TAU)\n const rr = Math.sqrt(srng.next()) * capR * 0.8\n const y = H * 0.9 + R * 0.02 + R * 0.45 * Math.sqrt(Math.max(0, 1 - (rr / capR) ** 2))\n spineTuft(ctx.spines, [Math.cos(a) * rr, y, Math.sin(a) * rr], [0, 1, 0], 3, R * 0.22, [0.96, 0.9, 0.8], srng)\n }\n for (let i = 0; i < 3; i++) {\n const a = i * 2.1\n const rr = capR * 0.3\n blossom(ctx.flowers, [Math.cos(a) * rr, H * 0.9 + R * 0.48, Math.sin(a) * rr], [0, 1, 0], R * 0.14, [0.95, 0.4, 0.6], [1, 0.9, 0.5], 0, 5, a)\n }\n }\n } else if (spec.flowers && ctx.condition !== 'dead' && ctx.lod < 2) {\n const fc = rgb(spec.flowers.color)\n const n = spec.flowers.count ?? 6\n for (let i = 0; i < n; i++) {\n const a = (i / n) * TAU\n const rr = radii[radii.length - 1] * 0.62\n const p: Vec3 = [Math.cos(a) * rr, topY - R * 0.1, Math.sin(a) * rr]\n blossom(ctx.flowers, p, norm([Math.cos(a) * 0.4, 1, Math.sin(a) * 0.4]), R * 0.22, fc, [0.95, 0.8, 0.3], 0, 8, a)\n }\n }\n return { collider: { kind: 'cylinder', radius: R * 1.0, height: H }, bendable: false, thorny: true, foliageMaterial: 'cactus' }\n}\n","import type { Lod, Vec3 } from '../types'\nimport { add, cross, dirFromAngles, lerp, mul, norm } from '../math'\nimport { shade, mix, jitter } from '../color'\nimport type { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\nimport { kite, leaf } from './leaf'\n\nexport interface PinnateOptions {\n origin: Vec3\n az: number\n /** elevation of the rachis at the base (radians) */\n elev: number\n length: number\n /** gravity droop: fraction of the length lost at the tip */\n droop: number\n /** leaflet length as a fraction of the frond length */\n leafletLen: number\n /** leaflet pairs at lod 0 */\n pairs: number\n c0: Vec3\n c1: Vec3\n lod: Lod\n rng: Rng\n /** sway at base / tip */\n swayBase: number\n swayTip: number\n /** how much leaflets hang down (V shape), default 0.45 */\n hang?: number\n /** leaflet width as a fraction of its length (default 0.2) */\n leafletWidth?: number\n}\n\n/** Curved rachis with leaflets on both sides (palm / date / areca frond). Returns the tip. */\nexport function pinnateFrond(b: MeshBuilder, o: PinnateOptions): Vec3 {\n const horiz = dirFromAngles(o.az, 0)\n const segs = o.lod === 0 ? 8 : o.lod === 1 ? 5 : 4\n const pts: Vec3[] = []\n const ce = Math.cos(o.elev)\n const se = Math.sin(o.elev)\n for (let k = 0; k <= segs; k++) {\n const t = k / segs\n pts.push([o.origin[0] + horiz[0] * o.length * t * ce, o.origin[1] + o.length * (t * se - o.droop * t * t), o.origin[2] + horiz[2] * o.length * t * ce])\n }\n const sideV = norm(cross(horiz, [0, 1, 0]))\n if (o.lod === 2) {\n // one narrow arched strip that droops along the rachis\n const mid = pts[Math.floor(segs / 2)]\n const d0 = norm([mid[0] - o.origin[0], mid[1] - o.origin[1] + 0.001, mid[2] - o.origin[2]])\n leaf(b, o.origin, d0, [0, 1, 0], o.length * 1.02, o.length * 0.15, shade(o.c0, 0.95), o.c1, { rows: 3, curl: o.droop * 1.1, fold: 0.6, swayBase: o.swayBase, swayTip: o.swayTip, peak: 0.4, round: 1.1, baseWidth: 0.1 })\n return pts[segs]\n }\n // rachis ribbon\n for (let k = 0; k < segs; k++) {\n const a = pts[k]\n const bq = pts[k + 1]\n const w = o.length * 0.012 * (1 - 0.7 * (k / segs))\n const t0 = k / segs\n const t1 = (k + 1) / segs\n const s0 = lerp(o.swayBase, o.swayTip, t0)\n const s1 = lerp(o.swayBase, o.swayTip, t1)\n const rc = shade(o.c0, 0.75)\n b.flatQuad(add(a, mul(sideV, -w)), add(a, mul(sideV, w)), add(bq, mul(sideV, w * 0.8)), add(bq, mul(sideV, -w * 0.8)), rc, rc, shade(o.c0, 0.9), shade(o.c0, 0.9), s0, s0, s1, s1, [0, 1, 0])\n }\n const pairs = o.lod === 0 ? o.pairs : Math.min(9, Math.max(5, Math.round(o.pairs * 0.6)))\n const hang = o.hang ?? 0.45\n const lw = o.leafletWidth ?? 0.2\n for (let k = 0; k < pairs; k++) {\n const t = lerp(0.14, 0.98, k / Math.max(1, pairs - 1))\n const f = t * segs\n const idx = Math.min(segs - 1, Math.floor(f))\n const u = f - idx\n const p: Vec3 = [lerp(pts[idx][0], pts[idx + 1][0], u), lerp(pts[idx][1], pts[idx + 1][1], u), lerp(pts[idx][2], pts[idx + 1][2], u)]\n const d = norm([pts[idx + 1][0] - pts[idx][0], pts[idx + 1][1] - pts[idx][1], pts[idx + 1][2] - pts[idx][2]])\n const prof = Math.sin(Math.PI * Math.min(1, 0.12 + t * 0.85)) ** 0.85\n const len = o.length * o.leafletLen * prof * (o.lod === 0 ? 1 : 1.5) * (0.9 + o.rng.next() * 0.2)\n const sw = lerp(o.swayBase, o.swayTip, t)\n const cc0 = jitter(o.c0, o.rng, 0.008, 0.05, 0.03)\n const cc1 = jitter(o.c1, o.rng, 0.008, 0.05, 0.03)\n for (const s of [-1, 1]) {\n const dir = norm(add(add(mul(sideV, s * 0.85), mul(d, 0.6)), [0, -hang, 0]))\n kite(b, p, dir, [0, 1, 0], len, len * lw * (o.lod === 0 ? 1 : 2.3), mix(cc0, cc1, 0.1), cc1, sw, Math.min(1, sw + 0.1))\n }\n }\n return pts[segs]\n}\n","import type { PalmSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, catmull, dirFromAngles, lerp, mul, norm } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { tube } from '../geometry/tube'\nimport { pinnateFrond } from '../geometry/fronds'\nimport { leaf } from '../geometry/leaf'\nimport { icoShell } from '../geometry/shell'\n\ninterface Defaults {\n height: number\n trunkRadius: number\n frondCount: number\n frondLength: number\n leaf: number\n trunk: number\n lean: number\n}\nconst DEF: Record<NonNullable<PalmSpec['variant']>, Defaults> = {\n coconut: { height: 7, trunkRadius: 0.17, frondCount: 18, frondLength: 2.7, leaf: 0x4e9a3c, trunk: 0xa08a68, lean: 0.2 },\n royal: { height: 11, trunkRadius: 0.27, frondCount: 13, frondLength: 3.8, leaf: 0x4a9a3c, trunk: 0xbab4a4, lean: 0.01 },\n fan: { height: 3.2, trunkRadius: 0.2, frondCount: 16, frondLength: 1.5, leaf: 0x5a9a44, trunk: 0x7a5c3c, lean: 0.03 },\n areca: { height: 2.6, trunkRadius: 0.03, frondCount: 5, frondLength: 1.5, leaf: 0x78ae3e, trunk: 0x9aa860, lean: 0.25 },\n date: { height: 6, trunkRadius: 0.24, frondCount: 20, frondLength: 3, leaf: 0x6a9a58, trunk: 0x8a6a48, lean: 0.05 },\n}\n\nexport function generatePalm(spec: PalmSpec, ctx: Ctx): ArchResult {\n const variant = spec.variant ?? 'coconut'\n const d = DEF[variant]\n const rng = ctx.rng\n const dead = ctx.condition === 'dead'\n const dry = ctx.condition === 'dry'\n const over = ctx.condition === 'overgrown'\n const H = (spec.height ?? d.height) * (over ? 1.08 : 1)\n const R = spec.trunkRadius ?? d.trunkRadius\n const trunkC = rgb(spec.trunkColor ?? d.trunk)\n const leafBase = tintGreen(rgb(spec.leafColor ?? d.leaf), ctx.condition)\n const lean = (spec.lean ?? d.lean) * (dead ? 1.4 : 1)\n const stems = variant === 'areca' || (variant === 'fan' && (spec.stems ?? 1) > 1) ? (spec.stems ?? 6) : 1\n const clump = stems > 1\n const frondN = Math.round((spec.frondCount ?? d.frondCount) * (dead ? 0.5 : dry ? 0.75 : over ? 1.2 : 1))\n const frondL = (spec.frondLength ?? d.frondLength) * (over ? 1.1 : 1)\n const c0 = shade(leafBase, 0.62)\n const c1 = mix(shade(leafBase, 1.12), [0.7, 0.85, 0.35], 0.12)\n const deadC = [0.45, 0.36, 0.22] as Vec3\n const crowns: { p: Vec3; r: number }[] = []\n\n const buildStem = (si: number, stemH: number, stemR: number, stemLean: number, az: number): void => {\n const trunkId = si === 0 ? 'trunk' : `stem${si}`\n ctx.piece(trunkId, si === 0 ? 'trunk' : 'stem')\n const srng = rng.fork(si * 101 + 7)\n const nPts = Math.max(4, Math.round(stemH / (clump ? 0.35 : 0.2)))\n const ctrl: Vec3[] = []\n const wob = srng.range(0, TAU)\n for (let i = 0; i <= 4; i++) {\n const t = i / 4\n const off = stemLean * stemH * (variant === 'coconut' ? 0.35 * t + 0.65 * t * t : t * t) + Math.sin(t * 3 + wob) * (variant === 'coconut' ? 0.045 : 0.02) * stemH\n ctrl.push([Math.cos(az) * off, stemH * t, Math.sin(az) * off])\n }\n const full = catmull(ctrl, Math.max(1, Math.round(nPts / 4)))\n const stride = ctx.pick(1, 2, Math.max(1, Math.floor(full.length / 3)))\n const path: Vec3[] = []\n for (let i = 0; i < full.length; i += stride) path.push(full[i])\n if ((full.length - 1) % stride !== 0) path.push(full[full.length - 1])\n const scars = variant === 'areca' ? 4 : variant === 'royal' ? 2.5 : 3.2\n const radii = path.map((_, i) => {\n const t = i / (path.length - 1)\n let r = stemR * (variant === 'royal' ? 1.02 + 0.18 * Math.sin(Math.min(1, t * 1.4) * Math.PI) - 0.28 * t : 1.0 - 0.22 * t)\n r *= 1 + 0.5 * Math.exp(-t * (variant === 'royal' ? 16 : 22))\n const ringPhase = Math.cos(t * stemH * scars * TAU)\n r *= 1 + (ctx.lod === 0 ? 0.045 : 0.02) * ringPhase\n return r\n })\n const sides = ctx.pick(clump ? 5 : 8, clump ? 4 : 6, 4)\n tube(ctx.wood, path, {\n sides,\n radii,\n color: (t, a) => {\n const ring = 0.84 + 0.16 * Math.cos(t * stemH * scars * TAU)\n const stripe = 0.94 + 0.06 * Math.cos(a * TAU * 3 + t * 4)\n let c = shade(trunkC, ring * stripe * (0.78 + 0.22 * Math.min(1, t * 6)))\n if (variant === 'royal') c = mix(c, [0.62, 0.62, 0.55], 0.25)\n if (dead) c = mix(c, [0.4, 0.37, 0.32], 0.5)\n return c\n },\n sway: (t) => 0.05 * t * t,\n end: 'flat',\n })\n const top = path[path.length - 1]\n let crownTop: Vec3 = top\n if (variant === 'royal') {\n // smooth green crownshaft\n const shaft: Vec3[] = [top, add(top, [0, 0.5, 0]), add(top, [0.0, 1.25, 0])]\n const shaftC = mix(leafBase, [0.55, 0.75, 0.3], 0.3)\n tube(ctx.wood, shaft, { sides: ctx.pick(7, 5, 4), radii: [stemR * 0.9, stemR * 0.95, stemR * 0.7], color: (t) => shade(shaftC, 0.8 + 0.3 * t), sway: () => 0.05, end: 'flat' })\n crownTop = add(top, [0, 1.25, 0])\n } else if (variant !== 'areca') {\n icoShell(ctx.wood, { center: add(top, [0, stemR * 0.7, 0]), radii: [stemR * 1.35, stemR * 1.0, stemR * 1.35], detail: 0, rng: srng, noise: 0.06, color: (v) => shade(mix(trunkC, [0.35, 0.45, 0.2], 0.55), 0.7 + v.h * 0.5), sway: () => 0.05 })\n crownTop = add(top, [0, stemR * 0.9, 0])\n }\n crowns.push({ p: crownTop, r: frondL })\n ctx.piece(si === 0 ? 'crown' : `crown${si}`, 'crown', trunkId)\n\n const n = clump ? Math.max(3, Math.round(frondN)) : frondN\n for (let i = 0; i < n; i++) {\n if (ctx.lod === 2 && variant === 'fan' && i % 2 === 1) continue\n const f = srng.fork(i)\n const ring = i % 3\n const az2 = (i / n) * TAU * 1.0 + f.range(-0.2, 0.2) + si\n let elev: number\n let droop: number\n if (variant === 'royal') {\n elev = [1.1, 0.65, 0.2][ring] + f.range(-0.1, 0.1)\n droop = [0.35, 0.65, 1.0][ring]\n } else if (variant === 'date') {\n elev = [1.15, 0.8, 0.45][ring] + f.range(-0.08, 0.08)\n droop = [0.3, 0.5, 0.75][ring]\n } else if (variant === 'areca') {\n elev = [1.1, 0.8, 0.5][ring] + f.range(-0.1, 0.1)\n droop = [0.45, 0.8, 1.1][ring]\n } else if (variant === 'fan') {\n elev = [1.3, 0.95, 0.6][ring] + f.range(-0.1, 0.1)\n droop = [0.25, 0.35, 0.5][ring]\n } else {\n elev = [1.15, 0.75, 0.38][ring] + f.range(-0.1, 0.1)\n droop = [0.45, 0.78, 1.1][ring]\n }\n if (dead) {\n elev = elev * 0.4 - 0.3\n droop *= 1.4\n }\n if (dry) droop *= 1.15\n const len = frondL * f.range(0.85, 1.1) * (ring === 2 ? 0.92 : 1)\n const colA = dead ? mix(c0, deadC, 0.8) : c0\n const colB = dead ? mix(c1, deadC, 0.7) : ring === 2 && dry ? mix(c1, deadC, 0.4) : c1\n if (variant === 'fan') {\n fanFrond(ctx, f, crownTop, az2, elev, len, droop, colA, colB)\n } else {\n pinnateFrond(ctx.foliage, {\n origin: crownTop,\n az: az2,\n elev,\n length: len,\n droop,\n leafletLen: variant === 'areca' ? 0.24 : variant === 'date' ? 0.2 : variant === 'coconut' ? 0.25 : 0.24,\n pairs: variant === 'areca' ? 10 : variant === 'royal' ? 26 : variant === 'coconut' ? 28 : 18,\n c0: colA,\n c1: colB,\n lod: ctx.lod,\n rng: f,\n swayBase: 0.25,\n swayTip: 1,\n hang: variant === 'date' ? 0.2 : variant === 'royal' ? 0.5 : variant === 'coconut' ? 0.8 : 0.45,\n leafletWidth: variant === 'date' ? 0.12 : variant === 'coconut' ? 0.13 : 0.2,\n })\n }\n }\n // fruit cluster\n if (spec.fruit && !dead && ctx.lod < 2) {\n const fc = rgb(spec.fruit.color)\n const fr = spec.fruit.radius ?? (variant === 'coconut' ? 0.1 : 0.03)\n const count = Math.round(spec.fruit.count * (ctx.lod === 0 ? 1 : 0.5))\n for (let i = 0; i < count; i++) {\n const a = (i / count) * TAU + srng.range(0, 1)\n const rr = stemR * 1.3 + fr * 0.8\n const p: Vec3 = [crownTop[0] + Math.cos(a) * rr, crownTop[1] - fr * (0.6 + srng.range(0, 1.4)) - 0.05, crownTop[2] + Math.sin(a) * rr]\n ctx.fruitItem(() => icoShell(ctx.fruit, { center: p, radii: [fr, fr * 1.15, fr], detail: 0, rng: srng, noise: 0.04, color: (v) => mix(shade(fc, 0.6), lighten(fc, 0.3), v.h), sway: () => 0.1 }))\n }\n }\n }\n\n if (!clump) {\n buildStem(0, H, R, lean, rng.range(0, TAU))\n } else {\n for (let i = 0; i < stems; i++) {\n const az = (i / stems) * TAU + rng.range(-0.4, 0.4)\n const hh = H * rng.range(0.62, 1.0)\n buildStem(i, hh, R * rng.range(0.85, 1.1), (spec.lean ?? d.lean) * rng.range(0.6, 1.3), az)\n }\n }\n const maxR = crowns.reduce((m, c) => Math.max(m, Math.hypot(c.p[0], c.p[2])), 0)\n return clump\n ? { collider: { kind: 'cylinder', radius: Math.max(0.15, maxR * 0.5 + R * 2), height: H * 0.5 }, bendable: true }\n : { collider: { kind: 'cylinder', radius: R * 1.15, height: H * 0.85 }, bendable: false }\n}\n\n/** Palmate frond: long petiole ending in a round, ribbed fan of folded segments whose tips droop. */\nfunction fanFrond(ctx: Ctx, rng: import('../rng').Rng, origin: Vec3, az: number, elev: number, len: number, droop: number, c0: Vec3, c1: Vec3): void {\n const horiz = dirFromAngles(az, 0)\n const petL = len * 0.82\n const pe = Math.max(0.15, elev)\n const tipPet: Vec3 = [origin[0] + horiz[0] * petL * Math.cos(pe) * 0.8, origin[1] + petL * (Math.sin(pe) * 0.9 - droop * 0.12), origin[2] + horiz[2] * petL * Math.cos(pe) * 0.8]\n const mid: Vec3 = [lerp(origin[0], tipPet[0], 0.5), lerp(origin[1], tipPet[1], 0.5) + petL * 0.06, lerp(origin[2], tipPet[2], 0.5)]\n tube(ctx.foliage, [origin, mid, tipPet], { sides: 3, radii: [len * 0.02, len * 0.015, len * 0.011], color: (t) => shade(mix(c0, [0.55, 0.5, 0.25], 0.35), 0.85 + 0.2 * t), sway: (t) => 0.1 + 0.5 * t, end: 'none' })\n const segs: number = ctx.pick(len < 1.3 ? 9 : 15, 7, 4)\n const span = 3.7\n const bR = len * 0.46\n const tilt = Math.min(1.1, pe) * 0.65\n const A: Vec3 = norm([horiz[0] * Math.cos(tilt), Math.sin(tilt) * 0.95, horiz[2] * Math.cos(tilt)])\n const B: Vec3 = [-horiz[2], 0, horiz[0]]\n for (let i = 0; i < segs; i++) {\n const u = segs === 1 ? 0 : i / (segs - 1) - 0.5\n const th = u * span\n const dir = norm(add(add(mul(A, Math.cos(th)), mul(B, Math.sin(th))), [0, 0.02 - Math.abs(u) * 0.12, 0]))\n const cc = jitter(mix(c0, c1, 0.45), rng, 0.01, 0.07, 0.05)\n const w = ((bR * (span / segs)) * 0.75) / 0.78 + 0.02\n leaf(ctx.foliage, tipPet, dir, [0, 1, 0], bR * (0.92 + 0.08 * Math.cos(th)), w, shade(cc, 0.7), lighten(c1, 0.95), { rows: ctx.pick(3, 2, 2), curl: 0.22 + Math.abs(u) * 0.14, fold: 0.5, swayBase: 0.35, swayTip: 1, peak: 0.82, round: 0.45, baseWidth: 0.04 })\n }\n}\n","import type { BananaSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, catmull, dirFromAngles, mul, norm } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { tube } from '../geometry/tube'\nimport { leaf } from '../geometry/leaf'\nimport { icoShell } from '../geometry/shell'\n\nexport function generateBanana(spec: BananaSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const dead = ctx.condition === 'dead'\n const dry = ctx.condition === 'dry'\n const over = ctx.condition === 'overgrown'\n const H = (spec.height ?? 3.6) * (over ? 1.12 : 1)\n const stemH = H * 0.5\n const R = H * 0.04\n const leafBase = tintGreen(rgb(spec.leafColor ?? 0x66a83e), ctx.condition)\n const nLeaves = Math.round((spec.leafCount ?? 8) * (dead ? 0.5 : over ? 1.2 : 1))\n const tornShare = spec.torn ?? (dry ? 0.9 : 0.5)\n const stemC = mix(rgb(0x9cb86a), tintGreen(rgb(0x9cb86a), ctx.condition), 1)\n\n // pseudostem: leaf sheaths read as bands and flares\n const ctrl: Vec3[] = []\n const lean = rng.range(-0.05, 0.05)\n for (let i = 0; i <= 4; i++) {\n const t = i / 4\n ctrl.push([lean * stemH * t * t, stemH * t, Math.sin(t * 2.5) * 0.02])\n }\n const full = catmull(ctrl, ctx.pick(5, 3, 1))\n const radii = full.map((_, i) => {\n const t = i / (full.length - 1)\n return R * (1 - 0.3 * t) * (1 + 0.45 * Math.exp(-t * 14)) * (1 + 0.04 * Math.cos(t * 26))\n })\n tube(ctx.wood, full, {\n sides: ctx.pick(9, 6, 5),\n radii,\n color: (t, a) => {\n const sheath = 0.86 + 0.14 * Math.cos(t * 26)\n const stripe = 0.93 + 0.07 * Math.cos(a * TAU * 4)\n let c = shade(stemC, sheath * stripe * (0.7 + 0.3 * Math.min(1, t * 5)))\n c = mix(c, [0.55, 0.4, 0.22], Math.max(0, 0.18 - t) * 2.2)\n if (dead) c = mix(c, [0.45, 0.36, 0.22], 0.7)\n return c\n },\n sway: (t) => 0.04 * t,\n end: 'flat',\n })\n const top = full[full.length - 1]\n ctx.piece('crown', 'crown', 'trunk')\n\n // leaves\n const rows = ctx.pick(9, 6, 3)\n for (let i = 0; i < nLeaves; i++) {\n const f = rng.fork(i)\n const ring = i % 3\n const az = (i / nLeaves) * TAU * 1.0 + f.range(-0.25, 0.25)\n const L = H * f.range(0.55, 0.72) * (ring === 2 ? 0.85 : 1)\n const el = [1.15, 0.8, 0.45][ring] + f.range(-0.12, 0.12)\n const horiz = dirFromAngles(az, 0)\n // petiole: a short stalk before the blade\n const petL = L * 0.18\n const pEnd: Vec3 = [top[0] + horiz[0] * petL * Math.cos(el), top[1] + petL * Math.sin(el), top[2] + horiz[2] * petL * Math.cos(el)]\n tube(ctx.foliage, [top, pEnd], { sides: 3, radii: [R * 0.22, R * 0.15], color: () => shade(leafBase, 0.85), sway: () => 0.2, end: 'none' })\n const torn = f.next() < tornShare || dead\n const c0 = dead ? mix(leafBase, [0.4, 0.32, 0.2], 0.85) : jitter(shade(leafBase, 0.7), f, 0.01, 0.06, 0.04)\n const c1 = dead ? mix(leafBase, [0.5, 0.42, 0.25], 0.8) : mix(jitter(lighten(leafBase, 0.5), f, 0.012, 0.06, 0.04), [0.75, 0.85, 0.35], 0.15)\n const tearSeed = f.range(0, 10)\n leaf(ctx.foliage, pEnd, norm([horiz[0] * Math.cos(el), Math.sin(el), horiz[2] * Math.cos(el)]), [0, 1, 0], L, L * 0.34, c0, c1, {\n rows,\n curl: [0.55, 0.7, 0.8][ring] * (dry ? 1.2 : 1),\n fold: 0.35,\n swayBase: 0.25,\n swayTip: 1,\n peak: 0.45,\n round: 0.5,\n baseWidth: 0.12,\n tear: torn ? (row, side) => (row % 2 === 1 && row > 1 && row < rows ? 0.35 + 0.35 * Math.abs(Math.sin(tearSeed + row * 1.3 + side)) : 1) : undefined,\n })\n }\n\n // bunch and bud\n if (spec.bunch && !dead && ctx.lod < 2) {\n const out = dirFromAngles(rng.range(0, TAU), 0)\n const stalk: Vec3[] = [add(top, [0, -0.05, 0]), add(top, add(mul(out, R * 1.6), [0, -0.2, 0])), add(top, add(mul(out, R * 2.2), [0, -0.7, 0])), add(top, add(mul(out, R * 2.1), [0, -1.1, 0]))]\n const sp = catmull(stalk, 2)\n tube(ctx.wood, sp, { sides: 4, radii: sp.map(() => R * 0.2), color: () => [0.35, 0.45, 0.2], sway: (t) => 0.15 + 0.3 * t, end: 'none' })\n const hands = ctx.pick(5, 3, 0)\n const fingers = ctx.pick(7, 4, 0)\n const green = rgb(0x86b04a)\n const yellow = rgb(0xc8c24a)\n const frng = rng.fork('bunch')\n ctx.fruitItem(() => {\n for (let h = 0; h < hands; h++) {\n const t = 0.45 + (0.5 * h) / Math.max(1, hands - 1)\n const idx = Math.min(sp.length - 1, Math.floor(t * (sp.length - 1)))\n const base = sp[idx]\n const ha = h * 1.9\n for (let k = 0; k < fingers; k++) {\n const a = ha + (k / fingers) * 2.4 - 1.2\n const dirOut = dirFromAngles(a, -0.9)\n const fl = 0.16\n const center = add(base, add(mul(dirOut, fl * 0.55 + R * 0.35), [0, -0.02, 0]))\n icoShell(ctx.fruit, {\n center,\n radii: [0.026, fl * 0.55, 0.026],\n detail: 0,\n rng: frng,\n noise: 0.04,\n color: (v) => mix(shade(green, 0.75), mix(green, yellow, 0.3), v.h),\n sway: () => 0.2,\n })\n }\n }\n })\n if (spec.bud) {\n const end = sp[sp.length - 1]\n const bc = rgb(0x7a2a62)\n icoShell(ctx.flowers, { center: add(end, [0, -0.17, 0]), radii: [0.08, 0.18, 0.08], detail: ctx.pick(1, 0, 0) as 0 | 1, rng: frng, noise: 0.05, color: (v) => mix(shade(bc, 0.6), lighten(bc, 0.5), v.h), sway: () => 0.3 })\n }\n } else if (spec.bud && !dead && ctx.lod < 2) {\n const bc = rgb(0x7a2a62)\n icoShell(ctx.flowers, { center: add(top, [0.1, 0.15, 0]), radii: [0.08, 0.18, 0.08], detail: 0, rng: rng.fork('bud'), noise: 0.05, color: (v) => mix(shade(bc, 0.6), lighten(bc, 0.5), v.h), sway: () => 0.3 })\n }\n return { collider: { kind: 'cylinder', radius: R * 1.05, height: stemH * 0.9 }, bendable: true }\n}\n","import type { Vec3 } from '../types'\nimport { add, mul, norm, lerp } from '../math'\nimport { shade } from '../color'\nimport type { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\n\nexport interface BoxShellOptions {\n center: Vec3\n /** full size x, y, z */\n size: Vec3\n /** grid cells along x, y, z (a single number applies to all three) */\n grid: number | [number, number, number]\n /** 0 = sharp box .. 1 = ellipsoid (pulls edges and corners in) */\n round: number\n rng: Rng\n /** displacement amplitude as a fraction of the smallest dimension (smooth 3D value noise) */\n noise: number\n /** noise frequency in cycles per meter (default 1.8 / smallest dimension) */\n freq?: number\n /** per-face colour jitter (0..1, default 0.1) */\n jitter?: number\n color: (p: Vec3, h: number, n: Vec3) => Vec3\n sway: (h: number) => number\n}\n\nfunction hash3(x: number, y: number, z: number, s: number): number {\n let h = (x * 374761393 + y * 668265263 + z * 2147483647 + s * 1274126177) | 0\n h = Math.imul(h ^ (h >>> 13), 1274126177)\n return ((h ^ (h >>> 16)) >>> 0) / 4294967296\n}\n\n/** Smooth 3D value noise in -1..1. */\nexport function valueNoise3(x: number, y: number, z: number, seed: number): number {\n const xi = Math.floor(x)\n const yi = Math.floor(y)\n const zi = Math.floor(z)\n const fx = x - xi\n const fy = y - yi\n const fz = z - zi\n const sx = fx * fx * (3 - 2 * fx)\n const sy = fy * fy * (3 - 2 * fy)\n const sz = fz * fz * (3 - 2 * fz)\n const n = (a: number, b: number, c: number): number => hash3(xi + a, yi + b, zi + c, seed)\n const x00 = lerp(n(0, 0, 0), n(1, 0, 0), sx)\n const x10 = lerp(n(0, 1, 0), n(1, 1, 0), sx)\n const x01 = lerp(n(0, 0, 1), n(1, 0, 1), sx)\n const x11 = lerp(n(0, 1, 1), n(1, 1, 1), sx)\n return lerp(lerp(x00, x10, sy), lerp(x01, x11, sy), sz) * 2 - 1\n}\n\n/**\n * Clipped hedge section: one subdivided box (bottom face omitted) whose vertices are pushed along their outward\n * direction by smooth value noise, with edges and corners pulled in. Flat shaded, per-face colour jitter.\n */\nexport function boxShell(b: MeshBuilder, o: BoxShellOptions): void {\n const [gx, gy, gz] = typeof o.grid === 'number' ? [o.grid, o.grid, o.grid] : o.grid\n const hx = o.size[0] / 2\n const hy = o.size[1] / 2\n const hz = o.size[2] / 2\n const minDim = Math.min(o.size[0], o.size[1], o.size[2])\n const amp = o.noise * minDim\n const freq = o.freq ?? 1.8 / minDim\n const seed = Math.floor(o.rng.next() * 1e6)\n const jit = o.jitter ?? 0.1\n const faces: { n: Vec3; u: Vec3; v: Vec3; cu: number; cv: number }[] = [\n { n: [1, 0, 0], u: [0, 0, 1], v: [0, 1, 0], cu: gz, cv: gy },\n { n: [-1, 0, 0], u: [0, 1, 0], v: [0, 0, 1], cu: gy, cv: gz },\n { n: [0, 0, 1], u: [1, 0, 0], v: [0, 1, 0], cu: gx, cv: gy },\n { n: [0, 0, -1], u: [0, 1, 0], v: [1, 0, 0], cu: gy, cv: gx },\n { n: [0, 1, 0], u: [0, 0, 1], v: [1, 0, 0], cu: gz, cv: gx },\n ]\n // shared grid vertices keyed by quantized cube coordinate so faces stay welded\n const cache = new Map<string, Vec3>()\n const vertex = (c: Vec3): Vec3 => {\n const key = c.map((x) => Math.round(x * 1000)).join(',')\n const hit = cache.get(key)\n if (hit) return hit\n const m = Math.max(Math.abs(c[0]), Math.abs(c[1]), Math.abs(c[2]))\n const s = norm(c)\n const sphere: Vec3 = [s[0] * m, s[1] * m, s[2] * m]\n const q: Vec3 = [lerp(c[0], sphere[0], o.round), lerp(c[1], sphere[1], o.round), lerp(c[2], sphere[2], o.round)]\n const base: Vec3 = [o.center[0] + q[0] * hx, o.center[1] + q[1] * hy, o.center[2] + q[2] * hz]\n const nz = valueNoise3(base[0] * freq, base[1] * freq, base[2] * freq, seed) * 0.75 + valueNoise3(base[0] * freq * 2.3, base[1] * freq * 2.3, base[2] * freq * 2.3, seed + 7) * 0.25\n const out = norm([q[0] / Math.max(hx, 1e-6), q[1] / Math.max(hy, 1e-6), q[2] / Math.max(hz, 1e-6)])\n const p: Vec3 = add(base, mul(out, nz * amp))\n cache.set(key, p)\n return p\n }\n let fi = 0\n for (const f of faces) {\n for (let i = 0; i < f.cu; i++) {\n for (let j = 0; j < f.cv; j++) {\n const u0 = (i / f.cu) * 2 - 1\n const u1 = ((i + 1) / f.cu) * 2 - 1\n const v0 = (j / f.cv) * 2 - 1\n const v1 = ((j + 1) / f.cv) * 2 - 1\n const corner = (u: number, v: number): Vec3 => add(add(mul(f.n, 1), mul(f.u, u)), mul(f.v, v))\n const ps = [vertex(corner(u0, v0)), vertex(corner(u1, v0)), vertex(corner(u1, v1)), vertex(corner(u0, v1))]\n const hs = ps.map((p) => (p[1] - (o.center[1] - hy)) / o.size[1])\n const fj = 1 - jit + 2 * jit * hash3(fi++, i, j, seed)\n const cs = ps.map((p, k) => shade(o.color(p, hs[k], f.n), fj))\n b.flatQuad(ps[0], ps[1], ps[2], ps[3], cs[0], cs[1], cs[2], cs[3], o.sway(hs[0]), o.sway(hs[1]), o.sway(hs[2]), o.sway(hs[3]), add(f.n, [0, 0, 0]))\n }\n }\n }\n}\n","import type { ShrubSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, clamp, lerp, mul, norm } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { Rng } from '../rng'\nimport { tube } from '../geometry/tube'\nimport { clump, clumpLeaves } from '../geometry/shell'\nimport { boxShell } from '../geometry/boxshell'\nimport { blossom, flowerHead, type FlowerKind } from '../geometry/flower'\nimport { leaf } from '../geometry/leaf'\nimport { leafAmount } from './shared'\n\nconst DEFAULT_LEAF = [0x3f8a3a, 0x4a9a42, 0x357a38]\n\nexport function generateShrub(spec: ShrubSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const shape = spec.shape ?? 'round'\n const over = ctx.condition === 'overgrown'\n const dead = ctx.condition === 'dead'\n const R = (spec.radius ?? 0.6) * (over ? 1.2 : 1)\n const H = (spec.height ?? (shape === 'hedge' ? 1.1 : R * 1.5)) * (over ? 1.15 : 1)\n const density = (spec.density ?? 1) * leafAmount(ctx, false)\n const palette = (spec.leafColor ?? DEFAULT_LEAF).map((c) => tintGreen(rgb(c), ctx.condition))\n const stemC = rgb(spec.stemColor ?? 0x6a4c34)\n const flowers = spec.flowers && !dead && !(ctx.season === 'winter' && rng.fork('w').next() < 0.5)\n const variegation = spec.variegation?.map(rgb)\n const lsize = spec.leafSize ?? 1\n\n const flowerDots = (center: Vec3, rx: number, ry: number, rz: number, count: number, frng: Rng, crown: Vec3): void => {\n if (!spec.flowers) return\n const fl = spec.flowers\n const colors = fl.colors.map(rgb)\n const size = (fl.size ?? 0.045) * (shape === 'hedge' ? 1 : 1)\n const style = fl.style ?? 'dots'\n for (let i = 0; i < count; i++) {\n const a = frng.range(0, TAU)\n const y = frng.range(0.05, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [center[0] + d[0] * rx * 1.0, center[1] + d[1] * ry * 1.0, center[2] + d[2] * rz * 1.0]\n const n = norm(add(d, mul(norm([p[0] - crown[0], p[1] - crown[1], p[2] - crown[2]]), 0.5)))\n const c = frng.pick(colors)\n if (style === 'dots') {\n blossom(ctx.flowers, add(p, mul(n, size * 0.2)), n, size, shade(c, 1.05), jitter(c, frng, 0.01, 0.05), 0.6, ctx.pick(5, 4, 3), frng.range(0, TAU))\n } else if (style === 'clusters') {\n flowerHead(ctx.flowers, { kind: 'bract', center: add(p, mul(n, size * 0.2)), axis: n, size: size * 1.4, colors, centerColor: [1, 1, 1], rng: frng.fork(i), lod: ctx.lod, sway: 0.6 })\n } else {\n flowerHead(ctx.flowers, { kind: (style === 'hibiscus' ? 'hibiscus' : 'bell') as FlowerKind, center: add(p, mul(n, size * 0.1)), axis: n, size: size * 1.6, colors, centerColor: [1, 0.85, 0.3], rng: frng.fork(i), lod: ctx.lod, sway: 0.6 })\n }\n }\n }\n\n if (shape === 'hedge') {\n const length = spec.length ?? 2.4\n const width = spec.width ?? Math.max(0.6, H * 0.6)\n const sections = Math.max(1, Math.round(length / (width * 1.1)))\n const secLen = length / sections\n const grid: [number, number, number] = ctx.lod === 0 ? [6, 4, 4] : ctx.lod === 1 ? [4, 3, 3] : [3, 2, 2]\n const base = dead ? mix(palette[0], [0.42, 0.33, 0.22], 0.65) : ctx.condition === 'dry' ? mix(palette[0], [0.5, 0.45, 0.22], 0.35) : palette[0]\n for (let i = 0; i < sections; i++) {\n const sr = rng.fork(i * 17 + 3)\n const cx = -length / 2 + secLen * (i + 0.5)\n const h = H * sr.range(0.96, 1.04)\n const seed = sr.seed()\n const sect = new Rng(seed)\n const c = jitter(base, sect, 0.01, 0.05, 0.04)\n boxShell(ctx.foliage, {\n center: [cx, h * 0.5, 0],\n size: [secLen * 1.04, h, width],\n grid,\n round: 0.42,\n rng: sect,\n noise: 0.12,\n freq: 3 / Math.min(secLen, h, width),\n jitter: 0.12,\n color: (p, hh, n) => {\n let k = lerp(0.7, 1.15, clamp(hh, 0, 1)) * (0.88 + 0.24 * ((Math.sin(p[0] * 47.3 + p[1] * 31.7 + p[2] * 53.9) + 1) / 2))\n if (n[1] > 0.5) k *= 1.08\n return mix(shade(c, k), lighten(c, 0.6), clamp((hh - 0.9) * 4, 0, 0.5))\n },\n sway: (hh) => 0.3 * hh,\n })\n if (ctx.lod === 0) {\n // leaf flecks poking from the clipped surface\n const lc0 = shade(c, 0.75)\n const lc1 = lighten(c, 0.9)\n for (let k = 0; k < 14; k++) {\n const onTop = k % 3 !== 0\n const px = cx + sr.range(-secLen / 2, secLen / 2)\n const pz = sr.range(-width / 2, width / 2) * 0.9\n const pos: Vec3 = onTop ? [px, h * 0.98, pz] : [px, sr.range(0.3, 0.9) * h, (pz > 0 ? 1 : -1) * width * 0.5]\n const n: Vec3 = onTop ? [sr.range(-0.3, 0.3), 1, sr.range(-0.3, 0.3)] : [0, 0.3, pz > 0 ? 1 : -1]\n leaf(ctx.foliage, pos, norm(add(n, [sr.range(-0.4, 0.4), 0, sr.range(-0.4, 0.4)])), n, 0.1 * lsize, 0.08 * lsize, lc0, lc1, { curl: 0.2, swayBase: 0.3, swayTip: 0.5 })\n }\n }\n if (flowers) flowerDots([cx, h * 0.5, 0], secLen * 0.5, h * 0.5, width * 0.5, ctx.pick(8, 5, 0) * Math.round((spec.flowers?.count ?? 10) / 10), sr.fork('f'), [cx, h * 0.3, 0])\n }\n return { collider: null, bendable: true }\n }\n\n // round / loose: multi stem bush with clumps\n const crownC: Vec3 = [0, H * 0.5, 0]\n const nStems = ctx.pick(6, 4, 3)\n const nClumps = Math.max(3, Math.round(ctx.pick(9, 10, 4) * clamp(density, 0.3, 1.4) * (shape === 'loose' ? 0.9 : 1)))\n const anchors: { p: Vec3; r: number; seed: number }[] = []\n for (let i = 0; i < nClumps; i++) {\n const f = rng.fork(i + 1)\n const a = (i / nClumps) * TAU * 1.0 + f.range(-0.5, 0.5)\n const layer = i % 3\n const rr = R * (layer === 0 ? f.range(0.0, 0.35) : f.range(0.45, 0.8)) * (shape === 'loose' ? 1.15 : 1)\n const y = H * (layer === 0 ? f.range(0.55, 0.8) : layer === 1 ? f.range(0.35, 0.55) : f.range(0.22, 0.4))\n anchors.push({ p: [Math.cos(a) * rr, y, Math.sin(a) * rr], r: R * f.range(0.42, 0.62) * (shape === 'loose' ? 0.9 : 1) * (ctx.lod === 1 ? 0.8 : 1), seed: f.seed() })\n }\n // stems from the ground to the lower clumps\n for (let i = 0; i < nStems; i++) {\n const a = anchors[i % anchors.length]\n const base: Vec3 = [a.p[0] * 0.12, 0, a.p[2] * 0.12]\n const mid: Vec3 = [a.p[0] * 0.5, a.p[1] * 0.5, a.p[2] * 0.5]\n tube(ctx.wood, [base, mid, [a.p[0] * 0.85, a.p[1] * 0.85, a.p[2] * 0.85]], { sides: ctx.pick(5, 4, 3), radii: [R * 0.05, R * 0.04, R * 0.025], color: (t) => shade(stemC, 0.7 + 0.4 * t), sway: (t) => 0.1 + 0.3 * t, end: 'point' })\n }\n anchors.forEach((a, idx) => {\n const crn = idx % 2 === 0\n const base = variegation && crn ? variegation[idx % variegation.length] : palette[idx % palette.length]\n const o = {\n center: a.p,\n radius: a.r,\n squash: shape === 'loose' ? 0.85 : 0.8,\n detail: (ctx.lod === 0 ? 1 : 0) as 0 | 1,\n seed: a.seed,\n base: dead ? mix(base, [0.4, 0.35, 0.27], 0.6) : base,\n crown: crownC,\n leaves: ctx.lod === 0 ? { count: 6 + Math.round(a.r * 8), length: a.r * 0.5 * lsize, width: a.r * 0.4 * lsize } : ctx.lod === 1 ? { count: 2 + Math.round(a.r * 3), length: a.r * 0.55 * lsize, width: a.r * 0.45 * lsize } : undefined,\n swayK: 0.7,\n noise: shape === 'loose' ? 0.3 : 0.2,\n flatBottom: 0.6,\n ao: 0.45,\n }\n clump(ctx.foliage, o)\n if (ctx.lod < 2) clumpLeaves(ctx.foliage, o)\n })\n if (variegation && ctx.lod < 2) {\n // colorful croton leaves: broad leaves in the variegation palette all over the surface\n const vr = rng.fork('vari')\n const n = ctx.pick(36, 14, 0)\n for (let i = 0; i < n; i++) {\n const a = vr.range(0, TAU)\n const y = vr.range(0.15, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [d[0] * R * 0.8, H * 0.5 + d[1] * H * 0.42, d[2] * R * 0.8]\n const c = vr.pick(variegation)\n leaf(ctx.foliage, p, norm(add(mul(d, 0.4), [0, 0.8, 0])), d, 0.17 * lsize, 0.1 * lsize, shade(c, 0.75), lighten(c, 0.3), { rows: 2, curl: 0.25, fold: 0.5, swayBase: 0.6, swayTip: 0.9, peak: 0.45 })\n }\n }\n if (flowers && spec.flowers) {\n const fr = rng.fork('flowers')\n const count = Math.round((spec.flowers.count ?? 24) * ctx.pick(1, 0.5, 0))\n flowerDots([0, H * 0.5, 0], R * 1.0, H * 0.52, R * 1.0, count, fr, crownC)\n }\n return { collider: null, bendable: true }\n}\n","import type { ConiferSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, catmull, dirFromAngles, lerp, mul } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { tube } from '../geometry/tube'\nimport { leaf } from '../geometry/leaf'\nimport { barkColor } from '../geometry/wood'\n\nexport function generateConifer(spec: ConiferSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const shape = spec.shape ?? 'cone'\n const dead = ctx.condition === 'dead'\n const over = ctx.condition === 'overgrown'\n const H = (spec.height ?? (shape === 'candelabra' ? 14 : 9)) * (over ? 1.08 : 1)\n const R = spec.radius ?? H * (shape === 'candelabra' ? 0.2 : 0.24)\n const trunkR = spec.trunkRadius ?? H * 0.02\n const leafBase = tintGreen(rgb(spec.leafColor ?? (shape === 'candelabra' ? 0x3d6e3a : 0x2f6e3a)), ctx.condition)\n const bark = rgb(spec.barkColor ?? (shape === 'candelabra' ? 0x6a5442 : 0x6b4b34))\n const tiers = spec.tiers ?? (shape === 'candelabra' ? 6 : 9)\n const lean = rng.range(-0.02, 0.02) * H\n const trunkTop = shape === 'candelabra' ? H : H * 0.96\n const ctrl: Vec3[] = []\n for (let i = 0; i <= 4; i++) {\n const t = i / 4\n ctrl.push([lean * t * t, trunkTop * t, Math.sin(t * 3 + 1) * 0.01 * H])\n }\n const tp = catmull(ctrl, ctx.pick(3, 2, 1))\n const tr = tp.map((_, i) => {\n const t = i / (tp.length - 1)\n return trunkR * (1 - 0.7 * t) * (1 + 0.5 * Math.exp(-t * 20))\n })\n tube(ctx.wood, tp, { sides: ctx.pick(8, 6, 4), radii: tr, color: barkColor(bark, 0), sway: () => 0.02, end: 'point' })\n ctx.piece('crown', 'crown', 'trunk')\n\n if (shape === 'cone') {\n const foliage = ctx.foliage\n const K = ctx.pick(10, 8, 6)\n const startY = H * (dead ? 0.35 : 0.14)\n for (let i = 0; i < tiers; i++) {\n const f = tiers === 1 ? 0 : i / (tiers - 1)\n const y = lerp(startY, H * 0.9, f)\n const tierH = (H * 0.9 - startY) / tiers * 1.9\n const r = R * lerp(1, 0.14, Math.pow(f, 0.95)) * (1 + (i % 2) * 0.06)\n const col = jitter(leafBase, rng.fork(i), 0.012, 0.06, 0.04)\n const lightTop = mix(lighten(col, 1.0), [0.75, 0.88, 0.5], 0.2)\n const dark = shade(col, 0.62)\n const apex: Vec3 = [lean * (y / H) ** 2, y + tierH * 0.55, 0]\n const innerR = r * 0.32\n const ring = (rad: number, yy: number, k: number, ph: number): Vec3 => [apex[0] + Math.cos((k / K) * TAU + ph) * rad, yy, Math.sin((k / K) * TAU + ph) * rad]\n const tphase = i * 0.7\n for (let k = 0; k < K; k++) {\n const jag = k % 2 === 0 ? 1 : 0.78\n const a0 = ring(innerR, y + tierH * 0.12, k, tphase)\n const a1 = ring(innerR, y + tierH * 0.12, k + 1, tphase)\n const o0 = ring(r * jag, y - tierH * 0.42, k, tphase)\n const o1 = ring(r * (k % 2 === 0 ? 0.78 : 1), y - tierH * 0.42, k + 1, tphase)\n const sw = 0.25 + 0.35 * (1 - f)\n // top surface\n foliage.flat(apex, a1, a0, shade(lightTop, 0.85), 0.2, [0, 1, 0])\n foliage.flatTri(a0, a1, o1, mix(col, lightTop, 0.2), mix(col, lightTop, 0.2), lightTop, 0.2, 0.2, sw, [0, 1, 0])\n foliage.flatTri(a0, o1, o0, mix(col, lightTop, 0.2), lightTop, lightTop, 0.2, sw, sw, [0, 1, 0])\n // underside, dark\n foliage.flatTri(a0, o0, o1, dark, shade(dark, 1.1), shade(dark, 1.1), 0.2, sw, sw, [0, -1, 0])\n foliage.flatTri(a0, o1, a1, dark, shade(dark, 1.1), dark, 0.2, sw, 0.2, [0, -1, 0])\n }\n if (ctx.lod === 0) {\n // drooping branchlets poking out of the skirt\n const nb = 8\n for (let k = 0; k < nb; k++) {\n const ang = (k / nb) * TAU + tphase * 0.5 + rng.fork(i * 9 + k).range(0, 0.5)\n const d = dirFromAngles(ang, -0.35)\n leaf(foliage, [apex[0] + Math.cos(ang) * r * 0.55, y - tierH * 0.2, apex[2] + Math.sin(ang) * r * 0.55], d, [0, 1, 0], r * 0.55, r * 0.22, shade(col, 0.7), lightTop, { rows: 2, curl: 0.45, fold: 0.5, swayBase: 0.3, swayTip: 0.7, peak: 0.4 })\n }\n }\n }\n } else {\n // candelabra (araucaria): whorls of upturned branches carrying thick needle sleeves\n const whorls = Math.max(3, Math.min(tiers, ctx.pick(5, 4, 3)))\n const perWhorl = ctx.pick(8, 6, 5)\n for (let w = 0; w < whorls; w++) {\n const f = whorls === 1 ? 1 : w / (whorls - 1)\n const y = lerp(H * 0.66, H * 0.9, f)\n const len = R * lerp(1.15, 0.6, f)\n const topY = H * lerp(0.93, 1.0, f)\n for (let k = 0; k < perWhorl; k++) {\n const fr = rng.fork(w * 31 + k)\n const az = (k / perWhorl) * TAU + w * 0.9 + fr.range(-0.2, 0.2)\n const out = dirFromAngles(az, 0)\n const start: Vec3 = [lean * (y / H) ** 2, y, 0]\n const rise = Math.max(0.5, topY - y)\n const p1 = add(start, add(mul(out, len * 0.4), [0, rise * 0.02, 0]))\n const p2 = add(start, add(mul(out, len * 0.75), [0, rise * 0.22, 0]))\n const p3 = add(start, add(mul(out, len * 1.0), [0, rise * 0.95, 0]))\n const path = catmull([start, p1, p2, p3], ctx.pick(2, 1, 1))\n const n = path.length\n if (ctx.lod < 2) tube(ctx.wood, path, { sides: ctx.pick(4, 3, 3), radii: path.map((_, i) => trunkR * 0.35 * (1 - 0.6 * (i / (n - 1)))), color: barkColor(bark, 1), sway: (t) => 0.1 + 0.2 * t, end: 'none' })\n const col = jitter(leafBase, fr, 0.012, 0.08, 0.05)\n const sleeve = path.slice(Math.floor(n * 0.2))\n const sr = Math.max(0.12, R * 0.085 * lerp(1, 0.85, f))\n tube(ctx.foliage, sleeve, {\n sides: ctx.pick(6, 5, 4),\n radii: sleeve.map((_, i) => sr * (0.55 + 0.45 * Math.sin(Math.min(1, (i + 0.5) / (sleeve.length - 0.5)) * Math.PI * 0.9 + 0.3))),\n color: (t, a) => mix(shade(col, 0.55), lighten(col, 0.7), clamp01(0.4 * t + 0.6 * (0.5 + 0.5 * Math.sin(a * TAU)))),\n sway: (t) => 0.2 + 0.4 * t,\n end: 'point',\n smooth: false,\n rough: ctx.lod === 0 ? (_r, i) => (i % 2 ? 0.28 : -0.12) : undefined,\n })\n }\n }\n // leader tuft\n tube(ctx.foliage, [[lean, H * 0.93, 0], [lean, H * 1.02, 0]], { sides: 5, radii: [R * 0.07, R * 0.03], color: () => shade(leafBase, 0.9), sway: () => 0.2, end: 'point' })\n }\n return { collider: { kind: 'cylinder', radius: trunkR * 1.2, height: H * 0.6 }, bendable: false }\n}\n\nconst clamp01 = (v: number): number => (v < 0 ? 0 : v > 1 ? 1 : v)\n","import type { VineSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { add, catmull, lerp, mul, norm, sampleLine, TAU, sub, cross } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { tube } from '../geometry/tube'\nimport { leaf } from '../geometry/leaf'\nimport { flowerHead } from '../geometry/flower'\n\n/** Climbing plant along a host polyline or a wall rectangle in the xy plane facing +z. */\nexport function generateVine(spec: VineSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const dead = ctx.condition === 'dead'\n const over = ctx.condition === 'overgrown'\n const host = spec.host ?? { wall: { width: 2.5, height: 2.2 } }\n const base = tintGreen(rgb(spec.leafColor ?? 0x3f8a3a), ctx.condition)\n const stemC = rgb(spec.stemColor ?? 0x5a4630)\n const lsize = spec.leafSize ?? 1\n const density = (spec.density ?? 1) * (over ? 1.5 : 1) * (dead ? 0.15 : ctx.condition === 'dry' ? 0.6 : 1)\n const c0 = shade(base, 0.65)\n const c1 = mix(lighten(base, 0.5), [0.7, 0.85, 0.4], 0.1)\n\n const stems: Vec3[][] = []\n if ('path' in host) {\n const pts = host.path\n const nStems = 2\n for (let s = 0; s < nStems; s++) {\n const off = rng.range(0.02, 0.06)\n const wob = rng.range(0, TAU)\n const path = pts.map((p, i) => add(p, [Math.sin(i * 1.7 + wob + s * 2) * off, Math.cos(i * 1.3 + wob) * off, Math.sin(i * 0.9 + s) * off]))\n stems.push(catmull(path, ctx.pick(2, 1, 1)))\n }\n } else {\n const W = host.wall.width\n const Hh = host.wall.height\n const n = Math.max(2, Math.round(W / 0.7))\n for (let i = 0; i < n; i++) {\n const x0 = -W / 2 + (W * (i + 0.5)) / n + rng.range(-0.1, 0.1)\n const topY = Hh * rng.range(0.55, 0.98) * (over ? 1 : 0.92)\n const ctrl: Vec3[] = [[x0, 0, 0.03]]\n let x = x0\n for (let k = 1; k <= 5; k++) {\n x += rng.range(-0.18, 0.18)\n ctrl.push([clamp(x, -W / 2, W / 2), (topY * k) / 5, 0.03 + rng.range(0, 0.02)])\n }\n const main = catmull(ctrl, ctx.pick(2, 1, 1))\n stems.push(main)\n // side branches spreading across the wall\n const nb = Math.round(rng.range(2, 3.5) * (over ? 1.4 : 1))\n for (let b = 0; b < nb; b++) {\n const t = rng.range(0.25, 0.85)\n const s = sampleLine(main, t)\n const dir = rng.sign()\n const len = W * rng.range(0.18, 0.4)\n const end: Vec3 = [clamp(s.p[0] + dir * len, -W / 2, W / 2), Math.min(Hh, s.p[1] + rng.range(0.05, 0.35)), 0.035]\n const mid: Vec3 = [lerp(s.p[0], end[0], 0.5), lerp(s.p[1], end[1], 0.5) + rng.range(-0.08, 0.08), 0.04]\n stems.push(catmull([s.p, mid, end], ctx.pick(2, 1, 1)))\n }\n }\n }\n // draw stems and leaves\n const flowers = spec.flowers && !dead\n for (let si = 0; si < stems.length; si++) {\n const st = stems[si]\n const n = st.length\n tube(ctx.wood, st, { sides: 3, radii: st.map((_, i) => (si < 3 ? 0.014 : 0.009) * (1 - 0.5 * (i / (n - 1)))), color: (t) => shade(stemC, 0.8 + 0.4 * t), sway: (t) => 0.1 + 0.3 * t, end: 'point' })\n const spacing = 0.16 / Math.max(0.2, density)\n let length = 0\n for (let i = 1; i < n; i++) length += Math.hypot(...(sub(st[i], st[i - 1]) as Vec3))\n const count = Math.max(0, Math.round((length / spacing) * ctx.pick(1, 0.4, 0.2)))\n const lrng = rng.fork(si + 100)\n for (let k = 0; k < count; k++) {\n const t = (k + lrng.range(0.1, 0.9)) / count\n const s = sampleLine(st, t)\n const side = k % 2 ? 1 : -1\n const hostNormal: Vec3 = 'path' in host ? norm(cross(s.d, [0, 1, 0.01])) : [0, 0, 1]\n const lateral = norm(cross(hostNormal, s.d))\n const dir = norm(add(add(mul(lateral, side * 0.9), mul(s.d, lrng.range(0.0, 0.5))), mul(hostNormal, 0.35)))\n const len = 0.17 * lsize * lrng.range(0.8, 1.3)\n const cc0 = jitter(c0, lrng, 0.012, 0.07, 0.04)\n const cc1 = jitter(c1, lrng, 0.012, 0.07, 0.04)\n leaf(ctx.foliage, add(s.p, mul(hostNormal, 0.01)), dir, hostNormal, len, len * 0.9, dead ? [0.4, 0.34, 0.24] : cc0, dead ? [0.5, 0.42, 0.28] : cc1, { rows: 2, curl: 0.15, fold: 0.4, swayBase: 0.3, swayTip: 0.8, peak: 0.4, round: 0.6, baseWidth: 0.2 })\n if (flowers && spec.flowers && lrng.next() < (0.16 * (spec.flowers.count ?? 12)) / 12 * ctx.pick(1, 0.6, 0)) {\n const cols = spec.flowers.colors.map(rgb)\n const sz = spec.flowers.style === 'passion' ? 0.06 : 0.055\n flowerHead(ctx.flowers, {\n kind: spec.flowers.style === 'passion' ? 'passion' : 'bract',\n center: add(s.p, mul(hostNormal, 0.05)),\n axis: norm(add(hostNormal, [lrng.range(-0.3, 0.3), 0.2, lrng.range(-0.3, 0.3)])),\n size: sz * lrng.range(0.9, 1.3),\n colors: cols,\n centerColor: [1, 1, 1],\n rng: lrng.fork(k),\n lod: ctx.lod,\n sway: 0.6,\n })\n }\n }\n }\n return { collider: null, bendable: true }\n}\n\nconst clamp = (v: number, a: number, b: number): number => (v < a ? a : v > b ? b : v)\n","import type { PartKind, PottedSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU } from '../math'\nimport { jitter, rgb, shade } from '../color'\nimport { tube } from '../geometry/tube'\nimport { generate } from '../generate'\n\n/** Plant in a pot: pot shell, soil disc, then the wrapped plant generated at the same lod / condition / season. */\nexport function generatePotted(spec: PottedSpec, ctx: Ctx): ArchResult {\n const pot = spec.pot ?? {}\n const shape = pot.shape ?? 'terracotta'\n const R = pot.radius ?? 0.2\n const h = pot.height ?? R * 1.6\n const col = rgb(pot.color ?? (shape === 'cachepot' ? 0xe8e2d4 : shape === 'cylinder' ? 0x6a6e72 : 0xb5603c))\n const sides = ctx.pick(shape === 'square' ? 4 : 12, shape === 'square' ? 4 : 8, shape === 'square' ? 4 : 5)\n const prof: { y: number; r: number }[] = []\n switch (shape) {\n case 'terracotta':\n prof.push({ y: 0, r: R * 0.62 }, { y: h * 0.1, r: R * 0.66 }, { y: h * 0.7, r: R * 0.92 }, { y: h * 0.78, r: R * 1.06 }, { y: h * 0.95, r: R * 1.08 }, { y: h * 0.98, r: R * 0.96 })\n break\n case 'cylinder':\n prof.push({ y: 0, r: R * 0.97 }, { y: h * 0.04, r: R }, { y: h * 0.92, r: R }, { y: h * 0.97, r: R * 1.03 }, { y: h * 0.98, r: R * 0.94 })\n break\n case 'square':\n prof.push({ y: 0, r: R * 1.0 }, { y: h * 0.92, r: R * 1.2 }, { y: h * 0.97, r: R * 1.24 }, { y: h * 0.98, r: R * 1.12 })\n break\n default: // cachepot\n prof.push({ y: 0, r: R * 0.8 }, { y: h * 0.12, r: R * 0.95 }, { y: h * 0.55, r: R * 1.12 }, { y: h * 0.88, r: R * 1.04 }, { y: h * 0.95, r: R * 1.06 }, { y: h * 0.98, r: R * 0.95 })\n }\n ctx.piece('pot', 'pot')\n const path: Vec3[] = prof.map((p) => [0, p.y, 0])\n tube(ctx.wood, path, {\n sides,\n radii: prof.map((p) => p.r),\n color: (t, a) => {\n const c = jitter(col, ctx.rng.fork(1), 0.004, 0.02, 0.02)\n const k = 0.7 + 0.35 * t + 0.04 * Math.cos(a * TAU * 2)\n return t > 0.93 ? shade(c, 1.12) : shade(c, k)\n },\n sway: () => 0,\n end: 'none',\n smooth: shape !== 'square',\n })\n // soil disc\n ctx.piece('soil', 'soil', 'pot')\n const soilY = h * 0.93\n const soil: Vec3 = [0.22, 0.15, 0.1]\n const rim = (prof[prof.length - 2]?.r ?? R) * 0.96\n for (let i = 0; i < sides; i++) {\n const a0 = (i / sides) * TAU\n const a1 = ((i + 1) / sides) * TAU\n ctx.wood.flatTri([0, soilY, 0], [Math.cos(a1) * rim, soilY, Math.sin(a1) * rim], [Math.cos(a0) * rim, soilY, Math.sin(a0) * rim], shade(soil, 0.9), soil, soil, 0, 0, 0, [0, 1, 0])\n }\n // inner plant\n const inner = generate(spec.plant, { seed: ctx.rng.fork('plant').seed(), lod: ctx.lod, condition: ctx.condition, season: ctx.season })\n const yOff = soilY - 0.02\n const tagsOf = (part: PartKind): ((t: number) => string) | undefined => {\n const mesh = inner.parts[part]\n if (!mesh) return undefined\n const tags = new Array<string>(mesh.triangleCount).fill('')\n for (const pc of inner.pieces) {\n if (pc.part !== part) continue\n if (!ctx.pieceMeta.has(pc.id)) ctx.pieceMeta.set(pc.id, { kind: pc.kind, parent: pc.parent, pivot: [pc.pivot[0], pc.pivot[1] + yOff, pc.pivot[2]], ...(pc.radius === undefined || pc.length === undefined || !pc.axis || !pc.base ? {} : { geom: { radius: pc.radius, length: pc.length, axis: pc.axis, base: [pc.base[0], pc.base[1] + yOff, pc.base[2]] as Vec3 } }) })\n for (let t = pc.indexStart / 3; t < (pc.indexStart + pc.indexCount) / 3; t++) tags[t] = pc.id\n }\n return (t) => tags[t]\n }\n if (inner.parts.wood) ctx.wood.appendMesh(inner.parts.wood, 0, yOff, 0, 0, 1, tagsOf('wood'))\n if (inner.parts.spines) ctx.spines.appendMesh(inner.parts.spines, 0, yOff, 0, 0, 1, tagsOf('spines'))\n if (inner.parts.foliage) ctx.foliage.appendMesh(inner.parts.foliage, 0, yOff, 0, 0, 1, tagsOf('foliage'))\n if (inner.parts.flowers) ctx.flowers.appendMesh(inner.parts.flowers, 0, yOff, 0, 0, 1, tagsOf('flowers'))\n if (inner.parts.fruit) ctx.fruit.appendMesh(inner.parts.fruit, 0, yOff, 0, 0, 1, tagsOf('fruit'))\n return {\n collider: { kind: 'cylinder', radius: Math.max(R * 1.1, 0.1), height: h },\n bendable: inner.bendable,\n thorny: inner.thorny,\n foliageMaterial: inner.parts.foliage?.material,\n }\n}\n","import type { Condition, GenerateOptions, Lod, PartKind, PieceGeometry, PieceKind, PlantMesh, PlantPiece, PlantSpec, Season, Vec3 } from './types'\nimport { materialKeyForPart, type MaterialKey } from './destruction'\nimport { Rng, toSeed } from './rng'\nimport { MeshBuilder } from './geometry/builder'\nimport type { ArchResult, Ctx, PieceMeta } from './ctx'\nimport { generateBroadleafTree } from './archetypes/broadleaf-tree'\nimport { generateDeadTree } from './archetypes/dead-tree'\nimport { generateFlowerPlant } from './archetypes/flower-plant'\nimport { generateGrassTuft } from './archetypes/grass-tuft'\nimport { generateFern } from './archetypes/fern'\nimport { generateRosette } from './archetypes/rosette'\nimport { generateColumnarCactus } from './archetypes/cactus-columnar'\nimport { generatePaddleCactus } from './archetypes/cactus-paddle'\nimport { generateGlobeCactus } from './archetypes/cactus-globe'\nimport { generatePalm } from './archetypes/palm'\nimport { generateBanana } from './archetypes/banana'\nimport { generateShrub } from './archetypes/shrub'\nimport { generateConifer } from './archetypes/conifer'\nimport { generateVine } from './archetypes/vine'\nimport { generatePotted } from './archetypes/potted'\n\ntype Gen = (spec: any, ctx: Ctx) => ArchResult\n\n/** Registry of archetype generators. Filled in by each archetype module through `GENERATORS`. */\nexport const GENERATORS: Record<string, Gen> = {\n broadleaf_tree: generateBroadleafTree,\n dead_tree: generateDeadTree,\n flower_plant: generateFlowerPlant,\n grass_tuft: generateGrassTuft,\n fern: generateFern,\n rosette: generateRosette,\n columnar_cactus: generateColumnarCactus,\n paddle_cactus: generatePaddleCactus,\n globe_cactus: generateGlobeCactus,\n palm: generatePalm,\n banana: generateBanana,\n shrub: generateShrub,\n conifer: generateConifer,\n vine: generateVine,\n potted: generatePotted,\n}\n\nexport function archetypes(): string[] {\n return Object.keys(GENERATORS)\n}\n\n/** Build a plant. Deterministic: same spec + seed + lod + condition + season => identical arrays. */\nexport function generate(spec: PlantSpec, opts: GenerateOptions = {}): PlantMesh {\n const gen = GENERATORS[spec.archetype]\n if (!gen) throw new Error(`game-vegetation: unknown archetype \"${(spec as { archetype: string }).archetype}\"`)\n const seed = toSeed(opts.seed)\n const lod: Lod = opts.lod ?? 0\n const condition: Condition = opts.condition ?? 'healthy'\n const season: Season = opts.season ?? 'spring'\n const scale = opts.scale ?? 1\n const pieceMeta = new Map<string, PieceMeta>()\n const treeLike = spec.archetype === 'broadleaf_tree' || spec.archetype === 'dead_tree' || spec.archetype === 'palm' || spec.archetype === 'conifer' || spec.archetype === 'banana'\n const rootId = treeLike ? 'trunk' : 'stem'\n let fruitCount = 0\n const ctx: Ctx = {\n pieceMeta,\n piece(id, kind, parent, pivot) {\n if (!pieceMeta.has(id)) pieceMeta.set(id, { kind, parent, pivot })\n ctx.wood.tag = id\n ctx.foliage.tag = id\n ctx.flowers.tag = id\n ctx.spines.tag = id\n },\n pieceGeom(id, geom) {\n const m = pieceMeta.get(id)\n if (m) m.geom = geom\n },\n fruitItem(draw) {\n const id = `fruit${fruitCount++}`\n pieceMeta.set(id, { kind: 'fruit', parent: undefined })\n const saved = [ctx.wood.tag, ctx.foliage.tag, ctx.flowers.tag, ctx.spines.tag, ctx.fruit.tag]\n ctx.wood.tag = id\n ctx.foliage.tag = id\n ctx.flowers.tag = id\n ctx.spines.tag = id\n ctx.fruit.tag = id\n draw()\n ;[ctx.wood.tag, ctx.foliage.tag, ctx.flowers.tag, ctx.spines.tag, ctx.fruit.tag] = saved\n },\n rng: new Rng(seed),\n lod,\n condition,\n season,\n wood: new MeshBuilder(),\n foliage: new MeshBuilder(),\n flowers: new MeshBuilder(),\n fruit: new MeshBuilder(),\n spines: new MeshBuilder(),\n pick: (a, b, c) => (lod === 0 ? a : lod === 1 ? b : c),\n }\n ctx.piece(rootId, treeLike ? 'trunk' : 'stem')\n ctx.fruit.tag = 'fruit'\n if (!pieceMeta.has('fruit')) pieceMeta.set('fruit', { kind: 'fruit', parent: undefined })\n const res = gen(spec, ctx)\n if (fruitCount > MAX_FRUIT_PIECES) clusterFruit(ctx, fruitCount)\n const parts: PlantMesh['parts'] = {\n wood: ctx.wood.build('wood', 'wood'),\n foliage: ctx.foliage.build('foliage', res.foliageMaterial ?? 'foliage'),\n flowers: ctx.flowers.build('flowers', 'foliage'),\n fruit: ctx.fruit.build('fruit', 'foliage'),\n spines: ctx.spines.build('spines', 'cactus'),\n }\n const builders = { wood: ctx.wood, foliage: ctx.foliage, flowers: ctx.flowers, fruit: ctx.fruit, spines: ctx.spines }\n let radius = 0\n let height = 0\n let tris = 0\n for (const key of Object.keys(parts) as (keyof typeof parts)[]) {\n const m = parts[key]\n if (!m) {\n delete parts[key]\n continue\n }\n tris += m.triangleCount\n const pos = m.positions\n for (let i = 0; i < pos.length; i += 3) {\n if (scale !== 1) {\n pos[i] *= scale\n pos[i + 1] *= scale\n pos[i + 2] *= scale\n }\n if (pos[i + 1] < 0) pos[i + 1] = 0\n const r = Math.hypot(pos[i], pos[i + 2])\n if (r > radius) radius = r\n if (pos[i + 1] > height) height = pos[i + 1]\n }\n }\n const pieces = buildPieces(parts, builders, pieceMeta, rootId, condition, scale)\n const collider = res.collider ? { kind: 'cylinder' as const, radius: res.collider.radius * scale, height: res.collider.height * scale } : null\n return {\n parts,\n pieces,\n bounds: { radius, height },\n collider,\n bendable: res.bendable,\n thorny: !!res.thorny,\n seed,\n species: opts.species ?? spec.archetype,\n lod,\n triangleCount: tris,\n condition,\n }\n}\n\n/** A plant has at most this many fruit pieces; more fruit is grouped into small clusters by proximity. */\nexport const MAX_FRUIT_PIECES = 24\n\n/** Group the fruit pieces `fruit0..n-1` into MAX_FRUIT_PIECES clusters (farthest-point seeds, nearest seed wins) and relabel their triangles. */\nfunction clusterFruit(ctx: Ctx, n: number): void {\n const builders = [ctx.wood, ctx.foliage, ctx.flowers, ctx.fruit, ctx.spines]\n const sum = new Map<string, [number, number, number, number]>()\n for (const b of builders) {\n for (let t = 0; t < b.triTag.length; t++) {\n const tg = b.triTag[t]\n if (!/^fruit\\d+$/.test(tg)) continue\n const s = sum.get(tg) ?? [0, 0, 0, 0]\n for (let k = 0; k < 3; k++) {\n const v = b.idx[t * 3 + k] * 3\n s[0] += b.pos[v]\n s[1] += b.pos[v + 1]\n s[2] += b.pos[v + 2]\n s[3]++\n }\n sum.set(tg, s)\n }\n }\n const centers: Vec3[] = []\n for (let i = 0; i < n; i++) {\n const s = sum.get(`fruit${i}`) ?? [0, 0, 0, 1]\n centers.push([s[0] / s[3], s[1] / s[3], s[2] / s[3]])\n }\n const d2 = (a: Vec3, b: Vec3): number => (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2\n const seeds = [0]\n const near = centers.map((c) => d2(c, centers[0]))\n while (seeds.length < MAX_FRUIT_PIECES) {\n let best = 0\n for (let i = 1; i < n; i++) if (near[i] > near[best]) best = i\n seeds.push(best)\n for (let i = 0; i < n; i++) near[i] = Math.min(near[i], d2(centers[i], centers[best]))\n }\n const cluster = centers.map((c) => {\n let bi = 0\n let bd = Infinity\n for (let k = 0; k < seeds.length; k++) {\n const d = d2(c, centers[seeds[k]])\n if (d < bd) {\n bd = d\n bi = k\n }\n }\n return bi\n })\n for (const b of builders) {\n for (let t = 0; t < b.triTag.length; t++) {\n const m = /^fruit(\\d+)$/.exec(b.triTag[t])\n if (m) b.triTag[t] = `fruit${cluster[Number(m[1])]}`\n }\n }\n for (let i = 0; i < n; i++) ctx.pieceMeta.delete(`fruit${i}`)\n for (let k = 0; k < MAX_FRUIT_PIECES; k++) ctx.pieceMeta.set(`fruit${k}`, { kind: 'fruit', parent: undefined })\n}\n\nconst PART_ORDER: PartKind[] = ['wood', 'foliage', 'flowers', 'fruit', 'spines']\n\n/** Pieces made of a straight-ish wood tube: they get a radius, length, axis and base. */\nconst WOOD_KINDS: ReadonlySet<PieceKind> = new Set<PieceKind>(['trunk', 'branch', 'stem', 'arm', 'pad'])\n/** The radius is measured away from the root flare (first 15 % of the length) and the tip taper (after 60 %). */\nconst FLARE_SKIP = 0.15\nconst BODY_END = 0.6\n\n/**\n * The straight-tube fit of a wood piece, in plant space (scaled): the mean radius of the body of its tube, its length along the centreline, the direction from its first to its last point\n * and the first point. An archetype that set `pieceGeom` wins. Returns `undefined` when no tube was drawn under the tag.\n */\nfunction pieceGeometry(tag: string, m: PieceMeta, builders: Record<PartKind, MeshBuilder>, scale: number): PieceGeometry | undefined {\n if (m.geom) {\n const g = m.geom\n return { radius: g.radius * scale, length: g.length * scale, axis: [...g.axis] as Vec3, base: [g.base[0] * scale, g.base[1] * scale, g.base[2] * scale] }\n }\n let tube: MeshBuilder['tubes'][number] | undefined\n for (const part of PART_ORDER) {\n tube = builders[part].tubes.find((t) => t.tag === tag)\n if (tube) break\n }\n if (!tube || tube.path.length < 2) return undefined\n const { path, radii } = tube\n const seg: number[] = []\n let total = 0\n for (let i = 1; i < path.length; i++) {\n const l = Math.hypot(path[i][0] - path[i - 1][0], path[i][1] - path[i - 1][1], path[i][2] - path[i - 1][2])\n seg.push(l)\n total += l\n }\n if (total <= 0) return undefined\n let wsum = 0\n let rsum = 0\n let all = 0\n let acc = 0\n for (let i = 0; i < seg.length; i++) {\n const r = (radii[i] + radii[i + 1]) / 2\n all += r * seg[i]\n const mid = acc + seg[i] / 2\n if (mid >= total * FLARE_SKIP && mid <= total * BODY_END) {\n rsum += r * seg[i]\n wsum += seg[i]\n }\n acc += seg[i]\n }\n const radius = wsum > 0 ? rsum / wsum : all / total\n const a = path[0]\n const b = path[path.length - 1]\n const d = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]) || 1\n return { radius: radius * scale, length: total * scale, axis: [(b[0] - a[0]) / d, (b[1] - a[1]) / d, (b[2] - a[2]) / d], base: [a[0] * scale, a[1] * scale, a[2] * scale] }\n}\n\n/** Turn the builders' tag ranges into pieces with ids, materials, pivots and bounds (positions already scaled). */\nfunction buildPieces(parts: PlantMesh['parts'], builders: Record<PartKind, MeshBuilder>, meta: Map<string, PieceMeta>, rootId: string, condition: Condition, scale: number): PlantPiece[] {\n const primary = new Map<string, PartKind>()\n for (const part of PART_ORDER) {\n if (!parts[part]) continue\n for (const r of builders[part].ranges) if (!primary.has(r.tag || rootId)) primary.set(r.tag || rootId, part)\n }\n if (parts.fruit) for (const r of builders.fruit.ranges) if (meta.get(r.tag || rootId)?.kind === 'fruit') primary.set(r.tag, 'fruit')\n // bounds of every tag over all its parts, to hang each fruit on the nearest non-fruit piece\n const tagBox = new Map<string, { min: Vec3; max: Vec3 }>()\n for (const part of PART_ORDER) {\n const mesh = parts[part]\n if (!mesh) continue\n for (const r of builders[part].ranges) {\n const tag = r.tag || rootId\n let box = tagBox.get(tag)\n if (!box) tagBox.set(tag, (box = { min: [Infinity, Infinity, Infinity], max: [-Infinity, -Infinity, -Infinity] }))\n for (let i = r.indexStart; i < r.indexStart + r.indexCount; i++) {\n const v = mesh.indices[i] * 3\n for (let a = 0; a < 3; a++) {\n const c = mesh.positions[v + a]\n if (c < box.min[a]) box.min[a] = c\n if (c > box.max[a]) box.max[a] = c\n }\n }\n }\n }\n const fruitHang = new Map<string, { parent?: string; pivot: Vec3 }>()\n const PRIORITY: Partial<Record<PieceKind, number>> = { branch: 0, pad: 0, arm: 0, stem: 1, trunk: 1, crown: 2 }\n for (const [tag, box] of tagBox) {\n if (meta.get(tag)?.kind !== 'fruit') continue\n const cx = (box.min[0] + box.max[0]) / 2\n const cy = (box.min[1] + box.max[1]) / 2\n const cz = (box.min[2] + box.max[2]) / 2\n let parent: string | undefined\n let pbox: { min: Vec3; max: Vec3 } | undefined\n let bd = Infinity\n let bp = 9\n for (const [ptag, pb] of tagBox) {\n const pk = meta.get(ptag)?.kind\n if (pk === undefined || PRIORITY[pk] === undefined) continue\n let d = 0\n const p = [cx, cy, cz]\n for (let a = 0; a < 3; a++) {\n const o = p[a] < pb.min[a] ? pb.min[a] - p[a] : p[a] > pb.max[a] ? p[a] - pb.max[a] : 0\n d += o * o\n }\n const pr = PRIORITY[pk]!\n if (d < bd - 1e-9 || (Math.abs(d - bd) <= 1e-9 && pr < bp)) {\n bd = d\n bp = pr\n parent = ptag\n pbox = pb\n }\n }\n // pivot: the point of the fruit's bounds nearest to the middle of what it hangs from (a stalk top, a trunk / pad side)\n const pc = pbox ? [(pbox.min[0] + pbox.max[0]) / 2, (pbox.min[1] + pbox.max[1]) / 2, (pbox.min[2] + pbox.max[2]) / 2] : [cx, box.max[1], cz]\n const pivot: Vec3 = [Math.min(box.max[0], Math.max(box.min[0], pc[0])), Math.min(box.max[1], Math.max(box.min[1], pc[1])), Math.min(box.max[2], Math.max(box.min[2], pc[2]))]\n fruitHang.set(tag, { parent, pivot })\n }\n const idOf = (tag: string, part: PartKind): string => (primary.get(tag) === part ? tag : `${tag}:${part}`)\n const out: PlantPiece[] = []\n for (const part of PART_ORDER) {\n const mesh = parts[part]\n if (!mesh) continue\n for (const r of builders[part].ranges) {\n const tag = r.tag || rootId\n const m = meta.get(tag) ?? { kind: 'stem' as const }\n const min: Vec3 = [Infinity, Infinity, Infinity]\n const max: Vec3 = [-Infinity, -Infinity, -Infinity]\n for (let i = r.indexStart; i < r.indexStart + r.indexCount; i++) {\n const v = mesh.indices[i] * 3\n for (let a = 0; a < 3; a++) {\n const c = mesh.positions[v + a]\n if (c < min[a]) min[a] = c\n if (c > max[a]) max[a] = c\n }\n }\n let pivot: Vec3\n const hang = fruitHang.get(tag)\n if (hang) pivot = hang.pivot\n else if (m.pivot) pivot = [m.pivot[0] * scale, Math.max(0, m.pivot[1] * scale), m.pivot[2] * scale]\n else if (m.kind === 'crown' || m.kind === 'fruit') pivot = [(min[0] + max[0]) / 2, (min[1] + max[1]) / 2, (min[2] + max[2]) / 2]\n else pivot = [(min[0] + max[0]) / 2, min[1], (min[2] + max[2]) / 2]\n if (m.kind === 'trunk' || m.kind === 'stem' || m.kind === 'pot' || m.kind === 'soil') pivot = [0, min[1], 0]\n let material: MaterialKey = materialKeyForPart(part, mesh.material, condition)\n if (m.kind === 'pot') material = 'pot'\n else if (m.kind === 'soil') material = 'soil'\n const parentTag = hang ? hang.parent : m.parent\n const parentId = parentTag !== undefined && primary.has(parentTag) ? idOf(parentTag, primary.get(parentTag)!) : undefined\n const geom = WOOD_KINDS.has(m.kind) ? pieceGeometry(tag, m, builders, scale) : undefined\n out.push({\n id: idOf(tag, part),\n kind: m.kind,\n material,\n ...(parentId === undefined ? {} : { parent: parentId }),\n part,\n indexStart: r.indexStart,\n indexCount: r.indexCount,\n pivot,\n bounds: { min, max },\n ...(geom ?? {}),\n })\n }\n }\n return out\n}\n","import type { Condition, GenerateOptions, Lod, MeshData, PartKind, PieceKind, Placement, PlantMesh, PlantSpec, Season, Vec3 } from './types'\nimport type { MaterialKey } from './destruction'\nimport { generate } from './generate'\nimport { MeshBuilder } from './geometry/builder'\nimport { hashMix, toSeed } from './rng'\n\nexport interface LotColliderData {\n x: number\n z: number\n r: number\n h: number\n damage?: 'thorns'\n}\n\n/** One separable piece of a plant inside the merged lot meshes. */\nexport interface LotPiece {\n id: string\n kind: PieceKind\n parent?: string\n /** the plant part the piece comes from */\n part: PartKind\n /** which merged mesh holds it (spines go to 'wood', fruit to 'flowers') */\n mesh: 'wood' | 'foliage' | 'flowers'\n /** triangle index range in `lot.meshes[mesh].indices` (a multiple of 3) */\n indexStart: number\n indexCount: number\n /** key of the destruction material table (see MaterialIds) */\n material: MaterialKey\n /** wood pieces: the straight-tube fit, as in `PlantPiece` */\n radius?: number\n length?: number\n axis?: Vec3\n base?: Vec3\n}\nexport interface LotPlantPieces {\n /** index into the `placements` array given to buildLot */\n plantIndex: number\n species: string\n x: number\n z: number\n ry: number\n scale: number\n lod: Lod\n pieces: LotPiece[]\n /** what is needed to regenerate the same plant as a separable object (see extractPlant) */\n spec: PlantSpec\n generateOptions: GenerateOptions\n}\n\nexport interface Lot {\n meshes: { wood?: MeshData; foliage?: MeshData; flowers?: MeshData }\n /** trunks only; foliage, flowers and grass never collide */\n colliders: LotColliderData[]\n triangleCount: number\n plantCount: number\n /** grass tufts left out to meet the triangle budget */\n thinnedCount: number\n /** plants kept at LOD0, LOD1 and LOD2 */\n lodCounts: [number, number, number]\n /** condition the lot was built with (default 'healthy') */\n condition?: Condition\n /** one entry per plant that made it into the meshes (thinned grass is absent), see extractPlant / hideLotPlant */\n pieceTable: LotPlantPieces[]\n}\n\nexport interface BuildLotOptions {\n seed?: number | string\n /** 'game' uses LOD1 for every plant; 'high' uses `lod` (default 0) */\n quality: 'high' | 'game'\n lod?: Lod\n condition?: Condition\n season?: Season\n /**\n * LOD used for small plants (grass tufts, small flowers, ferns...) so a yard full of them stays cheap.\n * Default: 2 in 'game' quality, `lod` (0 unless set) in 'high' quality. Set it equal to the main LOD to disable.\n */\n smallPlantsLod?: Lod\n /** plants not taller than this (meters, after placement scale) count as small (default 0.7) */\n smallPlantMaxHeight?: number\n /**\n * Soft triangle cap for the whole lot. When the plants exceed it: some grass tufts are left out first, then small\n * plants, then shrubs / hedges, and only then trees and palms are switched to LOD2 (smallest first) until the lot fits. Default: 20000 in 'game' quality, unlimited in 'high' quality.\n */\n triangleBudget?: number\n}\n\n/**\n * Merge every plant of an area into at most 3 meshes (wood + spines, foliage, flowers + fruit), with every vertex\n * already transformed by its placement (x, z, ry, scale). Engine agnostic.\n */\nexport function buildLot(placements: Placement[], resolveSpec: (id: string) => PlantSpec, opts: BuildLotOptions): Lot {\n const lod: Lod = opts.quality === 'game' ? 1 : (opts.lod ?? 0)\n const smallLod: Lod = opts.smallPlantsLod ?? (opts.quality === 'game' ? 2 : lod)\n const smallMax = opts.smallPlantMaxHeight ?? 0.8\n const budget = opts.triangleBudget ?? (opts.quality === 'game' ? 20000 : Infinity)\n const base = toSeed(opts.seed)\n const wood = new MeshBuilder()\n const foliage = new MeshBuilder()\n const flowers = new MeshBuilder()\n const colliders: LotColliderData[] = []\n const cache = new Map<string, PlantSpec>()\n const entries: { p: Placement; plant: PlantMesh; go: GenerateOptions; spec: PlantSpec; dropped?: boolean }[] = []\n let total = 0\n for (const p of placements) {\n let spec = cache.get(p.species)\n if (!spec) {\n spec = resolveSpec(p.species)\n cache.set(p.species, spec)\n }\n const go: GenerateOptions = { seed: hashMix(base, p.seed), lod, condition: opts.condition, season: opts.season }\n let plant: PlantMesh | undefined\n if (smallLod !== lod) {\n // small plants (judged by the cheap version) use the cheap LOD\n const cheap = generate(spec, { ...go, lod: smallLod })\n if (cheap.bounds.height * p.scale <= smallMax) plant = cheap\n }\n plant ??= generate(spec, go)\n total += plant.triangleCount\n entries.push({ p, plant, go, spec })\n }\n let thinned = 0\n if (total > budget) {\n const kindOf = (e: (typeof entries)[number]): number => {\n const a = e.spec.archetype\n if (a === 'grass_tuft' && e.plant.bounds.height * e.p.scale < 1) return 0\n if (a === 'broadleaf_tree' || a === 'conifer' || a === 'dead_tree' || a === 'palm' || a === 'banana') return 3\n return e.plant.bounds.height * e.p.scale <= smallMax ? 1 : 2\n }\n const cost = (e: (typeof entries)[number]): number => e.plant.triangleCount\n // 1) thin out grass tufts and weeds (a deterministic share, in hash order): they are tiny\n const grass = entries.filter((e) => kindOf(e) === 0).sort((a, b) => hashMix(a.p.seed, 7) - hashMix(b.p.seed, 7))\n const keepMin = Math.ceil(grass.length * 0.2)\n for (let i = 0; i < grass.length - keepMin && total > budget; i++) {\n total -= cost(grass[i])\n grass[i].dropped = true\n thinned++\n }\n // 2..4) small plants, then shrubs / hedges / the rest, then trees and palms: drop to LOD2, smallest first\n for (const kind of [1, 2, 3]) {\n const group = entries.filter((e) => !e.dropped && kindOf(e) === kind && e.plant.lod < 2).sort((a, b) => a.plant.bounds.height * a.p.scale - b.plant.bounds.height * b.p.scale)\n for (const e of group) {\n if (total <= budget) break\n const cheap = generate(e.spec, { ...e.go, lod: 2 })\n total += cheap.triangleCount - e.plant.triangleCount\n e.plant = cheap\n }\n }\n }\n const lodCounts: [number, number, number] = [0, 0, 0]\n const kept: { plantIndex: number; e: (typeof entries)[number] }[] = []\n for (let pi = 0; pi < entries.length; pi++) {\n const e = entries[pi]\n const { p, plant, dropped } = e\n if (dropped) continue\n kept.push({ plantIndex: pi, e })\n lodCounts[plant.lod]++\n const { parts } = plant\n // every triangle is tagged \"<plantIndex>|<piece id>\" so the merged builders report the piece ranges\n const tagsOf = (part: PartKind): ((t: number) => string) | undefined => {\n const mesh = parts[part]\n if (!mesh) return undefined\n const tags = new Array<string>(mesh.triangleCount).fill('')\n for (const pc of plant.pieces) {\n if (pc.part !== part) continue\n for (let t = pc.indexStart / 3; t < (pc.indexStart + pc.indexCount) / 3; t++) tags[t] = `${pi}|${pc.id}`\n }\n return (t) => tags[t]\n }\n if (parts.wood) wood.appendMesh(parts.wood, p.x, 0, p.z, p.ry, p.scale, tagsOf('wood'))\n if (parts.spines) wood.appendMesh(parts.spines, p.x, 0, p.z, p.ry, p.scale, tagsOf('spines'))\n if (parts.foliage) foliage.appendMesh(parts.foliage, p.x, 0, p.z, p.ry, p.scale, tagsOf('foliage'))\n if (parts.flowers) flowers.appendMesh(parts.flowers, p.x, 0, p.z, p.ry, p.scale, tagsOf('flowers'))\n if (parts.fruit) flowers.appendMesh(parts.fruit, p.x, 0, p.z, p.ry, p.scale, tagsOf('fruit'))\n if (plant.collider) {\n const c: LotColliderData = { x: p.x, z: p.z, r: plant.collider.radius * p.scale, h: plant.collider.height * p.scale }\n if (plant.thorny) c.damage = 'thorns'\n colliders.push(c)\n }\n }\n const meshes: Lot['meshes'] = {\n wood: wood.build('wood', 'wood'),\n foliage: foliage.build('foliage', 'foliage'),\n flowers: flowers.build('flowers', 'foliage'),\n }\n for (const k of Object.keys(meshes) as (keyof Lot['meshes'])[]) if (!meshes[k]) delete meshes[k]\n const rangeOf = new Map<string, { mesh: 'wood' | 'foliage' | 'flowers'; indexStart: number; indexCount: number }>()\n for (const [mesh, b] of [['wood', wood], ['foliage', foliage], ['flowers', flowers]] as const) {\n for (const r of b.ranges) if (r.tag) rangeOf.set(r.tag, { mesh, indexStart: r.indexStart, indexCount: r.indexCount })\n }\n const pieceTable: LotPlantPieces[] = kept.map(({ plantIndex, e }) => ({\n plantIndex,\n species: e.p.species,\n x: e.p.x,\n z: e.p.z,\n ry: e.p.ry,\n scale: e.p.scale,\n lod: e.plant.lod,\n spec: e.spec,\n generateOptions: { ...e.go, lod: e.plant.lod },\n pieces: e.plant.pieces.map((pc) => {\n const r = rangeOf.get(`${plantIndex}|${pc.id}`)!\n return { id: pc.id, kind: pc.kind, ...(pc.parent === undefined ? {} : { parent: pc.parent }), part: pc.part, mesh: r.mesh, indexStart: r.indexStart, indexCount: r.indexCount, material: pc.material, ...(pc.radius === undefined ? {} : { radius: pc.radius, length: pc.length, axis: pc.axis, base: pc.base }) }\n }),\n }))\n const triangleCount = (meshes.wood?.triangleCount ?? 0) + (meshes.foliage?.triangleCount ?? 0) + (meshes.flowers?.triangleCount ?? 0)\n return { meshes, colliders, triangleCount, plantCount: placements.length, thinnedCount: thinned, lodCounts, condition: opts.condition ?? 'healthy', pieceTable }\n}\n\nexport interface ExtractedPlant {\n /** the plant regenerated with the exact options used in the lot (same LOD, same seed): identical geometry, plus its pieces */\n plant: PlantMesh\n /** where the plant stood in the lot: build the separable object with position (x, 0, z), rotation.y = ry and scale */\n placement: { species: string; x: number; z: number; ry: number; scale: number }\n /** the index ranges the plant occupies in the merged meshes */\n ranges: LotPiece[]\n}\n\nfunction entryOf(lot: Lot, plantIndex: number): LotPlantPieces {\n const e = lot.pieceTable.find((t) => t.plantIndex === plantIndex)\n if (!e) throw new Error(`game-vegetation: plant ${plantIndex} is not in the lot (thinned out or out of range)`)\n return e\n}\n\n/**\n * Get a plant of the lot back as a stand-alone `PlantMesh` (with `pieces`) plus its placement, to spawn a separable version\n * (`createPlantObject(THREE, plant, mats, { separable: true })`) when the merged plant gets hit. Does not touch the lot.\n */\nexport function extractPlant(lot: Lot, plantIndex: number): ExtractedPlant {\n const e = entryOf(lot, plantIndex)\n return {\n plant: generate(e.spec, { ...e.generateOptions, species: e.species }),\n placement: { species: e.species, x: e.x, z: e.z, ry: e.ry, scale: e.scale },\n ranges: e.pieces,\n }\n}\n\n/**\n * Make a plant of the lot invisible by zeroing its index ranges in the merged meshes (degenerate triangles). Idempotent.\n * The indices array is shared with the three BufferGeometry, so set `geometry.index.needsUpdate = true` afterwards\n * (`removeLotPlant` in game-vegetation/three does that). Returns the ranges that were cleared.\n */\nexport function hideLotPlant(lot: Lot, plantIndex: number): LotPiece[] {\n const e = entryOf(lot, plantIndex)\n for (const r of e.pieces) {\n const m = lot.meshes[r.mesh]\n if (m) m.indices.fill(0, r.indexStart, r.indexStart + r.indexCount)\n }\n return e.pieces\n}\n","import type { Placement } from './types'\nimport { Rng, hashMix, toSeed } from './rng'\nimport { TAU, clamp } from './math'\n\nexport type Point2 = [number, number]\n/** `rect.x` / `rect.z` is the minimum corner; `w` runs along x and `d` along z. */\nexport type Region = { polygon: Point2[] } | { rect: { x: number; z: number; w: number; d: number } }\n\nexport interface ScatterRule {\n /** species id, a list (uniform pick) or weighted ids */\n species: string | string[] | { id: string; weight: number }[]\n /** plants per square meter */\n density: number\n /** minimum distance between plants of this rule, meters */\n minDistance: number\n /** areas where this rule must not place anything (paths, house footprint, ...) */\n exclude?: Region[]\n /** `edge` hugs the boundary (hedges, flowerbeds against walls), `center` avoids it */\n prefer?: 'edge' | 'center' | 'any'\n /** how fast the edge preference falls off with distance from the boundary (meters, default max(0.4, 0.8 * minDistance)) */\n edgeWidth?: number\n /** random scale range (default [1, 1]) */\n scale?: [number, number]\n /** random rotation about y: true = full circle (default), false = none, or [min, max] radians */\n rotate?: boolean | [number, number]\n /** cap on the number of placements of this rule */\n maxCount?: number\n}\n\nexport interface ScatterOptions {\n seed: number | string\n /** exclusions applied to every rule */\n exclude?: Region[]\n}\n\nexport function regionPolygon(r: Region): Point2[] {\n if ('polygon' in r) return r.polygon\n const { x, z, w, d } = r.rect\n return [[x, z], [x + w, z], [x + w, z + d], [x, z + d]]\n}\n\nexport function pointInPolygon(x: number, z: number, poly: Point2[]): boolean {\n let inside = false\n for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {\n const [xi, zi] = poly[i]\n const [xj, zj] = poly[j]\n if (zi > z !== zj > z && x < ((xj - xi) * (z - zi)) / (zj - zi) + xi) inside = !inside\n }\n return inside\n}\n\nexport function polygonArea(poly: Point2[]): number {\n let a = 0\n for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) a += (poly[j][0] + poly[i][0]) * (poly[j][1] - poly[i][1])\n return Math.abs(a) / 2\n}\n\n/** Distance from a point to the boundary of a polygon. */\nexport function distanceToBoundary(x: number, z: number, poly: Point2[]): number {\n let best = Infinity\n for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {\n const [ax, az] = poly[j]\n const [bx, bz] = poly[i]\n const dx = bx - ax\n const dz = bz - az\n const l2 = dx * dx + dz * dz\n const t = l2 === 0 ? 0 : clamp(((x - ax) * dx + (z - az) * dz) / l2, 0, 1)\n const d = Math.hypot(x - (ax + dx * t), z - (az + dz * t))\n if (d < best) best = d\n }\n return best\n}\n\nfunction pickSpecies(rule: ScatterRule, rng: Rng): string {\n const s = rule.species\n if (typeof s === 'string') return s\n if (s.length === 0) throw new Error('game-vegetation: scatter rule has no species')\n if (typeof s[0] === 'string') return rng.pick(s as string[])\n const w = s as { id: string; weight: number }[]\n const total = w.reduce((a, b) => a + b.weight, 0)\n let r = rng.next() * total\n for (const it of w) {\n r -= it.weight\n if (r <= 0) return it.id\n }\n return w[w.length - 1].id\n}\n\n/**\n * Poisson-disc style placement (dart throwing with a spatial hash) inside a polygon or rectangle.\n * Deterministic for a given seed. Rules are processed in order, so earlier rules keep their spots.\n */\nexport function scatter(area: Region, rules: ScatterRule[], opts: ScatterOptions): Placement[] {\n const poly = regionPolygon(area)\n const seed = toSeed(opts.seed)\n const area2 = polygonArea(poly)\n let minX = Infinity\n let minZ = Infinity\n let maxX = -Infinity\n let maxZ = -Infinity\n for (const [x, z] of poly) {\n minX = Math.min(minX, x)\n maxX = Math.max(maxX, x)\n minZ = Math.min(minZ, z)\n maxZ = Math.max(maxZ, z)\n }\n const globalEx = (opts.exclude ?? []).map(regionPolygon)\n const cell = Math.max(0.05, ...rules.map((r) => r.minDistance))\n const grid = new Map<string, { x: number; z: number; md: number }[]>()\n const key = (cx: number, cz: number): string => cx + ',' + cz\n const out: Placement[] = []\n const inradius = Math.max(0.5, Math.sqrt(area2) * 0.5)\n rules.forEach((rule, ri) => {\n const rng = new Rng(hashMix(seed, ri + 1))\n const ex = [...globalEx, ...(rule.exclude ?? []).map(regionPolygon)]\n let target = Math.round(area2 * rule.density)\n if (rule.maxCount !== undefined) target = Math.min(target, rule.maxCount)\n const prefer = rule.prefer ?? 'any'\n const edgeW = rule.edgeWidth ?? Math.max(0.4, rule.minDistance * 0.8)\n const sc = rule.scale ?? [1, 1]\n let placed = 0\n const attempts = target * 60 + 300\n for (let a = 0; a < attempts && placed < target; a++) {\n const x = rng.range(minX, maxX)\n const z = rng.range(minZ, maxZ)\n const accept = rng.next()\n const spec = pickSpecies(rule, rng)\n const sd = rng.seed()\n const ry = rule.rotate === false ? 0 : Array.isArray(rule.rotate) ? rng.range(rule.rotate[0], rule.rotate[1]) : rng.range(0, TAU)\n const scale = rng.range(sc[0], sc[1])\n if (!pointInPolygon(x, z, poly)) continue\n let blocked = false\n for (const e of ex) {\n if (pointInPolygon(x, z, e)) {\n blocked = true\n break\n }\n }\n if (blocked) continue\n if (prefer !== 'any') {\n const d = distanceToBoundary(x, z, poly)\n const p = prefer === 'edge' ? Math.max(0.02, Math.exp(-d / edgeW)) : Math.max(0.05, clamp(d / inradius, 0, 1))\n if (accept > p) continue\n }\n const cx = Math.floor(x / cell)\n const cz = Math.floor(z / cell)\n let ok = true\n for (let ix = cx - 2; ix <= cx + 2 && ok; ix++) {\n for (let iz = cz - 2; iz <= cz + 2 && ok; iz++) {\n const items = grid.get(key(ix, iz))\n if (!items) continue\n for (const it of items) {\n const need = (it.md + rule.minDistance) / 2\n if ((it.x - x) ** 2 + (it.z - z) ** 2 < need * need) {\n ok = false\n break\n }\n }\n }\n }\n if (!ok) continue\n const k = key(cx, cz)\n const list = grid.get(k)\n if (list) list.push({ x, z, md: rule.minDistance })\n else grid.set(k, [{ x, z, md: rule.minDistance }])\n out.push({ species: spec, x, z, ry, scale, seed: sd })\n placed++\n }\n })\n return out\n}\n","import { GENERATORS } from './generate'\n\nconst ENUMS: Record<string, readonly string[]> = {\n crownShape: ['round', 'spreading', 'columnar', 'weeping'],\n leafShape: ['clump', 'sparse'],\n crownStyle: ['dome', 'lumpy', 'cloud', 'sphere', 'umbrella', 'willow', 'sparse_high'],\n variant: ['coconut', 'royal', 'fan', 'areca', 'date'],\n shape: ['cone', 'candelabra', 'round', 'hedge', 'loose', 'terracotta', 'cylinder', 'square', 'cachepot'],\n flowerType: ['daisy', 'rose', 'tulip', 'sunflower', 'hibiscus', 'cluster', 'lily', 'bird_of_paradise', 'pompom', 'hydrangea'],\n form: ['agave', 'sword', 'aloe', 'echeveria'],\n armStyle: ['candelabra', 'saguaro', 'sprawl'],\n style: ['dots', 'clusters', 'hibiscus', 'bell', 'bract', 'passion'],\n}\nconst POSITIVE = [\n 'height', 'trunkRadius', 'crownRadius', 'radius', 'length', 'width', 'frondLength', 'padSize', 'leafSize', 'flowerSize', 'size', 'tiers', 'ribs', 'branchLevels',\n 'clumpSize', 'frondCount', 'leafCount', 'stemCount', 'stems', 'generations', 'count',\n]\nconst SEASONS = ['spring', 'summer', 'autumn', 'winter']\n\nfunction isColor(v: unknown): boolean {\n return typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 0xffffff\n}\n\n/**\n * Validate a plant spec. Returns a list of problems (empty when valid). It checks the archetype, numeric ranges, enum values,\n * color integers (0xRRGGBB) and nested specs (potted).\n */\nexport function validateSpec(spec: unknown, path = 'spec'): string[] {\n const errors: string[] = []\n if (typeof spec !== 'object' || spec === null || Array.isArray(spec)) return [`${path}: must be an object`]\n const obj = spec as Record<string, unknown>\n if (typeof obj.archetype !== 'string' || !(obj.archetype in GENERATORS)) {\n errors.push(`${path}.archetype: unknown archetype \"${String(obj.archetype)}\"`)\n return errors\n }\n const walk = (o: Record<string, unknown>, p: string): void => {\n for (const [k, v] of Object.entries(o)) {\n const here = `${p}.${k}`\n if (k === 'plant') {\n errors.push(...validateSpec(v, here))\n continue\n }\n if (v === null || v === undefined) continue\n if (/colou?rs?$/i.test(k) && k !== 'colors' && !Array.isArray(v) && typeof v !== 'object') {\n if (!isColor(v)) errors.push(`${here}: must be an integer color 0..0xffffff`)\n } else if (k === 'colors' || k === 'leafColor' || k === 'petalColors') {\n if (Array.isArray(v)) {\n if (v.length === 0) errors.push(`${here}: must not be empty`)\n v.forEach((c, i) => {\n if (!isColor(c)) errors.push(`${here}[${i}]: must be an integer color 0..0xffffff`)\n })\n } else if (k !== 'colors' && !isColor(v)) errors.push(`${here}: must be a color or an array of colors`)\n } else if (k === 'seasons') {\n if (!Array.isArray(v) || v.some((s) => !SEASONS.includes(s as string))) errors.push(`${here}: must be a list of seasons`)\n } else if (k === 'arms') {\n if (!(typeof v === 'number' || (Array.isArray(v) && v.length === 2 && v.every((n) => typeof n === 'number')))) errors.push(`${here}: must be a number or [min, max]`)\n } else if (k === 'host') {\n const h = v as Record<string, unknown>\n if (!('path' in h) && !('wall' in h)) errors.push(`${here}: needs path or wall`)\n } else if (k in ENUMS) {\n if (typeof v === 'string' && !ENUMS[k].includes(v)) errors.push(`${here}: \"${v}\" is not one of ${ENUMS[k].join(', ')}`)\n } else if (POSITIVE.includes(k)) {\n if (typeof v !== 'number' || !Number.isFinite(v) || v <= 0) errors.push(`${here}: must be a positive number`)\n }\n if (typeof v === 'object' && !Array.isArray(v) && k !== 'host') walk(v as Record<string, unknown>, here)\n }\n }\n walk(obj, path)\n return errors\n}\n","import type * as ThreeTypes from 'three'\nimport type { MaterialIds } from '../destruction'\n\n/** The THREE namespace is passed in by the host at runtime (r160). This package only imports its types. */\nexport type ThreeNS = typeof ThreeTypes\nexport type Material = ThreeTypes.Material\n\nexport const MAX_ACTORS = 4\n\nexport interface WindSettings {\n /** world-space direction on the xz plane (normalized internally) */\n direction: [number, number]\n /** 0..1 */\n strength: number\n /** 0..1 slowly varying extra push */\n gust: number\n}\nexport interface ActorInput {\n x: number\n y: number\n z: number\n radius: number\n}\nexport interface MaterialOptions {\n /** override of the destruction SDK material ids written to `userData.destructionMaterial` (see DEFAULT_MATERIAL_IDS) */\n materialIds?: Partial<MaterialIds>\n /** flat shaded foliage (default true) */\n flatShading?: boolean\n roughness?: number\n /** override the alpha cut etc. in the future; currently unused */\n [key: string]: unknown\n}\nexport interface VegetationMaterials {\n /** resolved destruction material ids used by createPlantObject / createLotObject unless they get their own `materialIds` */\n materialIds?: MaterialIds\n wood: ThreeTypes.MeshStandardMaterial\n foliage: ThreeTypes.MeshStandardMaterial\n flowers: ThreeTypes.MeshStandardMaterial\n fruit: ThreeTypes.MeshStandardMaterial\n spines: ThreeTypes.MeshStandardMaterial\n /** advance the wind clock (seconds). Does not allocate. */\n update(timeSeconds: number): void\n setWind(wind: Partial<WindSettings>): void\n /** up to MAX_ACTORS actors bend the vegetation away; extra entries are ignored. Does not allocate. */\n setActors(actors: readonly ActorInput[]): void\n dispose(): void\n}\n","import type { MaterialOptions, ThreeNS, VegetationMaterials, WindSettings, ActorInput } from './types'\nimport { MAX_ACTORS } from './types'\nimport { resolveMaterialIds } from '../destruction'\n\nconst COMMON = /* glsl */ `\n#include <common>\nattribute float sway;\nuniform float uVegTime;\nuniform vec2 uWindDir;\nuniform float uWindStrength;\nuniform float uWindGust;\nuniform vec4 uActors[${MAX_ACTORS}];\nvec3 vegDisplace( vec3 wp, vec3 origin, float s ) {\n float ph = dot( origin.xz, vec2( 1.7, 1.3 ) ) + dot( wp.xz, vec2( 0.35, 0.25 ) );\n float t = uVegTime;\n float w = sin( t * 1.6 + ph ) * 0.6 + sin( t * 3.3 + ph * 1.9 + 1.3 ) * 0.4;\n float g = 0.5 + 0.5 * sin( t * 0.45 + ph * 0.3 );\n float m = s * ( uWindStrength * ( 0.5 + 0.5 * w ) * 0.14 + uWindGust * g * 0.22 );\n float flutter = s * s * uWindStrength * sin( t * 7.0 + ph * 3.1 ) * 0.025;\n wp.xz += uWindDir * ( m + flutter );\n wp.y -= abs( m ) * 0.25;\n for ( int i = 0; i < ${MAX_ACTORS}; i ++ ) {\n vec4 a = uActors[ i ];\n if ( a.w > 0.0 ) {\n vec2 dv = wp.xz - a.xz;\n float d = length( dv );\n float f = ( 1.0 - smoothstep( 0.0, a.w, d ) ) * ( 1.0 - smoothstep( 1.6, 2.4, abs( wp.y - a.y ) ) );\n vec2 away = d > 0.0001 ? dv / d : vec2( 1.0, 0.0 );\n wp.xz += away * f * s * a.w * 0.6;\n wp.y -= f * s * 0.18;\n }\n }\n return wp;\n}\n`\n\nconst PROJECT = /* glsl */ `\nvec4 vegLocal = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n vegLocal = instanceMatrix * vegLocal;\n vec3 vegOrigin = ( modelMatrix * vec4( instanceMatrix[ 3 ].xyz, 1.0 ) ).xyz;\n#else\n vec3 vegOrigin = modelMatrix[ 3 ].xyz;\n#endif\nvec4 vegWorld = modelMatrix * vegLocal;\nvegWorld.xyz = vegDisplace( vegWorld.xyz, vegOrigin, sway );\nvec4 mvPosition = viewMatrix * vegWorld;\ngl_Position = projectionMatrix * mvPosition;\n`\n\n/**\n * Vertex-colored standard materials patched with wind sway (by the `sway` attribute) and actor bend, driven only by\n * shared uniforms: time, wind (direction / strength / gust) and up to 4 actors (vec4 x, y, z, radius).\n */\nexport function createVegetationMaterials(THREE: ThreeNS, opts: MaterialOptions = {}): VegetationMaterials {\n const uniforms = {\n uVegTime: { value: 0 },\n uWindDir: { value: new THREE.Vector2(1, 0.3).normalize() },\n uWindStrength: { value: 0.35 },\n uWindGust: { value: 0.15 },\n uActors: { value: Array.from({ length: MAX_ACTORS }, () => new THREE.Vector4(0, 0, 0, 0)) },\n }\n const patch = (m: InstanceType<ThreeNS['MeshStandardMaterial']>): void => {\n m.onBeforeCompile = (shader) => {\n Object.assign(shader.uniforms, uniforms)\n shader.vertexShader = shader.vertexShader.replace('#include <common>', COMMON).replace('#include <project_vertex>', PROJECT)\n }\n m.customProgramCacheKey = () => 'vegetation-sway-v1'\n }\n const flat = opts.flatShading !== false\n const rough = typeof opts.roughness === 'number' ? opts.roughness : 0.85\n const make = (flatShading: boolean, double: boolean, roughness: number) => {\n const m = new THREE.MeshStandardMaterial({\n vertexColors: true,\n flatShading,\n roughness,\n metalness: 0,\n side: double ? THREE.DoubleSide : THREE.FrontSide,\n })\n patch(m)\n return m\n }\n const wood = make(false, false, 0.95)\n const foliage = make(flat, true, rough)\n const flowers = make(flat, true, 0.7)\n const fruit = make(flat, false, 0.55)\n const spines = make(true, true, 0.8)\n const dir = uniforms.uWindDir.value\n return {\n materialIds: resolveMaterialIds(opts.materialIds),\n wood,\n foliage,\n flowers,\n fruit,\n spines,\n update(t: number) {\n uniforms.uVegTime.value = t\n },\n setWind(w: Partial<WindSettings>) {\n if (w.direction) {\n const l = Math.hypot(w.direction[0], w.direction[1]) || 1\n dir.set(w.direction[0] / l, w.direction[1] / l)\n }\n if (w.strength !== undefined) uniforms.uWindStrength.value = w.strength\n if (w.gust !== undefined) uniforms.uWindGust.value = w.gust\n },\n setActors(actors: readonly ActorInput[]) {\n const arr = uniforms.uActors.value\n for (let i = 0; i < MAX_ACTORS; i++) {\n const a = actors[i]\n if (a) arr[i].set(a.x, a.y, a.z, a.radius)\n else arr[i].set(0, 0, 0, 0)\n }\n },\n dispose() {\n wood.dispose()\n foliage.dispose()\n flowers.dispose()\n fruit.dispose()\n spines.dispose()\n },\n }\n}\n","import type { MeshData, PartKind, Vec3, Placement, PlantMesh, PlantSpec, GenerateOptions } from '../types'\nimport type { Lot } from '../lot'\nimport { extractPlant, hideLotPlant } from '../lot'\nimport { generate } from '../generate'\nimport type { ThreeNS, VegetationMaterials } from './types'\nimport { createVegetationMaterials } from './materials'\nimport { materialKeyForPart, resolveMaterialIds, type MaterialIds } from '../destruction'\nimport type { Condition } from '../types'\n\nimport type { BufferGeometry as Geo } from 'three'\ntype Obj = InstanceType<ThreeNS['Object3D']>\n\nconst PART_ORDER: PartKind[] = ['wood', 'foliage', 'flowers', 'fruit', 'spines']\n\n/** MeshData -> BufferGeometry with attributes position, normal, color, sway. */\nexport function toBufferGeometry(THREE: ThreeNS, mesh: MeshData): Geo {\n const g = new THREE.BufferGeometry()\n g.setAttribute('position', new THREE.BufferAttribute(mesh.positions, 3))\n g.setAttribute('normal', new THREE.BufferAttribute(mesh.normals, 3))\n g.setAttribute('color', new THREE.BufferAttribute(mesh.colors, 3))\n g.setAttribute('sway', new THREE.BufferAttribute(mesh.sway, 1))\n g.setIndex(new THREE.BufferAttribute(mesh.indices, 1))\n g.computeBoundingSphere()\n g.computeBoundingBox()\n return g\n}\n\nfunction inflate(g: Geo, m: number): void {\n // wind and bend move vertices a little outside the static bounds: keep culling safe\n if (g.boundingSphere) g.boundingSphere.radius += m\n}\n\nexport interface DestructionOptions {\n /** override any destruction material id (merged over the materials' own mapping, then DEFAULT_MATERIAL_IDS) */\n materialIds?: Partial<MaterialIds>\n}\nexport interface PlantObjectOptions extends DestructionOptions {\n /**\n * Build one child Mesh per `plant.pieces` entry instead of one per part. Each child is positioned at the piece pivot (so it can\n * fall / rotate about it), carries `userData.destructionPart = { id, kind, parent, material, materialKey }` (wood pieces add `radius`, `length`, `axis`, `base`) and\n * `userData.destructionMaterial`. Default false.\n */\n separable?: boolean\n}\n\nfunction idsFor(mats: VegetationMaterials, o?: DestructionOptions): MaterialIds {\n return resolveMaterialIds({ ...(mats.materialIds ?? {}), ...(o?.materialIds ?? {}) })\n}\n\nfunction meshFor(THREE: ThreeNS, data: MeshData, material: unknown, ids?: MaterialIds, condition?: Condition): InstanceType<ThreeNS['Mesh']> {\n const geo = toBufferGeometry(THREE, data)\n inflate(geo, 0.4)\n const mesh = new THREE.Mesh(geo, material as InstanceType<ThreeNS['Material']>)\n mesh.name = data.kind\n mesh.userData.damageable = { material: data.material }\n if (ids) mesh.userData.destructionMaterial = ids[materialKeyForPart(data.kind, data.material, condition)]\n return mesh\n}\n\n/** Copy the triangles of one index range into their own compact MeshData, moved by -origin. */\nexport function slicePiece(mesh: MeshData, indexStart: number, indexCount: number, origin: Vec3): MeshData {\n const remap = new Map<number, number>()\n const order: number[] = []\n const indices = new Uint32Array(indexCount)\n for (let i = 0; i < indexCount; i++) {\n const v = mesh.indices[indexStart + i]\n let n = remap.get(v)\n if (n === undefined) {\n n = order.length\n remap.set(v, n)\n order.push(v)\n }\n indices[i] = n\n }\n const positions = new Float32Array(order.length * 3)\n const normals = new Float32Array(order.length * 3)\n const colors = new Float32Array(order.length * 3)\n const sway = new Float32Array(order.length)\n for (let i = 0; i < order.length; i++) {\n const v = order[i]\n positions[i * 3] = mesh.positions[v * 3] - origin[0]\n positions[i * 3 + 1] = mesh.positions[v * 3 + 1] - origin[1]\n positions[i * 3 + 2] = mesh.positions[v * 3 + 2] - origin[2]\n normals.set(mesh.normals.subarray(v * 3, v * 3 + 3), i * 3)\n colors.set(mesh.colors.subarray(v * 3, v * 3 + 3), i * 3)\n sway[i] = mesh.sway[v]\n }\n return { positions, normals, colors, sway, indices, triangleCount: indexCount / 3, kind: mesh.kind, material: mesh.material }\n}\n\n/** One Mesh per part. userData: collider, bendable, thorny, species, bounds. */\nexport function createPlantObject(THREE: ThreeNS, plant: PlantMesh, materials?: VegetationMaterials, options: PlantObjectOptions = {}): InstanceType<ThreeNS['Group']> {\n const mats = materials ?? createVegetationMaterials(THREE)\n const ids = idsFor(mats, options)\n const g = new THREE.Group()\n g.name = plant.species\n if (options.separable) {\n for (const pc of plant.pieces) {\n const src = plant.parts[pc.part]\n if (!src) continue\n const data = slicePiece(src, pc.indexStart, pc.indexCount, pc.pivot)\n const mesh = meshFor(THREE, data, mats[pc.part])\n mesh.name = pc.id\n mesh.position.set(pc.pivot[0], pc.pivot[1], pc.pivot[2])\n const id = ids[pc.material]\n mesh.userData.destructionMaterial = id\n mesh.userData.destructionPart = { id: pc.id, kind: pc.kind, parent: pc.parent, material: id, materialKey: pc.material, ...(pc.radius === undefined ? {} : { radius: pc.radius, length: pc.length, axis: pc.axis, base: pc.base }) }\n g.add(mesh)\n }\n g.userData = { collider: plant.collider, bendable: plant.bendable, thorny: plant.thorny, species: plant.species, bounds: plant.bounds, pieces: plant.pieces, separable: true }\n return g\n }\n for (const kind of PART_ORDER) {\n const data = plant.parts[kind]\n if (!data) continue\n g.add(meshFor(THREE, data, mats[kind], ids, plant.condition))\n }\n g.userData = { collider: plant.collider, bendable: plant.bendable, thorny: plant.thorny, species: plant.species, bounds: plant.bounds, damageable: { material: plant.parts.wood?.material ?? 'foliage' }, destructionMaterial: ids[materialKeyForPart(plant.parts.wood ? 'wood' : 'foliage', plant.parts.wood?.material ?? 'foliage', plant.condition)] }\n return g\n}\n\n/** A merged lot: at most 3 meshes. userData: colliders, triangleCount. */\nexport function createLotObject(THREE: ThreeNS, lot: Lot, materials?: VegetationMaterials, options: DestructionOptions = {}): InstanceType<ThreeNS['Group']> {\n const mats = materials ?? createVegetationMaterials(THREE)\n const ids = idsFor(mats, options)\n const g = new THREE.Group()\n g.name = 'vegetation-lot'\n const { wood, foliage, flowers } = lot.meshes\n if (wood) g.add(meshFor(THREE, wood, mats.wood, ids, lot.condition))\n if (foliage) g.add(meshFor(THREE, foliage, mats.foliage, ids, lot.condition))\n if (flowers) g.add(meshFor(THREE, flowers, mats.flowers, ids, lot.condition))\n g.userData = { colliders: lot.colliders, triangleCount: lot.triangleCount, materialIds: ids }\n return g\n}\n\n/**\n * Swap one merged plant of a lot for its separable version: its triangles are hidden in the lot meshes (`lotObject` is the result\n * of createLotObject for `lot`) and a Group with one child per piece is returned, already placed (position, rotation.y, scale).\n * Add it to the scene yourself.\n */\nexport function separatePlantFromLot(THREE: ThreeNS, lot: Lot, lotObject: Obj, plantIndex: number, materials?: VegetationMaterials, options: DestructionOptions = {}): InstanceType<ThreeNS['Group']> {\n const { plant, placement } = extractPlant(lot, plantIndex)\n hideLotPlant(lot, plantIndex)\n lotObject.traverse((o) => {\n const geo = (o as InstanceType<ThreeNS['Mesh']>).geometry as Geo | undefined\n if (geo?.index) geo.index.needsUpdate = true\n })\n const obj = createPlantObject(THREE, plant, materials, { ...options, separable: true })\n obj.position.set(placement.x, 0, placement.z)\n obj.rotation.y = placement.ry\n obj.scale.setScalar(placement.scale)\n obj.userData.plantIndex = plantIndex\n return obj\n}\n\n/** InstancedMesh per part for many copies of one plant (grass, flowers, hedges). Wind phase varies per instance. */\nexport function createInstancedPlants(THREE: ThreeNS, plant: PlantMesh, placements: readonly Placement[], materials?: VegetationMaterials, options: PlantObjectOptions = {}): InstanceType<ThreeNS['Group']> {\n const mats = materials ?? createVegetationMaterials(THREE)\n const ids = idsFor(mats, options)\n const g = new THREE.Group()\n g.name = plant.species + '-instanced'\n const pos = new THREE.Vector3()\n const quat = new THREE.Quaternion()\n const scl = new THREE.Vector3()\n const up = new THREE.Vector3(0, 1, 0)\n const m4 = new THREE.Matrix4()\n for (const kind of PART_ORDER) {\n const data = plant.parts[kind]\n if (!data) continue\n const geo = toBufferGeometry(THREE, data)\n const im = new THREE.InstancedMesh(geo, mats[kind], Math.max(1, placements.length))\n im.count = placements.length\n for (let i = 0; i < placements.length; i++) {\n const p = placements[i]\n pos.set(p.x, 0, p.z)\n quat.setFromAxisAngle(up, p.ry)\n scl.setScalar(p.scale)\n m4.compose(pos, quat, scl)\n im.setMatrixAt(i, m4)\n }\n im.instanceMatrix.needsUpdate = true\n im.computeBoundingSphere()\n im.frustumCulled = false\n im.name = kind\n im.userData.damageable = { material: data.material }\n im.userData.destructionMaterial = ids[materialKeyForPart(data.kind, data.material, plant.condition)]\n g.add(im)\n }\n g.userData = { collider: plant.collider, bendable: plant.bendable, species: plant.species, count: placements.length }\n return g\n}\n\nexport interface LodObjectOptions extends GenerateOptions {\n /** distances at which lod 0 / 1 / 2 start (default 0, 25, 60) */\n distances?: [number, number, number]\n materials?: VegetationMaterials\n species?: string\n}\n\n/** THREE.LOD with the three LODs of a plant. */\nexport function lodObject(THREE: ThreeNS, spec: PlantSpec, opts: LodObjectOptions = {}): InstanceType<ThreeNS['LOD']> {\n const mats = opts.materials ?? createVegetationMaterials(THREE)\n const d = opts.distances ?? [0, 25, 60]\n const lod = new THREE.LOD()\n for (const l of [0, 1, 2] as const) {\n const plant = generate(spec, { ...opts, lod: l })\n lod.addLevel(createPlantObject(THREE, plant, mats) as Obj, d[l])\n }\n lod.userData = { collider: generate(spec, { ...opts, lod: 2 }).collider }\n return lod\n}\n","[\n {\n \"id\": \"mango_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 8.5,\n \"trunkRadius\": 0.34,\n \"crownRadius\": 4.6,\n \"crownShape\": \"spreading\",\n \"branchLevels\": 3,\n \"leafColor\": [\n \"#1f5a2a\",\n \"#2a6a30\",\n \"#2f7434\"\n ],\n \"barkColor\": \"#5a4030\",\n \"fruit\": {\n \"colors\": [\n \"#e8a02a\",\n \"#d9602d\",\n \"#c8d04a\",\n \"#e8c040\"\n ],\n \"count\": 16,\n \"radius\": 0.17\n },\n \"crownStyle\": \"dome\",\n \"trunkFraction\": 0.34\n },\n \"tags\": [\n \"tree\",\n \"fruit\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"yellow_ipe\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 9.5,\n \"trunkRadius\": 0.26,\n \"crownRadius\": 3.5,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.3,\n \"leafColor\": [\n \"#5aa045\",\n \"#4a9040\",\n \"#68ac4c\"\n ],\n \"barkColor\": \"#7a6a58\",\n \"bloom\": {\n \"colors\": [\n \"#f4c81e\",\n \"#f6d43a\",\n \"#ecb818\"\n ],\n \"seasons\": [\n \"winter\",\n \"spring\"\n ],\n \"replacesLeaves\": true,\n \"density\": 1\n },\n \"crownStyle\": \"dome\",\n \"clumpSize\": 0.95\n },\n \"tags\": [\n \"tree\",\n \"flowering\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"pink_ipe\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 9.5,\n \"trunkRadius\": 0.27,\n \"crownRadius\": 3.5,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.3,\n \"leafColor\": [\n \"#5aa045\",\n \"#4a9040\",\n \"#68ac4c\"\n ],\n \"barkColor\": \"#7d6e5c\",\n \"bloom\": {\n \"colors\": [\n \"#d86aa8\",\n \"#e88ac0\",\n \"#c2549a\"\n ],\n \"seasons\": [\n \"winter\",\n \"spring\"\n ],\n \"replacesLeaves\": true,\n \"density\": 1\n },\n \"crownStyle\": \"dome\",\n \"clumpSize\": 0.95\n },\n \"tags\": [\n \"tree\",\n \"flowering\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"jabuticaba_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 5,\n \"trunkRadius\": 0.2,\n \"crownRadius\": 2.4,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.34,\n \"branchLevels\": 3,\n \"leafColor\": [\n \"#2e6e34\",\n \"#3a7a3a\",\n \"#357a38\"\n ],\n \"barkColor\": \"#b8a68c\",\n \"fruit\": {\n \"colors\": [\n \"#6e2c92\",\n \"#7d3aa4\",\n \"#5e2480\"\n ],\n \"count\": 380,\n \"radius\": 0.085,\n \"onTrunk\": true\n },\n \"crownStyle\": \"cloud\",\n \"clumpSize\": 0.95\n },\n \"tags\": [\n \"tree\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"flamboyant\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 8,\n \"trunkRadius\": 0.3,\n \"crownRadius\": 5.8,\n \"crownShape\": \"spreading\",\n \"trunkFraction\": 0.44,\n \"leafColor\": [\n \"#6aa84a\",\n \"#7ab858\",\n \"#5a9a42\"\n ],\n \"barkColor\": \"#7a6a58\",\n \"bloom\": {\n \"colors\": [\n \"#e0361e\",\n \"#ec5a22\",\n \"#d02a1c\"\n ],\n \"seasons\": [\n \"spring\",\n \"summer\"\n ],\n \"replacesLeaves\": true,\n \"density\": 0.78\n },\n \"crownStyle\": \"umbrella\"\n },\n \"tags\": [\n \"tree\",\n \"flowering\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"guava_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 4.8,\n \"trunkRadius\": 0.15,\n \"crownRadius\": 2.6,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.3,\n \"leafColor\": [\n \"#74ae4c\",\n \"#82ba56\",\n \"#68a248\"\n ],\n \"barkColor\": \"#b28c6c\",\n \"fruit\": {\n \"colors\": [\n \"#d8e070\",\n \"#e8d450\",\n \"#c8dc5a\"\n ],\n \"count\": 10,\n \"radius\": 0.075\n },\n \"crownStyle\": \"cloud\"\n },\n \"tags\": [\n \"tree\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"avocado_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 8.5,\n \"trunkRadius\": 0.26,\n \"crownRadius\": 3.0,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.34,\n \"leafColor\": [\n \"#1c5628\",\n \"#266432\",\n \"#215e2c\"\n ],\n \"barkColor\": \"#6a5444\",\n \"fruit\": {\n \"colors\": [\n \"#1e2e14\",\n \"#2c3c1a\",\n \"#3a4a22\"\n ],\n \"count\": 10,\n \"radius\": 0.1\n },\n \"crownStyle\": \"cloud\"\n },\n \"tags\": [\n \"tree\",\n \"fruit\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"lemon_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 3.6,\n \"trunkRadius\": 0.13,\n \"crownRadius\": 2.1,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.28,\n \"leafColor\": [\n \"#70bc4a\",\n \"#80c856\",\n \"#62ac42\"\n ],\n \"barkColor\": \"#7a6a52\",\n \"fruit\": {\n \"colors\": [\n \"#f6dc2c\",\n \"#f0d020\",\n \"#f8e450\"\n ],\n \"count\": 18,\n \"radius\": 0.075\n },\n \"crownStyle\": \"cloud\"\n },\n \"tags\": [\n \"tree\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"pitanga_bush_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 3.4,\n \"trunkRadius\": 0.1,\n \"crownRadius\": 1.9,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.22,\n \"branchLevels\": 3,\n \"leafColor\": [\n \"#5eaa44\",\n \"#6eb850\",\n \"#80c45c\"\n ],\n \"barkColor\": \"#8a6a50\",\n \"fruit\": {\n \"colors\": [\n \"#d82a1a\",\n \"#e8501e\",\n \"#c01a18\"\n ],\n \"count\": 40,\n \"radius\": 0.04\n },\n \"crownStyle\": \"cloud\"\n },\n \"tags\": [\n \"tree\",\n \"fruit\",\n \"hedge\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"sidewalk_ficus\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 7,\n \"trunkRadius\": 0.22,\n \"crownRadius\": 2.6,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.5,\n \"clipped\": true,\n \"leafColor\": [\n \"#1e6428\",\n \"#256c2e\",\n \"#206028\"\n ],\n \"barkColor\": \"#9a8a78\",\n \"crownStyle\": \"sphere\"\n },\n \"tags\": [\n \"tree\",\n \"street\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"oak_like\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 10,\n \"trunkRadius\": 0.45,\n \"crownRadius\": 5,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.3,\n \"deciduous\": true,\n \"leafColor\": [\n \"#4a8a38\",\n \"#5e9c3e\",\n \"#72a032\",\n \"#3a7a34\"\n ],\n \"barkColor\": \"#5a4636\",\n \"crownStyle\": \"lumpy\"\n },\n \"tags\": [\n \"tree\",\n \"shade\"\n ],\n \"climate\": [\n \"temperate\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"weeping_willow\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 11.5,\n \"trunkRadius\": 0.34,\n \"crownRadius\": 4.3,\n \"crownShape\": \"weeping\",\n \"trunkFraction\": 0.28,\n \"deciduous\": true,\n \"leafColor\": [\n \"#8ab040\",\n \"#9ac053\",\n \"#7aa238\"\n ],\n \"barkColor\": \"#4a3c30\",\n \"crownStyle\": \"willow\"\n },\n \"tags\": [\n \"tree\",\n \"shade\"\n ],\n \"climate\": [\n \"temperate\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"araucaria\",\n \"archetype\": \"conifer\",\n \"params\": {\n \"shape\": \"candelabra\",\n \"height\": 16,\n \"radius\": 5,\n \"tiers\": 6,\n \"trunkRadius\": 0.3,\n \"leafColor\": \"#3d6e3a\",\n \"barkColor\": \"#5a4838\"\n },\n \"tags\": [\n \"tree\",\n \"conifer\"\n ],\n \"climate\": [\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"pine\",\n \"archetype\": \"conifer\",\n \"params\": {\n \"shape\": \"cone\",\n \"height\": 12,\n \"radius\": 2.8,\n \"tiers\": 10,\n \"trunkRadius\": 0.26,\n \"leafColor\": \"#37803f\",\n \"barkColor\": \"#6b4b34\"\n },\n \"tags\": [\n \"tree\",\n \"conifer\"\n ],\n \"climate\": [\n \"temperate\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"eucalyptus\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 16,\n \"trunkRadius\": 0.45,\n \"crownRadius\": 4.2,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.58,\n \"leafColor\": [\n \"#8c9f6a\",\n \"#7d9460\",\n \"#9aab74\"\n ],\n \"barkColor\": \"#a89a82\",\n \"crownStyle\": \"sparse_high\"\n },\n \"tags\": [\n \"tree\",\n \"street\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"dead_tree\",\n \"archetype\": \"dead_tree\",\n \"params\": {\n \"height\": 6,\n \"trunkRadius\": 0.24,\n \"crownRadius\": 2.4\n },\n \"tags\": [\n \"tree\",\n \"dead\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n }\n]\n","[\n {\n \"id\": \"coconut_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"coconut\",\n \"height\": 7.5,\n \"trunkRadius\": 0.2,\n \"frondCount\": 18,\n \"frondLength\": 3.4,\n \"fruit\": {\n \"color\": \"#6f8a2e\",\n \"count\": 9,\n \"radius\": 0.14\n }\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"royal_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"royal\",\n \"height\": 12,\n \"trunkRadius\": 0.28,\n \"frondCount\": 16,\n \"frondLength\": 4.6\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"street\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"fan_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"fan\",\n \"height\": 3.2,\n \"trunkRadius\": 0.2,\n \"frondCount\": 10,\n \"frondLength\": 2.3\n },\n \"tags\": [\n \"tree\",\n \"palm\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"areca_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"areca\",\n \"height\": 2.8,\n \"stems\": 7,\n \"trunkRadius\": 0.03\n },\n \"tags\": [\n \"palm\",\n \"shrub\",\n \"indoor\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"date_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"date\",\n \"height\": 6.5,\n \"trunkRadius\": 0.26,\n \"fruit\": {\n \"color\": \"#e8902a\",\n \"count\": 22,\n \"radius\": 0.03\n }\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"fruit\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"banana_plant\",\n \"archetype\": \"banana\",\n \"params\": {\n \"height\": 3.8,\n \"leafCount\": 8\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"tropical\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"banana_with_bunch\",\n \"archetype\": \"banana\",\n \"params\": {\n \"height\": 3.8,\n \"leafCount\": 8,\n \"bunch\": true,\n \"bud\": true\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"fruit\",\n \"tropical\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n }\n]\n","[\n {\n \"id\": \"boxwood_hedge\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"hedge\",\n \"length\": 2.4,\n \"height\": 1.0,\n \"width\": 0.65,\n \"leafColor\": [\n \"#347a3a\"\n ]\n },\n \"tags\": [\n \"shrub\",\n \"hedge\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"ixora_hedge\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"hedge\",\n \"length\": 2.4,\n \"height\": 1.1,\n \"width\": 0.7,\n \"leafColor\": [\n \"#2e6e34\"\n ],\n \"flowers\": {\n \"colors\": [\n \"#d8281e\",\n \"#e04a2a\"\n ],\n \"count\": 20,\n \"style\": \"dots\",\n \"size\": 0.05\n }\n },\n \"tags\": [\n \"shrub\",\n \"hedge\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"hibiscus_shrub\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"round\",\n \"radius\": 0.85,\n \"height\": 1.7,\n \"leafColor\": [\n \"#2f7a35\",\n \"#3a8a3a\"\n ],\n \"flowers\": {\n \"colors\": [\n \"#e0243a\",\n \"#f06a8a\"\n ],\n \"count\": 9,\n \"style\": \"hibiscus\",\n \"size\": 0.07\n }\n },\n \"tags\": [\n \"shrub\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"bougainvillea\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"loose\",\n \"radius\": 1.1,\n \"height\": 1.8,\n \"leafColor\": [\n \"#3f8a3a\",\n \"#4a9a42\"\n ],\n \"flowers\": {\n \"colors\": [\n \"#c8208a\",\n \"#d8409a\",\n \"#e060a8\"\n ],\n \"count\": 70,\n \"style\": \"clusters\",\n \"size\": 0.06\n }\n },\n \"tags\": [\n \"shrub\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"azalea\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"round\",\n \"radius\": 0.6,\n \"height\": 0.8,\n \"leafColor\": [\n \"#356e38\",\n \"#3f7a3e\"\n ],\n \"flowers\": {\n \"colors\": [\n \"#e870a8\",\n \"#f0a0c8\"\n ],\n \"count\": 60,\n \"style\": \"dots\",\n \"size\": 0.05\n }\n },\n \"tags\": [\n \"shrub\",\n \"flowering\"\n ],\n \"climate\": [\n \"temperate\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"croton\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"round\",\n \"radius\": 0.55,\n \"height\": 1.0,\n \"leafColor\": [\n \"#2f7a35\",\n \"#3a8a3a\"\n ],\n \"variegation\": [\n \"#f0c020\",\n \"#d84020\",\n \"#2f7a35\",\n \"#e88a20\"\n ],\n \"leafSize\": 1.2\n },\n \"tags\": [\n \"shrub\",\n \"ornamental\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"lady_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"fan\",\n \"stems\": 7,\n \"height\": 2.4,\n \"trunkRadius\": 0.025,\n \"frondLength\": 0.9,\n \"frondCount\": 3,\n \"trunkColor\": \"#6a5a3a\",\n \"lean\": 0.24\n },\n \"tags\": [\n \"palm\",\n \"shrub\",\n \"indoor\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"generic_round_shrub\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"round\",\n \"radius\": 0.7,\n \"height\": 1.0\n },\n \"tags\": [\n \"shrub\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"overgrown_bush\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"loose\",\n \"radius\": 1.0,\n \"height\": 1.5,\n \"density\": 1.3,\n \"leafColor\": [\n \"#3a7a34\",\n \"#2f6a30\",\n \"#4a8a3a\"\n ]\n },\n \"tags\": [\n \"shrub\",\n \"neglected\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"m\",\n \"solid\": false\n }\n]\n","[\n {\n \"id\": \"rose_bush_red\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"rose\",\n \"petalColors\": [\n \"#d0243a\"\n ],\n \"height\": 0.95\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"rose_bush_pink\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"rose\",\n \"petalColors\": [\n \"#f08ab0\"\n ],\n \"height\": 0.95\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"rose_bush_white\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"rose\",\n \"petalColors\": [\n \"#f6f0e6\"\n ],\n \"height\": 0.95\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"sunflower\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"sunflower\"\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"daisy\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"daisy\"\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"tulip\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"tulip\",\n \"petalColors\": [\n \"#e03a52\",\n \"#e8c020\",\n \"#f08ab0\"\n ]\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"lily\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"lily\"\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"marigold\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"pompom\",\n \"petalColors\": [\n \"#f08a1a\",\n \"#f5b020\",\n \"#e8701a\"\n ],\n \"height\": 0.34,\n \"stemCount\": 10\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"periwinkle_pink\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"daisy\",\n \"spreading\": true,\n \"petalColors\": [\n \"#f0a0c8\"\n ],\n \"height\": 0.24,\n \"stemCount\": 11,\n \"flowerSize\": 0.024\n },\n \"tags\": [\n \"flower\",\n \"flowering\",\n \"ground\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"periwinkle_white\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"daisy\",\n \"spreading\": true,\n \"petalColors\": [\n \"#f6f2ea\"\n ],\n \"height\": 0.24,\n \"stemCount\": 11,\n \"flowerSize\": 0.024\n },\n \"tags\": [\n \"flower\",\n \"flowering\",\n \"ground\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"hydrangea\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"hydrangea\",\n \"petalColors\": [\n \"#5a84d8\",\n \"#8aa8e8\",\n \"#9a90e0\"\n ],\n \"height\": 1.2,\n \"stemCount\": 6\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"temperate\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"bird_of_paradise\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"bird_of_paradise\"\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"wild_flowers\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"daisy\",\n \"petalColors\": [\n \"#f5f0e0\",\n \"#f08ab0\",\n \"#f2c230\",\n \"#a070e0\"\n ],\n \"stemCount\": 12,\n \"height\": 0.45\n },\n \"tags\": [\n \"flower\",\n \"flowering\",\n \"ground\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n }\n]\n","[\n {\n \"id\": \"mandacaru\",\n \"archetype\": \"columnar_cactus\",\n \"params\": {\n \"height\": 4.6,\n \"ribs\": 6,\n \"armStyle\": \"candelabra\",\n \"arms\": [\n 4,\n 6\n ],\n \"color\": \"#5a9a88\",\n \"spineColor\": \"#cdbf94\",\n \"flowers\": {\n \"color\": \"#fdf8f0\",\n \"count\": 1\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"semiarid\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"saguaro\",\n \"archetype\": \"columnar_cactus\",\n \"params\": {\n \"height\": 5.2,\n \"ribs\": 12,\n \"armStyle\": \"saguaro\",\n \"arms\": 2,\n \"color\": \"#5f9a62\"\n },\n \"tags\": [\n \"cactus\",\n \"spiny\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"xique_xique\",\n \"archetype\": \"columnar_cactus\",\n \"params\": {\n \"height\": 1.4,\n \"radius\": 0.07,\n \"ribs\": 6,\n \"armStyle\": \"sprawl\",\n \"arms\": [\n 5,\n 7\n ],\n \"color\": \"#7aa890\"\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"semiarid\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"prickly_pear\",\n \"archetype\": \"paddle_cactus\",\n \"params\": {\n \"fruit\": {\n \"color\": \"#c83a4a\",\n \"count\": 7\n },\n \"flowers\": {\n \"color\": \"#f2c230\",\n \"count\": 3\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"semiarid\",\n \"fruit\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"crown_cactus\",\n \"archetype\": \"globe_cactus\",\n \"params\": {\n \"radius\": 0.22,\n \"height\": 0.5,\n \"ribs\": 12,\n \"cephalium\": {\n \"color\": \"#c8305a\"\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"semiarid\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"barrel_cactus\",\n \"archetype\": \"globe_cactus\",\n \"params\": {\n \"radius\": 0.4,\n \"ribs\": 16,\n \"height\": 0.8,\n \"flowers\": {\n \"color\": \"#f2c230\",\n \"count\": 8\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"small_cactus\",\n \"archetype\": \"globe_cactus\",\n \"params\": {\n \"radius\": 0.09,\n \"height\": 0.14,\n \"ribs\": 10,\n \"flowers\": {\n \"color\": \"#f080b0\",\n \"count\": 5\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"indoor\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n }\n]\n","[\n {\n \"id\": \"snake_plant\",\n \"archetype\": \"rosette\",\n \"params\": {\n \"form\": \"sword\",\n \"height\": 0.9\n },\n \"tags\": [\n \"succulent\",\n \"indoor\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"agave\",\n \"archetype\": \"rosette\",\n \"params\": {\n \"form\": \"agave\",\n \"height\": 1.0\n },\n \"tags\": [\n \"succulent\",\n \"semiarid\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"aloe_vera\",\n \"archetype\": \"rosette\",\n \"params\": {\n \"form\": \"aloe\",\n \"height\": 0.55,\n \"bloom\": {\n \"color\": \"#e8702a\"\n }\n },\n \"tags\": [\n \"succulent\",\n \"indoor\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"echeveria\",\n \"archetype\": \"rosette\",\n \"params\": {\n \"form\": \"echeveria\",\n \"height\": 0.14\n },\n \"tags\": [\n \"succulent\",\n \"indoor\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n }\n]\n","[\n {\n \"id\": \"lawn_tuft\",\n \"archetype\": \"grass_tuft\",\n \"params\": {\n \"count\": 46,\n \"height\": 0.3,\n \"color\": \"#6aa646\"\n },\n \"tags\": [\n \"ground\",\n \"grass\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"wild_grass_tall\",\n \"archetype\": \"grass_tuft\",\n \"params\": {\n \"count\": 30,\n \"height\": 0.9,\n \"color\": \"#9ab05a\",\n \"seedHeads\": true\n },\n \"tags\": [\n \"ground\",\n \"grass\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"weeds\",\n \"archetype\": \"grass_tuft\",\n \"params\": {\n \"count\": 30,\n \"height\": 0.5,\n \"color\": \"#7a9a4a\",\n \"radius\": 0.3\n },\n \"tags\": [\n \"ground\",\n \"grass\",\n \"neglected\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"papyrus\",\n \"archetype\": \"grass_tuft\",\n \"params\": {\n \"count\": 30,\n \"height\": 1.8,\n \"color\": \"#5f9a44\",\n \"umbrellaHeads\": true,\n \"radius\": 0.55\n },\n \"tags\": [\n \"ground\",\n \"grass\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"fern\",\n \"archetype\": \"fern\",\n \"params\": {},\n \"tags\": [\n \"ground\",\n \"fern\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"boston_fern\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"cachepot\",\n \"radius\": 0.22,\n \"height\": 0.3,\n \"color\": \"#d8d0bc\"\n },\n \"plant\": {\n \"archetype\": \"fern\",\n \"frondCount\": 16,\n \"frondLength\": 0.85\n }\n },\n \"tags\": [\n \"ground\",\n \"fern\",\n \"potted\",\n \"indoor\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": true\n }\n]\n","[\n {\n \"id\": \"bougainvillea_vine\",\n \"archetype\": \"vine\",\n \"params\": {\n \"host\": {\n \"wall\": {\n \"width\": 2.6,\n \"height\": 2.4\n }\n },\n \"leafColor\": \"#3f8a3a\",\n \"flowers\": {\n \"colors\": [\n \"#c8208a\",\n \"#d8409a\",\n \"#e060a8\"\n ],\n \"style\": \"bract\",\n \"count\": 18\n }\n },\n \"tags\": [\n \"vine\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"ivy\",\n \"archetype\": \"vine\",\n \"params\": {\n \"host\": {\n \"wall\": {\n \"width\": 2.6,\n \"height\": 2.4\n }\n },\n \"leafColor\": \"#2f6e34\",\n \"leafSize\": 0.9,\n \"density\": 1.4\n },\n \"tags\": [\n \"vine\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"passion_fruit_vine\",\n \"archetype\": \"vine\",\n \"params\": {\n \"host\": {\n \"wall\": {\n \"width\": 2.6,\n \"height\": 2.4\n }\n },\n \"leafColor\": \"#4a9a40\",\n \"leafSize\": 1.2,\n \"flowers\": {\n \"colors\": [\n \"#f6f0f8\",\n \"#c8b0e0\",\n \"#6a3a9a\"\n ],\n \"style\": \"passion\",\n \"count\": 8\n }\n },\n \"tags\": [\n \"vine\",\n \"flowering\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n }\n]\n","[\n {\n \"id\": \"potted_fern\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"terracotta\",\n \"radius\": 0.2,\n \"height\": 0.3\n },\n \"plant\": {\n \"archetype\": \"fern\",\n \"frondCount\": 12,\n \"frondLength\": 0.65\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"fern\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_snake_plant\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"cylinder\",\n \"radius\": 0.17,\n \"height\": 0.28,\n \"color\": \"#6a6e72\"\n },\n \"plant\": {\n \"archetype\": \"rosette\",\n \"form\": \"sword\",\n \"height\": 0.8\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"succulent\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_areca\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"cachepot\",\n \"radius\": 0.27,\n \"height\": 0.38\n },\n \"plant\": {\n \"archetype\": \"palm\",\n \"variant\": \"areca\",\n \"height\": 1.6,\n \"stems\": 6,\n \"trunkRadius\": 0.02,\n \"frondLength\": 1.0\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"palm\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_cactus\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"terracotta\",\n \"radius\": 0.12,\n \"height\": 0.16\n },\n \"plant\": {\n \"archetype\": \"globe_cactus\",\n \"radius\": 0.1,\n \"height\": 0.18,\n \"ribs\": 11,\n \"flowers\": {\n \"color\": \"#f080b0\",\n \"count\": 4\n }\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"cactus\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_rose\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"terracotta\",\n \"radius\": 0.22,\n \"height\": 0.32\n },\n \"plant\": {\n \"archetype\": \"flower_plant\",\n \"flowerType\": \"rose\",\n \"petalColors\": [\n \"#e0405a\"\n ],\n \"height\": 0.6,\n \"stemCount\": 5\n }\n },\n \"tags\": [\n \"potted\",\n \"flowering\",\n \"flower\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_succulents\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"cachepot\",\n \"radius\": 0.14,\n \"height\": 0.14,\n \"color\": \"#e8e2d4\"\n },\n \"plant\": {\n \"archetype\": \"rosette\",\n \"form\": \"echeveria\",\n \"height\": 0.12\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"succulent\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n }\n]\n","{\n \"mango_tree\": {\n \"name\": \"Mangueira\",\n \"description\": \"Copa larga e sombreada com mangas penduradas.\"\n },\n \"yellow_ipe\": {\n \"name\": \"Ipê-amarelo\",\n \"description\": \"Verde no verão, copa coberta de flores amarelas na seca.\"\n },\n \"pink_ipe\": {\n \"name\": \"Ipê-roxo\",\n \"description\": \"Verde no verão, copa coberta de flores rosa na seca.\"\n },\n \"jabuticaba_tree\": {\n \"name\": \"Jabuticabeira\",\n \"description\": \"Árvore densa e pequena com frutos escuros brotando direto do tronco.\"\n },\n \"flamboyant\": {\n \"name\": \"Flamboyant\",\n \"description\": \"Copa em guarda-chuva coberta de flores vermelhas.\"\n },\n \"guava_tree\": {\n \"name\": \"Goiabeira\",\n \"description\": \"Árvore pequena e retorcida, casca lisa avermelhada e frutos redondos.\"\n },\n \"avocado_tree\": {\n \"name\": \"Abacateiro\",\n \"description\": \"Árvore alta de folhagem escura com frutos em forma de pera.\"\n },\n \"lemon_tree\": {\n \"name\": \"Limoeiro\",\n \"description\": \"Árvore pequena de quintal com limões amarelos.\"\n },\n \"pitanga_bush_tree\": {\n \"name\": \"Pitangueira\",\n \"description\": \"Árvore baixa e ramificada coberta de frutinhas vermelhas.\"\n },\n \"sidewalk_ficus\": {\n \"name\": \"Ficus de calçada\",\n \"description\": \"Copa redonda e podada, típica de calçadas.\"\n },\n \"oak_like\": {\n \"name\": \"Árvore de folha larga\",\n \"description\": \"Árvore de sombra genérica que muda com as estações.\"\n },\n \"weeping_willow\": {\n \"name\": \"Salgueiro-chorão\",\n \"description\": \"Cortinas caídas de folhas verde-claras.\"\n },\n \"araucaria\": {\n \"name\": \"Araucária\",\n \"description\": \"Tronco alto e limpo com copa em candelabro de ramos erguidos.\"\n },\n \"pine\": {\n \"name\": \"Pinheiro\",\n \"description\": \"Conífera cônica com camadas caídas.\"\n },\n \"eucalyptus\": {\n \"name\": \"Eucalipto\",\n \"description\": \"Árvore muito alta de casca clara e copa rala.\"\n },\n \"dead_tree\": {\n \"name\": \"Árvore morta\",\n \"description\": \"Tronco torcido e sem folhas, com galhos quebrados.\"\n },\n \"coconut_palm\": {\n \"name\": \"Coqueiro\",\n \"description\": \"Tronco curvo e inclinado, copa de frondes longas e cocos.\"\n },\n \"royal_palm\": {\n \"name\": \"Palmeira-imperial\",\n \"description\": \"Tronco reto, liso e cinza, com bainha verde sob a copa.\"\n },\n \"fan_palm\": {\n \"name\": \"Palmeira-leque\",\n \"description\": \"Tronco curto e grosso com frondes redondas em leque.\"\n },\n \"areca_palm\": {\n \"name\": \"Palmeira-areca\",\n \"description\": \"Palmeira em touceira com muitas hastes finas e frondes plumosas.\"\n },\n \"date_palm\": {\n \"name\": \"Tamareira\",\n \"description\": \"Tronco áspero, frondes rígidas e eretas e cachos de tâmaras.\"\n },\n \"banana_plant\": {\n \"name\": \"Bananeira\",\n \"description\": \"Falso tronco com folhas enormes, algumas rasgadas.\"\n },\n \"banana_with_bunch\": {\n \"name\": \"Bananeira com cacho\",\n \"description\": \"Bananeira com um cacho pendente e o coração roxo.\"\n },\n \"boxwood_hedge\": {\n \"name\": \"Cerca-viva de buxinho\",\n \"description\": \"Cerca-viva podada de verde escuro.\"\n },\n \"ixora_hedge\": {\n \"name\": \"Cerca-viva de ixora\",\n \"description\": \"Cerca-viva salpicada de cachos de flores vermelhas.\"\n },\n \"hibiscus_shrub\": {\n \"name\": \"Hibisco\",\n \"description\": \"Arbusto de folhas brilhantes com grandes flores vermelhas e rosa.\"\n },\n \"bougainvillea\": {\n \"name\": \"Primavera\",\n \"description\": \"Arbusto espalhado coberto de brácteas magenta.\"\n },\n \"azalea\": {\n \"name\": \"Azaleia\",\n \"description\": \"Arbusto baixo e redondo cheio de flores rosa.\"\n },\n \"croton\": {\n \"name\": \"Cróton\",\n \"description\": \"Arbusto de folhas multicoloridas em amarelo, vermelho e verde.\"\n },\n \"lady_palm\": {\n \"name\": \"Palmeira-ráfia\",\n \"description\": \"Palmeira-leque anã em touceira, com hastes finas (rhapis).\"\n },\n \"generic_round_shrub\": {\n \"name\": \"Arbusto redondo\",\n \"description\": \"Arbusto verde redondo e simples.\"\n },\n \"overgrown_bush\": {\n \"name\": \"Moita crescida\",\n \"description\": \"Moita desgrenhada e sem poda.\"\n },\n \"rose_bush_red\": {\n \"name\": \"Roseira vermelha\",\n \"description\": \"Hastes espinhosas com rosas vermelhas.\"\n },\n \"rose_bush_pink\": {\n \"name\": \"Roseira rosa\",\n \"description\": \"Hastes espinhosas com rosas cor-de-rosa.\"\n },\n \"rose_bush_white\": {\n \"name\": \"Roseira branca\",\n \"description\": \"Hastes espinhosas com rosas brancas.\"\n },\n \"sunflower\": {\n \"name\": \"Girassol\",\n \"description\": \"Hastes altas com grandes flores douradas.\"\n },\n \"daisy\": {\n \"name\": \"Margarida\",\n \"description\": \"Pétalas brancas em volta de um miolo amarelo.\"\n },\n \"tulip\": {\n \"name\": \"Tulipa\",\n \"description\": \"Flores em forma de taça sobre hastes retas.\"\n },\n \"lily\": {\n \"name\": \"Lírio\",\n \"description\": \"Flores brancas em forma de estrela.\"\n },\n \"marigold\": {\n \"name\": \"Cravo-de-defunto\",\n \"description\": \"Flores laranja redondas em pompom.\"\n },\n \"periwinkle_pink\": {\n \"name\": \"Vinca rosa\",\n \"description\": \"Tapete baixo de florzinhas rosa.\"\n },\n \"periwinkle_white\": {\n \"name\": \"Vinca branca\",\n \"description\": \"Tapete baixo de florzinhas brancas.\"\n },\n \"hydrangea\": {\n \"name\": \"Hortênsia\",\n \"description\": \"Grandes bolas azuis de florzinhas.\"\n },\n \"bird_of_paradise\": {\n \"name\": \"Estrelítzia\",\n \"description\": \"Flores laranja e azuis em forma de ave sobre folhas grandes.\"\n },\n \"wild_flowers\": {\n \"name\": \"Flores do campo\",\n \"description\": \"Mistura de florzinhas de campo.\"\n },\n \"mandacaru\": {\n \"name\": \"Mandacaru\",\n \"description\": \"Cacto alto em candelabro, azul-esverdeado, com grandes flores brancas noturnas.\"\n },\n \"saguaro\": {\n \"name\": \"Saguaro\",\n \"description\": \"Cacto colunar gigante com braços voltados para cima.\"\n },\n \"xique_xique\": {\n \"name\": \"Xique-xique\",\n \"description\": \"Cacto colunar baixo e espalhado do sertão.\"\n },\n \"prickly_pear\": {\n \"name\": \"Palma\",\n \"description\": \"Raquetes achatadas encadeadas, com frutos vermelhos.\"\n },\n \"crown_cactus\": {\n \"name\": \"Coroa-de-frade\",\n \"description\": \"Globo com costelas coroado por uma capa vermelha.\"\n },\n \"barrel_cactus\": {\n \"name\": \"Cacto-barril\",\n \"description\": \"Barril redondo com costelas e espinhos dourados.\"\n },\n \"small_cactus\": {\n \"name\": \"Cactinho\",\n \"description\": \"Cacto pequeno e redondo.\"\n },\n \"snake_plant\": {\n \"name\": \"Espada-de-são-jorge\",\n \"description\": \"Folhas altas e rígidas em forma de espada, com faixas.\"\n },\n \"agave\": {\n \"name\": \"Agave\",\n \"description\": \"Grande roseta azul-esverdeada de folhas grossas e pontudas.\"\n },\n \"aloe_vera\": {\n \"name\": \"Babosa\",\n \"description\": \"Folhas carnudas e serrilhadas com espiga de flores laranja.\"\n },\n \"echeveria\": {\n \"name\": \"Echeveria\",\n \"description\": \"Roseta compacta de folhas com pontas rosadas.\"\n },\n \"lawn_tuft\": {\n \"name\": \"Touceira de grama\",\n \"description\": \"Touceira curta de grama verde.\"\n },\n \"wild_grass_tall\": {\n \"name\": \"Capim alto\",\n \"description\": \"Capim alto com espigas.\"\n },\n \"weeds\": {\n \"name\": \"Mato\",\n \"description\": \"Tufo bagunçado de mato.\"\n },\n \"papyrus\": {\n \"name\": \"Papiro\",\n \"description\": \"Juncos altos coroados por penachos.\"\n },\n \"fern\": {\n \"name\": \"Samambaia\",\n \"description\": \"Frondes arqueadas de folíolos pequenos.\"\n },\n \"boston_fern\": {\n \"name\": \"Samambaia-americana\",\n \"description\": \"Samambaia farta em vaso, com frondes caindo pela borda.\"\n },\n \"bougainvillea_vine\": {\n \"name\": \"Primavera trepadeira\",\n \"description\": \"Trepadeira coberta de brácteas magenta.\"\n },\n \"ivy\": {\n \"name\": \"Hera\",\n \"description\": \"Trepadeira densa e verde escura para muros.\"\n },\n \"passion_fruit_vine\": {\n \"name\": \"Maracujazeiro\",\n \"description\": \"Trepadeira vigorosa com flores roxas e brancas.\"\n },\n \"potted_fern\": {\n \"name\": \"Samambaia de vaso\",\n \"description\": \"Samambaia em vaso de barro.\"\n },\n \"potted_snake_plant\": {\n \"name\": \"Espada-de-são-jorge de vaso\",\n \"description\": \"Espada-de-são-jorge em vaso cinza.\"\n },\n \"potted_areca\": {\n \"name\": \"Areca de vaso\",\n \"description\": \"Palmeira-areca em cachepô.\"\n },\n \"potted_cactus\": {\n \"name\": \"Cacto de vaso\",\n \"description\": \"Cacto redondo pequeno em vaso.\"\n },\n \"potted_rose\": {\n \"name\": \"Rosa de vaso\",\n \"description\": \"Roseira em vaso.\"\n },\n \"potted_succulents\": {\n \"name\": \"Suculenta de vaso\",\n \"description\": \"Echeveria em cachepô pequeno.\"\n }\n}\n","{\n \"mango_tree\": {\n \"name\": \"Mango tree\",\n \"description\": \"Broad umbrella crown with hanging mangoes.\"\n },\n \"yellow_ipe\": {\n \"name\": \"Yellow ipe\",\n \"description\": \"Green in summer, a crown of golden flowers in the dry season.\"\n },\n \"pink_ipe\": {\n \"name\": \"Pink ipe\",\n \"description\": \"Green in summer, a crown of pink flowers in the dry season.\"\n },\n \"jabuticaba_tree\": {\n \"name\": \"Jabuticaba tree\",\n \"description\": \"Dense small tree with dark fruit growing straight on the trunk.\"\n },\n \"flamboyant\": {\n \"name\": \"Flamboyant\",\n \"description\": \"Umbrella crown covered in red blooms.\"\n },\n \"guava_tree\": {\n \"name\": \"Guava tree\",\n \"description\": \"Small crooked tree with smooth reddish bark and round fruit.\"\n },\n \"avocado_tree\": {\n \"name\": \"Avocado tree\",\n \"description\": \"Tall dark-green tree with pear-shaped fruit.\"\n },\n \"lemon_tree\": {\n \"name\": \"Lemon tree\",\n \"description\": \"Small backyard tree with bright yellow lemons.\"\n },\n \"pitanga_bush_tree\": {\n \"name\": \"Pitanga tree\",\n \"description\": \"Bushy small tree covered in tiny red fruit.\"\n },\n \"sidewalk_ficus\": {\n \"name\": \"Street ficus\",\n \"description\": \"Clipped round crown typical of sidewalks.\"\n },\n \"oak_like\": {\n \"name\": \"Broadleaf tree\",\n \"description\": \"Generic broadleaf shade tree that changes with the seasons.\"\n },\n \"weeping_willow\": {\n \"name\": \"Weeping willow\",\n \"description\": \"Drooping curtains of pale green leaves.\"\n },\n \"araucaria\": {\n \"name\": \"Araucaria\",\n \"description\": \"Tall bare trunk with an umbrella of upturned branches.\"\n },\n \"pine\": {\n \"name\": \"Pine\",\n \"description\": \"Conical evergreen with drooping tiers.\"\n },\n \"eucalyptus\": {\n \"name\": \"Eucalyptus\",\n \"description\": \"Very tall tree with pale bark and a sparse crown.\"\n },\n \"dead_tree\": {\n \"name\": \"Dead tree\",\n \"description\": \"Bare twisted trunk with broken limbs.\"\n },\n \"coconut_palm\": {\n \"name\": \"Coconut palm\",\n \"description\": \"Leaning curved trunk with a crown of long fronds and coconuts.\"\n },\n \"royal_palm\": {\n \"name\": \"Royal palm\",\n \"description\": \"Straight smooth grey trunk and a green crownshaft.\"\n },\n \"fan_palm\": {\n \"name\": \"Fan palm\",\n \"description\": \"Short thick trunk with round fan-shaped fronds.\"\n },\n \"areca_palm\": {\n \"name\": \"Areca palm\",\n \"description\": \"Clumping palm with many thin canes and feathery fronds.\"\n },\n \"date_palm\": {\n \"name\": \"Date palm\",\n \"description\": \"Rough trunk with stiff upright fronds and date clusters.\"\n },\n \"banana_plant\": {\n \"name\": \"Banana plant\",\n \"description\": \"Pseudostem with huge torn paddle leaves.\"\n },\n \"banana_with_bunch\": {\n \"name\": \"Banana plant with bunch\",\n \"description\": \"Banana plant with a hanging bunch and a purple flower bud.\"\n },\n \"boxwood_hedge\": {\n \"name\": \"Boxwood hedge\",\n \"description\": \"Clipped dark green hedge.\"\n },\n \"ixora_hedge\": {\n \"name\": \"Ixora hedge\",\n \"description\": \"Hedge dotted with clusters of red flowers.\"\n },\n \"hibiscus_shrub\": {\n \"name\": \"Hibiscus shrub\",\n \"description\": \"Glossy shrub with big red and pink flowers.\"\n },\n \"bougainvillea\": {\n \"name\": \"Bougainvillea\",\n \"description\": \"Sprawling shrub covered in magenta bracts.\"\n },\n \"azalea\": {\n \"name\": \"Azalea\",\n \"description\": \"Low round shrub packed with pink blooms.\"\n },\n \"croton\": {\n \"name\": \"Croton\",\n \"description\": \"Shrub with multicoloured leaves in yellow, red and green.\"\n },\n \"lady_palm\": {\n \"name\": \"Lady palm\",\n \"description\": \"Dwarf clumping fan palm (rhapis) with slender canes.\"\n },\n \"generic_round_shrub\": {\n \"name\": \"Round shrub\",\n \"description\": \"Plain round green shrub.\"\n },\n \"overgrown_bush\": {\n \"name\": \"Overgrown bush\",\n \"description\": \"Shaggy untrimmed bush.\"\n },\n \"rose_bush_red\": {\n \"name\": \"Red rose bush\",\n \"description\": \"Thorny stems with deep red roses.\"\n },\n \"rose_bush_pink\": {\n \"name\": \"Pink rose bush\",\n \"description\": \"Thorny stems with pink roses.\"\n },\n \"rose_bush_white\": {\n \"name\": \"White rose bush\",\n \"description\": \"Thorny stems with white roses.\"\n },\n \"sunflower\": {\n \"name\": \"Sunflower\",\n \"description\": \"Tall stems with big golden heads.\"\n },\n \"daisy\": {\n \"name\": \"Daisy\",\n \"description\": \"White petals around a yellow eye.\"\n },\n \"tulip\": {\n \"name\": \"Tulip\",\n \"description\": \"Cup-shaped flowers on straight stems.\"\n },\n \"lily\": {\n \"name\": \"Lily\",\n \"description\": \"Star-shaped white flowers.\"\n },\n \"marigold\": {\n \"name\": \"Marigold\",\n \"description\": \"Round orange pompon flowers.\"\n },\n \"periwinkle_pink\": {\n \"name\": \"Pink periwinkle\",\n \"description\": \"Low carpet of small pink flowers.\"\n },\n \"periwinkle_white\": {\n \"name\": \"White periwinkle\",\n \"description\": \"Low carpet of small white flowers.\"\n },\n \"hydrangea\": {\n \"name\": \"Hydrangea\",\n \"description\": \"Big blue balls of small flowers.\"\n },\n \"bird_of_paradise\": {\n \"name\": \"Bird of paradise\",\n \"description\": \"Orange and blue crested flowers over big leaves.\"\n },\n \"wild_flowers\": {\n \"name\": \"Wild flowers\",\n \"description\": \"A mix of small meadow flowers.\"\n },\n \"mandacaru\": {\n \"name\": \"Mandacaru\",\n \"description\": \"Tall blue-green candelabra cactus with large white night flowers.\"\n },\n \"saguaro\": {\n \"name\": \"Saguaro\",\n \"description\": \"Giant columnar cactus with upturned arms.\"\n },\n \"xique_xique\": {\n \"name\": \"Xique-xique\",\n \"description\": \"Low sprawling columnar cactus of the dry backlands.\"\n },\n \"prickly_pear\": {\n \"name\": \"Prickly pear\",\n \"description\": \"Chained flat pads with red fruit.\"\n },\n \"crown_cactus\": {\n \"name\": \"Turk's cap cactus\",\n \"description\": \"Ribbed globe topped by a red cap.\"\n },\n \"barrel_cactus\": {\n \"name\": \"Barrel cactus\",\n \"description\": \"Round ribbed barrel with golden spines.\"\n },\n \"small_cactus\": {\n \"name\": \"Small cactus\",\n \"description\": \"Tiny round cactus.\"\n },\n \"snake_plant\": {\n \"name\": \"Snake plant\",\n \"description\": \"Tall stiff sword leaves with banded colour.\"\n },\n \"agave\": {\n \"name\": \"Agave\",\n \"description\": \"Big blue-green rosette of thick pointed leaves.\"\n },\n \"aloe_vera\": {\n \"name\": \"Aloe vera\",\n \"description\": \"Fleshy toothed leaves with an orange flower spike.\"\n },\n \"echeveria\": {\n \"name\": \"Echeveria\",\n \"description\": \"Tight rosette with pink-tipped leaves.\"\n },\n \"lawn_tuft\": {\n \"name\": \"Lawn tuft\",\n \"description\": \"Short green grass tuft.\"\n },\n \"wild_grass_tall\": {\n \"name\": \"Tall wild grass\",\n \"description\": \"Tall wild grass with seed heads.\"\n },\n \"weeds\": {\n \"name\": \"Weeds\",\n \"description\": \"Untidy patch of weeds.\"\n },\n \"papyrus\": {\n \"name\": \"Papyrus\",\n \"description\": \"Tall reeds topped with feathery heads.\"\n },\n \"fern\": {\n \"name\": \"Fern\",\n \"description\": \"Arching fronds of small leaflets.\"\n },\n \"boston_fern\": {\n \"name\": \"Boston fern\",\n \"description\": \"Lush fern in a pot, fronds spilling over the rim.\"\n },\n \"bougainvillea_vine\": {\n \"name\": \"Bougainvillea vine\",\n \"description\": \"Climbing vine covered in magenta bracts.\"\n },\n \"ivy\": {\n \"name\": \"Ivy\",\n \"description\": \"Dense dark green climber for walls.\"\n },\n \"passion_fruit_vine\": {\n \"name\": \"Passion fruit vine\",\n \"description\": \"Vigorous climber with intricate purple and white flowers.\"\n },\n \"potted_fern\": {\n \"name\": \"Potted fern\",\n \"description\": \"Fern in a terracotta pot.\"\n },\n \"potted_snake_plant\": {\n \"name\": \"Potted snake plant\",\n \"description\": \"Snake plant in a grey pot.\"\n },\n \"potted_areca\": {\n \"name\": \"Potted areca palm\",\n \"description\": \"Areca palm in a cachepot.\"\n },\n \"potted_cactus\": {\n \"name\": \"Potted cactus\",\n \"description\": \"Small round cactus in a pot.\"\n },\n \"potted_rose\": {\n \"name\": \"Potted rose\",\n \"description\": \"Rose bush in a pot.\"\n },\n \"potted_succulents\": {\n \"name\": \"Potted succulent\",\n \"description\": \"Echeveria in a small cachepot.\"\n }\n}\n","{\n \"id\": \"br\",\n \"name\": \"Brazil (urban)\",\n \"contexts\": {\n \"front_yard\": [\n {\n \"species\": \"boxwood_hedge\",\n \"weight\": 6\n },\n {\n \"species\": \"hibiscus_shrub\",\n \"weight\": 5\n },\n {\n \"species\": \"ixora_hedge\",\n \"weight\": 4\n },\n {\n \"species\": \"bougainvillea\",\n \"weight\": 4\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"croton\",\n \"weight\": 4\n },\n {\n \"species\": \"rose_bush_red\",\n \"weight\": 3\n },\n {\n \"species\": \"rose_bush_pink\",\n \"weight\": 3\n },\n {\n \"species\": \"rose_bush_white\",\n \"weight\": 2\n },\n {\n \"species\": \"azalea\",\n \"weight\": 3\n },\n {\n \"species\": \"potted_fern\",\n \"weight\": 2\n },\n {\n \"species\": \"lemon_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"bird_of_paradise\",\n \"weight\": 2\n },\n {\n \"species\": \"daisy\",\n \"weight\": 2\n },\n {\n \"species\": \"marigold\",\n \"weight\": 2\n },\n {\n \"species\": \"banana_plant\",\n \"weight\": 1\n },\n {\n \"species\": \"periwinkle_pink\",\n \"weight\": 2\n },\n {\n \"species\": \"periwinkle_white\",\n \"weight\": 2\n },\n {\n \"species\": \"areca_palm\",\n \"weight\": 2\n },\n {\n \"species\": \"bougainvillea_vine\",\n \"weight\": 1\n },\n {\n \"species\": \"sidewalk_ficus\",\n \"weight\": 1\n }\n ],\n \"backyard\": [\n {\n \"species\": \"mango_tree\",\n \"weight\": 4\n },\n {\n \"species\": \"banana_plant\",\n \"weight\": 5\n },\n {\n \"species\": \"banana_with_bunch\",\n \"weight\": 3\n },\n {\n \"species\": \"guava_tree\",\n \"weight\": 3\n },\n {\n \"species\": \"lemon_tree\",\n \"weight\": 3\n },\n {\n \"species\": \"pitanga_bush_tree\",\n \"weight\": 3\n },\n {\n \"species\": \"avocado_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"jabuticaba_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"coconut_palm\",\n \"weight\": 1\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 6\n },\n {\n \"species\": \"weeds\",\n \"weight\": 4\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 2\n },\n {\n \"species\": \"fern\",\n \"weight\": 2\n },\n {\n \"species\": \"aloe_vera\",\n \"weight\": 2\n },\n {\n \"species\": \"snake_plant\",\n \"weight\": 1\n },\n {\n \"species\": \"passion_fruit_vine\",\n \"weight\": 2\n },\n {\n \"species\": \"papyrus\",\n \"weight\": 1\n },\n {\n \"species\": \"hibiscus_shrub\",\n \"weight\": 1\n }\n ],\n \"sidewalk_tree\": [\n {\n \"species\": \"sidewalk_ficus\",\n \"weight\": 8\n },\n {\n \"species\": \"yellow_ipe\",\n \"weight\": 3\n },\n {\n \"species\": \"pink_ipe\",\n \"weight\": 3\n },\n {\n \"species\": \"royal_palm\",\n \"weight\": 2\n },\n {\n \"species\": \"eucalyptus\",\n \"weight\": 2\n },\n {\n \"species\": \"mango_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"flamboyant\",\n \"weight\": 2\n },\n {\n \"species\": \"oak_like\",\n \"weight\": 1\n },\n {\n \"species\": \"coconut_palm\",\n \"weight\": 1\n }\n ],\n \"square\": [\n {\n \"species\": \"royal_palm\",\n \"weight\": 4\n },\n {\n \"species\": \"flamboyant\",\n \"weight\": 3\n },\n {\n \"species\": \"yellow_ipe\",\n \"weight\": 3\n },\n {\n \"species\": \"pink_ipe\",\n \"weight\": 3\n },\n {\n \"species\": \"mango_tree\",\n \"weight\": 3\n },\n {\n \"species\": \"sidewalk_ficus\",\n \"weight\": 3\n },\n {\n \"species\": \"araucaria\",\n \"weight\": 2\n },\n {\n \"species\": \"fan_palm\",\n \"weight\": 2\n },\n {\n \"species\": \"boxwood_hedge\",\n \"weight\": 4\n },\n {\n \"species\": \"azalea\",\n \"weight\": 3\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"rose_bush_red\",\n \"weight\": 2\n },\n {\n \"species\": \"hibiscus_shrub\",\n \"weight\": 2\n },\n {\n \"species\": \"weeping_willow\",\n \"weight\": 1\n },\n {\n \"species\": \"coconut_palm\",\n \"weight\": 1\n }\n ],\n \"vacant_lot\": [\n {\n \"species\": \"weeds\",\n \"weight\": 8\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 7\n },\n {\n \"species\": \"overgrown_bush\",\n \"weight\": 4\n },\n {\n \"species\": \"dead_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"guava_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"eucalyptus\",\n \"weight\": 1\n },\n {\n \"species\": \"wild_flowers\",\n \"weight\": 2\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 3\n },\n {\n \"species\": \"mango_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"banana_plant\",\n \"weight\": 1\n },\n {\n \"species\": \"prickly_pear\",\n \"weight\": 1\n }\n ],\n \"indoor\": [\n {\n \"species\": \"potted_fern\",\n \"weight\": 4\n },\n {\n \"species\": \"potted_snake_plant\",\n \"weight\": 4\n },\n {\n \"species\": \"potted_areca\",\n \"weight\": 3\n },\n {\n \"species\": \"potted_cactus\",\n \"weight\": 2\n },\n {\n \"species\": \"potted_rose\",\n \"weight\": 1\n },\n {\n \"species\": \"potted_succulents\",\n \"weight\": 3\n },\n {\n \"species\": \"boston_fern\",\n \"weight\": 2\n }\n ],\n \"semiarid\": [\n {\n \"species\": \"mandacaru\",\n \"weight\": 5\n },\n {\n \"species\": \"xique_xique\",\n \"weight\": 5\n },\n {\n \"species\": \"prickly_pear\",\n \"weight\": 4\n },\n {\n \"species\": \"crown_cactus\",\n \"weight\": 2\n },\n {\n \"species\": \"barrel_cactus\",\n \"weight\": 1\n },\n {\n \"species\": \"agave\",\n \"weight\": 2\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 3\n },\n {\n \"species\": \"weeds\",\n \"weight\": 3\n },\n {\n \"species\": \"dead_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"aloe_vera\",\n \"weight\": 1\n }\n ]\n }\n}\n","{\n \"id\": \"default\",\n \"name\": \"Temperate (generic)\",\n \"contexts\": {\n \"front_yard\": [\n {\n \"species\": \"boxwood_hedge\",\n \"weight\": 5\n },\n {\n \"species\": \"azalea\",\n \"weight\": 4\n },\n {\n \"species\": \"rose_bush_red\",\n \"weight\": 3\n },\n {\n \"species\": \"rose_bush_pink\",\n \"weight\": 2\n },\n {\n \"species\": \"tulip\",\n \"weight\": 3\n },\n {\n \"species\": \"daisy\",\n \"weight\": 3\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"generic_round_shrub\",\n \"weight\": 4\n },\n {\n \"species\": \"hydrangea\",\n \"weight\": 3\n },\n {\n \"species\": \"lily\",\n \"weight\": 2\n },\n {\n \"species\": \"potted_fern\",\n \"weight\": 1\n }\n ],\n \"backyard\": [\n {\n \"species\": \"oak_like\",\n \"weight\": 3\n },\n {\n \"species\": \"lemon_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"weeds\",\n \"weight\": 3\n },\n {\n \"species\": \"wild_flowers\",\n \"weight\": 2\n },\n {\n \"species\": \"fern\",\n \"weight\": 2\n },\n {\n \"species\": \"generic_round_shrub\",\n \"weight\": 3\n },\n {\n \"species\": \"sunflower\",\n \"weight\": 2\n },\n {\n \"species\": \"ivy\",\n \"weight\": 1\n }\n ],\n \"sidewalk_tree\": [\n {\n \"species\": \"oak_like\",\n \"weight\": 6\n },\n {\n \"species\": \"sidewalk_ficus\",\n \"weight\": 2\n },\n {\n \"species\": \"pine\",\n \"weight\": 2\n },\n {\n \"species\": \"weeping_willow\",\n \"weight\": 1\n }\n ],\n \"square\": [\n {\n \"species\": \"oak_like\",\n \"weight\": 5\n },\n {\n \"species\": \"pine\",\n \"weight\": 3\n },\n {\n \"species\": \"weeping_willow\",\n \"weight\": 2\n },\n {\n \"species\": \"boxwood_hedge\",\n \"weight\": 4\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"rose_bush_red\",\n \"weight\": 2\n },\n {\n \"species\": \"tulip\",\n \"weight\": 2\n },\n {\n \"species\": \"daisy\",\n \"weight\": 2\n }\n ],\n \"vacant_lot\": [\n {\n \"species\": \"weeds\",\n \"weight\": 8\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 7\n },\n {\n \"species\": \"overgrown_bush\",\n \"weight\": 3\n },\n {\n \"species\": \"dead_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"wild_flowers\",\n \"weight\": 2\n },\n {\n \"species\": \"pine\",\n \"weight\": 1\n }\n ],\n \"indoor\": [\n {\n \"species\": \"potted_fern\",\n \"weight\": 4\n },\n {\n \"species\": \"potted_snake_plant\",\n \"weight\": 3\n },\n {\n \"species\": \"potted_succulents\",\n \"weight\": 2\n },\n {\n \"species\": \"potted_cactus\",\n \"weight\": 1\n },\n {\n \"species\": \"boston_fern\",\n \"weight\": 2\n }\n ],\n \"semiarid\": [\n {\n \"species\": \"agave\",\n \"weight\": 3\n },\n {\n \"species\": \"prickly_pear\",\n \"weight\": 3\n },\n {\n \"species\": \"barrel_cactus\",\n \"weight\": 2\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 4\n },\n {\n \"species\": \"weeds\",\n \"weight\": 3\n },\n {\n \"species\": \"dead_tree\",\n \"weight\": 1\n }\n ]\n }\n}\n","import type { ScatterRule } from '@adatechnology/game-vegetation'\nimport { getSpecies, pickForContext } from './index'\nimport type { Region, Species } from './types'\n\n/** The four groups the picked species are split into, each planted by its own scatter rule. */\nexport type PlantGroup = 'trees' | 'hedges' | 'mid' | 'ground'\n\nexport interface ScatterRulesOptions {\n /** How many different species to pick for the context (default 12). */\n n?: number\n /** How many draws of the regional table to try to find `n` usable species (default 60). */\n draws?: number\n /** Archetypes left out of the picks (default `['vine']`: a vine needs a support to climb). */\n skipArchetypes?: readonly string[]\n /** Leave out the big trees (size `l`, or a tree that is not of size `s`): the front yard and the narrow strips beside the house. */\n noLarge?: boolean\n /** Cap on the plants of each group (the page's `trees`, `hedges`, `mid`, `ground`); no cap when absent. */\n maxCount?: Partial<Record<PlantGroup, number>>\n /** Trees per square metre (default 0.03). */\n treeDensity?: number\n /** Replaces or extends the rule of a group (the defaults are the Viveiro's numbers). */\n groupRules?: Partial<Record<PlantGroup, Partial<Omit<ScatterRule, 'species'>>>>\n /** Which species form each group. Defaults: trees are tagged `tree` and not size `s`; hedges are shrubs tagged `hedge`; ground is grass tufts and ferns; mid is the rest. */\n classify?: (species: Species) => PlantGroup\n}\n\nexport interface ScatterRulesResult {\n /** One rule for each group that has species, in the order trees, hedges, mid, ground. */\n rules: ScatterRule[]\n /** The distinct species picked, in the order they were drawn. */\n picks: Species[]\n}\n\nconst isTree = (s: Species): boolean => s.tags.includes('tree') && s.size !== 's'\n\n/** The Viveiro's split: trees, then hedges, then ground cover (grass and ferns), then the rest. */\nexport const defaultClassify = (s: Species): PlantGroup => (isTree(s) ? 'trees' : s.archetype === 'shrub' && s.tags.includes('hedge') ? 'hedges' : s.archetype === 'grass_tuft' || s.archetype === 'fern' ? 'ground' : 'mid')\n\nconst DEFAULT_RULES: Record<PlantGroup, Omit<ScatterRule, 'species' | 'maxCount'>> = {\n trees: { density: 0.03, minDistance: 4.2, scale: [0.85, 1.05], prefer: 'any' },\n hedges: { density: 0.5, minDistance: 1.1, prefer: 'edge', edgeWidth: 0.6, scale: [0.9, 1.1] },\n mid: { density: 0.45, minDistance: 0.9, scale: [0.85, 1.15] },\n ground: { density: 1.2, minDistance: 0.5, scale: [0.8, 1.2] },\n}\n\nconst ORDER: PlantGroup[] = ['trees', 'hedges', 'mid', 'ground']\n\n/**\n * Turns the regional planting table of a context into scatter rules for `scatter` of `@adatechnology/game-vegetation`: draws species from the table (the same seed draws the same),\n * leaves out what cannot be planted alone (vines) and, when asked, the big trees, and splits the picks into trees, hedges, the middle layer and the ground cover, each with its own\n * density, spacing and scale. Port of the Viveiro's `rulesFor` (vegetacao__viveiro.js 77943-77963); every number of it is an option.\n */\nexport function scatterRulesFor(region: Region, context: string, seed: number | string, options: ScatterRulesOptions = {}): ScatterRulesResult {\n const n = options.n ?? 12\n const draws = options.draws ?? 60\n const skip = new Set(options.skipArchetypes ?? ['vine'])\n const classify = options.classify ?? defaultClassify\n const seen = new Set<string>()\n const picks: Species[] = []\n for (let i = 0; i < draws && picks.length < n; i++) {\n const id = pickForContext(region, context, `${seed}:${context}:${i}`)\n const species = getSpecies(id)\n if (!species || seen.has(id) || skip.has(species.archetype)) continue\n if (options.noLarge && (species.size === 'l' || isTree(species))) continue\n seen.add(id)\n picks.push(species)\n }\n const groups: Record<PlantGroup, string[]> = { trees: [], hedges: [], mid: [], ground: [] }\n for (const species of picks) groups[classify(species)].push(species.id)\n const rules: ScatterRule[] = []\n for (const group of ORDER) {\n const ids = groups[group]\n if (ids.length === 0) continue\n const base = { ...DEFAULT_RULES[group], ...(group === 'trees' && options.treeDensity !== undefined ? { density: options.treeDensity } : {}), ...options.groupRules?.[group] }\n const maxCount = options.maxCount?.[group]\n rules.push({ species: ids, ...base, ...(maxCount === undefined ? {} : { maxCount }) })\n }\n return { rules, picks }\n}\n","import type { PlantSpec } from '@adatechnology/game-vegetation'\nimport trees from '../data/species/trees.json'\nimport palms from '../data/species/palms.json'\nimport shrubs from '../data/species/shrubs.json'\nimport flowers from '../data/species/flowers.json'\nimport cacti from '../data/species/cacti.json'\nimport succulents from '../data/species/succulents.json'\nimport grasses from '../data/species/grasses.json'\nimport vines from '../data/species/vines.json'\nimport potted from '../data/species/potted.json'\nimport ptBR from '../data/locales/pt-BR.json'\nimport en from '../data/locales/en.json'\nimport br from '../data/regions/br.json'\nimport defaultRegion from '../data/regions/default.json'\nimport type { Locale, LocaleTable, Region, Species } from './types'\n\nexport * from './types'\n\n/** Every species of the pack. */\nexport const species: Species[] = [\n ...trees,\n ...palms,\n ...shrubs,\n ...flowers,\n ...cacti,\n ...succulents,\n ...grasses,\n ...vines,\n ...potted,\n] as Species[]\n\nconst byId = new Map<string, Species>(species.map((s) => [s.id, s]))\n\nexport function getSpecies(id: string): Species | undefined {\n return byId.get(id)\n}\n\nexport function listIds(): string[] {\n return species.map((s) => s.id)\n}\n\nexport function byTag(tag: string): Species[] {\n return species.filter((s) => s.tags.includes(tag))\n}\n\nconst HEX = /^#[0-9a-fA-F]{6}$/\n\n/** Replace `#rrggbb` strings by 0xRRGGBB integers, recursively. */\nfunction resolveColors(v: unknown): unknown {\n if (typeof v === 'string' && HEX.test(v)) return parseInt(v.slice(1), 16)\n if (Array.isArray(v)) return v.map(resolveColors)\n if (v && typeof v === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, x] of Object.entries(v)) out[k] = resolveColors(x)\n return out\n }\n return v\n}\n\n/** Convert a species (or its id) into a spec for `generate()`, with hex colors turned into integers. */\nexport function toSpec(s: Species | string): PlantSpec {\n const sp = typeof s === 'string' ? getSpecies(s) : s\n if (!sp) throw new Error(`game-vegetation-species: unknown species \"${String(s)}\"`)\n return { archetype: sp.archetype, ...(resolveColors(sp.params) as Record<string, unknown>) } as PlantSpec\n}\n\nconst locales: Record<Locale, LocaleTable> = { 'pt-BR': ptBR as LocaleTable, en: en as LocaleTable }\n\n/** Display texts for a locale (unknown locales fall back to `en`). */\nexport function loadLocale(locale: Locale | string = 'en'): LocaleTable {\n return (locales as Record<string, LocaleTable>)[locale] ?? locales.en\n}\n\nexport function name(id: string, locale: Locale | string = 'en'): string {\n return loadLocale(locale)[id]?.name ?? locales.en[id]?.name ?? id\n}\n\nexport function description(id: string, locale: Locale | string = 'en'): string {\n return loadLocale(locale)[id]?.description ?? locales.en[id]?.description ?? ''\n}\n\nexport const regions = { br: br as Region, default: defaultRegion as Region }\n\n/** Anything that yields numbers in [0, 1): a function, an object with `next()`, or a seed. */\nexport type RngLike = (() => number) | { next(): number } | number | string\n\nfunction toNext(rng: RngLike): () => number {\n if (typeof rng === 'function') return rng\n if (typeof rng === 'object') return () => rng.next()\n // mulberry32 seeded from a number or string\n let s = typeof rng === 'number' ? rng >>> 0 : 0x811c9dc5\n if (typeof rng === 'string') {\n for (let i = 0; i < rng.length; i++) {\n s ^= rng.charCodeAt(i)\n s = Math.imul(s, 0x01000193)\n }\n s >>>= 0\n }\n return () => {\n s = (s + 0x6d2b79f5) >>> 0\n let t = s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** Weighted pick of a species id for a context ('front_yard', 'sidewalk_tree', ...) of a region. */\nexport function pickForContext(region: Region, context: string, rng: RngLike): string {\n const list = region.contexts[context]\n if (!list || list.length === 0) throw new Error(`game-vegetation-species: region \"${region.id}\" has no context \"${context}\"`)\n const next = toNext(rng)\n const total = list.reduce((a, b) => a + b.weight, 0)\n let r = next() * total\n for (const it of list) {\n r -= it.weight\n if (r <= 0) return it.species\n }\n return list[list.length - 1].species\n}\n\nexport { scatterRulesFor, defaultClassify } from './rules'\nexport type { PlantGroup, ScatterRulesOptions, ScatterRulesResult } from './rules'\n","import type { Condition, Lod, Placement, Season } from '@adatechnology/game-vegetation'\nimport type { ScatterRulesOptions } from '@adatechnology/game-vegetation-species'\nimport { shapeGeometries } from '@adatechnology/game-shapes-three'\n\nimport type { MaterialsLike, SpeciesSdk, VegetationSdk } from './types'\n\ntype Three = any\n\n/** The plot of the Viveiro's lot demo, in metres: the corner at (0, 0), the street on the negative z side. */\nexport const LOT = { W: 12, D: 20 } as const\nexport const HOUSE = { x0: 2.5, x1: 9.5, z0: 6.5, z1: 13 } as const\n/** The walker's route (x, z). */\nexport const WAY: readonly (readonly [number, number])[] = [[6, 1.2], [6, 5.4], [10.8, 5.4], [10.8, 14.2], [8, 18.6], [3, 18.6], [1.2, 14.2], [1.2, 5.4], [4, 3.2], [8, 3.2]]\n\ntype Rect = { rect: { x: number; z: number; w: number; d: number } }\nexport const EX_HOUSE: Rect = { rect: { x: HOUSE.x0 - 0.7, z: HOUSE.z0 - 0.7, w: HOUSE.x1 - HOUSE.x0 + 1.4, d: HOUSE.z1 - HOUSE.z0 + 1.4 } }\nexport const EX_PATH: Rect = { rect: { x: 5.1, z: 0, w: 1.8, d: HOUSE.z0 } }\n/** Where each kind of planting goes. */\nexport const AREAS: Readonly<Record<'front_yard' | 'backyard' | 'sides' | 'sidewalk_tree', Rect[]>> = {\n front_yard: [{ rect: { x: 0.5, z: 0.5, w: 11, d: 5.6 } }],\n backyard: [{ rect: { x: 0.5, z: 13.7, w: 11, d: 5.8 } }],\n sides: [{ rect: { x: 0.5, z: 6.2, w: 1.3, d: 7.4 } }, { rect: { x: 10.2, z: 6.2, w: 1.3, d: 7.4 } }],\n sidewalk_tree: [{ rect: { x: 0.8, z: -1.9, w: 10.4, d: 1.2 } }],\n}\n\n/** The four plantings of the lot: the context of the regional table, where, how many of each group, and the tag of the scatter seed. */\nexport type Planting = { context: string; areas: Rect[]; options: ScatterRulesOptions & { n: number }; tag: string }\nexport const PLANTINGS: readonly Planting[] = [\n { context: 'front_yard', areas: AREAS.front_yard, options: { n: 12, noLarge: true, maxCount: { trees: 1, hedges: 10, mid: 14, ground: 40 } }, tag: 'f' },\n { context: 'backyard', areas: AREAS.backyard, options: { n: 14, maxCount: { trees: 3, hedges: 4, mid: 12, ground: 50 } }, tag: 'b' },\n { context: 'front_yard', areas: AREAS.sides, options: { n: 8, noLarge: true, maxCount: { trees: 0, hedges: 4, mid: 6, ground: 14 } }, tag: 's' },\n { context: 'sidewalk_tree', areas: AREAS.sidewalk_tree, options: { n: 4, treeDensity: 0.3, maxCount: { trees: 2, hedges: 0, mid: 0, ground: 0 } }, tag: 'c' },\n]\n\nexport type NurserySettings = { seed: number; quality: 'high' | 'game'; lod: Lod; condition: Condition; season: Season }\n\nexport type LotStats = { triangles: number; plants: number; colliders: number; meshes: number; lod: [number, number, number]; buildMs: number; species: number }\n\n/**\n * The scatter of the lot: the same picks, rules and placements as the Viveiro's `buildLotVeg`. Every planting draws its species from the regional table of its context, splits\n * them into trees, hedges, middle layer and ground cover, and scatters each group over the areas of the plot without touching the house or the path.\n */\nexport function scatterLot(sdk: VegetationSdk, species: SpeciesSdk, seedNumber: number, plantings: readonly Planting[] = PLANTINGS): { placements: Placement[]; used: Set<string> } {\n const seed = `quintal-${seedNumber}`\n const placements: Placement[] = []\n const used = new Set<string>()\n for (const planting of plantings) {\n const { rules, picks } = species.scatterRulesFor(species.regions.br, planting.context, seed, planting.options)\n for (const p of picks) used.add(p.id)\n planting.areas.forEach((area, i) => {\n const exclude = [EX_HOUSE, EX_PATH]\n const perArea = rules.map((rule) => ({ ...rule, maxCount: Math.max(1, Math.ceil((rule.maxCount as number) / planting.areas.length)) }))\n placements.push(...sdk.scatter(area as never, perArea, { seed: `${seed}:${planting.tag}:${i}`, exclude: exclude as never }))\n })\n }\n return { placements, used }\n}\n\n/** The static scenery of the plot: ground, street, sidewalk, path, house and walls. Simple boxes; the room's own floor is under it. */\nfunction buildScenery(THREE: Three): any {\n const g = new THREE.Group()\n g.name = 'nursery-scenery'\n const material = (color: number, roughness = 0.9): any => new THREE.MeshStandardMaterial({ color, roughness, metalness: 0 })\n const mats = { ground: material(0x5f7d45), asphalt: material(0x3a3d42), concrete: material(0xb7b3a8), house: material(0xe3d6bd), roof: material(0x9a4d38), door: material(0x6b4a2f), glass: material(0x9fc7dd, 0.2), wall: material(0xc9c2b2) }\n const box = (w: number, h: number, d: number, m: any, x: number, y: number, z: number): any => {\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), m)\n mesh.position.set(x, y, z)\n mesh.castShadow = mesh.receiveShadow = true\n g.add(mesh)\n return mesh\n }\n const yard = new THREE.Mesh(new THREE.PlaneGeometry(LOT.W, LOT.D), mats.ground)\n yard.rotation.x = -Math.PI / 2\n yard.position.set(6, 0.01, 10)\n yard.receiveShadow = true\n g.add(yard)\n box(30, 0.04, 4.6, mats.asphalt, 6, 0.0, -4.6) // street\n box(30, 0.1, 2.2, mats.concrete, 6, 0.04, -1.1) // sidewalk\n box(1.6, 0.03, 6.6, mats.concrete, 6, 0.02, 3.2) // path to the door\n const hw = HOUSE.x1 - HOUSE.x0\n const hd = HOUSE.z1 - HOUSE.z0\n const hcx = (HOUSE.x0 + HOUSE.x1) / 2\n const hcz = (HOUSE.z0 + HOUSE.z1) / 2\n box(hw, 2.8, hd, mats.house, hcx, 1.4, hcz)\n const roof = new THREE.Mesh(new THREE.ConeGeometry(1, 1.5, 4), mats.roof)\n roof.rotation.y = Math.PI / 4\n roof.scale.set((hw + 1.2) / Math.SQRT2, 1, (hd + 1.2) / Math.SQRT2)\n roof.position.set(hcx, 2.8 + 0.75, hcz)\n roof.castShadow = roof.receiveShadow = true\n g.add(roof)\n box(1.1, 2.1, 0.08, mats.door, 6, 1.05, HOUSE.z0 - 0.04)\n box(1.6, 1.1, 0.08, mats.glass, 3.8, 1.5, HOUSE.z0 - 0.04)\n box(1.6, 1.1, 0.08, mats.glass, 8.2, 1.5, HOUSE.z0 - 0.04)\n // walls\n box(5, 1.4, 0.2, mats.wall, 2.5, 0.7, 0)\n box(5, 1.4, 0.2, mats.wall, 9.5, 0.7, 0)\n box(0.2, 1.8, LOT.D, mats.wall, 0, 0.9, 10)\n box(0.2, 1.8, LOT.D, mats.wall, LOT.W, 0.9, 10)\n box(LOT.W, 1.8, 0.2, mats.wall, 6, 0.9, LOT.D)\n return g\n}\n\n/**\n * The nursery: the 12 x 20 m plot of the Viveiro's lot demo (house, walls, street, path) planted by `scatterRulesFor` + `scatter` + `buildLot`, and the walker that crosses it and bends\n * the plants (the wind shader's actors). The module owns it; `plant` builds it, `clear` takes it away.\n */\nexport function createNursery(sdk: VegetationSdk, species: SpeciesSdk, THREE: Three, materials: MaterialsLike, parent: any, origin: readonly [number, number]) {\n // three with its primitive geometries made by game-shapes (bit-identical, cached by parameters)\n const T = shapeGeometries(THREE) as Three\n const group = new THREE.Group()\n group.name = 'nursery'\n group.position.set(origin[0], 0, origin[1])\n const dynamic = new THREE.Group()\n const colliders = new THREE.Group()\n colliders.visible = false\n let scenery: any = null\n let lotObject: any = null\n let data: ReturnType<VegetationSdk['buildLot']> | null = null\n let stats: LotStats | null = null\n let actor: any = null\n const walker = { x: WAY[0]![0], z: WAY[0]![1], waypoint: 0, on: false }\n const actors = [{ x: 0, y: 0.8, z: 0, radius: 1.5 }]\n let attached = false\n\n const disposeObject = (object: any): void => {\n object.traverse((child: any) => {\n child.geometry?.dispose?.()\n })\n }\n const clearGroup = (g: any): void => {\n for (const child of [...g.children]) {\n g.remove(child)\n disposeObject(child)\n child.material?.dispose?.()\n }\n }\n const ensure = (): void => {\n if (attached) return\n attached = true\n scenery = buildScenery(T)\n // a capsule where this three.js has one (r139+), else a cylinder of the same size\n const body = T.CapsuleGeometry ? new T.CapsuleGeometry(0.28, 1.0, 4, 10) : new T.CylinderGeometry(0.28, 0.28, 1.56, 10)\n actor = new THREE.Mesh(body, new THREE.MeshStandardMaterial({ color: 0xd9822b, roughness: 0.7 }))\n actor.castShadow = true\n actor.position.set(walker.x, 0.78, walker.z)\n actor.visible = false\n group.add(scenery, dynamic, colliders, actor)\n parent.add(group)\n }\n\n const blocked = (x: number, z: number): boolean => {\n if (x < 0.55 || x > LOT.W - 0.55 || z < 0.55 || z > LOT.D - 0.55) return true\n if (x > HOUSE.x0 - 0.4 && x < HOUSE.x1 + 0.4 && z > HOUSE.z0 - 0.4 && z < HOUSE.z1 + 0.4) return true\n if (data) {\n for (const c of data.colliders) {\n const dx = x - c.x\n const dz = z - c.z\n const r = c.r + 0.3\n if (dx * dx + dz * dz < r * r) return true\n }\n }\n return false\n }\n\n return {\n group,\n get stats(): LotStats | null {\n return stats\n },\n get planted(): boolean {\n return lotObject !== null\n },\n get walking(): boolean {\n return walker.on\n },\n get position(): { x: number; z: number } {\n return { x: walker.x, z: walker.z }\n },\n /** Plants the lot with the settings (replaces the one standing). */\n plant(settings: NurserySettings): LotStats {\n ensure()\n if (lotObject) {\n dynamic.remove(lotObject)\n disposeObject(lotObject)\n lotObject = null\n }\n clearGroup(colliders)\n const { placements, used } = scatterLot(sdk, species, settings.seed)\n const t0 = Date.now()\n data = sdk.buildLot(placements, (id) => species.toSpec(id), { seed: `quintal-${settings.seed}`, quality: settings.quality, lod: settings.lod, condition: settings.condition, season: settings.season })\n const buildMs = Date.now() - t0\n lotObject = sdk.createLotObject(THREE, data, materials as never)\n lotObject.traverse((c: any) => {\n if (c.isMesh) {\n c.castShadow = true\n c.receiveShadow = true\n }\n })\n dynamic.add(lotObject)\n for (const c of data.colliders) {\n const m = new THREE.Mesh(new T.CylinderGeometry(c.r, c.r, c.h, 14, 1, true), new THREE.MeshBasicMaterial({ color: c.damage ? 0xff7a1a : 0xe5251d, wireframe: true }))\n m.position.set(c.x, c.h / 2, c.z)\n colliders.add(m)\n }\n stats = { triangles: data.triangleCount, plants: data.plantCount, colliders: data.colliders.length, meshes: Object.keys(data.meshes).length, lod: data.lodCounts, buildMs, species: used.size }\n return stats\n },\n /** The colliders of the lot as wire cylinders. */\n showColliders(on: boolean): void {\n colliders.visible = on\n },\n /** Starts or stops the walker that crosses the lot along `WAY`, bending the plants. */\n setWalker(on: boolean): void {\n ensure()\n walker.on = on\n actor.visible = on\n if (!on) {\n actors[0]!.radius = 0\n materials.setActors(actors)\n } else actors[0]!.radius = 1.5\n },\n step(dt: number): void {\n if (!attached || !walker.on) return\n const target = WAY[walker.waypoint]!\n const ddx = target[0] - walker.x\n const ddz = target[1] - walker.z\n const d = Math.hypot(ddx, ddz)\n let dx = 0\n let dz = 0\n if (d < 0.25) walker.waypoint = (walker.waypoint + 1) % WAY.length\n else {\n dx = ddx / d\n dz = ddz / d\n }\n if (dx || dz) {\n const sp = 2.0 * dt\n const nx = walker.x + dx * sp\n const nz = walker.z + dz * sp\n if (!blocked(nx, walker.z)) walker.x = nx\n if (!blocked(walker.x, nz)) walker.z = nz\n if (blocked(nx, nz)) walker.waypoint = (walker.waypoint + 1) % WAY.length\n actor.rotation.y = Math.atan2(dx, dz)\n }\n actor.position.set(walker.x, 0.78, walker.z)\n const a = actors[0]!\n a.x = origin[0] + walker.x\n a.z = origin[1] + walker.z\n a.y = 0.8\n materials.setActors(actors)\n },\n /** Takes the lot, the walker and the scenery away. */\n clear(): void {\n if (walker.on) this.setWalker(false)\n if (lotObject) {\n dynamic.remove(lotObject)\n disposeObject(lotObject)\n lotObject = null\n }\n clearGroup(colliders)\n if (attached) {\n parent.remove(group)\n clearGroup(group)\n attached = false\n scenery = null\n actor = null\n }\n data = null\n stats = null\n walker.x = WAY[0]![0]\n walker.z = WAY[0]![1]\n walker.waypoint = 0\n },\n }\n}\n\nexport type Nursery = ReturnType<typeof createNursery>\n","import type { AnimationClipSpec, DestructibleSpec, JointSpec, PartSpec, TestableItem } from '@adatechnology/game-contracts'\nimport type { Condition, PlantMesh, PlantSpec } from '@adatechnology/game-vegetation'\n\nimport type { MaterialsLike, SpeciesSdk, VegetationSdk } from './types'\n\n/** The seed of every plant of the area (the Viveiro's module fixes it, so the plants are the same in every run). */\nexport const PLANT_SEED = 3\n\nexport type PlantDefKind = 'tree' | 'shrub' | 'hedge' | 'flower' | 'cactus' | 'pot' | 'tuft'\n\n/** One item of the area: a species of the pack (or a variant of it) and how it is built. */\nexport type PlantDef = {\n readonly id: string\n /** The species the plant is generated from (default: `id`). */\n readonly base?: string\n readonly kind: PlantDefKind\n readonly sway: boolean\n /** Fields of the species spec replaced for this item. */\n readonly over?: Readonly<Record<string, number>>\n /** The name, `[pt-BR, en]`, when the species name does not fit the variant. */\n readonly name?: readonly [string, string]\n readonly condition?: Condition\n /** Plants side by side (a hedge is 4 sections joined by their stems). */\n readonly segments?: number\n readonly movable?: boolean\n}\n\n/** The 18 items of the Viveiro's module, in its order. */\nexport const PLANT_DEFS: readonly PlantDef[] = [\n { id: 'mango_tree', kind: 'tree', sway: true },\n // young mango trees (same species, thin trunk): the 15 and 30 cm trunks on which the SDK documents the number of axe swings\n { id: 'mango_young_15', base: 'mango_tree', kind: 'tree', sway: true, over: { height: 1.7, trunkRadius: 0.1, crownRadius: 1.0 }, name: ['Mangueira jovem (tronco de 15 cm)', 'Young mango tree (15 cm trunk)'] },\n { id: 'mango_young_30', base: 'mango_tree', kind: 'tree', sway: true, over: { height: 1.7, trunkRadius: 0.17, crownRadius: 1.2 }, name: ['Mangueira jovem (tronco de 30 cm)', 'Young mango tree (30 cm trunk)'] },\n { id: 'yellow_ipe', kind: 'tree', sway: true },\n { id: 'coconut_palm', kind: 'tree', sway: true },\n { id: 'banana_with_bunch', kind: 'tree', sway: true },\n { id: 'araucaria', kind: 'tree', sway: true },\n { id: 'dead_tree', kind: 'tree', sway: true, condition: 'dead' },\n { id: 'hibiscus_shrub', kind: 'shrub', sway: true },\n { id: 'boxwood_hedge', kind: 'hedge', sway: true, segments: 4 },\n { id: 'rose_bush_red', kind: 'shrub', sway: true },\n { id: 'sunflower', kind: 'flower', sway: true },\n { id: 'mandacaru', kind: 'cactus', sway: false },\n { id: 'prickly_pear', kind: 'cactus', sway: false },\n { id: 'crown_cactus', kind: 'cactus', sway: false },\n { id: 'potted_fern', kind: 'pot', sway: true, movable: true },\n { id: 'potted_cactus', kind: 'pot', sway: false, movable: true },\n { id: 'lawn_tuft', kind: 'tuft', sway: true },\n]\n\n/** The id of a mesh or a joint: lower case, runs of other characters turned into one `_` (`crown:flowers` becomes `crown_flowers`). */\nexport const sanitize = (s: string): string => String(s).toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '')\n\n/** What `buildObject` records in `userData.veg` of each piece mesh. */\nexport type PieceMeta = {\n id: string\n piece: string\n kind: string\n sub: string | null\n base: string\n parent: string | null\n seg: number\n materialKey: string\n radius?: number\n length?: number\n axis?: [number, number, number]\n /** Where the plant of this section stands along x in the object (sections of a hedge are side by side). */\n dx: number\n}\n\ntype Three = any\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] }\n\n/** Fraction of the volume of the shape that is solid, by destruction material (what the spec reports as `fill`). */\nconst FILL: Record<string, number> = { green_wood: 0.5, wood_soft: 0.5, foliage: 0.035, flowers: 0.03, flesh_fruit: 0.8, ceramic: 0.2, soil: 0.7, cactus: 0.5 }\n/** Radians of sway, by kind of piece. */\nconst SWAY_AMPLITUDE: Record<string, number> = { trunk: 0.004, branch: 0.012, crown: 0.03, fruit: 0.04, stem: 0.025, arm: 0, pad: 0, pot: 0, soil: 0 }\n\nexport function createPlants(sdk: VegetationSdk, species: SpeciesSdk, materials: (THREE: Three) => MaterialsLike, seed = PLANT_SEED) {\n const defs = new Map(PLANT_DEFS.map((def) => [def.id, def]))\n const specFor = (def: PlantDef): PlantSpec => {\n const spec = species.toSpec(def.base ?? def.id)\n return def.over ? ({ ...spec, ...def.over } as PlantSpec) : spec\n }\n const cache = new Map<string, PlantMesh>()\n const plantFor = (def: PlantDef, segment: number): PlantMesh => {\n const key = `${def.id}:${segment}`\n let plant = cache.get(key)\n if (!plant) {\n plant = sdk.generate(specFor(def), { seed: seed + segment * 7, ...(def.condition ? { condition: def.condition } : {}) })\n cache.set(key, plant)\n }\n return plant\n }\n\n // ---- the 3D object ----------------------------------------------------------------------------------------------------------------------\n function buildObject(THREE: Three, def: PlantDef): any {\n const root = new THREE.Group()\n root.name = def.id\n const segments = def.segments ?? 1\n let spacing = 0\n for (let s = 0; s < segments; s++) {\n const plant = plantFor(def, s)\n const object: any = sdk.createPlantObject(THREE, plant, materials(THREE), { separable: true })\n const prefix = segments > 1 ? `s${s}_` : ''\n const children = object.children.slice()\n if (s === 0 && segments > 1) {\n const g0 = children[0].geometry\n g0.computeBoundingBox()\n spacing = (g0.boundingBox.max.x - g0.boundingBox.min.x) * 0.9\n }\n for (const mesh of children) {\n const piece = mesh.userData.destructionPart\n const bits = String(piece.id).split(':')\n const id = prefix + sanitize(piece.id)\n mesh.name = id\n const dx = (s - (segments - 1) / 2) * spacing\n const meta: PieceMeta = {\n id,\n piece: piece.id,\n kind: piece.kind,\n sub: bits[1] ?? null,\n base: prefix + sanitize(bits[0] as string),\n parent: piece.parent ? prefix + sanitize(piece.parent) : null,\n seg: s,\n materialKey: piece.materialKey,\n radius: piece.radius,\n length: piece.length,\n axis: piece.axis,\n dx,\n }\n mesh.userData.veg = meta\n mesh.position.x += dx\n mesh.castShadow = true\n root.add(mesh)\n }\n if (s === 0) {\n root.userData.collider = plant.collider || null\n root.userData.thorny = !!plant.thorny\n }\n }\n root.userData.speciesId = def.id\n root.userData.separable = true\n root.userData.segments = segments\n return root\n }\n\n // ---- the destruction spec -----------------------------------------------------------------------------------------------------------------\n function buildSpec(root: any, def: PlantDef): DestructibleSpec {\n const meshes: any[] = root.children.filter((c: any) => c.isMesh && c.userData.veg)\n const byId: Record<string, any> = {}\n for (const m of meshes) byId[(m.userData.veg as PieceMeta).id] = m\n const parts: Mutable<PartSpec>[] = []\n for (const m of meshes) {\n const v = m.userData.veg as PieceMeta\n const g = m.geometry\n if (!g.boundingBox) g.computeBoundingBox()\n const b = g.boundingBox\n const mn = [b.min.x + m.position.x, b.min.y + m.position.y, b.min.z + m.position.z]\n const mx = [b.max.x + m.position.x, b.max.y + m.position.y, b.max.z + m.position.z]\n const size: [number, number, number] = [Math.max(mx[0]! - mn[0]!, 0.02), Math.max(mx[1]! - mn[1]!, 0.02), Math.max(mx[2]! - mn[2]!, 0.02)]\n const c: [number, number, number] = [(mn[0]! + mx[0]!) / 2, (mn[1]! + mx[1]!) / 2, (mn[2]! + mx[2]!) / 2]\n const material = m.userData.destructionMaterial as string\n const round = v.kind === 'trunk' || v.kind === 'pot'\n let shape: PartSpec['shape'] = round ? { kind: 'cylinder', radius: Math.max(size[0], size[2]) / 2, height: size[1] } : { kind: 'box', size }\n // wood pieces: the real thickness of the SDK (2 x radius by the length along the axis) instead of the bounding box, which overstates leaning trunks, flared bases and curved pieces\n let rotation: [number, number, number] | null = null\n if (!v.sub && (v.radius ?? 0) > 0 && (v.length ?? 0) > 0 && (v.kind === 'trunk' || v.kind === 'branch' || v.kind === 'arm' || v.kind === 'stem')) {\n const rr = Math.max(v.radius as number, 0.01)\n const ll = Math.max(v.length as number, 0.02)\n shape = v.kind === 'trunk' ? { kind: 'cylinder', radius: rr, height: ll } : { kind: 'box', size: [rr * 2, ll, rr * 2] }\n if (v.axis) {\n // the y axis of the shape along the axis of the piece (Euler XYZ: x = atan2(az, ay), z = -asin(ax))\n const ax = v.axis\n const tilt = Math.hypot(ax[0], ax[2])\n if (tilt > 0.02 && ax[1] > -0.99) rotation = [Math.atan2(ax[2], ax[1]), 0, -Math.asin(Math.max(-1, Math.min(1, ax[0])))]\n }\n }\n const tags: string[] = []\n const p: Mutable<PartSpec> = { id: v.id, material, shape, position: c, tags }\n if (rotation) p.rotation = rotation\n p.fill = v.sub === 'spines' ? 0.02 : v.sub === 'flowers' ? 0.01 : v.kind === 'trunk' ? 0.8 : v.kind === 'branch' ? 0.1 : v.kind === 'arm' ? 0.12 : v.kind === 'pad' ? 0.3 : (FILL[material] ?? 0.5)\n if (v.kind === 'fruit' || v.sub === 'wood') p.mass = 15\n if (v.kind === 'trunk') {\n p.grain = 'y'\n tags.push('trunk')\n }\n if (v.kind === 'branch') tags.push('branch')\n if (material === 'foliage' || v.sub === 'foliage') tags.push('leaf')\n if (v.sub === 'flowers') tags.push('flower')\n if (v.sub === 'spines') tags.push('thorns')\n if (v.kind === 'fruit') tags.push('fruit')\n if (v.kind === 'arm') tags.push('arm')\n if (v.kind === 'pad') tags.push('pad')\n if (v.kind === 'pot') {\n // explicit hp: a terracotta pot breaks in 1 to 3 shots of 9 mm\n p.mass = 2.4\n p.hp = 25\n tags.push('pot')\n }\n if (v.kind === 'soil') {\n p.mass = 3.2\n tags.push('soil')\n }\n if (def.kind === 'pot' && v.kind === 'stem' && !v.sub) p.mass = 0.4\n if (def.kind === 'pot' && v.sub) p.mass = 0.05\n // the root piece is fixed to the ground (a loose pot anchors nothing)\n const isRoot = !v.parent && !v.sub && (v.kind === 'trunk' || v.kind === 'pad' || (v.kind === 'stem' && def.kind !== 'pot'))\n if (isRoot && !def.movable) p.anchored = true\n parts.push(p)\n }\n\n const joints: JointSpec[] = []\n const seen = new Set<string>()\n const add = (a: string | null, b: string, kind: JointSpec['kind'], extra?: Partial<JointSpec>): void => {\n if (!a || !b || a === b || !byId[a] || !byId[b]) return\n const id = `${a}~${b}`\n if (seen.has(id)) return\n seen.add(id)\n joints.push({ id, a, b, kind, ...extra })\n }\n const firstOf = (seg: number, kind: string): string | null => {\n for (const m of meshes) {\n const v = m.userData.veg as PieceMeta\n if (v.seg === seg && v.kind === kind && !v.sub) return v.id\n }\n return null\n }\n for (const m of meshes) {\n const v = m.userData.veg as PieceMeta\n if (v.sub) {\n add(v.base, v.id, 'tie')\n continue\n }\n if (v.kind === 'soil') {\n add(v.parent, v.id, 'resting')\n continue\n }\n if (v.parent) {\n add(v.parent, v.id, 'stem', v.kind === 'arm' ? { strength: 60 } : undefined)\n continue\n }\n if (v.kind === 'fruit') {\n add(firstOf(v.seg, 'crown') || firstOf(v.seg, 'pad') || firstOf(v.seg, 'stem') || firstOf(v.seg, 'trunk'), v.id, 'stem')\n continue\n }\n if (def.kind === 'pot' && v.kind === 'stem') add(firstOf(v.seg, 'soil'), v.id, 'tie')\n }\n // hedge: neighbouring sections held by their stems\n const segments = def.segments ?? 1\n if (segments > 1) for (let s = 0; s + 1 < segments; s++) add(`s${s}_stem`, `s${s + 1}_stem`, 'stem')\n return { name: def.id, parts, joints, tags: ['plant'] }\n }\n\n // ---- the wind -----------------------------------------------------------------------------------------------------------------------------\n function swayClip(def: PlantDef): AnimationClipSpec {\n const plant = plantFor(def, 0)\n const segments = def.segments ?? 1\n const keys: { t: number; parts: Record<string, { rotation: [number, number, number] }> }[] = []\n const N = 8\n const D = 4\n for (let k = 0; k <= N; k++) {\n const ph = (k / N) * Math.PI * 2\n const parts: Record<string, { rotation: [number, number, number] }> = {}\n for (let s = 0; s < segments; s++) {\n const prefix = segments > 1 ? `s${s}_` : ''\n for (const pc of plant.pieces) {\n const a = SWAY_AMPLITUDE[pc.kind] || 0\n if (!a) continue\n if (pc.kind === 'stem' && /(^|:)wood$/.test(pc.id)) continue\n if (def.kind === 'pot' && pc.kind === 'stem' && pc.id.indexOf(':') < 0 && def.id === 'potted_cactus') continue\n const f = pc.id.indexOf(':flowers') > 0 ? 1.6 : 1\n parts[prefix + sanitize(pc.id)] = { rotation: [Math.sin(ph + s) * a * f * 0.6, 0, Math.sin(ph * 1 + 0.7 + s) * a * f] }\n }\n }\n keys.push({ t: (k / N) * D, parts: k === 0 || k === N ? {} : parts })\n }\n return { id: 'sway', duration: D, keys, events: [{ t: 0.2, type: 'sound', data: { key: 'leaves_rustle' } }] } as AnimationClipSpec\n }\n\n // ---- the items ----------------------------------------------------------------------------------------------------------------------------\n function items(locale: string, defsToUse: readonly PlantDef[] = PLANT_DEFS): TestableItem[] {\n const loc = String(locale || 'pt-BR').toLowerCase().indexOf('en') === 0 ? 'en' : 'pt-BR'\n return defsToUse.map((def) => {\n const item: Mutable<TestableItem> = {\n id: def.id,\n name: def.name ? (def.name[loc === 'en' ? 1 : 0] as string) : species.name(def.base ?? def.id, loc),\n build: (THREE: unknown) => buildObject(THREE, def),\n spec: (root: unknown) => {\n const spec = buildSpec(root, def)\n ;(root as { userData: Record<string, unknown> }).userData.vegSpec = spec\n return spec\n },\n movable: !!def.movable,\n }\n if (def.sway) item.animations = [swayClip(def)]\n return item\n })\n }\n\n return { defs, specFor, plantFor, buildObject, buildSpec, swayClip, items }\n}\n\nexport type Plants = ReturnType<typeof createPlants>\n","import type { ModuleScenario } from '@adatechnology/game-contracts'\n\nimport type { VegetationContext, VegetationRoom } from './types'\n\ntype A = any\ntype V3 = [number, number, number]\ntype Spawned = { objectId: string; root: { userData: Record<string, any> } }\n\n/**\n * The 13 scenarios of the Viveiro's vegetation module, literal (same objects, same tools, same sentences, in both languages). `veg_*` are the ids of the page.\n * A tool is taken with `setTool`; the room gives every tool its draw time, so each one waits for it (`room.waitUntilReady`) where the page's room used it at once.\n */\nexport function createScenarios(locale: string): ModuleScenario<VegetationContext>[] {\n const en = String(locale || 'pt-BR').toLowerCase().indexOf('en') === 0\n const L = (pt: string, e: string): string => (en ? e : pt)\n const yn = (b: unknown): string => (b ? L('sim', 'yes') : L('não', 'no'))\n\n const specOf = (so: Spawned): A => so.root.userData.vegSpec\n const partSpec = (so: Spawned, pid: string): A => specOf(so).parts.filter((p: A) => p.id === pid)[0]\n const world = (so: Spawned, local: V3): V3 => {\n const r = so.root as A\n return [r.position.x + local[0], r.position.y + local[1], r.position.z + local[2]]\n }\n const norm = (v: V3): V3 => {\n const l = Math.hypot(v[0], v[1], v[2]) || 1\n return [v[0] / l, v[1] / l, v[2] / l]\n }\n const dist = (a: V3, b: V3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2])\n const DIRS: V3[] = [[0, 0, -1], [1, 0, 0], [-1, 0, 0], [0, 0, 1], [0.7, 0, -0.7], [-0.7, 0, -0.7], [0.7, 0, 0.7], [-0.7, 0, 0.7], [0, -1, 0]]\n\n const center = (so: Spawned, pid: string): V3 => world(so, partSpec(so, pid).position)\n\n // Joint tools (saw, knife): the camera position from which the ray hits something within 0.45 m of the joint asked for. Aims the camera.\n const aim = (room: VegetationRoom, so: Spawned, target: V3, standoff: number, opt: { beyond?: number; joint?: string; jointRange?: number } = {}): A => {\n let best: A = null\n for (const dir of DIRS) {\n const d = norm(dir)\n const origin: V3 = [target[0] - d[0] * standoff, target[1] - d[1] * standoff, target[2] - d[2] * standoff]\n if (origin[1] < 0.25) continue\n const hit = room.world.raycast(origin, d, standoff + (opt.beyond == null ? 0.6 : opt.beyond))\n if (!hit || hit.object !== so.objectId) continue\n let score = dist(hit.point, target)\n if (opt.joint) {\n const nj = room.world.nearestJoint(so.objectId, hit.point, opt.jointRange || 0.45)\n if (!nj || nj.id !== opt.joint) score += 20\n }\n if (!best || score < best.score) best = { score, origin, target, hit }\n }\n if (!best) best = { score: 99, origin: [target[0], target[1], target[2] + standoff], target, hit: null }\n room.look(best.origin, best.target)\n return best\n }\n // Weapons and fire: finds a horizontal (or from above) direction from which the first hit of the ray is the piece `pid`, and puts the camera `gap` metres from the surface\n // (blade stroke: 0.5; lighter: 0.08; shot: 2.5). `at` changes the aimed point (object local).\n const AIMDIRS: V3[] = [[0, 0, -1], [0.7, 0, -0.7], [-0.7, 0, -0.7], [1, 0, 0], [-1, 0, 0], [0, -1, 0], [0.7, 0, 0.7], [-0.7, 0, 0.7], [0, 0, 1]]\n const aimPart = (room: VegetationRoom, so: Spawned, pidsIn: string | string[], gap: number, at?: V3): { origin: V3; point: V3; found: boolean; pid: string } => {\n const pids = typeof pidsIn === 'string' ? [pidsIn] : pidsIn\n let best: A = null\n for (const pid of pids) {\n const c = at ? world(so, at) : center(so, pid)\n for (const dir of AIMDIRS) {\n const d = norm(dir)\n const far = 8\n const origin: V3 = [c[0] - d[0] * far, c[1] - d[1] * far, c[2] - d[2] * far]\n if (origin[1] < 0.3) continue\n const hit = room.world.raycast(origin, d, far + 3)\n if (!hit || hit.object !== so.objectId || hit.part !== pid) continue\n const score = dist(hit.point, c)\n if (!best || score < best.score) best = { score, d, hit, pid }\n }\n }\n if (!best) best = { score: 99, d: [0, 0, -1], hit: { point: center(so, pids[0] as string) }, pid: pids[0] }\n const H = best.hit.point as V3\n const from: V3 = [H[0] - best.d[0] * gap, H[1] - best.d[1] * gap, H[2] - best.d[2] * gap]\n if (from[1] < 0.3) from[1] = 0.3\n room.look(from, [H[0] + best.d[0] * 0.3, H[1] + best.d[1] * 0.3, H[2] + best.d[2] * 0.3])\n return { origin: from, point: H, found: best.score < 99, pid: best.pid }\n }\n const crownsOf = (so: Spawned): string[] => specOf(so).parts.filter((p: A) => /^(s\\d+_)?crown\\d*$/.test(p.id)).map((p: A) => p.id)\n const jointPos = (so: Spawned, jid: string): V3 => {\n const j = specOf(so).joints.filter((x: A) => x.id === jid)[0]\n const a = partSpec(so, j.a)\n const b = partSpec(so, j.b)\n const box = (p: A): { min: V3; max: V3 } => {\n const h: V3 = p.shape.kind === 'box' ? p.shape.size.map((s: number) => s / 2) : [p.shape.radius, p.shape.height / 2, p.shape.radius]\n const r = p.rotation || [0, 0, 0] // only x and z (see buildSpec): Euler XYZ = Rx * Rz\n const cx = Math.cos(r[0]), sx = Math.sin(r[0]), cz = Math.cos(r[2]), sz = Math.sin(r[2])\n const mn: V3 = [Infinity, Infinity, Infinity]\n const mx: V3 = [-Infinity, -Infinity, -Infinity]\n for (let i = 0; i < 8; i++) {\n const x = (i & 1 ? 1 : -1) * h[0], y = (i & 2 ? 1 : -1) * h[1], z = (i & 4 ? 1 : -1) * h[2]\n const x1 = x * cz - y * sz, y1 = x * sz + y * cz\n const w = [x1, y1 * cx - z * sx, y1 * sx + z * cx]\n for (let k = 0; k < 3; k++) {\n mn[k] = Math.min(mn[k] as number, p.position[k] + (w[k] as number))\n mx[k] = Math.max(mx[k] as number, p.position[k] + (w[k] as number))\n }\n }\n return { min: mn, max: mx }\n }\n const A_ = box(a)\n const B_ = box(b)\n return world(so, [0, 1, 2].map((k) => (Math.max(A_.min[k] as number, B_.min[k] as number) + Math.min(A_.max[k] as number, B_.max[k] as number)) / 2) as V3)\n }\n const lost = (p: A): boolean => !p || p.status === 'broken' || p.status === 'ashes' || p.status === 'melted'\n // The state of a piece at an instant: world.snapshot(id) gives a copy (state() / part() are live views).\n const snap = (room: VegetationRoom, so: Spawned, pid: string): A => {\n const st = room.world.snapshot(so.objectId)\n const p = st && st.parts.filter((x: A) => x.id === pid)[0]\n if (!p) return null\n return { status: p.status, hp: p.hp, maxHp: p.maxHp, temperature: p.temperature, burning: p.burning, char: p.char || 0, fuel: p.fuel, holes: (p.holes || []).length, material: p.material }\n }\n const logCount = (room: VegetationRoom, so: Spawned, type: string): number => room.log.entries({ type, objectId: so.objectId }).length\n // Joints opened in the log: 'detach' lines (one per joint, or several in one) plus those the 'fracture' event sums up in jointsOpened.\n const jointsOpened = (room: VegetationRoom, so: Spawned): number => {\n let n = 0\n for (const e of room.log.entries({ type: 'detach', objectId: so.objectId })) n += e.data && e.data.joints ? e.data.joints.length : 1\n for (const e of room.log.entries({ type: 'fracture', objectId: so.objectId })) n += (e.data && e.data.jointsOpened) || 0\n return n\n }\n const detachedJoint = (room: VegetationRoom, so: Spawned, jid: string): boolean =>\n room.log.entries({ type: 'detach', objectId: so.objectId }).some((e: A) => e.data && (e.data.joint === jid || (e.data.joints || []).indexOf(jid) >= 0))\n const spawn = (room: VegetationRoom, id: string, x: number, z: number): Spawned => room.spawn(id, [x, 0, z], 0)\n // When a group comes loose, the world moves it to a new object (`obj_N`). `home` is the original object, `loose` the ones that came off.\n const split = (room: VegetationRoom, so: Spawned): A => {\n const home = room.world.snapshot(so.objectId)\n const loose = room.world.ids().filter((i) => /^obj_/.test(i)).map((i) => ({ id: i, st: room.world.snapshot(i) }))\n const anchored: Record<string, boolean> = {}\n for (const p of specOf(so).parts) if (p.anchored) anchored[p.id] = true\n const rooted: string[] = []\n for (const g of home.groups as string[][]) if (g.some((pid) => anchored[pid])) for (const pid of g) rooted.push(pid)\n const inLoose = (pid: string): boolean => loose.some((o) => o.st.parts.some((p: A) => p.id === pid && !lost(p)))\n const inHome = (pid: string): boolean => home.parts.some((p: A) => p.id === pid && !lost(p))\n return { home, loose, rooted, inLoose, inHome, sections: home.groups.length + loose.length }\n }\n\n // Axe on the trunk until it breaks (at most `max` swings); gives the count and the state of the trunk.\n const fell = (room: VegetationRoom, ctx: VegetationContext, so: Spawned, max: number): { swings: number; trunk: A } => {\n take(room, 'axe')\n let swings = 0\n const h = partSpec(so, 'trunk').shape.height\n for (let i = 0; i < max; i++) {\n aimPart(room, so, 'trunk', 0.5, [0, Math.min(0.9, h / 3), 0])\n room.use()\n ctx.step(1.5)\n swings++\n if (lost(room.world.part(so.objectId, 'trunk'))) break\n }\n ctx.step(5)\n return { swings, trunk: snap(room, so, 'trunk') }\n }\n\n const sc = (id: string, ptName: string, enName: string, run: (ctx: VegetationContext) => void): ModuleScenario<VegetationContext> => ({ id: `veg_${id}`, name: L(ptName, enName), run })\n const pct = (x: number): string => `${Math.round((x || 0) * 100)}%`\n // the room gives every tool its draw time; the page's room used the tool the moment it was taken\n const take = (room: VegetationRoom, id: string): void => {\n room.setTool(id)\n room.waitUntilReady()\n }\n\n return [\n // 1 ---------------------------------------------------------------------------------------------------------------\n sc('axe_fells_crown', 'Machado no tronco de 15 cm derruba a copa (8 a 15 golpes)', 'Axe on a 15 cm trunk fells the crown (8 to 15 swings)', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_young_15', 0, -6)\n const r = fell(room, ctx, so, 60)\n const sp = split(room, so)\n const crownGone = lost(room.world.part(so.objectId, 'crown')) || !sp.inHome('crown') || sp.rooted.indexOf('crown') < 0\n const branches: string[] = specOf(so).parts.filter((p: A) => p.tags.indexOf('branch') >= 0).map((p: A) => p.id)\n const branchesFree = branches.every((b) => sp.rooted.indexOf(b) < 0)\n const detach = jointsOpened(room, so)\n ctx.expect(r.trunk.status === 'broken' && r.swings >= 8 && r.swings <= 15, L(`Machado no tronco de 15 cm (hp ${Math.round(r.trunk.maxHp)}): tronco ${r.trunk.status} depois de ${r.swings} golpes (esperado: broken em 8 a 15 golpes)`, `Axe on a 15 cm trunk (hp ${Math.round(r.trunk.maxHp)}): trunk ${r.trunk.status} after ${r.swings} swings (expected: broken in 8 to 15 swings)`), { swings: r.swings, status: r.trunk.status, maxHp: r.trunk.maxHp })\n ctx.expect(sp.rooted.length === 0 && crownGone && branchesFree, L(`Nada da copa continua preso ao chão: peças ainda enraizadas ${sp.rooted.length}, copa solta ${yn(crownGone)}, ${branches.length} galhos soltos ${yn(branchesFree)} (esperado: 0, sim, sim)`, `Nothing of the crown stays rooted: rooted pieces ${sp.rooted.length}, crown free ${yn(crownGone)}, ${branches.length} branches free ${yn(branchesFree)} (expected: 0, yes, yes)`), { rooted: sp.rooted.length })\n ctx.expect(detach > 0 && sp.loose.length > 0, L(`Registro: ${detach} soltura(s) de junta (as juntas se abrem quando o tronco se perde) e ${sp.loose.length} pedaço(s) caindo como objeto próprio (esperado: 1 ou mais de cada)`, `Log: ${detach} joint detach(es) (joints open when the trunk is lost) and ${sp.loose.length} piece(s) falling as their own object (expected: 1+ each)`), { detach, loose: sp.loose.length })\n }),\n sc('axe_fells_30cm', 'Machado no tronco de 30 cm (25 a 40 golpes)', 'Axe on a 30 cm trunk (25 to 40 swings)', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_young_30', 0, -6)\n const r = fell(room, ctx, so, 90)\n const sp = split(room, so)\n ctx.expect(r.trunk.status === 'broken' && r.swings >= 25 && r.swings <= 40, L(`Machado no tronco de 30 cm (hp ${Math.round(r.trunk.maxHp)}): tronco ${r.trunk.status} depois de ${r.swings} golpes (esperado: broken em 25 a 40 golpes)`, `Axe on a 30 cm trunk (hp ${Math.round(r.trunk.maxHp)}): trunk ${r.trunk.status} after ${r.swings} swings (expected: broken in 25 to 40 swings)`), { swings: r.swings, status: r.trunk.status, maxHp: r.trunk.maxHp })\n ctx.expect(sp.rooted.length === 0, L(`Árvore caída: peças ainda presas ao chão ${sp.rooted.length} (esperado: 0)`, `Fallen tree: pieces still rooted ${sp.rooted.length} (expected: 0)`), { rooted: sp.rooted.length })\n }),\n sc('axe_cuts_branch_joint', 'Machado passa pela junta tronco-galho', 'Axe works through the trunk-branch joint', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_tree', 0, -6)\n const jid = 'trunk~branch1'\n take(room, 'axe')\n let swings = 0\n let detached = false\n for (let i = 0; i < 60 && !detached; i++) {\n aim(room, so, jointPos(so, jid), 0.5, { joint: jid, beyond: 0.3 })\n room.use()\n ctx.step(1.5)\n swings++\n detached = detachedJoint(room, so, jid)\n }\n ctx.step(3)\n const trunk = snap(room, so, 'trunk')\n const sp = split(room, so)\n const branchOff = sp.inLoose('branch1') && !sp.inHome('branch1')\n const restStays = sp.inHome('trunk') && sp.rooted.indexOf('trunk') >= 0\n ctx.expect(detached && branchOff, L(`Machado na junta ${jid}: galho solto ${yn(branchOff)} depois de ${swings} golpe(s), com o tronco ${trunk.status} (esperado: sim)`, `Axe on joint ${jid}: branch detached ${yn(branchOff)} after ${swings} swing(s), trunk ${trunk.status} (expected: yes)`), { swings })\n ctx.expect(trunk.status !== 'broken' && restStays, L(`A junta cedeu antes do tronco: tronco ${trunk.status}, tronco de pé e preso ao chão ${yn(restStays)} (esperado: não quebrado, sim)`, `The joint gave way before the trunk: trunk ${trunk.status}, trunk standing and rooted ${yn(restStays)} (expected: not broken, yes)`), {})\n }),\n sc('shot_cannot_fell', 'Tiro de 9 mm não derruba a árvore', 'A 9 mm shot never fells a tree', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_young_15', 0, -6)\n take(room, 'pistol_9mm')\n let shots = 0\n for (let i = 0; i < 30; i++) {\n aimPart(room, so, 'trunk', 2.5, [0, 0.5, 0])\n room.use()\n ctx.step(0.4)\n shots++\n }\n const trunk = snap(room, so, 'trunk')\n const sp = split(room, so)\n ctx.expect(trunk.status !== 'broken' && trunk.hp > 0, L(`${shots} tiros de 9 mm no tronco de 15 cm: tronco ${trunk.status}, hp ${Math.round(trunk.hp)}/${Math.round(trunk.maxHp)} (esperado: não quebrado)`, `${shots} 9 mm shots on the 15 cm trunk: trunk ${trunk.status}, hp ${Math.round(trunk.hp)}/${Math.round(trunk.maxHp)} (expected: not broken)`), { shots, hp: trunk.hp })\n ctx.expect(sp.loose.length === 0 && sp.inHome('trunk') && sp.rooted.indexOf('crown') >= 0, L(`A árvore continua de pé: pedaços soltos ${sp.loose.length}, copa presa ao chão ${yn(sp.rooted.indexOf('crown') >= 0)} (esperado: 0, sim)`, `The tree still stands: loose pieces ${sp.loose.length}, crown rooted ${yn(sp.rooted.indexOf('crown') >= 0)} (expected: 0, yes)`), {})\n }),\n // 2 ---------------------------------------------------------------------------------------------------------------\n sc('saw_cuts_branch', 'Serra no galho', 'Saw on a branch', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'yellow_ipe', 0, -6)\n const jid = 'trunk~branch1'\n take(room, 'hacksaw')\n aim(room, so, jointPos(so, jid), 0.45, { joint: jid })\n room.use(4)\n ctx.step(1)\n const sp = split(room, so)\n const movedBranch = sp.inLoose('branch1') && !sp.inHome('branch1')\n const movedCrown = sp.inLoose('crown1')\n const restStays = ['trunk', 'branch0', 'branch2', 'branch3', 'crown'].every((pid) => sp.inHome(pid) && sp.rooted.indexOf(pid) >= 0)\n const detach = logCount(room, so, 'detach')\n ctx.expect(movedBranch && detach > 0, L(`Serra na junta tronco-galho 1: galho solto do tronco ${yn(movedBranch)}, ${detach} linha(s) de soltura no log (esperado: sim, 1)`, `Saw on the trunk-branch 1 joint: branch detached ${yn(movedBranch)}, ${detach} detach line(s) in the log (expected: yes, 1)`), { detach })\n ctx.expect(movedCrown, L(`A folhagem do galho cortado foi junto: ${yn(movedCrown)} (esperado: sim)`, `The foliage of the cut branch went with it: ${yn(movedCrown)} (expected: yes)`), {})\n ctx.expect(restStays, L(`O resto da árvore (tronco, outros galhos e copa) continua inteiro e preso ao chão: ${yn(restStays)} (esperado: sim)`, `The rest of the tree (trunk, other branches, crown) stays whole and rooted: ${yn(restStays)} (expected: yes)`), {})\n }),\n // 3 ---------------------------------------------------------------------------------------------------------------\n sc('lighter_ignites_foliage', 'Isqueiro na folhagem pega fogo', 'Lighter on the foliage catches fire', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_tree', 0, -6)\n take(room, 'lighter')\n const a = aimPart(room, so, crownsOf(so), 0.08)\n room.use(6)\n const crown = snap(room, so, a.pid)\n const lit = crown.burning || crown.temperature > 300\n let peak = 0\n let charMax = 0\n for (let t = 0; t < 18; t++) {\n ctx.step(5)\n for (const p of room.world.state(so.objectId).parts) {\n if (p.material === 'green_wood') {\n peak = Math.max(peak, p.temperature)\n charMax = Math.max(charMax, p.char || 0)\n }\n }\n }\n const st = room.world.state(so.objectId)\n const burnt = st.parts.filter((p: A) => p.material === 'foliage' && (p.burning || p.char > 0 || p.status === 'ashes')).length\n ctx.expect(lit, L(`Isqueiro na copa: folhagem acesa ou acima de 300 °C = ${yn(lit)} (${Math.round(crown.temperature)} °C; esperado: sim)`, `Lighter on the crown: foliage lit or above 300 C = ${yn(lit)} (${Math.round(crown.temperature)} C; expected: yes)`), { temperature: crown.temperature })\n ctx.expect(burnt > 0, L(`Depois de 90 s: ${burnt} peça(s) de folhagem queimando, carbonizada(s) ou em cinza (esperado: 1 ou mais)`, `After 90 s: ${burnt} foliage piece(s) burning, charred or ash (expected: 1+)`), { burnt })\n ctx.expect(peak > 150 || charMax > 0, L(`O fogo da folhagem passa para a madeira verde (tronco e galhos): pico de ${Math.round(peak)} °C, carbonização máxima ${pct(charMax)} (esperado: pico acima de 150 °C ou carbonização acima de 0; a madeira verde só pega fogo acima de 400 °C)`, `Foliage fire reaches the green wood (trunk and branches): peak ${Math.round(peak)} C, max char ${pct(charMax)} (expected: peak above 150 C or char above 0; green wood only ignites above 400 C)`), { peak, charMax })\n }),\n // 4 ---------------------------------------------------------------------------------------------------------------\n sc('shot_strips_leaves', 'Tiro na copa arranca folhas', 'A shot into the crown strips leaves', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_tree', 0, -6)\n take(room, 'pistol_9mm')\n const tgt = aimPart(room, so, crownsOf(so), 2.5).pid\n const before = snap(room, so, tgt)\n for (let i = 0; i < 3; i++) {\n aimPart(room, so, tgt, 2.5)\n room.use()\n ctx.step(0.6)\n }\n const crown = snap(room, so, tgt)\n const leaves = room.log.entries({ type: 'debris', objectId: so.objectId }).filter((e: A) => e.data && e.data.kind === 'leaves').length\n const hurt = crown.hp < before.hp || crown.status === 'broken'\n ctx.expect(hurt && crown.status !== 'intact', L(`Três tiros na copa: hp ${Math.round(before.hp)} para ${Math.round(crown.hp)}, estado ${crown.status} (esperado: hp menor, não intacta)`, `Three shots into the crown: hp ${Math.round(before.hp)} to ${Math.round(crown.hp)}, status ${crown.status} (expected: lower hp, not intact)`), { hp: crown.hp })\n ctx.expect(leaves > 0 || crown.holes > 0, L(`Folhas arrancadas: ${leaves} linha(s) de folhas voando, ${crown.holes} furo(s) na copa (esperado: 1 ou mais)`, `Leaves torn off: ${leaves} flying-leaf line(s), ${crown.holes} hole(s) in the crown (expected: 1+)`), { leaves, holes: crown.holes })\n }),\n // 5 ---------------------------------------------------------------------------------------------------------------\n sc('shot_breaks_pot', 'Tiros quebram o vaso e a terra se espalha', 'Shots break the pot and the soil spills', (ctx) => {\n const room = ctx.room\n const so = room.spawn('potted_fern', [0, 0, -4], 0)\n take(room, 'pistol_9mm')\n // terracotta pot with an explicit hp of 25: it breaks in 1 to 3 shots of 9 mm; the pot-soil joint bursts and the soil comes loose\n let shots = 0\n for (let i = 0; i < 12; i++) {\n const cur = snap(room, so, 'pot')\n if (!cur) break // the pot already left the original object\n aimPart(room, so, 'pot', 1.5)\n room.use()\n ctx.step(0.5)\n shots++\n const after = snap(room, so, 'pot')\n if (after && (after.status === 'broken' || after.hp <= 0)) break // broke\n }\n ctx.step(3)\n const sp = split(room, so)\n let potNow = snap(room, so, 'pot')\n for (const o of sp.loose) {\n const q = o.st.parts.filter((x: A) => x.id === 'pot')[0]\n if (q) potNow = q\n }\n const soilOut = sp.inLoose('soil') || !sp.inHome('soil')\n const soilApart = !sp.home.groups.some((g: string[]) => g.indexOf('soil') >= 0 && g.indexOf('pot') >= 0)\n const cracks = room.log.entries({ type: 'crack', objectId: so.objectId }).length\n const dt = jointsOpened(room, so)\n ctx.expect(!!potNow && (potNow.status === 'broken' || potNow.hp <= 0) && shots >= 1 && shots <= 4, L(`Tiros no vaso: o vaso quebra: cerâmica ${potNow && potNow.status} com hp ${potNow ? `${Math.round(potNow.hp)}/${Math.round(potNow.maxHp)}` : '?'} e ${cracks} trinca(s) depois de ${shots} tiro(s) de 9 mm (esperado: vaso quebrado em 1 a 4 tiros)`, `Shots into the pot: the pot breaks: ceramic ${potNow && potNow.status} with hp ${potNow ? `${Math.round(potNow.hp)}/${Math.round(potNow.maxHp)}` : '?'} and ${cracks} crack(s) after ${shots} 9 mm shot(s) (expected: pot broken in 1 to 4 shots)`), { status: potNow && potNow.status, shots, cracks })\n ctx.expect(soilApart || soilOut, L(`A terra saiu do vaso e caiu junto com a planta: ${yn(soilApart || soilOut)} (esperado: sim)`, `The soil left the pot and fell with the plant: ${yn(soilApart || soilOut)} (expected: yes)`), {})\n ctx.expect(dt > 0, L(`Registro: ${dt} soltura(s) de junta (esperado: 1 ou mais)`, `Log: ${dt} joint detach(es) (expected: 1+)`), { detach: dt })\n }),\n // 6 ---------------------------------------------------------------------------------------------------------------\n sc('machete_arm', 'Machete na junta do braço do mandacaru', 'Machete on the mandacaru arm joint', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mandacaru', 0, -5)\n take(room, 'machete')\n const arm = 'arm0'\n const jid = `stem~${arm}`\n let swings = 0\n let detached = false\n for (let i = 0; i < 40 && !detached; i++) {\n aim(room, so, jointPos(so, jid), 0.55, { joint: jid, beyond: 0.3 })\n room.use()\n ctx.step(1.2)\n swings++\n detached = detachedJoint(room, so, jid) || lost(room.world.part(so.objectId, arm))\n }\n ctx.step(3)\n const a = snap(room, so, arm)\n const sp = split(room, so)\n const armOff = !a || a.status === 'broken' || (sp.inLoose(arm) && !sp.inHome(arm))\n const stemOk = sp.inHome('stem') && sp.rooted.indexOf('stem') >= 0 && room.world.part(so.objectId, 'stem').status !== 'broken'\n const spines = specOf(so).parts.filter((p: A) => p.tags.indexOf('thorns') >= 0)\n const thorny = so.root.userData.thorny === true && spines.length > 0\n const spinesOff = !sp.rooted.some((pid: string) => pid.indexOf(`${arm}_spines`) === 0)\n ctx.expect(armOff, L(`Machete na junta ${jid}: braço ${a ? a.status : 'solto como objeto próprio'} depois de ${swings} golpe(s) (esperado: solto do caule pela junta)`, `Machete on joint ${jid}: arm ${a ? a.status : 'loose as its own object'} after ${swings} swing(s) (expected: off the stem through the joint)`), { swings })\n ctx.expect(stemOk, L(`O caule principal continua de pé e preso ao chão: ${yn(stemOk)} (esperado: sim)`, `The main stem stays standing and rooted: ${yn(stemOk)} (expected: yes)`), {})\n ctx.expect(thorny && spinesOff, L(`Espinhos: cacto marcado como espinhoso (userData.thorny, ${spines.length} peças de espinho) ${yn(thorny)}, espinhos do braço saíram junto ${yn(spinesOff)} (esperado: sim, sim)`, `Thorns: cactus flagged thorny (userData.thorny, ${spines.length} spine pieces) ${yn(thorny)}, the arm spines went with it ${yn(spinesOff)} (expected: yes, yes)`), { spines: spines.length })\n }),\n // 7 ---------------------------------------------------------------------------------------------------------------\n sc('pad_pulled', 'Palma arrancada', 'Prickly pear pad pulled off', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'prickly_pear', 0, -4)\n const jid = 'pad0~pad1'\n take(room, 'utility_knife')\n aim(room, so, jointPos(so, jid), 0.25, { joint: jid, beyond: 0.3 })\n room.use(1.7)\n ctx.step(1)\n const sp = split(room, so)\n const padOff = sp.inLoose('pad1') && !sp.inHome('pad1')\n const childWith = sp.inLoose('pad3')\n const spinesWith = sp.inLoose('pad1_spines')\n const motherOk = sp.inHome('pad0') && sp.rooted.indexOf('pad0') >= 0 && sp.inHome('pad2')\n ctx.expect(padOff, L(`Raquete 1 cortada da planta-mãe na junta ${jid}: ${yn(padOff)} (esperado: sim)`, `Pad 1 cut off the mother plant at joint ${jid}: ${yn(padOff)} (expected: yes)`), {})\n ctx.expect(childWith && spinesWith, L(`A raquete filha (3) e os espinhos da raquete 1 vão junto: ${yn(childWith && spinesWith)} (esperado: sim)`, `The child pad (3) and the spines of pad 1 go with it: ${yn(childWith && spinesWith)} (expected: yes)`), {})\n ctx.expect(motherOk, L(`A planta-mãe (raquetes 0 e 2) fica presa ao chão: ${yn(motherOk)} (esperado: sim)`, `The mother plant (pads 0 and 2) stays rooted: ${yn(motherOk)} (expected: yes)`), {})\n }),\n // 8 ---------------------------------------------------------------------------------------------------------------\n sc('dead_burns_faster', 'Árvore morta queima mais rápido que viva', 'A dead tree burns faster than a living one', (ctx) => {\n const room = ctx.room\n const dead = spawn(room, 'dead_tree', -4, -6)\n const live = spawn(room, 'mango_tree', 4, -6)\n take(room, 'lighter')\n for (const so of [dead, live]) {\n aimPart(room, so, 'trunk', 0.08, [0, 0.8, 0])\n room.use(8)\n }\n const d0 = snap(room, dead, 'trunk')\n const l0 = snap(room, live, 'trunk')\n ctx.step(120)\n const d = snap(room, dead, 'trunk')\n const l = snap(room, live, 'trunk')\n const score = (p: A): number => (p ? Math.max(p.char, p.burning ? 0.01 : 0, (p.temperature - 20) / 2000) : 0)\n ctx.expect(d0.material === 'wood_soft' && l0.material === 'green_wood', L(`Materiais do tronco: árvore morta ${d0.material}, viva ${l0.material} (esperado: wood_soft, green_wood)`, `Trunk materials: dead tree ${d0.material}, living ${l0.material} (expected: wood_soft, green_wood)`), { dead: d0.material, live: l0.material })\n ctx.expect(score(d) > score(l), L(`Depois de 8 s de isqueiro e 120 s de espera: morta queimando ${yn(d.burning)}, ${Math.round(d.temperature)} °C, carbonização ${pct(d.char)}; viva queimando ${yn(l.burning)}, ${Math.round(l.temperature)} °C, carbonização ${pct(l.char)} (esperado: a morta mais queimada)`, `After 8 s of lighter and 120 s of waiting: dead burning ${yn(d.burning)}, ${Math.round(d.temperature)} C, char ${pct(d.char)}; living burning ${yn(l.burning)}, ${Math.round(l.temperature)} C, char ${pct(l.char)} (expected: dead burns more)`), { dead: score(d), live: score(l) })\n }),\n // 9 ---------------------------------------------------------------------------------------------------------------\n sc('hedge_cut_pieces', 'Cerca viva cortada em partes', 'Hedge cut into sections', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'boxwood_hedge', 0, -5)\n take(room, 'hacksaw')\n for (const jid of ['s0_stem~s1_stem', 's2_stem~s3_stem']) {\n aim(room, so, jointPos(so, jid), 0.45, { joint: jid })\n room.use(1.7)\n ctx.step(0.3)\n }\n ctx.step(1)\n const sp = split(room, so)\n const all: A[] = [...sp.home.parts]\n for (const o of sp.loose) all.push(...o.st.parts)\n const alive = all.filter((p) => !lost(p)).length\n const total = specOf(so).parts.length\n ctx.expect(sp.sections === 3, L(`Duas serradas na cerca viva: ${sp.sections} parte(s) separada(s) (esperado: 3)`, `Two saw cuts in the hedge: ${sp.sections} separate section(s) (expected: 3)`), { sections: sp.sections })\n ctx.expect(alive === total, L(`Nenhuma seção foi destruída, só separada: ${alive} de ${total} peças inteiras (esperado: todas)`, `No section was destroyed, only separated: ${alive} of ${total} pieces intact (expected: all)`), { alive, total })\n }),\n // 10 --------------------------------------------------------------------------------------------------------------\n sc('walk_on_grass', 'Pisar na grama não colide', 'Walking on grass does not collide', (ctx) => {\n const room = ctx.room\n const tuft = spawn(room, 'lawn_tuft', 0, -3)\n const tree = spawn(room, 'mango_tree', 4, -3)\n const noBlock = !tuft.root.userData.collider\n const treeBlock = !!(tree.root.userData.collider && tree.root.userData.collider.kind)\n ctx.expect(noBlock && treeBlock, L(`Colisor do SDK: touceira ${noBlock ? 'nenhum' : 'tem'}, tronco da mangueira ${treeBlock ? 'tem' : 'nenhum'} (esperado: nenhum, tem)`, `SDK collider: tuft ${noBlock ? 'none' : 'has one'}, mango trunk ${treeBlock ? 'has one' : 'none'} (expected: none, has one)`), {})\n // really walks: room.walk(to, seconds) moves the player through the room's own loop (ctx.step advances the simulation, with no host loop)\n room.look([0, 1.7, -0.5], [0, 1.7, -6])\n const before = room.camera.position.z\n room.walk([0, 1.7, -6], 3)\n ctx.step(3.2)\n const after = room.camera.position.z\n const tp = snap(room, tuft, 'stem')\n ctx.expect(after < -3.3 && !!tp && tp.status === 'intact', L(`Andando para a frente (room.walk): z foi de ${before.toFixed(1)} a ${after.toFixed(1)}, atravessou a touceira ${yn(after < -3.3)}, touceira ${tp && tp.status} (esperado: atravessou, intacta)`, `Walking forward (room.walk): z went from ${before.toFixed(1)} to ${after.toFixed(1)}, crossed the tuft ${yn(after < -3.3)}, tuft ${tp && tp.status} (expected: crossed, intact)`), { before, after })\n }),\n ]\n}\n","/** Words of the vegetation area's bench. */\nexport type VegetationText = {\n group: string\n name: string\n controls: Record<'seed' | 'quality' | 'lod' | 'condition' | 'season' | 'wind' | 'gust', string>\n hints: Record<'seed' | 'quality' | 'lod' | 'condition' | 'season' | 'wind' | 'gust', string>\n options: { quality: Record<string, string>; lod: Record<string, string>; condition: Record<string, string>; season: Record<string, string> }\n actions: Record<'plant_lot' | 'clear_lot' | 'toggle_walker', string>\n layers: Record<'colliders' | 'piece_boxes' | 'wood_axes', string>\n metrics: Record<'plants' | 'pieces' | 'triangles' | 'draw_calls' | 'lot_triangles' | 'lot_plants' | 'lot_colliders' | 'lot_lod0' | 'lot_lod1' | 'lot_lod2' | 'lot_ms', string>\n lot: Record<'planted' | 'cleared' | 'walker_on' | 'walker_off', string>\n}\n\nexport const TEXT: Record<string, VegetationText> = {\n en: {\n group: 'Trees, plants and flowers',\n name: 'Vegetation',\n controls: { seed: 'Lot seed', quality: 'Lot quality', lod: 'Lot detail (LOD)', condition: 'Condition', season: 'Season', wind: 'Wind', gust: 'Gusts' },\n hints: {\n seed: 'The seed of the nursery lot: the same seed plants the same yard',\n quality: 'High: every plant at the detail below. Game: one level for all plants and small ones cheaper, with a triangle budget',\n lod: 'Level of detail of the plants of the lot (0 the most detailed)',\n condition: 'How the lot plants look: healthy, dry, dead or overgrown (decides green or dry wood for the destruction)',\n season: 'Season of the lot (flowers and leaf colours)',\n wind: 'Strength of the wind that sways the leaves, flowers and grass',\n gust: 'Slowly varying extra push on top of the wind',\n },\n options: {\n quality: { high: 'High', game: 'Game' },\n lod: { '0': 'LOD 0', '1': 'LOD 1', '2': 'LOD 2' },\n condition: { healthy: 'Healthy', dry: 'Dry', dead: 'Dead', overgrown: 'Overgrown' },\n season: { spring: 'Spring', summer: 'Summer', autumn: 'Autumn', winter: 'Winter' },\n },\n actions: { plant_lot: 'Plant the nursery lot', clear_lot: 'Remove the nursery lot', toggle_walker: 'Start or stop the walker' },\n layers: { colliders: 'Colliders (trunks and cactus bodies)', piece_boxes: 'Boxes of the pieces', wood_axes: 'Wood axes (radius, length, axis)' },\n metrics: { plants: 'Plants placed', pieces: 'Pieces', triangles: 'Triangles', draw_calls: 'Draw calls', lot_triangles: 'Lot triangles', lot_plants: 'Lot plants', lot_colliders: 'Lot colliders', lot_lod0: 'Lot plants at LOD 0', lot_lod1: 'Lot plants at LOD 1', lot_lod2: 'Lot plants at LOD 2', lot_ms: 'Lot build time' },\n lot: { planted: 'Nursery lot planted: {0} plants, {1} triangles, {2} colliders', cleared: 'Nursery lot removed', walker_on: 'The walker crosses the lot and bends the plants', walker_off: 'The walker stopped' },\n },\n 'pt-BR': {\n group: 'Árvores, plantas e flores',\n name: 'Vegetação',\n controls: { seed: 'Semente do canteiro', quality: 'Qualidade do canteiro', lod: 'Detalhe do canteiro (LOD)', condition: 'Condição', season: 'Estação', wind: 'Vento', gust: 'Rajadas' },\n hints: {\n seed: 'A semente do canteiro: a mesma semente planta o mesmo quintal',\n quality: 'Alta: todas as plantas no detalhe abaixo. Jogo: um nível para todas e as pequenas mais baratas, com orçamento de triângulos',\n lod: 'Nível de detalhe das plantas do canteiro (0 o mais detalhado)',\n condition: 'Como ficam as plantas do canteiro: saudável, seca, morta ou malcuidada (decide madeira verde ou seca na destruição)',\n season: 'Estação do canteiro (flores e cor das folhas)',\n wind: 'Força do vento que balança folhas, flores e grama',\n gust: 'Empurrão extra que varia devagar, somado ao vento',\n },\n options: {\n quality: { high: 'Alta', game: 'Jogo' },\n lod: { '0': 'LOD 0', '1': 'LOD 1', '2': 'LOD 2' },\n condition: { healthy: 'Saudável', dry: 'Seca', dead: 'Morta', overgrown: 'Malcuidada' },\n season: { spring: 'Primavera', summer: 'Verão', autumn: 'Outono', winter: 'Inverno' },\n },\n actions: { plant_lot: 'Plantar o canteiro', clear_lot: 'Tirar o canteiro', toggle_walker: 'Ligar ou desligar o caminhante' },\n layers: { colliders: 'Colisores (troncos e corpos de cacto)', piece_boxes: 'Caixas das peças', wood_axes: 'Eixos da madeira (raio, comprimento, eixo)' },\n metrics: { plants: 'Plantas postas', pieces: 'Peças', triangles: 'Triângulos', draw_calls: 'Chamadas de desenho', lot_triangles: 'Triângulos do canteiro', lot_plants: 'Plantas do canteiro', lot_colliders: 'Colisores do canteiro', lot_lod0: 'Plantas do canteiro em LOD 0', lot_lod1: 'Plantas do canteiro em LOD 1', lot_lod2: 'Plantas do canteiro em LOD 2', lot_ms: 'Tempo de montagem do canteiro' },\n lot: { planted: 'Canteiro plantado: {0} plantas, {1} triângulos, {2} colisores', cleared: 'Canteiro retirado', walker_on: 'O caminhante cruza o canteiro e dobra as plantas', walker_off: 'O caminhante parou' },\n },\n}\n\nexport const fill = (template: string, ...values: readonly unknown[]): string => template.replace(/\\{(\\d+)\\}/g, (_m, i: string) => String(values[Number(i)]))\n","import type { BenchChange, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ModuleScenario, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { shapeGeometries } from '@adatechnology/game-shapes-three'\nimport * as GameVegetationMain from '@adatechnology/game-vegetation'\nimport * as GameVegetationAdapter from '@adatechnology/game-vegetation/three'\nimport * as GameVegetationSpeciesMain from '@adatechnology/game-vegetation-species'\nimport type { Condition, Lod, Season } from '@adatechnology/game-vegetation'\n\nimport { createNursery } from './nursery'\nimport type { Nursery } from './nursery'\nimport { createPlants, PLANT_DEFS, PLANT_SEED } from './plants'\nimport type { PieceMeta } from './plants'\nimport { createScenarios } from './scenarios'\nimport { fill, TEXT } from './text'\nimport type { MaterialsLike, SpeciesSdk, VegetationContext, VegetationSdk, VegetationTestOptions } from './types'\n\nexport const VEGETATION_AREA_ID = 'vegetation'\n\n/** The 18 item ids of the Viveiro's module, in its order. */\nexport const VEGETATION_ITEM_IDS: readonly string[] = PLANT_DEFS.map((def) => def.id)\n\n/** The ids of the 13 scenarios (the ids of the Viveiro's page, `veg_*`). */\nexport const VEGETATION_SCENARIO_IDS: readonly string[] = [\n 'veg_axe_fells_crown',\n 'veg_axe_fells_30cm',\n 'veg_axe_cuts_branch_joint',\n 'veg_shot_cannot_fell',\n 'veg_saw_cuts_branch',\n 'veg_lighter_ignites_foliage',\n 'veg_shot_strips_leaves',\n 'veg_shot_breaks_pot',\n 'veg_machete_arm',\n 'veg_pad_pulled',\n 'veg_dead_burns_faster',\n 'veg_hedge_cut_pieces',\n 'veg_walk_on_grass',\n]\n\ntype Three = any\ntype Placed = { readonly root: any; helpers: any[] }\n\nconst defaultSdk = (): VegetationSdk => ({ ...GameVegetationMain, ...GameVegetationAdapter }) as VegetationSdk\nconst AXIS_COLOURS: Record<string, number> = { trunk: 0xd9822b, branch: 0xe5c07b, arm: 0x6fcf6f, stem: 0x6fcf97, pad: 0x6fb7cf }\n\n/**\n * The vegetation test area as a `TestableModule`: the 18 plants of the Viveiro (mango trees of three sizes, ipe, palm, banana, araucaria, dead tree, hibiscus, hedge, rose, sunflower, three\n * cacti, two pots, a lawn tuft) as items of the default destruction world, each piece a mesh with its spec (shape from the real wood thickness, joints, anchors, tags, sway clip), and the 13\n * scenarios of that page (literal). The bench plants the nursery lot (12 x 20 m, with house, walls and path, by `scatterRulesFor`) with its seed, quality, detail, condition and season, sets\n * the wind and starts the walker that bends the plants; its layers show the colliders, the boxes of the pieces and the axes of the wood; its metrics read triangles, pieces and draw calls.\n */\nexport function createVegetationTestModule(options: VegetationTestOptions = {}): TestableModule<VegetationContext> & { readonly placed: ReadonlyMap<string, unknown>; materials(THREE?: unknown): MaterialsLike; tick(t: number): void; readonly itemIds: readonly string[] } {\n const locale = options.locale ?? 'pt-BR'\n const text = TEXT[locale.toLowerCase().startsWith('en') ? 'en' : 'pt-BR'] as (typeof TEXT)[string]\n const sdk: VegetationSdk = options.GameVegetation ?? defaultSdk()\n const species: SpeciesSdk = options.GameVegetationSpecies ?? (GameVegetationSpeciesMain as SpeciesSdk)\n let mats: MaterialsLike | null = options.materials ?? null\n let three: Three = null\n let host: ModuleHost | null = null\n const materials = (THREE?: unknown): MaterialsLike => {\n if (!mats) mats = sdk.createVegetationMaterials((THREE ?? three) as never) as unknown as MaterialsLike\n return mats\n }\n const plants = createPlants(sdk, species, (THREE) => materials(THREE), options.seed ?? PLANT_SEED)\n const placed = new Map<string, Placed>()\n const settings = { seed: 1, quality: 'high' as 'high' | 'game', lod: 0 as Lod, condition: 'healthy' as Condition, season: 'spring' as Season, wind: 0.35, gust: 0.15 }\n let nursery: Nursery | null = null\n let clock = 0\n let helpersShown = ''\n\n const item = (base: TestableItem): TestableItem => ({\n ...base,\n build: (THREE: unknown) => {\n three = THREE\n const root = base.build(THREE) as any\n placed.set(root.uuid, { root, helpers: [] })\n return root\n },\n })\n\n // ---- the layers ---------------------------------------------------------------------------------------------------------------------------\n const clearHelpers = (): void => {\n for (const entry of placed.values()) {\n for (const helper of entry.helpers) helper.parent?.remove(helper)\n entry.helpers = []\n }\n helpersShown = ''\n }\n const boxKey = (): string => `${host?.bench?.layer('colliders')}|${host?.bench?.layer('piece_boxes')}|${host?.bench?.layer('wood_axes')}|${placed.size}`\n const refreshLayers = (): void => {\n if (!host?.bench || !three) return\n clearHelpers()\n nursery?.showColliders(host.bench.layer('colliders'))\n for (const entry of placed.values()) {\n const root = entry.root\n if (!root.parent) continue\n const mark = (helper: any): void => {\n helper.userData.helper = true\n root.add(helper)\n entry.helpers.push(helper)\n }\n if (host.bench.layer('colliders') && root.userData.collider && root.userData.collider.kind) {\n const c = root.userData.collider\n const wire = new three.Mesh(new (shapeGeometries(three) as any).CylinderGeometry(c.radius, c.radius, c.height, 14, 1, true), new three.MeshBasicMaterial({ color: root.userData.thorny ? 0xff7a1a : 0xe5251d, wireframe: true }))\n wire.position.set(0, c.height / 2, 0)\n mark(wire)\n }\n for (const mesh of root.children) {\n const v = mesh.userData?.veg as PieceMeta | undefined\n if (!v || !mesh.geometry) continue\n if (host.bench.layer('piece_boxes')) {\n mesh.geometry.computeBoundingBox()\n const box = mesh.geometry.boundingBox.clone().translate(mesh.position)\n mark(new three.Box3Helper(box, 0x66ccff))\n }\n if (host.bench.layer('wood_axes') && v.radius !== undefined && v.length !== undefined && v.axis && !v.sub) {\n // the base of the piece is in plant space; the section of a hedge stands `dx` to the side\n const base = pieceBase(root, v)\n if (base) {\n const from = new three.Vector3(base[0] + v.dx, base[1], base[2])\n const to = from.clone().add(new three.Vector3(v.axis[0], v.axis[1], v.axis[2]).multiplyScalar(v.length))\n const line = new three.Line(new three.BufferGeometry().setFromPoints([from, to]), new three.LineBasicMaterial({ color: AXIS_COLOURS[v.kind] ?? 0xffffff }))\n mark(line)\n }\n }\n }\n }\n helpersShown = boxKey()\n }\n // the `base` of a wood piece is recorded on the destruction part of its mesh by the SDK; the module keeps it in `userData.destructionPart` of the mesh\n const pieceBase = (root: any, v: PieceMeta): Vec3 | null => {\n const mesh = root.children.find((c: any) => c.userData?.veg?.id === v.id)\n const base = mesh?.userData?.destructionPart?.base\n return Array.isArray(base) ? (base as Vec3) : null\n }\n\n // ---- the nursery ----------------------------------------------------------------------------------------------------------------------------\n const nurseryOf = (): Nursery | null => {\n if (!host || !three) return null\n if (!nursery) nursery = createNursery(sdk, species, three, materials(three), host.scene, options.nurseryOrigin ?? [-6, 14])\n return nursery\n }\n const plantLot = (): void => {\n const n = nurseryOf()\n if (!n || !host) return\n const stats = n.plant(settings)\n n.showColliders(Boolean(host.bench?.layer('colliders')))\n host.log(fill(text.lot.planted, stats.plants, stats.triangles, stats.colliders), { plants: stats.plants, triangles: stats.triangles })\n }\n const replant = (): void => {\n if (nursery?.planted) plantLot()\n }\n\n // ---- the bench ---------------------------------------------------------------------------------------------------------------------------------\n const applyWind = (): void => {\n if (mats) mats.setWind({ strength: settings.wind, gust: settings.gust })\n }\n const onChange = (change: BenchChange): void => {\n if (change.kind === 'layer') return refreshLayers()\n if (change.kind === 'action') {\n if (change.id === 'plant_lot') plantLot()\n else if (change.id === 'clear_lot') {\n nursery?.clear()\n host?.log(text.lot.cleared)\n } else if (change.id === 'toggle_walker') {\n const n = nurseryOf()\n if (!n) return\n if (!n.planted) plantLot()\n n.setWalker(!n.walking)\n host?.log(n.walking ? text.lot.walker_on : text.lot.walker_off)\n }\n return\n }\n switch (change.id) {\n case 'seed': settings.seed = Number(change.value); replant(); break\n case 'quality': settings.quality = String(change.value) as 'high' | 'game'; replant(); break\n case 'lod': settings.lod = Number(change.value) as Lod; replant(); break\n case 'condition': settings.condition = String(change.value) as Condition; replant(); break\n case 'season': settings.season = String(change.value) as Season; replant(); break\n case 'wind': settings.wind = Number(change.value); applyWind(); break\n case 'gust': settings.gust = Number(change.value); applyWind(); break\n default: break\n }\n }\n\n const frame = (dt: number): void => {\n clock += dt\n if (mats) mats.update(clock)\n for (const [id, entry] of placed) if (!entry.root.parent) placed.delete(id)\n if (host?.bench && boxKey() !== helpersShown && (host.bench.layer('colliders') || host.bench.layer('piece_boxes') || host.bench.layer('wood_axes') || helpersShown !== '')) refreshLayers()\n nursery?.step(dt)\n }\n\n const count = (): { drawCalls: number; triangles: number; pieces: number } => {\n let drawCalls = 0\n let triangles = 0\n let pieces = 0\n for (const entry of placed.values()) {\n entry.root.traverse((mesh: any) => {\n if (!mesh.isMesh || mesh.userData.helper) return\n for (let p = mesh; p; p = p.parent) if (p.visible === false) return\n drawCalls += 1\n if (mesh.userData.veg) pieces += 1\n const g = mesh.geometry\n triangles += (g.index ? g.index.count : g.attributes.position.count) / 3\n })\n }\n return { drawCalls, triangles: Math.round(triangles), pieces }\n }\n const lotCalls = (): number => {\n let calls = 0\n nursery?.group.traverse((o: any) => {\n if (o.isMesh && o.visible) calls += 1\n })\n return calls\n }\n\n return {\n id: VEGETATION_AREA_ID,\n name: text.name,\n group: text.group,\n get placed() {\n return placed\n },\n itemIds: VEGETATION_ITEM_IDS,\n materials,\n tick: (t: number) => {\n if (mats) mats.update(t)\n },\n items: (loc: string) => plants.items(loc || locale).map(item),\n scenarios: (loc: string): ModuleScenario<VegetationContext>[] => createScenarios(loc || locale),\n area: (): ModuleArea => {\n // three rows by size, each plant given room by its width: the small ones in front, the middle ones behind them, the trees at the back\n const rows: { z: number; ids: readonly string[] }[] = [\n { z: -4, ids: ['hibiscus_shrub', 'rose_bush_red', 'sunflower', 'mandacaru', 'prickly_pear', 'crown_cactus'] },\n { z: -9, ids: ['banana_with_bunch', 'dead_tree', 'boxwood_hedge', 'potted_fern', 'potted_cactus', 'lawn_tuft'] },\n { z: -16, ids: ['mango_tree', 'yellow_ipe', 'coconut_palm', 'araucaria', 'mango_young_30', 'mango_young_15'] },\n ]\n const widths: Record<string, number> = { mango_tree: 5, yellow_ipe: 5, coconut_palm: 4.5, araucaria: 4, mango_young_30: 3, mango_young_15: 2.6, banana_with_bunch: 3.5, dead_tree: 3.5, boxwood_hedge: 5.5, hibiscus_shrub: 2, rose_bush_red: 1.6, sunflower: 1.4, mandacaru: 2.2, prickly_pear: 2, crown_cactus: 1.8, potted_fern: 1.4, potted_cactus: 1.2, lawn_tuft: 1.2 }\n const gap = 1.2\n const placements = rows.flatMap((row) => {\n const total = row.ids.reduce((sum, id) => sum + (widths[id] ?? 2) + gap, -gap)\n let cursor = -total / 2\n return row.ids.map((id) => {\n const width = widths[id] ?? 2\n const x = cursor + width / 2\n cursor += width + gap\n return { item: id, position: [x, 0, row.z] as Vec3, rotationY: 0 }\n })\n })\n return { placements, view: { eye: [0, 6, 8], target: [0, 1.8, -10] } }\n },\n controls: (): ModuleControl[] => [\n { kind: 'number', id: 'seed', name: text.controls.seed, hint: text.hints.seed, min: 0, max: 99999, step: 1, default: 1 },\n { kind: 'choice', id: 'quality', name: text.controls.quality, hint: text.hints.quality, options: (['high', 'game'] as const).map((id) => ({ id, name: text.options.quality[id] as string })), default: 'high' },\n { kind: 'choice', id: 'lod', name: text.controls.lod, hint: text.hints.lod, options: (['0', '1', '2'] as const).map((id) => ({ id, name: text.options.lod[id] as string })), default: '0' },\n { kind: 'choice', id: 'condition', name: text.controls.condition, hint: text.hints.condition, options: (['healthy', 'dry', 'dead', 'overgrown'] as const).map((id) => ({ id, name: text.options.condition[id] as string })), default: 'healthy' },\n { kind: 'choice', id: 'season', name: text.controls.season, hint: text.hints.season, options: (['spring', 'summer', 'autumn', 'winter'] as const).map((id) => ({ id, name: text.options.season[id] as string })), default: 'spring' },\n { kind: 'number', id: 'wind', name: text.controls.wind, hint: text.hints.wind, min: 0, max: 1, step: 0.05, default: 0.35 },\n { kind: 'number', id: 'gust', name: text.controls.gust, hint: text.hints.gust, min: 0, max: 1, step: 0.05, default: 0.15 },\n { kind: 'action', id: 'plant_lot', name: text.actions.plant_lot, slow: true },\n { kind: 'action', id: 'clear_lot', name: text.actions.clear_lot },\n { kind: 'action', id: 'toggle_walker', name: text.actions.toggle_walker, slow: true },\n ],\n layers: (): ModuleLayer[] => (['colliders', 'piece_boxes', 'wood_axes'] as const).map((id) => ({ id, name: text.layers[id], default: false })),\n metrics: (): ModuleMetric[] => [\n { id: 'plants', name: text.metrics.plants, read: () => placed.size },\n { id: 'pieces', name: text.metrics.pieces, read: () => count().pieces },\n { id: 'triangles', name: text.metrics.triangles, read: () => count().triangles },\n { id: 'draw_calls', name: text.metrics.draw_calls, read: () => count().drawCalls + lotCalls() },\n { id: 'lot_triangles', name: text.metrics.lot_triangles, read: () => nursery?.stats?.triangles ?? 0 },\n { id: 'lot_plants', name: text.metrics.lot_plants, read: () => nursery?.stats?.plants ?? 0 },\n { id: 'lot_colliders', name: text.metrics.lot_colliders, read: () => nursery?.stats?.colliders ?? 0 },\n { id: 'lot_lod0', name: text.metrics.lot_lod0, read: () => nursery?.stats?.lod[0] ?? 0 },\n { id: 'lot_lod1', name: text.metrics.lot_lod1, read: () => nursery?.stats?.lod[1] ?? 0 },\n { id: 'lot_lod2', name: text.metrics.lot_lod2, read: () => nursery?.stats?.lod[2] ?? 0 },\n { id: 'lot_ms', name: text.metrics.lot_ms, unit: 'ms', read: () => nursery?.stats?.buildMs ?? 0 },\n ],\n attach(lent) {\n host = lent\n three = lent.THREE\n const stopChange = lent.bench?.onChange(onChange)\n const stopFrame = lent.onFrame(frame)\n applyWind()\n return () => {\n stopChange?.()\n stopFrame()\n clearHelpers()\n nursery?.clear()\n nursery = null\n host = null\n }\n },\n }\n}\n\n/** What `loadVegetationTestModule` needs of a room: `TestRoom.loadModule` has it. */\nexport type ModuleRoomLike = { loadModule(module: never): unknown }\n\n/** Loads the vegetation module into a room. */\nexport function loadVegetationTestModule<Room extends ModuleRoomLike>(room: Room, options: VegetationTestOptions = {}): ReturnType<Room['loadModule']> {\n return room.loadModule(createVegetationTestModule(options) as never) as ReturnType<Room['loadModule']>\n}\n"],"mappings":"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,KAAK,EAAE,CAAC,EAAE,SAAS;AACxE,WAAO;EACT;;;;;;;;;;;;;;;;;;AClNA,MAAA,gBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,cAAgB;QAChB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;QACd,eAAiB;MAClB;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,SAAW;YACV;YACA;UACD;UACA,gBAAkB;UAClB,SAAW;QACZ;QACA,YAAc;QACd,WAAa;MACd;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,SAAW;YACV;YACA;UACD;UACA,gBAAkB;UAClB,SAAW;QACZ;QACA,YAAc;QACd,WAAa;MACd;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,cAAgB;QAChB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;UACV,SAAW;QACZ;QACA,YAAc;QACd,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,SAAW;YACV;YACA;UACD;UACA,gBAAkB;UAClB,SAAW;QACZ;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,cAAgB;QAChB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,SAAW;QACX,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;QACb,WAAa;UACZ;UACA;UACA;UACA;QACD;QACA,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;QACb,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,OAAS;QACT,aAAe;QACf,WAAa;QACb,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,OAAS;QACT,aAAe;QACf,WAAa;QACb,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;MAChB;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AC7hBA,MAAA,gBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,aAAe;QACf,YAAc;QACd,aAAe;QACf,OAAS;UACR,OAAS;UACT,OAAS;UACT,QAAU;QACX;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,aAAe;QACf,YAAc;QACd,aAAe;MAChB;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,aAAe;QACf,YAAc;QACd,aAAe;MAChB;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,OAAS;QACT,aAAe;MAChB;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,aAAe;QACf,OAAS;UACR,OAAS;UACT,OAAS;UACT,QAAU;QACX;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,WAAa;MACd;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,WAAa;QACb,OAAS;QACT,KAAO;MACR;MACA,MAAQ;QACP;QACA;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AChKA,MAAA,iBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,OAAS;QACT,WAAa;UACZ;QACD;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,OAAS;QACT,WAAa;UACZ;QACD;QACA,SAAW;UACV,QAAU;YACT;YACA;UACD;UACA,OAAS;UACT,OAAS;UACT,MAAQ;QACT;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,WAAa;UACZ;UACA;QACD;QACA,SAAW;UACV,QAAU;YACT;YACA;UACD;UACA,OAAS;UACT,OAAS;UACT,MAAQ;QACT;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,WAAa;UACZ;UACA;QACD;QACA,SAAW;UACV,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,OAAS;UACT,MAAQ;QACT;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,WAAa;UACZ;UACA;QACD;QACA,SAAW;UACV,QAAU;YACT;YACA;UACD;UACA,OAAS;UACT,OAAS;UACT,MAAQ;QACT;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,WAAa;UACZ;UACA;QACD;QACA,aAAe;UACd;UACA;UACA;UACA;QACD;QACA,UAAY;MACb;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,OAAS;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,YAAc;QACd,MAAQ;MACT;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;MACX;MACA,MAAQ;QACP;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,SAAW;QACX,WAAa;UACZ;UACA;UACA;QACD;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AChQA,MAAA,kBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;QACD;QACA,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;QACD;QACA,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;QACD;QACA,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;UACA;UACA;QACD;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;UACA;UACA;QACD;QACA,QAAU;QACV,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,WAAa;QACb,aAAe;UACd;QACD;QACA,QAAU;QACV,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,WAAa;QACb,aAAe;UACd;QACD;QACA,QAAU;QACV,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;UACA;UACA;QACD;QACA,QAAU;QACV,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;UACA;UACA;UACA;QACD;QACA,WAAa;QACb,QAAU;MACX;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AC/RA,MAAA,gBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,MAAQ;QACR,UAAY;QACZ,MAAQ;UACP;UACA;QACD;QACA,OAAS;QACT,YAAc;QACd,SAAW;UACV,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,MAAQ;QACR,UAAY;QACZ,MAAQ;QACR,OAAS;MACV;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,QAAU;QACV,MAAQ;QACR,UAAY;QACZ,MAAQ;UACP;UACA;QACD;QACA,OAAS;MACV;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;UACR,OAAS;UACT,OAAS;QACV;QACA,SAAW;UACV,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,QAAU;QACV,MAAQ;QACR,WAAa;UACZ,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,MAAQ;QACR,QAAU;QACV,SAAW;UACV,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,QAAU;QACV,MAAQ;QACR,SAAW;UACV,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;ACvKA,MAAA,qBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;QACR,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;QACR,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;QACR,QAAU;QACV,OAAS;UACR,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;QACR,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AChFA,MAAA,kBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,OAAS;MACV;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,OAAS;QACT,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,OAAS;QACT,QAAU;MACX;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,OAAS;QACT,eAAiB;QACjB,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU,CAAC;MACX,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;UACV,OAAS;QACV;QACA,OAAS;UACR,WAAa;UACb,YAAc;UACd,aAAe;QAChB;MACD;MACA,MAAQ;QACP;QACA;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;ACpIA,MAAA,gBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;UACP,MAAQ;YACP,OAAS;YACT,QAAU;UACX;QACD;QACA,WAAa;QACb,SAAW;UACV,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;UACP,MAAQ;YACP,OAAS;YACT,QAAU;UACX;QACD;QACA,WAAa;QACb,UAAY;QACZ,SAAW;MACZ;MACA,MAAQ;QACP;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;UACP,MAAQ;YACP,OAAS;YACT,QAAU;UACX;QACD;QACA,WAAa;QACb,UAAY;QACZ,SAAW;UACV,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AC5FA,MAAA,iBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;QACX;QACA,OAAS;UACR,WAAa;UACb,YAAc;UACd,aAAe;QAChB;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;UACV,OAAS;QACV;QACA,OAAS;UACR,WAAa;UACb,MAAQ;UACR,QAAU;QACX;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;QACX;QACA,OAAS;UACR,WAAa;UACb,SAAW;UACX,QAAU;UACV,OAAS;UACT,aAAe;UACf,aAAe;QAChB;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;QACX;QACA,OAAS;UACR,WAAa;UACb,QAAU;UACV,QAAU;UACV,MAAQ;UACR,SAAW;YACV,OAAS;YACT,OAAS;UACV;QACD;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;QACX;QACA,OAAS;UACR,WAAa;UACb,YAAc;UACd,aAAe;YACd;UACD;UACA,QAAU;UACV,WAAa;QACd;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;UACV,OAAS;QACV;QACA,OAAS;UACR,WAAa;UACb,MAAQ;UACR,QAAU;QACX;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AC7LA,MAAA,gBAAA;IACC,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,QAAU;MACT,MAAQ;MACR,aAAe;IAChB;IACA,QAAU;MACT,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,qBAAuB;MACtB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,kBAAoB;MACnB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,kBAAoB;MACnB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,SAAW;MACV,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,SAAW;MACV,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,KAAO;MACN,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;EACD;AC7RA,MAAA,aAAA;IACC,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,QAAU;MACT,MAAQ;MACR,aAAe;IAChB;IACA,QAAU;MACT,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,qBAAuB;MACtB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,kBAAoB;MACnB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,kBAAoB;MACnB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,SAAW;MACV,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,SAAW;MACV,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,KAAO;MACN,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;EACD;AC7RA,MAAA,aAAA;IACC,IAAM;IACN,MAAQ;IACR,UAAY;MACX,YAAc;QACb;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,UAAY;QACX;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,eAAiB;QAChB;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,QAAU;QACT;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,YAAc;QACb;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,QAAU;QACT;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,UAAY;QACX;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;IACD;EACD;AC/XA,MAAA,kBAAA;IACC,IAAM;IACN,MAAQ;IACR,UAAY;MACX,YAAc;QACb;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,UAAY;QACX;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,eAAiB;QAChB;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,QAAU;QACT;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,YAAc;QACb;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;U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","names":["width","height","depth","indexArray","sign","tube","len","list","num","equals","area","ring","bs","layeroffset","cache","tube","make","srgbToLinear","n","a","b","c","acc","smooth","ring","len","color","sub","anchors","clump","cache","sphere","DEFAULT_LEAF","clamp","generate","mesh","tube","box","area","area2","list","COMMON","make","PART_ORDER","mesh","generate","species","list","species","area","color","box","mesh","stats","object","species","cache","object","mesh","byId","add","norm","dist","box","species","dist_exports","mesh","box","stats"]}
1
+ {"version":3,"sources":["../src/index.ts","../../game-shapes/src/color.ts","../../game-shapes/src/hash.ts","../../game-shapes/src/math.ts","../../game-shapes/src/primitives/three-generators.ts","../../game-shapes/src/primitives/difference.ts","../../game-shapes/src/primitives/earcut.ts","../../game-shapes/src/primitives/extrude.ts","../../game-shapes/src/primitives/index.ts","../../game-shapes/src/random.ts","../../game-shapes/src/registry.ts","../../game-shapes/schema/shape.schema.json","../../game-shapes/src/schema.ts","../../game-shapes/src/generate.ts","../../game-shapes/src/merge.ts","../../game-shapes/src/worker.ts","../../game-shapes-three/src/geometry.ts","../../game-shapes-three/src/namespace.ts","../../game-shapes-three/src/object.ts","../../game-shapes-three/src/merge-by-material.ts","../../game-vegetation/src/destruction.ts","../../game-vegetation/src/rng.ts","../../game-vegetation/src/math.ts","../../game-vegetation/src/color.ts","../../game-vegetation/src/geometry/builder.ts","../../game-vegetation/src/geometry/branches.ts","../../game-vegetation/src/geometry/tube.ts","../../game-vegetation/src/geometry/wood.ts","../../game-vegetation/src/geometry/ico.ts","../../game-vegetation/src/geometry/leaf.ts","../../game-vegetation/src/geometry/shell.ts","../../game-vegetation/src/geometry/flower.ts","../../game-vegetation/src/archetypes/pieces.ts","../../game-vegetation/src/archetypes/shared.ts","../../game-vegetation/src/archetypes/dead-tree.ts","../../game-vegetation/src/archetypes/tree-styles.ts","../../game-vegetation/src/archetypes/broadleaf-tree.ts","../../game-vegetation/src/archetypes/flower-plant.ts","../../game-vegetation/src/geometry/blade.ts","../../game-vegetation/src/archetypes/grass-tuft.ts","../../game-vegetation/src/archetypes/fern.ts","../../game-vegetation/src/geometry/succulent.ts","../../game-vegetation/src/archetypes/rosette.ts","../../game-vegetation/src/geometry/spines.ts","../../game-vegetation/src/archetypes/cactus-columnar.ts","../../game-vegetation/src/archetypes/cactus-paddle.ts","../../game-vegetation/src/archetypes/cactus-globe.ts","../../game-vegetation/src/geometry/fronds.ts","../../game-vegetation/src/archetypes/palm.ts","../../game-vegetation/src/archetypes/banana.ts","../../game-vegetation/src/geometry/boxshell.ts","../../game-vegetation/src/archetypes/shrub.ts","../../game-vegetation/src/archetypes/conifer.ts","../../game-vegetation/src/archetypes/vine.ts","../../game-vegetation/src/archetypes/potted.ts","../../game-vegetation/src/generate.ts","../../game-vegetation/src/lot.ts","../../game-vegetation/src/scatter.ts","../../game-vegetation/src/validate.ts","../../game-vegetation/src/three/types.ts","../../game-vegetation/src/three/materials.ts","../../game-vegetation/src/three/objects.ts","../../game-vegetation-species/data/species/trees.json","../../game-vegetation-species/data/species/palms.json","../../game-vegetation-species/data/species/shrubs.json","../../game-vegetation-species/data/species/flowers.json","../../game-vegetation-species/data/species/cacti.json","../../game-vegetation-species/data/species/succulents.json","../../game-vegetation-species/data/species/grasses.json","../../game-vegetation-species/data/species/vines.json","../../game-vegetation-species/data/species/potted.json","../../game-vegetation-species/data/locales/pt-BR.json","../../game-vegetation-species/data/locales/en.json","../../game-vegetation-species/data/regions/br.json","../../game-vegetation-species/data/regions/default.json","../../game-vegetation-species/src/rules.ts","../../game-vegetation-species/src/index.ts","../src/test-area/nursery.ts","../../game-contracts/src/blast-shove.ts","../../game-contracts/src/impact.ts","../../game-contracts/src/body.ts","../../game-contracts/src/spec.ts","../../game-contracts/src/weapons.ts","../../game-contracts/src/ignition.ts","../../game-contracts/src/animation.ts","../../game-contracts/src/tool-animation.ts","../../game-contracts/src/registry.ts","../../game-contracts/src/bench.ts","../../game-contracts/src/environment.ts","../../game-contracts/src/categories.ts","../../game-contracts/src/origin.ts","../src/test-area/plants.ts","../src/test-area/scenarios.ts","../src/test-area/text.ts","../src/test-area/module.ts"],"sourcesContent":["export * from './test-area'\n","import type { Color } from './types'\n\n/** A colour as `0xRRGGBB`: numbers as given (floored, as three's `setHex`), `'#rrggbb'` strings parsed. */\nexport function colorHex(color: Color | undefined, fallback = 0xffffff): number {\n if (color === undefined) return fallback\n if (typeof color === 'number') return Math.floor(color)\n const match = /^#([0-9a-fA-F]{6})$/.exec(color)\n if (!match) throw new Error(`game-shapes: colour \"${color}\" is not 0xRRGGBB or #rrggbb`)\n return parseInt(match[1] as string, 16)\n}\n\n/** three's `SRGBToLinear` (r160 `ColorManagement`), the same constants. */\nexport const srgbToLinear = (c: number): number => (c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4))\n\n/**\n * The rgb floats of a hex colour as three's `Color.setHex` stores them: the channels over 255 (`'srgb'`), converted to the linear working space\n * when colour management is on (`'linear'`).\n */\nexport function colorChannels(hex: number, space: 'linear' | 'srgb'): [number, number, number] {\n const r = ((hex >> 16) & 255) / 255\n const g = ((hex >> 8) & 255) / 255\n const b = (hex & 255) / 255\n return space === 'linear' ? [srgbToLinear(r), srgbToLinear(g), srgbToLinear(b)] : [r, g, b]\n}\n","/**\n * Canonical JSON (keys sorted, `undefined` left out, `-0` kept as `-0`, typed arrays as plain lists) and a 64-bit FNV-1a of it in two 32-bit\n * lanes: the key a shape is cached and shared by.\n */\nexport function canonicalJson(value: unknown): string {\n if (value === null) return 'null'\n if (typeof value === 'number') return Object.is(value, -0) ? '-0' : Number.isFinite(value) ? String(value) : JSON.stringify(String(value))\n if (typeof value === 'string') return JSON.stringify(value)\n if (typeof value === 'boolean') return value ? 'true' : 'false'\n if (typeof value === 'function') throw new Error('game-shapes: a function cannot be part of a shape (register it as a generator)')\n if (ArrayBuffer.isView(value)) return canonicalJson(Array.from(value as unknown as ArrayLike<number>))\n if (Array.isArray(value)) return `[${value.map((item) => (item === undefined ? 'null' : canonicalJson(item))).join(',')}]`\n if (typeof value === 'object') {\n const record = value as Record<string, unknown>\n const keys = Object.keys(record).filter((key) => record[key] !== undefined).sort()\n return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(',')}}`\n }\n return 'null'\n}\n\nconst lane = (text: string, offset: number, prime: number): string => {\n let hash = offset\n for (let index = 0; index < text.length; index++) {\n hash ^= text.charCodeAt(index)\n hash = Math.imul(hash, prime)\n }\n return (hash >>> 0).toString(16).padStart(8, '0')\n}\n\n/** 64-bit FNV-1a of a text as 16 hex digits (two independent 32-bit lanes). */\nexport const hash64 = (text: string): string => lane(text, 0x811c9dc5, 0x01000193) + lane(text, 0x050c5d1f, 0x5bd1e995)\n\n/** `hash64(canonicalJson(value))`. */\nexport const hashValue = (value: unknown): string => hash64(canonicalJson(value))\n","/*\n * Matrix and quaternion arithmetic as three.js r160 does it (MIT, https://github.com/mrdoob/three.js): the same expressions in the same order, so a\n * vertex baked here has the same bits as one baked by `Matrix4.compose` / `multiplyMatrices` / `Matrix3.getNormalMatrix` / `Vector3.normalize`.\n * Matrices are column-major arrays of 16 (4 x 4) or 9 (3 x 3) numbers, the layout of three's `elements`.\n */\nimport type { Mat4, RotationOrder, Transform, Vec3 } from './types'\n\nexport type Matrix4 = number[]\nexport type Matrix3 = number[]\n\nexport const identity4 = (): Matrix4 => [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]\n\n/** `Quaternion.setFromEuler` (x, y, z, w). */\nexport function quaternionFromEuler(x: number, y: number, z: number, order: RotationOrder = 'XYZ'): [number, number, number, number] {\n const cos = Math.cos\n const sin = Math.sin\n const c1 = cos(x / 2)\n const c2 = cos(y / 2)\n const c3 = cos(z / 2)\n const s1 = sin(x / 2)\n const s2 = sin(y / 2)\n const s3 = sin(z / 2)\n switch (order) {\n case 'XYZ':\n return [s1 * c2 * c3 + c1 * s2 * s3, c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]\n case 'YXZ':\n return [s1 * c2 * c3 + c1 * s2 * s3, c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 - s1 * s2 * c3, c1 * c2 * c3 + s1 * s2 * s3]\n case 'ZXY':\n return [s1 * c2 * c3 - c1 * s2 * s3, c1 * s2 * c3 + s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]\n case 'ZYX':\n return [s1 * c2 * c3 - c1 * s2 * s3, c1 * s2 * c3 + s1 * c2 * s3, c1 * c2 * s3 - s1 * s2 * c3, c1 * c2 * c3 + s1 * s2 * s3]\n case 'YZX':\n return [s1 * c2 * c3 + c1 * s2 * s3, c1 * s2 * c3 + s1 * c2 * s3, c1 * c2 * s3 - s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]\n case 'XZY':\n return [s1 * c2 * c3 - c1 * s2 * s3, c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 + s1 * s2 * s3]\n default:\n throw new Error(`game-shapes: unknown rotation order \"${String(order)}\"`)\n }\n}\n\n/** `Matrix4.compose(position, quaternion, scale)`. */\nexport function compose(px: number, py: number, pz: number, q: readonly [number, number, number, number], sx: number, sy: number, sz: number): Matrix4 {\n const [x, y, z, w] = q\n const x2 = x + x\n const y2 = y + y\n const z2 = z + z\n const xx = x * x2\n const xy = x * y2\n const xz = x * z2\n const yy = y * y2\n const yz = y * z2\n const zz = z * z2\n const wx = w * x2\n const wy = w * y2\n const wz = w * z2\n return [\n (1 - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n (xy - wz) * sy, (1 - (xx + zz)) * sy, (yz + wx) * sy, 0,\n (xz + wy) * sz, (yz - wx) * sz, (1 - (xx + yy)) * sz, 0,\n px, py, pz, 1,\n ]\n}\n\n/** `Matrix4.makeRotationY(theta)` followed by `setPosition(x, y, z)`. */\nexport function headingMatrix(theta: number, x = 0, y = 0, z = 0): Matrix4 {\n const c = Math.cos(theta)\n const s = Math.sin(theta)\n return [c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, x, y, z, 1]\n}\n\n/** `Matrix4.multiplyMatrices(a, b)`: a x b. */\nexport function multiply(ae: readonly number[], be: readonly number[]): Matrix4 {\n const a11 = ae[0]!, a12 = ae[4]!, a13 = ae[8]!, a14 = ae[12]!\n const a21 = ae[1]!, a22 = ae[5]!, a23 = ae[9]!, a24 = ae[13]!\n const a31 = ae[2]!, a32 = ae[6]!, a33 = ae[10]!, a34 = ae[14]!\n const a41 = ae[3]!, a42 = ae[7]!, a43 = ae[11]!, a44 = ae[15]!\n const b11 = be[0]!, b12 = be[4]!, b13 = be[8]!, b14 = be[12]!\n const b21 = be[1]!, b22 = be[5]!, b23 = be[9]!, b24 = be[13]!\n const b31 = be[2]!, b32 = be[6]!, b33 = be[10]!, b34 = be[14]!\n const b41 = be[3]!, b42 = be[7]!, b43 = be[11]!, b44 = be[15]!\n return [\n a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41,\n a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41,\n a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41,\n a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41,\n a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42,\n a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42,\n a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42,\n a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42,\n a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43,\n a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43,\n a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43,\n a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43,\n a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44,\n a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44,\n a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44,\n a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44,\n ]\n}\n\n/** `Matrix3.getNormalMatrix(m)`: the inverse transpose of the upper 3 x 3 (all zeros when singular, as three). */\nexport function normalMatrix(me: readonly number[]): Matrix3 {\n // setFromMatrix4\n const n11 = me[0]!, n21 = me[1]!, n31 = me[2]!\n const n12 = me[4]!, n22 = me[5]!, n32 = me[6]!\n const n13 = me[8]!, n23 = me[9]!, n33 = me[10]!\n // invert\n const t11 = n33 * n22 - n32 * n23\n const t12 = n32 * n13 - n33 * n12\n const t13 = n23 * n12 - n22 * n13\n const det = n11 * t11 + n21 * t12 + n31 * t13\n if (det === 0) return [0, 0, 0, 0, 0, 0, 0, 0, 0]\n const detInv = 1 / det\n const te = [\n t11 * detInv,\n (n31 * n23 - n33 * n21) * detInv,\n (n32 * n21 - n31 * n22) * detInv,\n t12 * detInv,\n (n33 * n11 - n31 * n13) * detInv,\n (n31 * n12 - n32 * n11) * detInv,\n t13 * detInv,\n (n21 * n13 - n23 * n11) * detInv,\n (n22 * n11 - n21 * n12) * detInv,\n ]\n // transpose\n let tmp = te[1]!\n te[1] = te[3]!\n te[3] = tmp\n tmp = te[2]!\n te[2] = te[6]!\n te[6] = tmp\n tmp = te[5]!\n te[5] = te[7]!\n te[7] = tmp\n return te\n}\n\n/** True when the last row is (0, 0, 0, 1): `applyMatrix4`'s divide by w is then a multiply by exactly 1. */\nexport const isAffine = (e: readonly number[]): boolean => e[3] === 0 && e[7] === 0 && e[11] === 0 && e[15] === 1\n\n/** `Vector3.applyMatrix4`. */\nexport function transformPoint(e: readonly number[], x: number, y: number, z: number): [number, number, number] {\n const w = 1 / (e[3]! * x + e[7]! * y + e[11]! * z + e[15]!)\n return [(e[0]! * x + e[4]! * y + e[8]! * z + e[12]!) * w, (e[1]! * x + e[5]! * y + e[9]! * z + e[13]!) * w, (e[2]! * x + e[6]! * y + e[10]! * z + e[14]!) * w]\n}\n\nconst toVec3 = (scale: number | Vec3 | undefined): Vec3 => (scale === undefined ? [1, 1, 1] : typeof scale === 'number' ? [scale, scale, scale] : scale)\n\n/** True when the transform has no field set. */\nexport const isIdentityTransform = (t: Transform): boolean =>\n t.matrix === undefined && t.heading === undefined && t.position === undefined && t.rotation === undefined && t.scale === undefined\n\n/** The local matrix of a transform, or `null` when it has none. */\nexport function matrixOf(t: Transform): Matrix4 | null {\n if (t.matrix !== undefined) return [...t.matrix]\n if (t.heading !== undefined) {\n const p = t.position ?? [0, 0, 0]\n return headingMatrix(t.heading, p[0], p[1], p[2])\n }\n if (t.position === undefined && t.rotation === undefined && t.scale === undefined) return null\n const p = t.position ?? [0, 0, 0]\n const r = t.rotation ?? [0, 0, 0]\n const s = toVec3(t.scale)\n return compose(p[0], p[1], p[2], quaternionFromEuler(r[0], r[1], r[2], t.rotationOrder ?? 'XYZ'), s[0], s[1], s[2])\n}\n\n/** The matrix as given, as a plain array (for `ShapePart.matrix`). */\nexport const asMat4 = (m: Matrix4 | null): Mat4 => (m ? [...m] : identity4())\n","/*\n * The geometry generators of three.js r160 (MIT, https://github.com/mrdoob/three.js, src/geometries/*.js), ported line by line: the same loops,\n * the same expressions in the same order, numbers pushed into plain arrays and stored as Float32 at the end, exactly as `Float32BufferAttribute`\n * does. A test compares every array of every generator with three's, bit for bit, over a grid of parameters.\n */\nimport type { GeometryGroup, PrimitiveBuffers } from '../types'\n\nexport interface Arrays {\n vertices: number[]\n normals: number[]\n uvs: number[]\n indices: number[] | null\n groups: GeometryGroup[]\n}\n\n/** three's `arrayNeedsUint32`: 32-bit indices once any index reaches 65535. */\nexport function needsUint32(array: ArrayLike<number>): boolean {\n for (let i = array.length - 1; i >= 0; --i) if ((array[i] as number) >= 65535) return true\n return false\n}\n\nexport const indexArray = (indices: ArrayLike<number>): Uint16Array | Uint32Array => (needsUint32(indices) ? new Uint32Array(indices) : new Uint16Array(indices))\n\nexport function pack(type: string, parameters: Record<string, unknown>, a: Arrays): PrimitiveBuffers {\n return {\n type,\n parameters,\n positions: new Float32Array(a.vertices),\n normals: new Float32Array(a.normals),\n uvs: new Float32Array(a.uvs),\n ...(a.indices ? { indices: indexArray(a.indices) } : {}),\n groups: a.groups,\n }\n}\n\nconst normalize3 = (x: number, y: number, z: number): [number, number, number] => {\n const length = Math.sqrt(x * x + y * y + z * z)\n const s = 1 / (length || 1)\n return [x * s, y * s, z * s]\n}\n\nexport function box(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1): PrimitiveBuffers {\n const parameters = { width, height, depth, widthSegments, heightSegments, depthSegments }\n widthSegments = Math.floor(widthSegments)\n heightSegments = Math.floor(heightSegments)\n depthSegments = Math.floor(depthSegments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n const groups: GeometryGroup[] = []\n let numberOfVertices = 0\n let groupStart = 0\n type Axis = 'x' | 'y' | 'z'\n const buildPlane = (u: Axis, v: Axis, w: Axis, udir: number, vdir: number, width: number, height: number, depth: number, gridX: number, gridY: number, materialIndex: number): void => {\n const segmentWidth = width / gridX\n const segmentHeight = height / gridY\n const widthHalf = width / 2\n const heightHalf = height / 2\n const depthHalf = depth / 2\n const gridX1 = gridX + 1\n const gridY1 = gridY + 1\n let vertexCounter = 0\n let groupCount = 0\n const vector = { x: 0, y: 0, z: 0 }\n for (let iy = 0; iy < gridY1; iy++) {\n const y = iy * segmentHeight - heightHalf\n for (let ix = 0; ix < gridX1; ix++) {\n const x = ix * segmentWidth - widthHalf\n vector[u] = x * udir\n vector[v] = y * vdir\n vector[w] = depthHalf\n vertices.push(vector.x, vector.y, vector.z)\n vector[u] = 0\n vector[v] = 0\n vector[w] = depth > 0 ? 1 : -1\n normals.push(vector.x, vector.y, vector.z)\n uvs.push(ix / gridX)\n uvs.push(1 - iy / gridY)\n vertexCounter += 1\n }\n }\n for (let iy = 0; iy < gridY; iy++) {\n for (let ix = 0; ix < gridX; ix++) {\n const a = numberOfVertices + ix + gridX1 * iy\n const b = numberOfVertices + ix + gridX1 * (iy + 1)\n const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1)\n const d = numberOfVertices + (ix + 1) + gridX1 * iy\n indices.push(a, b, d)\n indices.push(b, c, d)\n groupCount += 6\n }\n }\n groups.push({ start: groupStart, count: groupCount, materialIndex })\n groupStart += groupCount\n numberOfVertices += vertexCounter\n }\n buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0)\n buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1)\n buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2)\n buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3)\n buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4)\n buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5)\n return pack('BoxGeometry', parameters, { vertices, normals, uvs, indices, groups })\n}\n\nfunction cylinderArrays(radiusTop: number, radiusBottom: number, height: number, radialSegments: number, heightSegments: number, openEnded: boolean, thetaStart: number, thetaLength: number): Arrays {\n radialSegments = Math.floor(radialSegments)\n heightSegments = Math.floor(heightSegments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n const groups: GeometryGroup[] = []\n let index = 0\n const indexArray: number[][] = []\n const halfHeight = height / 2\n let groupStart = 0\n\n const generateTorso = (): void => {\n let groupCount = 0\n const slope = (radiusBottom - radiusTop) / height\n for (let y = 0; y <= heightSegments; y++) {\n const indexRow: number[] = []\n const v = y / heightSegments\n const radius = v * (radiusBottom - radiusTop) + radiusTop\n for (let x = 0; x <= radialSegments; x++) {\n const u = x / radialSegments\n const theta = u * thetaLength + thetaStart\n const sinTheta = Math.sin(theta)\n const cosTheta = Math.cos(theta)\n vertices.push(radius * sinTheta, -v * height + halfHeight, radius * cosTheta)\n const n = normalize3(sinTheta, slope, cosTheta)\n normals.push(n[0], n[1], n[2])\n uvs.push(u, 1 - v)\n indexRow.push(index++)\n }\n indexArray.push(indexRow)\n }\n for (let x = 0; x < radialSegments; x++) {\n for (let y = 0; y < heightSegments; y++) {\n const a = indexArray[y]![x]!\n const b = indexArray[y + 1]![x]!\n const c = indexArray[y + 1]![x + 1]!\n const d = indexArray[y]![x + 1]!\n indices.push(a, b, d)\n indices.push(b, c, d)\n groupCount += 6\n }\n }\n groups.push({ start: groupStart, count: groupCount, materialIndex: 0 })\n groupStart += groupCount\n }\n\n const generateCap = (top: boolean): void => {\n const centerIndexStart = index\n let groupCount = 0\n const radius = top === true ? radiusTop : radiusBottom\n const sign = top === true ? 1 : -1\n for (let x = 1; x <= radialSegments; x++) {\n vertices.push(0, halfHeight * sign, 0)\n normals.push(0, sign, 0)\n uvs.push(0.5, 0.5)\n index++\n }\n const centerIndexEnd = index\n for (let x = 0; x <= radialSegments; x++) {\n const u = x / radialSegments\n const theta = u * thetaLength + thetaStart\n const cosTheta = Math.cos(theta)\n const sinTheta = Math.sin(theta)\n vertices.push(radius * sinTheta, halfHeight * sign, radius * cosTheta)\n normals.push(0, sign, 0)\n uvs.push(cosTheta * 0.5 + 0.5, sinTheta * 0.5 * sign + 0.5)\n index++\n }\n for (let x = 0; x < radialSegments; x++) {\n const c = centerIndexStart + x\n const i = centerIndexEnd + x\n if (top === true) indices.push(i, i + 1, c)\n else indices.push(i + 1, i, c)\n groupCount += 3\n }\n groups.push({ start: groupStart, count: groupCount, materialIndex: top === true ? 1 : 2 })\n groupStart += groupCount\n }\n\n generateTorso()\n if (openEnded === false) {\n if (radiusTop > 0) generateCap(true)\n if (radiusBottom > 0) generateCap(false)\n }\n return { vertices, normals, uvs, indices, groups }\n}\n\nexport function cylinder(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }\n return pack('CylinderGeometry', parameters, cylinderArrays(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))\n}\n\nexport function cone(radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }\n return pack('ConeGeometry', parameters, cylinderArrays(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))\n}\n\nexport function sphere(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI): PrimitiveBuffers {\n const parameters = { radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength }\n widthSegments = Math.max(3, Math.floor(widthSegments))\n heightSegments = Math.max(2, Math.floor(heightSegments))\n const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI)\n let index = 0\n const grid: number[][] = []\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n for (let iy = 0; iy <= heightSegments; iy++) {\n const verticesRow: number[] = []\n const v = iy / heightSegments\n let uOffset = 0\n if (iy === 0 && thetaStart === 0) uOffset = 0.5 / widthSegments\n else if (iy === heightSegments && thetaEnd === Math.PI) uOffset = -0.5 / widthSegments\n for (let ix = 0; ix <= widthSegments; ix++) {\n const u = ix / widthSegments\n const x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength)\n const y = radius * Math.cos(thetaStart + v * thetaLength)\n const z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength)\n vertices.push(x, y, z)\n const n = normalize3(x, y, z)\n normals.push(n[0], n[1], n[2])\n uvs.push(u + uOffset, 1 - v)\n verticesRow.push(index++)\n }\n grid.push(verticesRow)\n }\n for (let iy = 0; iy < heightSegments; iy++) {\n for (let ix = 0; ix < widthSegments; ix++) {\n const a = grid[iy]![ix + 1]!\n const b = grid[iy]![ix]!\n const c = grid[iy + 1]![ix]!\n const d = grid[iy + 1]![ix + 1]!\n if (iy !== 0 || thetaStart > 0) indices.push(a, b, d)\n if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d)\n }\n }\n return pack('SphereGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function plane(width = 1, height = 1, widthSegments = 1, heightSegments = 1): PrimitiveBuffers {\n const parameters = { width, height, widthSegments, heightSegments }\n const widthHalf = width / 2\n const heightHalf = height / 2\n const gridX = Math.floor(widthSegments)\n const gridY = Math.floor(heightSegments)\n const gridX1 = gridX + 1\n const gridY1 = gridY + 1\n const segmentWidth = width / gridX\n const segmentHeight = height / gridY\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n for (let iy = 0; iy < gridY1; iy++) {\n const y = iy * segmentHeight - heightHalf\n for (let ix = 0; ix < gridX1; ix++) {\n const x = ix * segmentWidth - widthHalf\n vertices.push(x, -y, 0)\n normals.push(0, 0, 1)\n uvs.push(ix / gridX)\n uvs.push(1 - iy / gridY)\n }\n }\n for (let iy = 0; iy < gridY; iy++) {\n for (let ix = 0; ix < gridX; ix++) {\n const a = ix + gridX1 * iy\n const b = ix + gridX1 * (iy + 1)\n const c = ix + 1 + gridX1 * (iy + 1)\n const d = ix + 1 + gridX1 * iy\n indices.push(a, b, d)\n indices.push(b, c, d)\n }\n }\n return pack('PlaneGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function circle(radius = 1, segments = 32, thetaStart = 0, thetaLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { radius, segments, thetaStart, thetaLength }\n segments = Math.max(3, segments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n vertices.push(0, 0, 0)\n normals.push(0, 0, 1)\n uvs.push(0.5, 0.5)\n for (let s = 0, i = 3; s <= segments; s++, i += 3) {\n const segment = thetaStart + (s / segments) * thetaLength\n // the vector's z stays 0, as three's Vector3\n vertices.push(radius * Math.cos(segment), radius * Math.sin(segment), 0)\n normals.push(0, 0, 1)\n uvs.push(((vertices[i] as number) / radius + 1) / 2, ((vertices[i + 1] as number) / radius + 1) / 2)\n }\n for (let i = 1; i <= segments; i++) indices.push(i, i + 1, 0)\n return pack('CircleGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function ring(innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength }\n thetaSegments = Math.max(3, thetaSegments)\n phiSegments = Math.max(1, phiSegments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n let radius = innerRadius\n const radiusStep = (outerRadius - innerRadius) / phiSegments\n for (let j = 0; j <= phiSegments; j++) {\n for (let i = 0; i <= thetaSegments; i++) {\n const segment = thetaStart + (i / thetaSegments) * thetaLength\n const x = radius * Math.cos(segment)\n const y = radius * Math.sin(segment)\n vertices.push(x, y, 0)\n normals.push(0, 0, 1)\n uvs.push((x / outerRadius + 1) / 2, (y / outerRadius + 1) / 2)\n }\n radius += radiusStep\n }\n for (let j = 0; j < phiSegments; j++) {\n const thetaSegmentLevel = j * (thetaSegments + 1)\n for (let i = 0; i < thetaSegments; i++) {\n const segment = i + thetaSegmentLevel\n const a = segment\n const b = segment + thetaSegments + 1\n const c = segment + thetaSegments + 2\n const d = segment + 1\n indices.push(a, b, d)\n indices.push(b, c, d)\n }\n }\n return pack('RingGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function lathe(points: ReadonlyArray<readonly [number, number]>, segments = 12, phiStart = 0, phiLength = Math.PI * 2): PrimitiveBuffers {\n const parameters = { points: points.map(([x, y]) => ({ x, y })), segments, phiStart, phiLength }\n segments = Math.floor(segments)\n phiLength = Math.max(0, Math.min(Math.PI * 2, phiLength))\n const indices: number[] = []\n const vertices: number[] = []\n const uvs: number[] = []\n const initNormals: number[] = []\n const normals: number[] = []\n const inverseSegments = 1.0 / segments\n const normal = { x: 0, y: 0, z: 0 }\n const curNormal = { x: 0, y: 0, z: 0 }\n const prevNormal = { x: 0, y: 0, z: 0 }\n let dx = 0\n let dy = 0\n const last = points.length - 1\n const px = (j: number): number => (points[j] as readonly [number, number])[0]\n const py = (j: number): number => (points[j] as readonly [number, number])[1]\n const setNormalized = (): void => {\n const n = normalize3(normal.x, normal.y, normal.z)\n normal.x = n[0]\n normal.y = n[1]\n normal.z = n[2]\n }\n for (let j = 0; j <= last; j++) {\n if (j === 0) {\n dx = px(j + 1) - px(j)\n dy = py(j + 1) - py(j)\n normal.x = dy * 1.0\n normal.y = -dx\n normal.z = dy * 0.0\n prevNormal.x = normal.x\n prevNormal.y = normal.y\n prevNormal.z = normal.z\n setNormalized()\n initNormals.push(normal.x, normal.y, normal.z)\n } else if (j === last) {\n initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z)\n } else {\n dx = px(j + 1) - px(j)\n dy = py(j + 1) - py(j)\n normal.x = dy * 1.0\n normal.y = -dx\n normal.z = dy * 0.0\n curNormal.x = normal.x\n curNormal.y = normal.y\n curNormal.z = normal.z\n normal.x += prevNormal.x\n normal.y += prevNormal.y\n normal.z += prevNormal.z\n setNormalized()\n initNormals.push(normal.x, normal.y, normal.z)\n prevNormal.x = curNormal.x\n prevNormal.y = curNormal.y\n prevNormal.z = curNormal.z\n }\n }\n for (let i = 0; i <= segments; i++) {\n const phi = phiStart + i * inverseSegments * phiLength\n const sin = Math.sin(phi)\n const cos = Math.cos(phi)\n for (let j = 0; j <= last; j++) {\n vertices.push(px(j) * sin, py(j), px(j) * cos)\n uvs.push(i / segments, j / (points.length - 1))\n const x = (initNormals[3 * j + 0] as number) * sin\n const y = initNormals[3 * j + 1] as number\n const z = (initNormals[3 * j + 0] as number) * cos\n normals.push(x, y, z)\n }\n }\n for (let i = 0; i < segments; i++) {\n for (let j = 0; j < points.length - 1; j++) {\n const base = j + i * points.length\n const a = base\n const b = base + points.length\n const c = base + points.length + 1\n const d = base + 1\n indices.push(a, b, d)\n indices.push(c, d, b)\n }\n }\n return pack('LatheGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n\nexport function torus(radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2): PrimitiveBuffers {\n const parameters = { radius, tube, radialSegments, tubularSegments, arc }\n radialSegments = Math.floor(radialSegments)\n tubularSegments = Math.floor(tubularSegments)\n const indices: number[] = []\n const vertices: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n for (let j = 0; j <= radialSegments; j++) {\n for (let i = 0; i <= tubularSegments; i++) {\n const u = (i / tubularSegments) * arc\n const v = (j / radialSegments) * Math.PI * 2\n const x = (radius + tube * Math.cos(v)) * Math.cos(u)\n const y = (radius + tube * Math.cos(v)) * Math.sin(u)\n const z = tube * Math.sin(v)\n vertices.push(x, y, z)\n const cx = radius * Math.cos(u)\n const cy = radius * Math.sin(u)\n const n = normalize3(x - cx, y - cy, z - 0)\n normals.push(n[0], n[1], n[2])\n uvs.push(i / tubularSegments)\n uvs.push(j / radialSegments)\n }\n }\n for (let j = 1; j <= radialSegments; j++) {\n for (let i = 1; i <= tubularSegments; i++) {\n const a = (tubularSegments + 1) * j + i - 1\n const b = (tubularSegments + 1) * (j - 1) + i - 1\n const c = (tubularSegments + 1) * (j - 1) + i\n const d = (tubularSegments + 1) * j + i\n indices.push(a, b, d)\n indices.push(b, c, d)\n }\n }\n return pack('TorusGeometry', parameters, { vertices, normals, uvs, indices, groups: [] })\n}\n","import type { HoleSpec, PrimitiveBuffers, Vec3 } from '../types'\nimport { indexArray } from './three-generators'\n\n/**\n * A box (centred, `size = [w, h, d]`) minus rectangular prisms that go all the way through it along z: the cheap, exact boolean (walls with\n * windows and doors). The face is cut into a grid at every hole edge; each solid cell gets its front and back quads, and every cell edge between\n * solid and empty (a hole or the outside) gets a quad over the depth facing the empty side, so the outer sides and the reveals come out of the\n * same rule. Front uvs map the face to [0, 1]; side uvs run along the edge and the depth.\n */\nexport function difference(size: Vec3, subtract: readonly HoleSpec[]): PrimitiveBuffers {\n const [w, h, d] = size\n const hw = w / 2\n const hh = h / 2\n const hd = d / 2\n const holes = subtract\n .map((hole) => ({ x0: Math.max(-hw, Math.min(hole.min[0], hole.max[0])), x1: Math.min(hw, Math.max(hole.min[0], hole.max[0])), y0: Math.max(-hh, Math.min(hole.min[1], hole.max[1])), y1: Math.min(hh, Math.max(hole.min[1], hole.max[1])) }))\n .filter((hole) => hole.x1 > hole.x0 && hole.y1 > hole.y0)\n const cuts = (lo: number, hi: number, values: number[]): number[] => [...new Set([lo, hi, ...values.filter((v) => v > lo && v < hi)])].sort((a, b) => a - b)\n const xs = cuts(-hw, hw, holes.flatMap((hole) => [hole.x0, hole.x1]))\n const ys = cuts(-hh, hh, holes.flatMap((hole) => [hole.y0, hole.y1]))\n const nx = xs.length - 1\n const ny = ys.length - 1\n const solid = (i: number, j: number): boolean => {\n if (i < 0 || j < 0 || i >= nx || j >= ny) return false\n const cx = ((xs[i] as number) + (xs[i + 1] as number)) / 2\n const cy = ((ys[j] as number) + (ys[j + 1] as number)) / 2\n return !holes.some((hole) => cx > hole.x0 && cx < hole.x1 && cy > hole.y0 && cy < hole.y1)\n }\n const positions: number[] = []\n const normals: number[] = []\n const uvs: number[] = []\n const indices: number[] = []\n const quad = (corners: readonly (readonly [number, number, number])[], normal: readonly [number, number, number], uv: readonly (readonly [number, number])[]): void => {\n const base = positions.length / 3\n for (let k = 0; k < 4; k++) {\n positions.push(...(corners[k] as [number, number, number]))\n normals.push(...normal)\n uvs.push(...(uv[k] as [number, number]))\n }\n indices.push(base, base + 1, base + 2, base, base + 2, base + 3)\n }\n const fu = (x: number): number => (x + hw) / w\n const fv = (y: number): number => (y + hh) / h\n for (let j = 0; j < ny; j++) {\n for (let i = 0; i < nx; i++) {\n if (!solid(i, j)) continue\n const x0 = xs[i] as number\n const x1 = xs[i + 1] as number\n const y0 = ys[j] as number\n const y1 = ys[j + 1] as number\n quad([[x0, y0, hd], [x1, y0, hd], [x1, y1, hd], [x0, y1, hd]], [0, 0, 1], [[fu(x0), fv(y0)], [fu(x1), fv(y0)], [fu(x1), fv(y1)], [fu(x0), fv(y1)]])\n quad([[x1, y0, -hd], [x0, y0, -hd], [x0, y1, -hd], [x1, y1, -hd]], [0, 0, -1], [[1 - fu(x1), fv(y0)], [1 - fu(x0), fv(y0)], [1 - fu(x0), fv(y1)], [1 - fu(x1), fv(y1)]])\n const zu = (z: number): number => (z + hd) / d\n if (!solid(i - 1, j)) quad([[x0, y0, -hd], [x0, y0, hd], [x0, y1, hd], [x0, y1, -hd]], [-1, 0, 0], [[zu(-hd), fv(y0)], [zu(hd), fv(y0)], [zu(hd), fv(y1)], [zu(-hd), fv(y1)]])\n if (!solid(i + 1, j)) quad([[x1, y0, hd], [x1, y0, -hd], [x1, y1, -hd], [x1, y1, hd]], [1, 0, 0], [[zu(hd), fv(y0)], [zu(-hd), fv(y0)], [zu(-hd), fv(y1)], [zu(hd), fv(y1)]])\n if (!solid(i, j - 1)) quad([[x0, y0, -hd], [x1, y0, -hd], [x1, y0, hd], [x0, y0, hd]], [0, -1, 0], [[fu(x0), zu(-hd)], [fu(x1), zu(-hd)], [fu(x1), zu(hd)], [fu(x0), zu(hd)]])\n if (!solid(i, j + 1)) quad([[x0, y1, hd], [x1, y1, hd], [x1, y1, -hd], [x0, y1, -hd]], [0, 1, 0], [[fu(x0), zu(hd)], [fu(x1), zu(hd)], [fu(x1), zu(-hd)], [fu(x0), zu(-hd)]])\n }\n }\n return {\n type: 'BufferGeometry',\n parameters: { size: [w, h, d], subtract: holes.map((hole) => ({ min: [hole.x0, hole.y0], max: [hole.x1, hole.y1] })) },\n positions: new Float32Array(positions),\n normals: new Float32Array(normals),\n uvs: new Float32Array(uvs),\n indices: indexArray(indices),\n groups: [],\n }\n}\n","/* eslint-disable */\n// @ts-nocheck -- verbatim copy of three.js r160 src/extras/Earcut.js (MIT), itself a port of mapbox/earcut v2.2.4 (ISC); kept as is so triangulation matches three\n/**\n * Port from https://github.com/mapbox/earcut (v2.2.4)\n */\n\nconst Earcut = {\n\n\ttriangulate: function ( data, holeIndices, dim = 2 ) {\n\n\t\tconst hasHoles = holeIndices && holeIndices.length;\n\t\tconst outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length;\n\t\tlet outerNode = linkedList( data, 0, outerLen, dim, true );\n\t\tconst triangles = [];\n\n\t\tif ( ! outerNode || outerNode.next === outerNode.prev ) return triangles;\n\n\t\tlet minX, minY, maxX, maxY, x, y, invSize;\n\n\t\tif ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim );\n\n\t\t// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n\t\tif ( data.length > 80 * dim ) {\n\n\t\t\tminX = maxX = data[ 0 ];\n\t\t\tminY = maxY = data[ 1 ];\n\n\t\t\tfor ( let i = dim; i < outerLen; i += dim ) {\n\n\t\t\t\tx = data[ i ];\n\t\t\t\ty = data[ i + 1 ];\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\n\t\t\t}\n\n\t\t\t// minX, minY and invSize are later used to transform coords into integers for z-order calculation\n\t\t\tinvSize = Math.max( maxX - minX, maxY - minY );\n\t\t\tinvSize = invSize !== 0 ? 32767 / invSize : 0;\n\n\t\t}\n\n\t\tearcutLinked( outerNode, triangles, dim, minX, minY, invSize, 0 );\n\n\t\treturn triangles;\n\n\t}\n\n};\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList( data, start, end, dim, clockwise ) {\n\n\tlet i, last;\n\n\tif ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) {\n\n\t\tfor ( i = start; i < end; i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );\n\n\t} else {\n\n\t\tfor ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );\n\n\t}\n\n\tif ( last && equals( last, last.next ) ) {\n\n\t\tremoveNode( last );\n\t\tlast = last.next;\n\n\t}\n\n\treturn last;\n\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints( start, end ) {\n\n\tif ( ! start ) return start;\n\tif ( ! end ) end = start;\n\n\tlet p = start,\n\t\tagain;\n\tdo {\n\n\t\tagain = false;\n\n\t\tif ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) {\n\n\t\t\tremoveNode( p );\n\t\t\tp = end = p.prev;\n\t\t\tif ( p === p.next ) break;\n\t\t\tagain = true;\n\n\t\t} else {\n\n\t\t\tp = p.next;\n\n\t\t}\n\n\t} while ( again || p !== end );\n\n\treturn end;\n\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) {\n\n\tif ( ! ear ) return;\n\n\t// interlink polygon nodes in z-order\n\tif ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize );\n\n\tlet stop = ear,\n\t\tprev, next;\n\n\t// iterate through ears, slicing them one by one\n\twhile ( ear.prev !== ear.next ) {\n\n\t\tprev = ear.prev;\n\t\tnext = ear.next;\n\n\t\tif ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) {\n\n\t\t\t// cut off the triangle\n\t\t\ttriangles.push( prev.i / dim | 0 );\n\t\t\ttriangles.push( ear.i / dim | 0 );\n\t\t\ttriangles.push( next.i / dim | 0 );\n\n\t\t\tremoveNode( ear );\n\n\t\t\t// skipping the next vertex leads to less sliver triangles\n\t\t\tear = next.next;\n\t\t\tstop = next.next;\n\n\t\t\tcontinue;\n\n\t\t}\n\n\t\tear = next;\n\n\t\t// if we looped through the whole remaining polygon and can't find any more ears\n\t\tif ( ear === stop ) {\n\n\t\t\t// try filtering points and slicing again\n\t\t\tif ( ! pass ) {\n\n\t\t\t\tearcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 );\n\n\t\t\t\t// if this didn't work, try curing all small self-intersections locally\n\n\t\t\t} else if ( pass === 1 ) {\n\n\t\t\t\tear = cureLocalIntersections( filterPoints( ear ), triangles, dim );\n\t\t\t\tearcutLinked( ear, triangles, dim, minX, minY, invSize, 2 );\n\n\t\t\t\t// as a last resort, try splitting the remaining polygon into two\n\n\t\t\t} else if ( pass === 2 ) {\n\n\t\t\t\tsplitEarcut( ear, triangles, dim, minX, minY, invSize );\n\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar( ear ) {\n\n\tconst a = ear.prev,\n\t\tb = ear,\n\t\tc = ear.next;\n\n\tif ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear\n\n\t// now make sure we don't have other points inside the potential ear\n\tconst ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;\n\n\t// triangle bbox; min & max are calculated like this for speed\n\tconst x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ),\n\t\ty0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ),\n\t\tx1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ),\n\t\ty1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy );\n\n\tlet p = c.next;\n\twhile ( p !== a ) {\n\n\t\tif ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) &&\n\t\t\tarea( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.next;\n\n\t}\n\n\treturn true;\n\n}\n\nfunction isEarHashed( ear, minX, minY, invSize ) {\n\n\tconst a = ear.prev,\n\t\tb = ear,\n\t\tc = ear.next;\n\n\tif ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear\n\n\tconst ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;\n\n\t// triangle bbox; min & max are calculated like this for speed\n\tconst x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ),\n\t\ty0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ),\n\t\tx1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ),\n\t\ty1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy );\n\n\t// z-order range for the current triangle bbox;\n\tconst minZ = zOrder( x0, y0, minX, minY, invSize ),\n\t\tmaxZ = zOrder( x1, y1, minX, minY, invSize );\n\n\tlet p = ear.prevZ,\n\t\tn = ear.nextZ;\n\n\t// look for points inside the triangle in both directions\n\twhile ( p && p.z >= minZ && n && n.z <= maxZ ) {\n\n\t\tif ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.prevZ;\n\n\t\tif ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false;\n\t\tn = n.nextZ;\n\n\t}\n\n\t// look for remaining points in decreasing z-order\n\twhile ( p && p.z >= minZ ) {\n\n\t\tif ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.prevZ;\n\n\t}\n\n\t// look for remaining points in increasing z-order\n\twhile ( n && n.z <= maxZ ) {\n\n\t\tif ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&\n\t\t\tpointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false;\n\t\tn = n.nextZ;\n\n\t}\n\n\treturn true;\n\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections( start, triangles, dim ) {\n\n\tlet p = start;\n\tdo {\n\n\t\tconst a = p.prev,\n\t\t\tb = p.next.next;\n\n\t\tif ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) {\n\n\t\t\ttriangles.push( a.i / dim | 0 );\n\t\t\ttriangles.push( p.i / dim | 0 );\n\t\t\ttriangles.push( b.i / dim | 0 );\n\n\t\t\t// remove two nodes involved\n\t\t\tremoveNode( p );\n\t\t\tremoveNode( p.next );\n\n\t\t\tp = start = b;\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\treturn filterPoints( p );\n\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut( start, triangles, dim, minX, minY, invSize ) {\n\n\t// look for a valid diagonal that divides the polygon into two\n\tlet a = start;\n\tdo {\n\n\t\tlet b = a.next.next;\n\t\twhile ( b !== a.prev ) {\n\n\t\t\tif ( a.i !== b.i && isValidDiagonal( a, b ) ) {\n\n\t\t\t\t// split the polygon in two by the diagonal\n\t\t\t\tlet c = splitPolygon( a, b );\n\n\t\t\t\t// filter colinear points around the cuts\n\t\t\t\ta = filterPoints( a, a.next );\n\t\t\t\tc = filterPoints( c, c.next );\n\n\t\t\t\t// run earcut on each half\n\t\t\t\tearcutLinked( a, triangles, dim, minX, minY, invSize, 0 );\n\t\t\t\tearcutLinked( c, triangles, dim, minX, minY, invSize, 0 );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tb = b.next;\n\n\t\t}\n\n\t\ta = a.next;\n\n\t} while ( a !== start );\n\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles( data, holeIndices, outerNode, dim ) {\n\n\tconst queue = [];\n\tlet i, len, start, end, list;\n\n\tfor ( i = 0, len = holeIndices.length; i < len; i ++ ) {\n\n\t\tstart = holeIndices[ i ] * dim;\n\t\tend = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length;\n\t\tlist = linkedList( data, start, end, dim, false );\n\t\tif ( list === list.next ) list.steiner = true;\n\t\tqueue.push( getLeftmost( list ) );\n\n\t}\n\n\tqueue.sort( compareX );\n\n\t// process holes from left to right\n\tfor ( i = 0; i < queue.length; i ++ ) {\n\n\t\touterNode = eliminateHole( queue[ i ], outerNode );\n\n\t}\n\n\treturn outerNode;\n\n}\n\nfunction compareX( a, b ) {\n\n\treturn a.x - b.x;\n\n}\n\n// find a bridge between vertices that connects hole with an outer ring and link it\nfunction eliminateHole( hole, outerNode ) {\n\n\tconst bridge = findHoleBridge( hole, outerNode );\n\tif ( ! bridge ) {\n\n\t\treturn outerNode;\n\n\t}\n\n\tconst bridgeReverse = splitPolygon( bridge, hole );\n\n\t// filter collinear points around the cuts\n\tfilterPoints( bridgeReverse, bridgeReverse.next );\n\treturn filterPoints( bridge, bridge.next );\n\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge( hole, outerNode ) {\n\n\tlet p = outerNode,\n\t\tqx = - Infinity,\n\t\tm;\n\n\tconst hx = hole.x, hy = hole.y;\n\n\t// find a segment intersected by a ray from the hole's leftmost point to the left;\n\t// segment's endpoint with lesser x will be potential connection point\n\tdo {\n\n\t\tif ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) {\n\n\t\t\tconst x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y );\n\t\t\tif ( x <= hx && x > qx ) {\n\n\t\t\t\tqx = x;\n\t\t\t\tm = p.x < p.next.x ? p : p.next;\n\t\t\t\tif ( x === hx ) return m; // hole touches outer segment; pick leftmost endpoint\n\n\t\t\t}\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== outerNode );\n\n\tif ( ! m ) return null;\n\n\t// look for points inside the triangle of hole point, segment intersection and endpoint;\n\t// if there are no points found, we have a valid connection;\n\t// otherwise choose the point of the minimum angle with the ray as connection point\n\n\tconst stop = m,\n\t\tmx = m.x,\n\t\tmy = m.y;\n\tlet tanMin = Infinity, tan;\n\n\tp = m;\n\n\tdo {\n\n\t\tif ( hx >= p.x && p.x >= mx && hx !== p.x &&\n\t\t\t\tpointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) {\n\n\t\t\ttan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential\n\n\t\t\tif ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) {\n\n\t\t\t\tm = p;\n\t\t\t\ttanMin = tan;\n\n\t\t\t}\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== stop );\n\n\treturn m;\n\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector( m, p ) {\n\n\treturn area( m.prev, m, p.prev ) < 0 && area( p.next, m, m.next ) < 0;\n\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve( start, minX, minY, invSize ) {\n\n\tlet p = start;\n\tdo {\n\n\t\tif ( p.z === 0 ) p.z = zOrder( p.x, p.y, minX, minY, invSize );\n\t\tp.prevZ = p.prev;\n\t\tp.nextZ = p.next;\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\tp.prevZ.nextZ = null;\n\tp.prevZ = null;\n\n\tsortLinked( p );\n\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked( list ) {\n\n\tlet i, p, q, e, tail, numMerges, pSize, qSize,\n\t\tinSize = 1;\n\n\tdo {\n\n\t\tp = list;\n\t\tlist = null;\n\t\ttail = null;\n\t\tnumMerges = 0;\n\n\t\twhile ( p ) {\n\n\t\t\tnumMerges ++;\n\t\t\tq = p;\n\t\t\tpSize = 0;\n\t\t\tfor ( i = 0; i < inSize; i ++ ) {\n\n\t\t\t\tpSize ++;\n\t\t\t\tq = q.nextZ;\n\t\t\t\tif ( ! q ) break;\n\n\t\t\t}\n\n\t\t\tqSize = inSize;\n\n\t\t\twhile ( pSize > 0 || ( qSize > 0 && q ) ) {\n\n\t\t\t\tif ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) {\n\n\t\t\t\t\te = p;\n\t\t\t\t\tp = p.nextZ;\n\t\t\t\t\tpSize --;\n\n\t\t\t\t} else {\n\n\t\t\t\t\te = q;\n\t\t\t\t\tq = q.nextZ;\n\t\t\t\t\tqSize --;\n\n\t\t\t\t}\n\n\t\t\t\tif ( tail ) tail.nextZ = e;\n\t\t\t\telse list = e;\n\n\t\t\t\te.prevZ = tail;\n\t\t\t\ttail = e;\n\n\t\t\t}\n\n\t\t\tp = q;\n\n\t\t}\n\n\t\ttail.nextZ = null;\n\t\tinSize *= 2;\n\n\t} while ( numMerges > 1 );\n\n\treturn list;\n\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder( x, y, minX, minY, invSize ) {\n\n\t// coords are transformed into non-negative 15-bit integer range\n\tx = ( x - minX ) * invSize | 0;\n\ty = ( y - minY ) * invSize | 0;\n\n\tx = ( x | ( x << 8 ) ) & 0x00FF00FF;\n\tx = ( x | ( x << 4 ) ) & 0x0F0F0F0F;\n\tx = ( x | ( x << 2 ) ) & 0x33333333;\n\tx = ( x | ( x << 1 ) ) & 0x55555555;\n\n\ty = ( y | ( y << 8 ) ) & 0x00FF00FF;\n\ty = ( y | ( y << 4 ) ) & 0x0F0F0F0F;\n\ty = ( y | ( y << 2 ) ) & 0x33333333;\n\ty = ( y | ( y << 1 ) ) & 0x55555555;\n\n\treturn x | ( y << 1 );\n\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost( start ) {\n\n\tlet p = start,\n\t\tleftmost = start;\n\tdo {\n\n\t\tif ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p;\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\treturn leftmost;\n\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) {\n\n\treturn ( cx - px ) * ( ay - py ) >= ( ax - px ) * ( cy - py ) &&\n ( ax - px ) * ( by - py ) >= ( bx - px ) * ( ay - py ) &&\n ( bx - px ) * ( cy - py ) >= ( cx - px ) * ( by - py );\n\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal( a, b ) {\n\n\treturn a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // dones't intersect other edges\n ( locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ) && // locally visible\n ( area( a.prev, a, b.prev ) || area( a, b.prev, b ) ) || // does not create opposite-facing sectors\n equals( a, b ) && area( a.prev, a, a.next ) > 0 && area( b.prev, b, b.next ) > 0 ); // special zero-length case\n\n}\n\n// signed area of a triangle\nfunction area( p, q, r ) {\n\n\treturn ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y );\n\n}\n\n// check if two points are equal\nfunction equals( p1, p2 ) {\n\n\treturn p1.x === p2.x && p1.y === p2.y;\n\n}\n\n// check if two segments intersect\nfunction intersects( p1, q1, p2, q2 ) {\n\n\tconst o1 = sign( area( p1, q1, p2 ) );\n\tconst o2 = sign( area( p1, q1, q2 ) );\n\tconst o3 = sign( area( p2, q2, p1 ) );\n\tconst o4 = sign( area( p2, q2, q1 ) );\n\n\tif ( o1 !== o2 && o3 !== o4 ) return true; // general case\n\n\tif ( o1 === 0 && onSegment( p1, p2, q1 ) ) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n\tif ( o2 === 0 && onSegment( p1, q2, q1 ) ) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n\tif ( o3 === 0 && onSegment( p2, p1, q2 ) ) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n\tif ( o4 === 0 && onSegment( p2, q1, q2 ) ) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n\treturn false;\n\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment( p, q, r ) {\n\n\treturn q.x <= Math.max( p.x, r.x ) && q.x >= Math.min( p.x, r.x ) && q.y <= Math.max( p.y, r.y ) && q.y >= Math.min( p.y, r.y );\n\n}\n\nfunction sign( num ) {\n\n\treturn num > 0 ? 1 : num < 0 ? - 1 : 0;\n\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon( a, b ) {\n\n\tlet p = a;\n\tdo {\n\n\t\tif ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n\t\t\tintersects( p, p.next, a, b ) ) return true;\n\t\tp = p.next;\n\n\t} while ( p !== a );\n\n\treturn false;\n\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside( a, b ) {\n\n\treturn area( a.prev, a, a.next ) < 0 ?\n\t\tarea( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 :\n\t\tarea( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0;\n\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside( a, b ) {\n\n\tlet p = a,\n\t\tinside = false;\n\tconst px = ( a.x + b.x ) / 2,\n\t\tpy = ( a.y + b.y ) / 2;\n\tdo {\n\n\t\tif ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y &&\n\t\t\t( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) )\n\t\t\tinside = ! inside;\n\t\tp = p.next;\n\n\t} while ( p !== a );\n\n\treturn inside;\n\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon( a, b ) {\n\n\tconst a2 = new Node( a.i, a.x, a.y ),\n\t\tb2 = new Node( b.i, b.x, b.y ),\n\t\tan = a.next,\n\t\tbp = b.prev;\n\n\ta.next = b;\n\tb.prev = a;\n\n\ta2.next = an;\n\tan.prev = a2;\n\n\tb2.next = a2;\n\ta2.prev = b2;\n\n\tbp.next = b2;\n\tb2.prev = bp;\n\n\treturn b2;\n\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode( i, x, y, last ) {\n\n\tconst p = new Node( i, x, y );\n\n\tif ( ! last ) {\n\n\t\tp.prev = p;\n\t\tp.next = p;\n\n\t} else {\n\n\t\tp.next = last.next;\n\t\tp.prev = last;\n\t\tlast.next.prev = p;\n\t\tlast.next = p;\n\n\t}\n\n\treturn p;\n\n}\n\nfunction removeNode( p ) {\n\n\tp.next.prev = p.prev;\n\tp.prev.next = p.next;\n\n\tif ( p.prevZ ) p.prevZ.nextZ = p.nextZ;\n\tif ( p.nextZ ) p.nextZ.prevZ = p.prevZ;\n\n}\n\nfunction Node( i, x, y ) {\n\n\t// vertex index in coordinates array\n\tthis.i = i;\n\n\t// vertex coordinates\n\tthis.x = x;\n\tthis.y = y;\n\n\t// previous and next vertex nodes in a polygon ring\n\tthis.prev = null;\n\tthis.next = null;\n\n\t// z-order curve value\n\tthis.z = 0;\n\n\t// previous and next nodes in z-order\n\tthis.prevZ = null;\n\tthis.nextZ = null;\n\n\t// indicates whether this is a steiner point\n\tthis.steiner = false;\n\n}\n\nfunction signedArea( data, start, end, dim ) {\n\n\tlet sum = 0;\n\tfor ( let i = start, j = end - dim; i < end; i += dim ) {\n\n\t\tsum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] );\n\t\tj = i;\n\n\t}\n\n\treturn sum;\n\n}\n\nexport { Earcut };\n","/*\n * three.js r160 `ExtrudeGeometry` (MIT) for straight-edged shapes, ported line by line: the outline is sampled as `Shape.extractPoints` samples a\n * path of `LineCurve`s, triangulated by three's `ShapeUtils.triangulateShape` (Earcut), bevelled and walled in the same order, with the\n * `WorldUVGenerator` uvs and `computeVertexNormals` on the Float32 positions. Path extrusion (`extrudePath`) is not supported.\n */\nimport type { BevelSpec, GeometryGroup, PrimitiveBuffers, ShapeOutline, Vec2 } from '../types'\nimport { Earcut } from './earcut'\n\ninterface P {\n x: number\n y: number\n}\n\nconst equals = (a: P, b: P): boolean => a.x === b.x && a.y === b.y\n\n/** `LineCurve.getPoint(t)`. */\nconst linePoint = (v1: P, v2: P, t: number): P => (t === 1 ? { x: v2.x, y: v2.y } : { x: (v2.x - v1.x) * t + v1.x, y: (v2.y - v1.y) * t + v1.y })\n\n/** `Path.setFromPoints(points).getPoints()`: one `LineCurve` per edge, resolution 1, consecutive duplicates dropped, not closed. */\nfunction pathPoints(points: readonly Vec2[]): P[] {\n const out: P[] = []\n let last: P | undefined\n for (let i = 1; i < points.length; i++) {\n const v1 = { x: (points[i - 1] as Vec2)[0], y: (points[i - 1] as Vec2)[1] }\n const v2 = { x: (points[i] as Vec2)[0], y: (points[i] as Vec2)[1] }\n for (let d = 0; d <= 1; d++) {\n const point = linePoint(v1, v2, d / 1)\n if (last && equals(last, point)) continue\n out.push(point)\n last = point\n }\n }\n return out\n}\n\nfunction area(contour: readonly P[]): number {\n const n = contour.length\n let a = 0.0\n for (let p = n - 1, q = 0; q < n; p = q++) a += (contour[p] as P).x * (contour[q] as P).y - (contour[q] as P).x * (contour[p] as P).y\n return a * 0.5\n}\nconst isClockWise = (pts: readonly P[]): boolean => area(pts) < 0\n\nfunction removeDupEndPts(points: P[]): void {\n const l = points.length\n if (l > 2 && equals(points[l - 1] as P, points[0] as P)) points.pop()\n}\n\nfunction triangulateShape(contour: P[], holes: P[][]): number[][] {\n const vertices: number[] = []\n const holeIndices: number[] = []\n const faces: number[][] = []\n removeDupEndPts(contour)\n for (const p of contour) vertices.push(p.x, p.y)\n let holeIndex = contour.length\n holes.forEach(removeDupEndPts)\n for (let i = 0; i < holes.length; i++) {\n holeIndices.push(holeIndex)\n holeIndex += (holes[i] as P[]).length\n for (const p of holes[i] as P[]) vertices.push(p.x, p.y)\n }\n const triangles: number[] = Earcut.triangulate(vertices, holeIndices)\n for (let i = 0; i < triangles.length; i += 3) faces.push(triangles.slice(i, i + 3))\n return faces\n}\n\n/** `BufferGeometry.computeVertexNormals` for non-indexed Float32 positions, then `normalizeNormals`, both stored as Float32. */\nexport function computeVertexNormals(positions: Float32Array, indices?: ArrayLike<number>): Float32Array {\n const normals = new Float32Array(positions.length)\n const get = (array: Float32Array, i: number): [number, number, number] => [array[i * 3] as number, array[i * 3 + 1] as number, array[i * 3 + 2] as number]\n const face = (vA: number, vB: number, vC: number): [number, number, number] => {\n const pA = get(positions, vA)\n const pB = get(positions, vB)\n const pC = get(positions, vC)\n const cb = [pC[0] - pB[0], pC[1] - pB[1], pC[2] - pB[2]] as const\n const ab = [pA[0] - pB[0], pA[1] - pB[1], pA[2] - pB[2]] as const\n // Vector3.cross\n return [cb[1] * ab[2] - cb[2] * ab[1], cb[2] * ab[0] - cb[0] * ab[2], cb[0] * ab[1] - cb[1] * ab[0]]\n }\n const set = (i: number, x: number, y: number, z: number): void => {\n normals[i * 3] = x\n normals[i * 3 + 1] = y\n normals[i * 3 + 2] = z\n }\n if (indices) {\n for (let i = 0; i < indices.length; i += 3) {\n const vA = indices[i] as number\n const vB = indices[i + 1] as number\n const vC = indices[i + 2] as number\n const cb = face(vA, vB, vC)\n for (const v of [vA, vB, vC]) {\n const n = get(normals, v)\n set(v, n[0] + cb[0], n[1] + cb[1], n[2] + cb[2])\n }\n }\n } else {\n for (let i = 0; i < positions.length / 3; i += 3) {\n const cb = face(i, i + 1, i + 2)\n set(i, cb[0], cb[1], cb[2])\n set(i + 1, cb[0], cb[1], cb[2])\n set(i + 2, cb[0], cb[1], cb[2])\n }\n }\n for (let i = 0; i < normals.length / 3; i++) {\n const [x, y, z] = get(normals, i)\n const s = 1 / (Math.sqrt(x * x + y * y + z * z) || 1)\n set(i, x * s, y * s, z * s)\n }\n return normals\n}\n\nexport function extrude(outline: ShapeOutline, depth = 1, steps = 1, bevel: false | BevelSpec | undefined = undefined): PrimitiveBuffers {\n const parameters = { shape: outline, depth, steps, bevel: bevel ?? {} }\n const verticesArray: number[] = []\n const uvArray: number[] = []\n const groups: GeometryGroup[] = []\n const placeholder: number[] = []\n\n const bevelEnabled = bevel !== false\n const spec: BevelSpec = bevel === false || bevel === undefined ? {} : bevel\n let bevelThickness = spec.thickness !== undefined ? spec.thickness : 0.2\n let bevelSize = spec.size !== undefined ? spec.size : bevelThickness - 0.1\n let bevelOffset = spec.offset !== undefined ? spec.offset : 0\n let bevelSegments = spec.segments !== undefined ? spec.segments : 3\n if (!bevelEnabled) {\n bevelSegments = 0\n bevelThickness = 0\n bevelSize = 0\n bevelOffset = 0\n }\n\n let vertices = pathPoints(outline.outer)\n const holes = (outline.holes ?? []).map(pathPoints)\n const reverse = !isClockWise(vertices)\n if (reverse) {\n vertices = vertices.reverse()\n for (let h = 0; h < holes.length; h++) {\n const ahole = holes[h] as P[]\n if (isClockWise(ahole)) holes[h] = ahole.reverse()\n }\n }\n const faces = triangulateShape(vertices, holes)\n const contour = vertices\n for (const ahole of holes) vertices = vertices.concat(ahole)\n\n const scalePt2 = (pt: P, vec: P, size: number): P => ({ x: pt.x + vec.x * size, y: pt.y + vec.y * size })\n const vlen = vertices.length\n const flen = faces.length\n\n const getBevelVec = (inPt: P, inPrev: P, inNext: P): P => {\n let vTransX: number\n let vTransY: number\n let shrinkBy: number\n const vPrevX = inPt.x - inPrev.x\n const vPrevY = inPt.y - inPrev.y\n const vNextX = inNext.x - inPt.x\n const vNextY = inNext.y - inPt.y\n const vPrevLensq = vPrevX * vPrevX + vPrevY * vPrevY\n const collinear0 = vPrevX * vNextY - vPrevY * vNextX\n if (Math.abs(collinear0) > Number.EPSILON) {\n const vPrevLen = Math.sqrt(vPrevLensq)\n const vNextLen = Math.sqrt(vNextX * vNextX + vNextY * vNextY)\n const ptPrevShiftX = inPrev.x - vPrevY / vPrevLen\n const ptPrevShiftY = inPrev.y + vPrevX / vPrevLen\n const ptNextShiftX = inNext.x - vNextY / vNextLen\n const ptNextShiftY = inNext.y + vNextX / vNextLen\n const sf = ((ptNextShiftX - ptPrevShiftX) * vNextY - (ptNextShiftY - ptPrevShiftY) * vNextX) / (vPrevX * vNextY - vPrevY * vNextX)\n vTransX = ptPrevShiftX + vPrevX * sf - inPt.x\n vTransY = ptPrevShiftY + vPrevY * sf - inPt.y\n const vTransLensq = vTransX * vTransX + vTransY * vTransY\n if (vTransLensq <= 2) return { x: vTransX, y: vTransY }\n shrinkBy = Math.sqrt(vTransLensq / 2)\n } else {\n let directionEq = false\n if (vPrevX > Number.EPSILON) {\n if (vNextX > Number.EPSILON) directionEq = true\n } else if (vPrevX < -Number.EPSILON) {\n if (vNextX < -Number.EPSILON) directionEq = true\n } else if (Math.sign(vPrevY) === Math.sign(vNextY)) {\n directionEq = true\n }\n if (directionEq) {\n vTransX = -vPrevY\n vTransY = vPrevX\n shrinkBy = Math.sqrt(vPrevLensq)\n } else {\n vTransX = vPrevX\n vTransY = vPrevY\n shrinkBy = Math.sqrt(vPrevLensq / 2)\n }\n }\n return { x: vTransX / shrinkBy, y: vTransY / shrinkBy }\n }\n\n const movements = (ring: readonly P[]): P[] => {\n const out: P[] = []\n for (let i = 0, il = ring.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) {\n if (j === il) j = 0\n if (k === il) k = 0\n out[i] = getBevelVec(ring[i] as P, ring[j] as P, ring[k] as P)\n }\n return out\n }\n const contourMovements = movements(contour)\n const holesMovements: P[][] = []\n let verticesMovements = contourMovements.concat()\n for (const ahole of holes) {\n const oneHoleMovements = movements(ahole)\n holesMovements.push(oneHoleMovements)\n verticesMovements = verticesMovements.concat(oneHoleMovements)\n }\n\n const v = (x: number, y: number, z: number): void => {\n placeholder.push(x)\n placeholder.push(y)\n placeholder.push(z)\n }\n const bevelLayer = (b: number, zOf: (z: number) => number): void => {\n const t = b / bevelSegments\n const z = bevelThickness * Math.cos((t * Math.PI) / 2)\n const bs = bevelSize * Math.sin((t * Math.PI) / 2) + bevelOffset\n for (let i = 0; i < contour.length; i++) {\n const vert = scalePt2(contour[i] as P, contourMovements[i] as P, bs)\n v(vert.x, vert.y, zOf(z))\n }\n for (let h = 0; h < holes.length; h++) {\n const ahole = holes[h] as P[]\n const oneHoleMovements = holesMovements[h] as P[]\n for (let i = 0; i < ahole.length; i++) {\n const vert = scalePt2(ahole[i] as P, oneHoleMovements[i] as P, bs)\n v(vert.x, vert.y, zOf(z))\n }\n }\n }\n for (let b = 0; b < bevelSegments; b++) bevelLayer(b, (z) => -z)\n const bs = bevelSize + bevelOffset\n for (let i = 0; i < vlen; i++) {\n const vert = bevelEnabled ? scalePt2(vertices[i] as P, verticesMovements[i] as P, bs) : (vertices[i] as P)\n v(vert.x, vert.y, 0)\n }\n for (let s = 1; s <= steps; s++) {\n for (let i = 0; i < vlen; i++) {\n const vert = bevelEnabled ? scalePt2(vertices[i] as P, verticesMovements[i] as P, bs) : (vertices[i] as P)\n v(vert.x, vert.y, (depth / steps) * s)\n }\n }\n for (let b = bevelSegments - 1; b >= 0; b--) bevelLayer(b, (z) => depth + z)\n\n const addVertex = (index: number): void => {\n verticesArray.push(placeholder[index * 3 + 0] as number)\n verticesArray.push(placeholder[index * 3 + 1] as number)\n verticesArray.push(placeholder[index * 3 + 2] as number)\n }\n const addUV = (x: number, y: number): void => {\n uvArray.push(x)\n uvArray.push(y)\n }\n const at = (index: number, axis: number): number => verticesArray[index * 3 + axis] as number\n const f3 = (a: number, b: number, c: number): void => {\n addVertex(a)\n addVertex(b)\n addVertex(c)\n const nextIndex = verticesArray.length / 3\n for (const index of [nextIndex - 3, nextIndex - 2, nextIndex - 1]) addUV(at(index, 0), at(index, 1))\n }\n const f4 = (a: number, b: number, c: number, d: number): void => {\n addVertex(a)\n addVertex(b)\n addVertex(d)\n addVertex(b)\n addVertex(c)\n addVertex(d)\n const nextIndex = verticesArray.length / 3\n const iA = nextIndex - 6\n const iB = nextIndex - 3\n const iC = nextIndex - 2\n const iD = nextIndex - 1\n const byX = Math.abs(at(iA, 1) - at(iB, 1)) < Math.abs(at(iA, 0) - at(iB, 0))\n const uv = (index: number): [number, number] => [byX ? at(index, 0) : at(index, 1), 1 - at(index, 2)]\n const uvs = [uv(iA), uv(iB), uv(iC), uv(iD)]\n for (const k of [0, 1, 3, 1, 2, 3]) addUV(...(uvs[k] as [number, number]))\n }\n\n // lid faces\n let start = verticesArray.length / 3\n if (bevelEnabled) {\n let offset = 0\n for (let i = 0; i < flen; i++) {\n const face = faces[i] as number[]\n f3((face[2] as number) + offset, (face[1] as number) + offset, (face[0] as number) + offset)\n }\n const layer = steps + bevelSegments * 2\n offset = vlen * layer\n for (let i = 0; i < flen; i++) {\n const face = faces[i] as number[]\n f3((face[0] as number) + offset, (face[1] as number) + offset, (face[2] as number) + offset)\n }\n } else {\n for (let i = 0; i < flen; i++) {\n const face = faces[i] as number[]\n f3(face[2] as number, face[1] as number, face[0] as number)\n }\n for (let i = 0; i < flen; i++) {\n const face = faces[i] as number[]\n f3((face[0] as number) + vlen * steps, (face[1] as number) + vlen * steps, (face[2] as number) + vlen * steps)\n }\n }\n groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 0 })\n\n // side faces\n start = verticesArray.length / 3\n const sidewalls = (ring: readonly P[], layeroffset: number): void => {\n let i = ring.length\n while (--i >= 0) {\n const j = i\n let k = i - 1\n if (k < 0) k = ring.length - 1\n for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) {\n const slen1 = vlen * s\n const slen2 = vlen * (s + 1)\n f4(layeroffset + j + slen1, layeroffset + k + slen1, layeroffset + k + slen2, layeroffset + j + slen2)\n }\n }\n }\n let layeroffset = 0\n sidewalls(contour, layeroffset)\n layeroffset += contour.length\n for (const ahole of holes) {\n sidewalls(ahole, layeroffset)\n layeroffset += ahole.length\n }\n groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 1 })\n\n const positions = new Float32Array(verticesArray)\n return { type: 'ExtrudeGeometry', parameters, positions, normals: computeVertexNormals(positions), uvs: new Float32Array(uvArray), groups }\n}\n","import { canonicalJson } from '../hash'\nimport type { PrimitiveBuffers, PrimitiveNode } from '../types'\nimport { difference } from './difference'\nimport { computeVertexNormals, extrude } from './extrude'\nimport { box, circle, cone, cylinder, indexArray, lathe, plane, ring, sphere, torus } from './three-generators'\n\nexport { box, circle, cone, cylinder, lathe, plane, ring, sphere, torus } from './three-generators'\nexport { computeVertexNormals, extrude } from './extrude'\nexport { difference } from './difference'\n\n/** How a level of detail changes a primitive. */\nexport interface DetailOptions {\n /** Multiplies the segment counts of round primitives (1 leaves them as given). */\n readonly detail?: number\n /** Floor of the scaled segment counts (default 3). */\n readonly minSegments?: number\n}\n\nconst PARAMETER_KEYS: Readonly<Record<PrimitiveNode['kind'], readonly string[]>> = {\n box: ['size', 'segments'],\n cylinder: ['radiusTop', 'radiusBottom', 'height', 'radialSegments', 'heightSegments', 'openEnded', 'thetaStart', 'thetaLength'],\n cone: ['radius', 'height', 'radialSegments', 'heightSegments', 'openEnded', 'thetaStart', 'thetaLength'],\n sphere: ['radius', 'widthSegments', 'heightSegments', 'phiStart', 'phiLength', 'thetaStart', 'thetaLength'],\n plane: ['width', 'height', 'widthSegments', 'heightSegments'],\n circle: ['radius', 'segments', 'thetaStart', 'thetaLength'],\n ring: ['innerRadius', 'outerRadius', 'thetaSegments', 'phiSegments', 'thetaStart', 'thetaLength'],\n lathe: ['points', 'segments', 'phiStart', 'phiLength'],\n torus: ['radius', 'tube', 'radialSegments', 'tubularSegments', 'arc'],\n extrude: ['shape', 'depth', 'steps', 'bevel'],\n difference: ['size', 'subtract'],\n mesh: ['positions', 'normals', 'uvs', 'indices'],\n}\n\n/** The segment fields `detail` scales, per kind. */\nconst SEGMENT_KEYS: Readonly<Partial<Record<PrimitiveNode['kind'], readonly string[]>>> = {\n cylinder: ['radialSegments'],\n cone: ['radialSegments'],\n sphere: ['widthSegments', 'heightSegments'],\n circle: ['segments'],\n ring: ['thetaSegments'],\n lathe: ['segments'],\n torus: ['radialSegments', 'tubularSegments'],\n}\n/** three's defaults of the segment fields, so a scaled default is scaled from the right number. */\nconst SEGMENT_DEFAULTS: Readonly<Record<string, number>> = { radialSegments: 32, widthSegments: 32, heightSegments: 16, segments: 12, thetaSegments: 32, tubularSegments: 48 }\nconst segmentDefault = (kind: string, key: string): number => (kind === 'circle' && key === 'segments' ? 32 : kind === 'torus' && key === 'radialSegments' ? 12 : (SEGMENT_DEFAULTS[key] as number))\n\n/** The parameters of a primitive node (no transform, colour or name), with the level of detail applied: what its geometry depends on. */\nexport function primitiveParameters(node: PrimitiveNode, options: DetailOptions = {}): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const source = node as unknown as Record<string, unknown>\n for (const key of PARAMETER_KEYS[node.kind]) if (source[key] !== undefined) out[key] = source[key]\n const detail = options.detail ?? 1\n if (detail !== 1) {\n const floor = options.minSegments ?? 3\n for (const key of SEGMENT_KEYS[node.kind] ?? []) {\n const given = (out[key] as number | undefined) ?? segmentDefault(node.kind, key)\n out[key] = Math.max(floor, Math.round(given * detail))\n }\n }\n return out\n}\n\nfunction mesh(p: Record<string, unknown>): PrimitiveBuffers {\n const positions = new Float32Array(p.positions as number[])\n const indices = p.indices ? indexArray(p.indices as number[]) : undefined\n return {\n type: 'BufferGeometry',\n parameters: {},\n positions,\n normals: p.normals ? new Float32Array(p.normals as number[]) : computeVertexNormals(positions, indices),\n uvs: p.uvs ? new Float32Array(p.uvs as number[]) : new Float32Array((positions.length / 3) * 2),\n ...(indices ? { indices } : {}),\n groups: [],\n }\n}\n\nfunction make(kind: PrimitiveNode['kind'], p: Record<string, any>): PrimitiveBuffers {\n switch (kind) {\n case 'box': {\n const size = (p.size ?? [1, 1, 1]) as number[]\n const segments = (p.segments ?? [1, 1, 1]) as number[]\n return box(size[0], size[1], size[2], segments[0], segments[1], segments[2])\n }\n case 'cylinder':\n return cylinder(p.radiusTop, p.radiusBottom, p.height, p.radialSegments, p.heightSegments, p.openEnded, p.thetaStart, p.thetaLength)\n case 'cone':\n return cone(p.radius, p.height, p.radialSegments, p.heightSegments, p.openEnded, p.thetaStart, p.thetaLength)\n case 'sphere':\n return sphere(p.radius, p.widthSegments, p.heightSegments, p.phiStart, p.phiLength, p.thetaStart, p.thetaLength)\n case 'plane':\n return plane(p.width, p.height, p.widthSegments, p.heightSegments)\n case 'circle':\n return circle(p.radius, p.segments, p.thetaStart, p.thetaLength)\n case 'ring':\n return ring(p.innerRadius, p.outerRadius, p.thetaSegments, p.phiSegments, p.thetaStart, p.thetaLength)\n case 'lathe':\n return lathe(p.points, p.segments, p.phiStart, p.phiLength)\n case 'torus':\n return torus(p.radius, p.tube, p.radialSegments, p.tubularSegments, p.arc)\n case 'extrude':\n return extrude(p.shape, p.depth, p.steps, p.bevel)\n case 'difference':\n return difference(p.size, p.subtract ?? [])\n case 'mesh':\n return mesh(p)\n default:\n throw new Error(`game-shapes: unknown primitive kind \"${String(kind)}\"`)\n }\n}\n\n/** Templates by their parameter text: the same cylinder is generated once per process. Read-only by contract. */\nconst templates = new Map<string, PrimitiveBuffers>()\nlet templateLimit = 4096\nconst stats = { hits: 0, misses: 0 }\n\n/** Sets how many primitive templates are kept (least recently used out; 0 turns the cache off). */\nexport function setTemplateCacheSize(size: number): void {\n templateLimit = Math.max(0, Math.floor(size))\n while (templates.size > templateLimit) templates.delete(templates.keys().next().value as string)\n}\nexport function clearTemplateCache(): void {\n templates.clear()\n stats.hits = 0\n stats.misses = 0\n}\nexport const templateCacheStats = (): { size: number; hits: number; misses: number } => ({ size: templates.size, ...stats })\n\n/**\n * The geometry of one primitive on its own, not baked: the arrays three's generator of the same kind builds, bit for bit (meshes and differences\n * are `BufferGeometry`). The result comes from a shared template cache and must not be written to (copy it with `clonePrimitive`).\n */\nexport function buildPrimitive(node: PrimitiveNode, options: DetailOptions = {}): PrimitiveBuffers {\n const parameters = primitiveParameters(node, options)\n // raw meshes are not worth a key of their whole arrays; they are cheap to wrap\n if (node.kind === 'mesh' || templateLimit === 0) return make(node.kind, parameters)\n const key = `${node.kind}:${canonicalJson(parameters)}`\n const cached = templates.get(key)\n if (cached) {\n stats.hits++\n templates.delete(key)\n templates.set(key, cached)\n return cached\n }\n stats.misses++\n const built = make(node.kind, parameters)\n templates.set(key, built)\n if (templates.size > templateLimit) templates.delete(templates.keys().next().value as string)\n return built\n}\n\n/** A copy that owns its arrays. */\nexport function clonePrimitive(p: PrimitiveBuffers): PrimitiveBuffers {\n return {\n type: p.type,\n parameters: p.parameters,\n positions: p.positions.slice(),\n normals: p.normals.slice(),\n uvs: p.uvs.slice(),\n ...(p.indices ? { indices: p.indices.slice() } : {}),\n groups: p.groups.map((group) => ({ ...group })),\n }\n}\n","import { hash64 } from './hash'\n\n/** mulberry32: a small, fast 32-bit seeded stream in [0, 1). */\nexport function mulberry32(seed: number): () => number {\n let state = seed >>> 0\n return () => {\n state = (state + 0x6d2b79f5) >>> 0\n let t = state\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** The stream of one node: its own per (seed, generator, path), so adding a node never shifts another node's draws. */\nexport const streamFor = (seed: number | string, generator: string, path: string): (() => number) =>\n mulberry32(parseInt(hash64(`${String(seed)}\\u0000${generator}\\u0000${path}`).slice(0, 8), 16))\n","import type { ShapeGenerator } from './types'\n\nconst generators = new Map<string, ShapeGenerator>()\n\n/**\n * Registers a generator for `{ kind: 'custom', generator: name, params }` nodes: a pure function of its params and a seeded stream that returns a\n * node. A worker that generates shapes with custom nodes must register the same generators (import the same module in the worker script).\n */\nexport function registerGenerator(name: string, generator: ShapeGenerator): void {\n if (!/^[a-zA-Z][\\w.:-]*$/.test(name)) throw new Error(`game-shapes: generator name \"${name}\" must start with a letter and use letters, digits, \".\", \":\", \"-\" or \"_\"`)\n generators.set(name, generator)\n}\nexport const unregisterGenerator = (name: string): boolean => generators.delete(name)\nexport const getGenerator = (name: string): ShapeGenerator | undefined => generators.get(name)\nexport const listGenerators = (): string[] => [...generators.keys()].sort()\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://github.com/Andersonfrfilho/adatechnology-game-kit/packages/game-shapes/schema/shape.schema.json\",\n \"title\": \"game-shapes shape\",\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"root\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"version\": {\n \"const\": 1\n },\n \"name\": {\n \"type\": \"string\"\n },\n \"materials\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"$ref\": \"#/$defs/material\"\n }\n },\n \"root\": {\n \"$ref\": \"#/$defs/node\"\n },\n \"lod\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/lodLevel\"\n }\n },\n \"cullDistance\": {\n \"type\": \"number\",\n \"exclusiveMinimum\": 0\n }\n },\n \"$defs\": {\n \"number\": {\n \"type\": \"number\"\n },\n \"count\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"vec2\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n },\n \"minItems\": 2,\n \"maxItems\": 2\n },\n \"vec3\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n },\n \"minItems\": 3,\n \"maxItems\": 3\n },\n \"mat4\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n },\n \"minItems\": 16,\n \"maxItems\": 16\n },\n \"color\": {\n \"oneOf\": [\n {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 16777215\n },\n {\n \"type\": \"string\",\n \"pattern\": \"^#[0-9a-fA-F]{6}$\"\n }\n ]\n },\n \"uvRect\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"u0\",\n \"v0\",\n \"u1\",\n \"v1\"\n ],\n \"properties\": {\n \"u0\": {\n \"type\": \"number\"\n },\n \"v0\": {\n \"type\": \"number\"\n },\n \"u1\": {\n \"type\": \"number\"\n },\n \"v1\": {\n \"type\": \"number\"\n }\n }\n },\n \"rotationOrder\": {\n \"enum\": [\n \"XYZ\",\n \"YXZ\",\n \"ZXY\",\n \"ZYX\",\n \"YZX\",\n \"XZY\"\n ]\n },\n \"transform\": {\n \"type\": \"object\",\n \"properties\": {\n \"position\": {\n \"$ref\": \"#/$defs/vec3\"\n },\n \"rotation\": {\n \"$ref\": \"#/$defs/vec3\"\n },\n \"rotationOrder\": {\n \"$ref\": \"#/$defs/rotationOrder\"\n },\n \"scale\": {\n \"oneOf\": [\n {\n \"type\": \"number\"\n },\n {\n \"$ref\": \"#/$defs/vec3\"\n }\n ]\n },\n \"heading\": {\n \"type\": \"number\"\n },\n \"matrix\": {\n \"$ref\": \"#/$defs/mat4\"\n }\n }\n },\n \"instance\": {\n \"allOf\": [\n {\n \"$ref\": \"#/$defs/transform\"\n }\n ],\n \"properties\": {\n \"position\": true,\n \"rotation\": true,\n \"rotationOrder\": true,\n \"scale\": true,\n \"heading\": true,\n \"matrix\": true,\n \"color\": {\n \"$ref\": \"#/$defs/color\"\n }\n },\n \"unevaluatedProperties\": false\n },\n \"material\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"color\": {\n \"$ref\": \"#/$defs/color\"\n },\n \"roughness\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"metalness\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"opacity\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"transparent\": {\n \"type\": \"boolean\"\n },\n \"emissive\": {\n \"$ref\": \"#/$defs/color\"\n },\n \"emissiveIntensity\": {\n \"type\": \"number\",\n \"minimum\": 0\n },\n \"side\": {\n \"enum\": [\n \"front\",\n \"back\",\n \"double\"\n ]\n },\n \"flatShading\": {\n \"type\": \"boolean\"\n },\n \"vertexColors\": {\n \"type\": \"boolean\"\n },\n \"depthWrite\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"lodLevel\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"distance\",\n \"detail\"\n ],\n \"properties\": {\n \"distance\": {\n \"type\": \"number\",\n \"minimum\": 0\n },\n \"detail\": {\n \"type\": \"number\",\n \"exclusiveMinimum\": 0,\n \"maximum\": 1\n },\n \"minSize\": {\n \"type\": \"number\",\n \"minimum\": 0\n },\n \"minSegments\": {\n \"type\": \"integer\",\n \"minimum\": 3\n }\n }\n },\n \"common\": {\n \"allOf\": [\n {\n \"$ref\": \"#/$defs/transform\"\n }\n ],\n \"properties\": {\n \"kind\": {\n \"type\": \"string\"\n },\n \"name\": {\n \"type\": \"string\"\n },\n \"part\": {\n \"type\": \"string\"\n },\n \"material\": {\n \"type\": \"string\"\n },\n \"color\": {\n \"$ref\": \"#/$defs/color\"\n },\n \"uv\": {\n \"$ref\": \"#/$defs/uvRect\"\n },\n \"instances\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/instance\"\n }\n },\n \"minDetail\": {\n \"type\": \"number\",\n \"exclusiveMinimum\": 0,\n \"maximum\": 1\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"node\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"allOf\": [\n {\n \"$ref\": \"#/$defs/common\"\n }\n ],\n \"oneOf\": [\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"group\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/node\"\n }\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"box\"\n },\n \"size\": {\n \"$ref\": \"#/$defs/vec3\"\n },\n \"segments\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"minItems\": 3,\n \"maxItems\": 3\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"cylinder\"\n },\n \"radiusTop\": {\n \"type\": \"number\"\n },\n \"radiusBottom\": {\n \"type\": \"number\"\n },\n \"height\": {\n \"type\": \"number\"\n },\n \"radialSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"heightSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"openEnded\": {\n \"type\": \"boolean\"\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"cone\"\n },\n \"radius\": {\n \"type\": \"number\"\n },\n \"height\": {\n \"type\": \"number\"\n },\n \"radialSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"heightSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"openEnded\": {\n \"type\": \"boolean\"\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"sphere\"\n },\n \"radius\": {\n \"type\": \"number\"\n },\n \"widthSegments\": {\n \"type\": \"integer\",\n \"minimum\": 3\n },\n \"heightSegments\": {\n \"type\": \"integer\",\n \"minimum\": 2\n },\n \"phiStart\": {\n \"type\": \"number\"\n },\n \"phiLength\": {\n \"type\": \"number\"\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"plane\"\n },\n \"width\": {\n \"type\": \"number\"\n },\n \"height\": {\n \"type\": \"number\"\n },\n \"widthSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"heightSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"circle\"\n },\n \"radius\": {\n \"type\": \"number\"\n },\n \"segments\": {\n \"type\": \"integer\",\n \"minimum\": 3\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"ring\"\n },\n \"innerRadius\": {\n \"type\": \"number\"\n },\n \"outerRadius\": {\n \"type\": \"number\"\n },\n \"thetaSegments\": {\n \"type\": \"integer\",\n \"minimum\": 3\n },\n \"phiSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"thetaStart\": {\n \"type\": \"number\"\n },\n \"thetaLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"required\": [\n \"points\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"lathe\"\n },\n \"points\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/vec2\"\n },\n \"minItems\": 2\n },\n \"segments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"phiStart\": {\n \"type\": \"number\"\n },\n \"phiLength\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"torus\"\n },\n \"radius\": {\n \"type\": \"number\"\n },\n \"tube\": {\n \"type\": \"number\"\n },\n \"radialSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"tubularSegments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"arc\": {\n \"type\": \"number\"\n }\n }\n },\n {\n \"required\": [\n \"shape\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"extrude\"\n },\n \"shape\": {\n \"type\": \"object\",\n \"required\": [\n \"outer\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"outer\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/vec2\"\n },\n \"minItems\": 3\n },\n \"holes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/vec2\"\n },\n \"minItems\": 3\n }\n }\n }\n },\n \"depth\": {\n \"type\": \"number\"\n },\n \"steps\": {\n \"type\": \"integer\",\n \"minimum\": 1\n },\n \"bevel\": {\n \"oneOf\": [\n {\n \"const\": false\n },\n {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"thickness\": {\n \"type\": \"number\"\n },\n \"size\": {\n \"type\": \"number\"\n },\n \"offset\": {\n \"type\": \"number\"\n },\n \"segments\": {\n \"type\": \"integer\",\n \"minimum\": 1\n }\n }\n }\n ]\n }\n }\n },\n {\n \"required\": [\n \"size\",\n \"subtract\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"difference\"\n },\n \"size\": {\n \"$ref\": \"#/$defs/vec3\"\n },\n \"subtract\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"min\",\n \"max\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"min\": {\n \"$ref\": \"#/$defs/vec2\"\n },\n \"max\": {\n \"$ref\": \"#/$defs/vec2\"\n }\n }\n }\n }\n }\n },\n {\n \"required\": [\n \"positions\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"mesh\"\n },\n \"positions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n }\n },\n \"normals\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n }\n },\n \"uvs\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"number\"\n }\n },\n \"indices\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/count\"\n }\n }\n }\n },\n {\n \"properties\": {\n \"kind\": {\n \"const\": \"point\"\n },\n \"data\": {}\n }\n },\n {\n \"required\": [\n \"generator\"\n ],\n \"properties\": {\n \"kind\": {\n \"const\": \"custom\"\n },\n \"generator\": {\n \"type\": \"string\"\n },\n \"params\": {}\n }\n }\n ]\n }\n }\n}\n","import schemaJson from '../schema/shape.schema.json'\nimport type { ShapeSchema } from './types'\n\n/** The JSON Schema (draft 2020-12) of a shape document; the same file ships as `@adatechnology/game-shapes/schema.json`. */\nexport const SHAPE_SCHEMA: Readonly<Record<string, unknown>> = schemaJson\n\ntype Check = (value: unknown) => string | null\n\nconst num: Check = (v) => (typeof v === 'number' && Number.isFinite(v) ? null : 'expected a finite number')\nconst bool: Check = (v) => (typeof v === 'boolean' ? null : 'expected a boolean')\nconst str: Check = (v) => (typeof v === 'string' ? null : 'expected a string')\nconst int = (min: number): Check => (v) => (typeof v === 'number' && Number.isInteger(v) && v >= min ? null : `expected an integer >= ${min}`)\nconst range = (lo: number, hi: number, loOpen = false): Check => (v) =>\n typeof v === 'number' && (loOpen ? v > lo : v >= lo) && v <= hi ? null : `expected a number in ${loOpen ? '(' : '['}${lo}, ${hi}]`\nconst tuple = (n: number, item: Check = num): Check => (v) => {\n if (!Array.isArray(v) || v.length !== n) return `expected an array of ${n}`\n for (const x of v) if (item(x)) return `expected an array of ${n} numbers`\n return null\n}\nconst list = (item: Check, min = 0): Check => (v) => {\n if (!Array.isArray(v)) return 'expected an array'\n if (v.length < min) return `expected at least ${min} items`\n for (let i = 0; i < v.length; i++) {\n const e = item(v[i])\n if (e) return `[${i}]: ${e}`\n }\n return null\n}\nconst color: Check = (v) =>\n (typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 0xffffff) || (typeof v === 'string' && /^#[0-9a-fA-F]{6}$/.test(v)) ? null : 'expected 0xRRGGBB or \"#rrggbb\"'\nconst oneOf = (values: readonly unknown[]): Check => (v) => (values.includes(v) ? null : `expected one of ${values.map((x) => JSON.stringify(x)).join(', ')}`)\nconst object = (fields: Readonly<Record<string, Check>>, required: readonly string[] = []): Check => (v) => {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return 'expected an object'\n const record = v as Record<string, unknown>\n for (const key of required) if (record[key] === undefined) return `${key}: required`\n for (const key of Object.keys(record)) {\n if (record[key] === undefined) continue\n const check = fields[key]\n if (!check) return `${key}: unknown field`\n const e = check(record[key])\n if (e) return `${key}: ${e}`\n }\n return null\n}\n\nconst ORDERS = ['XYZ', 'YXZ', 'ZXY', 'ZYX', 'YZX', 'XZY'] as const\nconst TRANSFORM: Record<string, Check> = {\n position: tuple(3),\n rotation: tuple(3),\n rotationOrder: oneOf(ORDERS),\n scale: (v) => (typeof v === 'number' ? num(v) : tuple(3)(v)),\n heading: num,\n matrix: tuple(16),\n}\nconst UV = object({ u0: num, v0: num, u1: num, v1: num }, ['u0', 'v0', 'u1', 'v1'])\nconst INSTANCE = object({ ...TRANSFORM, color })\nconst COMMON: Record<string, Check> = {\n ...TRANSFORM,\n kind: str,\n name: str,\n part: str,\n material: str,\n color,\n uv: UV,\n instances: list(INSTANCE),\n minDetail: range(0, 1, true),\n tags: list(str),\n}\nconst vec2 = tuple(2)\nconst BEVEL: Check = (v) => (v === false ? null : object({ thickness: num, size: num, offset: num, segments: int(1) })(v))\nconst KINDS: Readonly<Record<string, { fields: Record<string, Check>; required?: string[] }>> = {\n group: { fields: {} },\n box: { fields: { size: tuple(3), segments: tuple(3, int(1)) } },\n cylinder: { fields: { radiusTop: num, radiusBottom: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },\n cone: { fields: { radius: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },\n sphere: { fields: { radius: num, widthSegments: int(3), heightSegments: int(2), phiStart: num, phiLength: num, thetaStart: num, thetaLength: num } },\n plane: { fields: { width: num, height: num, widthSegments: int(1), heightSegments: int(1) } },\n circle: { fields: { radius: num, segments: int(3), thetaStart: num, thetaLength: num } },\n ring: { fields: { innerRadius: num, outerRadius: num, thetaSegments: int(3), phiSegments: int(1), thetaStart: num, thetaLength: num } },\n lathe: { fields: { points: list(vec2, 2), segments: int(1), phiStart: num, phiLength: num }, required: ['points'] },\n torus: { fields: { radius: num, tube: num, radialSegments: int(1), tubularSegments: int(1), arc: num } },\n extrude: {\n fields: { shape: object({ outer: list(vec2, 3), holes: list(list(vec2, 3)) }, ['outer']), depth: num, steps: int(1), bevel: BEVEL },\n required: ['shape'],\n },\n difference: { fields: { size: tuple(3), subtract: list(object({ min: vec2, max: vec2 }, ['min', 'max'])) }, required: ['size', 'subtract'] },\n mesh: {\n fields: {\n positions: (v) => list(num)(v) ?? ((v as unknown[]).length % 3 === 0 ? null : 'expected a multiple of 3 numbers'),\n normals: list(num),\n uvs: list(num),\n indices: list(int(0)),\n },\n required: ['positions'],\n },\n point: { fields: { data: () => null } },\n custom: { fields: { generator: str, params: () => null }, required: ['generator'] },\n}\n\nfunction validateNode(node: unknown, path: string, errors: string[]): void {\n if (!node || typeof node !== 'object' || Array.isArray(node)) {\n errors.push(`${path}: expected a node object`)\n return\n }\n const record = node as Record<string, unknown>\n const spec = typeof record.kind === 'string' ? KINDS[record.kind] : undefined\n if (!spec) {\n errors.push(`${path}.kind: expected one of ${Object.keys(KINDS).join(', ')}`)\n return\n }\n for (const key of spec.required ?? []) if (record[key] === undefined) errors.push(`${path}.${key}: required`)\n for (const key of Object.keys(record)) {\n if (record[key] === undefined || key === 'children') continue\n const check = spec.fields[key] ?? COMMON[key]\n if (!check) {\n errors.push(`${path}.${key}: unknown field for a ${String(record.kind)}`)\n continue\n }\n const e = check(record[key])\n if (e) errors.push(`${path}.${key}: ${e}`)\n }\n const exclusive = ['matrix', 'heading'].filter((key) => record[key] !== undefined)\n if (record.matrix !== undefined && (record.position !== undefined || record.rotation !== undefined || record.scale !== undefined || record.heading !== undefined))\n errors.push(`${path}.matrix: cannot be combined with position, rotation, scale or heading`)\n else if (exclusive.includes('heading') && (record.rotation !== undefined || record.scale !== undefined)) errors.push(`${path}.heading: cannot be combined with rotation or scale`)\n if (record.children !== undefined) {\n if (record.kind !== 'group') errors.push(`${path}.children: only a group has children`)\n else if (!Array.isArray(record.children)) errors.push(`${path}.children: expected an array`)\n else record.children.forEach((child, index) => validateNode(child, `${path}.children[${index}]`, errors))\n }\n}\n\n/** Every rule of the JSON Schema, checked without a schema engine: one message per problem, with its path (`root.children[3].radialSegments: ...`). */\nexport function validateShape(schema: unknown): string[] {\n const errors: string[] = []\n if (!schema || typeof schema !== 'object' || Array.isArray(schema)) return ['expected a shape object']\n const record = schema as Record<string, unknown>\n for (const key of Object.keys(record)) if (!['version', 'name', 'materials', 'root', 'lod', 'cullDistance'].includes(key) && record[key] !== undefined) errors.push(`${key}: unknown field`)\n if (record.version !== 1) errors.push('version: expected 1')\n if (record.name !== undefined && typeof record.name !== 'string') errors.push('name: expected a string')\n if (record.materials !== undefined) {\n if (!record.materials || typeof record.materials !== 'object' || Array.isArray(record.materials)) errors.push('materials: expected an object')\n else {\n const material = object({\n color,\n roughness: range(0, 1),\n metalness: range(0, 1),\n opacity: range(0, 1),\n transparent: bool,\n emissive: color,\n emissiveIntensity: (v) => (typeof v === 'number' && v >= 0 ? null : 'expected a number >= 0'),\n side: oneOf(['front', 'back', 'double']),\n flatShading: bool,\n vertexColors: bool,\n depthWrite: bool,\n })\n for (const [id, hint] of Object.entries(record.materials)) {\n const e = material(hint)\n if (e) errors.push(`materials.${id}: ${e}`)\n }\n }\n }\n if (record.lod !== undefined) {\n const e = list(object({ distance: (v) => (typeof v === 'number' && v >= 0 ? null : 'expected a number >= 0'), detail: range(0, 1, true), minSize: (v) => (typeof v === 'number' && v >= 0 ? null : 'expected a number >= 0'), minSegments: int(3) }, ['distance', 'detail']))(record.lod)\n if (e) errors.push(`lod${e.startsWith('[') ? '' : ': '}${e}`)\n }\n if (record.cullDistance !== undefined && !(typeof record.cullDistance === 'number' && record.cullDistance > 0)) errors.push('cullDistance: expected a number > 0')\n if (record.root === undefined) errors.push('root: required')\n else validateNode(record.root, 'root', errors)\n return errors\n}\n\n/** Throws with every problem when the schema is not valid. */\nexport function assertValidShape(schema: unknown): asserts schema is ShapeSchema {\n const errors = validateShape(schema)\n if (errors.length) throw new Error(`game-shapes: invalid shape\\n ${errors.slice(0, 20).join('\\n ')}${errors.length > 20 ? `\\n ... ${errors.length - 20} more` : ''}`)\n}\n","import { colorChannels, colorHex } from './color'\nimport { hashValue } from './hash'\nimport { asMat4, identity4, isAffine, matrixOf, multiply, normalMatrix, transformPoint } from './math'\nimport type { Matrix4 } from './math'\nimport { buildPrimitive, primitiveParameters } from './primitives'\nimport { canonicalJson } from './hash'\nimport { streamFor } from './random'\nimport { getGenerator } from './registry'\nimport { assertValidShape } from './schema'\nimport type {\n Bounds,\n GenerateOptions,\n InstancedBatch,\n NamedRange,\n PrimitiveBuffers,\n PrimitiveNode,\n ShapeBatch,\n ShapeBuffers,\n ShapeLevel,\n ShapeNode,\n ShapePart,\n ShapePoint,\n ShapeSchema,\n UvRect,\n} from './types'\n\nconst PRIMITIVE_KINDS = new Set(['box', 'cylinder', 'cone', 'sphere', 'plane', 'circle', 'ring', 'lathe', 'torus', 'extrude', 'difference', 'mesh'])\nexport const isPrimitiveNode = (node: ShapeNode): node is PrimitiveNode => PRIMITIVE_KINDS.has(node.kind)\n\n/** The options that change the output, as they enter the cache key. */\nexport function keyOptions(options: GenerateOptions = {}): Record<string, unknown> {\n return {\n seed: options.seed ?? 0,\n colors: options.colors ?? 'linear',\n indexed: options.indexed ?? true,\n materials: options.materials,\n fallbackMaterial: options.fallbackMaterial,\n materialAlias: options.materialAlias,\n instancing: options.instancing,\n levels: options.levels,\n }\n}\n\n/** The cache key of a shape under some options: 64-bit FNV-1a of the canonical schema text and the options that change the output. */\nexport const shapeKey = (schema: ShapeSchema, options: GenerateOptions = {}): string => hashValue({ schema, options: keyOptions(options) })\n\nconst IDENTITY_UV: UvRect = { u0: 0, v0: 0, u1: 1, v1: 1 }\n\nclass FloatList {\n array: Float32Array\n length = 0\n constructor(capacity = 256) {\n this.array = new Float32Array(capacity)\n }\n reserve(extra: number): void {\n if (this.length + extra <= this.array.length) return\n let capacity = this.array.length * 2\n while (capacity < this.length + extra) capacity *= 2\n const next = new Float32Array(capacity)\n next.set(this.array.subarray(0, this.length))\n this.array = next\n }\n done(): Float32Array {\n return this.array.slice(0, this.length)\n }\n}\nclass IndexList {\n array: Uint32Array\n length = 0\n constructor(capacity = 256) {\n this.array = new Uint32Array(capacity)\n }\n reserve(extra: number): void {\n if (this.length + extra <= this.array.length) return\n let capacity = this.array.length * 2\n while (capacity < this.length + extra) capacity *= 2\n const next = new Uint32Array(capacity)\n next.set(this.array.subarray(0, this.length))\n this.array = next\n }\n}\n\n/** Growing buffers of one (target, material). */\nclass Accumulator {\n readonly positions = new FloatList()\n readonly normals = new FloatList()\n readonly uvs = new FloatList(170)\n readonly colors = new FloatList()\n readonly indices = new IndexList()\n readonly ranges: NamedRange[] = []\n vertices = 0\n constructor(\n readonly material: string,\n readonly part: string | null,\n ) {}\n}\n\ninterface Target {\n readonly part: string | null\n readonly accs: Map<string, Accumulator>\n}\n\ninterface Settings {\n readonly colors: 'linear' | 'srgb' | 'none'\n readonly indexed: boolean\n readonly materials?: ReadonlySet<string>\n readonly fallback?: string\n readonly alias?: Readonly<Record<string, string>>\n readonly seed: number | string\n readonly generators?: GenerateOptions['generators']\n readonly autoMin?: number\n}\n\ninterface LevelSpec {\n readonly distance: number\n readonly detail: number\n readonly minSize?: number\n readonly minSegments?: number\n readonly index: number\n}\n\ninterface Inherited {\n readonly material: string\n readonly color: number\n readonly uv: UvRect\n readonly target: Target\n}\n\n/**\n * Bakes a template into an accumulator: positions by the world matrix, normals by its normal matrix and normalised, uvs into the atlas cell,\n * one colour for all, indices offset. The arithmetic is three's (`createMeshApi`, `BufferGeometry.applyMatrix4`), so the bits match.\n */\nfunction bake(acc: Accumulator, t: PrimitiveBuffers, world: readonly number[], rgb: readonly number[] | null, u: UvRect, indexed: boolean): void {\n const e = world\n const nm = normalMatrix(world)\n const affine = isAffine(world)\n const source = t.positions\n const count = source.length / 3\n const order: ArrayLike<number> | null = indexed ? null : t.indices ?? null\n const emitted = order ? order.length : count\n acc.positions.reserve(emitted * 3)\n acc.normals.reserve(emitted * 3)\n acc.uvs.reserve(emitted * 2)\n if (rgb) acc.colors.reserve(emitted * 3)\n const P = acc.positions.array\n const N = acc.normals.array\n const U = acc.uvs.array\n const C = acc.colors.array\n let pi = acc.positions.length\n let ni = acc.normals.length\n let ui = acc.uvs.length\n let ci = acc.colors.length\n const du = u.u1 - u.u0\n const dv = u.v1 - u.v0\n const tn = t.normals\n const tu = t.uvs\n for (let k = 0; k < emitted; k++) {\n const i = order ? (order[k] as number) : k\n const x = source[i * 3] as number\n const y = source[i * 3 + 1] as number\n const z = source[i * 3 + 2] as number\n if (affine) {\n P[pi++] = e[0]! * x + e[4]! * y + e[8]! * z + e[12]!\n P[pi++] = e[1]! * x + e[5]! * y + e[9]! * z + e[13]!\n P[pi++] = e[2]! * x + e[6]! * y + e[10]! * z + e[14]!\n } else {\n const p = transformPoint(e, x, y, z)\n P[pi++] = p[0]\n P[pi++] = p[1]\n P[pi++] = p[2]\n }\n const nx = tn[i * 3] as number\n const ny = tn[i * 3 + 1] as number\n const nz = tn[i * 3 + 2] as number\n const vx = nm[0]! * nx + nm[3]! * ny + nm[6]! * nz\n const vy = nm[1]! * nx + nm[4]! * ny + nm[7]! * nz\n const vz = nm[2]! * nx + nm[5]! * ny + nm[8]! * nz\n const s = 1 / (Math.sqrt(vx * vx + vy * vy + vz * vz) || 1)\n N[ni++] = vx * s\n N[ni++] = vy * s\n N[ni++] = vz * s\n U[ui++] = u.u0 + (tu[i * 2] as number) * du\n U[ui++] = u.v0 + (tu[i * 2 + 1] as number) * dv\n if (rgb) {\n C[ci++] = rgb[0]!\n C[ci++] = rgb[1]!\n C[ci++] = rgb[2]!\n }\n }\n acc.positions.length = pi\n acc.normals.length = ni\n acc.uvs.length = ui\n acc.colors.length = ci\n if (indexed) {\n const base = acc.vertices\n const idx = t.indices\n const n = idx ? idx.length : count\n acc.indices.reserve(n)\n const I = acc.indices.array\n let ii = acc.indices.length\n for (let k = 0; k < n; k++) I[ii++] = base + (idx ? (idx[k] as number) : k)\n acc.indices.length = ii\n }\n acc.vertices += emitted\n}\n\nfunction boundsOf(positions: Float32Array): Bounds {\n const min: [number, number, number] = [Infinity, Infinity, Infinity]\n const max: [number, number, number] = [-Infinity, -Infinity, -Infinity]\n for (let i = 0; i < positions.length; i += 3) {\n for (let axis = 0; axis < 3; axis++) {\n const v = positions[i + axis] as number\n if (v < min[axis]!) min[axis] = v\n if (v > max[axis]!) max[axis] = v\n }\n }\n return { min, max }\n}\n\nfunction finish(acc: Accumulator, indexed: boolean, withColors: boolean): ShapeBatch {\n const positions = acc.positions.done()\n const indices = indexed ? (acc.vertices > 65535 ? acc.indices.array.slice(0, acc.indices.length) : Uint16Array.from(acc.indices.array.subarray(0, acc.indices.length))) : undefined\n return {\n material: acc.material,\n part: acc.part,\n positions,\n normals: acc.normals.done(),\n uvs: acc.uvs.done(),\n ...(withColors ? { colors: acc.colors.done() } : {}),\n ...(indices ? { indices } : {}),\n ranges: acc.ranges,\n bounds: boundsOf(positions),\n }\n}\n\nconst radiusOf = (t: PrimitiveBuffers, world: readonly number[]): number => {\n let r = 0\n const p = t.positions\n for (let i = 0; i < p.length; i += 3) r = Math.max(r, Math.hypot(p[i] as number, p[i + 1] as number, p[i + 2] as number))\n const sx = Math.hypot(world[0]!, world[1]!, world[2]!)\n const sy = Math.hypot(world[4]!, world[5]!, world[6]!)\n const sz = Math.hypot(world[8]!, world[9]!, world[10]!)\n return r * Math.max(sx, sy, sz)\n}\n\ninterface LevelResult {\n readonly level: ShapeLevel\n readonly parts: ShapePart[]\n readonly points: ShapePoint[]\n readonly primitives: number\n}\n\n/** Expands a custom node into the node its generator returns (wrapped so that the custom node's own fields still apply). */\nfunction expandCustom(node: Extract<ShapeNode, { kind: 'custom' }>, settings: Settings, detail: number, path: string): ShapeNode {\n const generator = settings.generators?.[node.generator] ?? getGenerator(node.generator)\n if (!generator) throw new Error(`game-shapes: no generator \"${node.generator}\" (register it with registerGenerator, in the worker too) at ${path}`)\n const generated = generator(node.params, { random: streamFor(settings.seed, node.generator, path), seed: settings.seed, detail, path })\n const { kind: _kind, generator: _generator, params: _params, ...common } = node\n return { ...common, kind: 'group', children: [generated] }\n}\n\n/** The key two leaf primitives share when one can stand for the other as an instance. */\nconst leafKey = (node: PrimitiveNode, material: string, color: number, uv: UvRect, level: LevelSpec): string =>\n `${node.kind}|${canonicalJson(primitiveParameters(node, level))}|${material}|${color}|${uv.u0},${uv.v0},${uv.u1},${uv.v1}`\n\nfunction runLevel(schema: ShapeSchema, settings: Settings, level: LevelSpec): LevelResult {\n const bakeParts = level.index > 0\n const root: Target = { part: null, accs: new Map() }\n const targets: Target[] = [root]\n const partTargets = new Map<string, Target>()\n const parts: ShapePart[] = []\n const points: ShapePoint[] = []\n const instanced: InstancedBatch[] = []\n let primitives = 0\n const space = settings.colors === 'none' ? null : settings.colors\n const channels = new Map<number, readonly number[]>()\n const rgbOf = (hex: number): readonly number[] | null => {\n if (!space) return null\n let c = channels.get(hex)\n if (!c) {\n c = colorChannels(hex, space)\n channels.set(hex, c)\n }\n return c\n }\n const resolveMaterial = (id: string): string => {\n let out = id\n if (settings.materials && !settings.materials.has(out)) out = settings.fallback ?? out\n return settings.alias?.[out] ?? out\n }\n const accOf = (target: Target, material: string): Accumulator => {\n let acc = target.accs.get(material)\n if (!acc) {\n acc = new Accumulator(material, target.part)\n target.accs.set(material, acc)\n }\n return acc\n }\n\n // automatic instancing: count the leaves first\n const autoCounts = new Map<string, number>()\n const autoGroups = new Map<string, { node: PrimitiveNode; material: string; color: number; part: string | null; matrices: number[] }>()\n\n const count = (node: ShapeNode, inherited: { material: string; color: number; uv: UvRect; inPart: boolean }, path: string): void => {\n if (node.minDetail !== undefined && level.detail < node.minDetail) return\n if (node.kind === 'custom') return count(expandCustom(node, settings, level.detail, path), inherited, path)\n const next = {\n material: node.material !== undefined ? resolveMaterial(node.material) : inherited.material,\n color: node.color !== undefined ? colorHex(node.color) : inherited.color,\n uv: node.uv ?? inherited.uv,\n inPart: inherited.inPart || (node.part !== undefined && !bakeParts),\n }\n if (node.instances) return\n if (node.kind === 'group') {\n node.children?.forEach((child, index) => count(child, next, `${path}/${index}`))\n return\n }\n if (isPrimitiveNode(node) && node.name === undefined && !next.inPart) {\n const key = leafKey(node, next.material, next.color, next.uv, level)\n autoCounts.set(key, (autoCounts.get(key) ?? 0) + 1)\n }\n }\n const rootMaterial = resolveMaterial('default')\n if (settings.autoMin !== undefined) count(schema.root, { material: rootMaterial, color: 0xffffff, uv: IDENTITY_UV, inPart: false }, 'root')\n\n /** Draws a subtree into `collector` (a target) under `parent` (null: identity). */\n const visit = (node: ShapeNode, parent: Matrix4 | null, inherited: Inherited, path: string): void => {\n if (node.minDetail !== undefined && level.detail < node.minDetail) return\n if (node.kind === 'custom') return visit(expandCustom(node, settings, level.detail, path), parent, inherited, path)\n let target = inherited.target\n let parentWorld = parent\n if (node.part !== undefined) {\n if (bakeParts) {\n // far levels freeze the parts at rest: the part's pivot is relative to the root\n parentWorld = null\n } else {\n let partTarget = partTargets.get(node.part)\n if (!partTarget) {\n partTarget = { part: node.part, accs: new Map() }\n partTargets.set(node.part, partTarget)\n targets.push(partTarget)\n const { position, rotation, rotationOrder, scale, heading, matrix } = node\n parts.push({\n id: node.part,\n ...(position ? { position } : {}),\n ...(rotation ? { rotation } : {}),\n ...(rotationOrder ? { rotationOrder } : {}),\n ...(scale !== undefined ? { scale } : {}),\n ...(heading !== undefined ? { heading } : {}),\n ...(matrix ? { matrix } : { matrix: asMat4(matrixOf(node)) }),\n })\n }\n target = partTarget\n }\n }\n const isPart = node.part !== undefined && !bakeParts\n const local = isPart ? null : matrixOf(node)\n const world = isPart ? null : local ? (parentWorld ? multiply(parentWorld, local) : local) : parentWorld\n const next: Inherited = {\n material: node.material !== undefined ? resolveMaterial(node.material) : inherited.material,\n color: node.color !== undefined ? colorHex(node.color) : inherited.color,\n uv: node.uv ?? inherited.uv,\n target,\n }\n\n if (node.instances) {\n drawInstanced(node, parentWorld, next, path)\n return\n }\n\n const snapshot = node.name !== undefined ? new Map([...target.accs].map(([m, a]) => [m, { v: a.vertices, i: a.indices.length }])) : null\n\n if (node.kind === 'group') {\n node.children?.forEach((child, index) => visit(child, world, next, `${path}/${index}`))\n } else if (node.kind === 'point') {\n const p = node.position ?? [0, 0, 0]\n points.push({\n ...(node.name !== undefined ? { name: node.name } : {}),\n part: target.part,\n position: parent ? transformPoint(parent, p[0], p[1], p[2]) : [p[0], p[1], p[2]],\n ...(node.data !== undefined ? { data: node.data } : {}),\n ...(node.tags ? { tags: node.tags } : {}),\n })\n } else if (isPrimitiveNode(node)) {\n const template = buildPrimitive(node, level)\n const m = world ?? identity4()\n if (level.minSize !== undefined && radiusOf(template, m) < level.minSize) return\n primitives++\n if (settings.autoMin !== undefined && node.name === undefined && target.part === null) {\n const key = leafKey(node, next.material, next.color, next.uv, level)\n if ((autoCounts.get(key) ?? 0) >= settings.autoMin) {\n let group = autoGroups.get(key)\n if (!group) {\n group = { node, material: next.material, color: next.color, part: null, matrices: [] }\n autoGroups.set(key, group)\n }\n group.matrices.push(...m)\n return\n }\n }\n bake(accOf(target, next.material), template, m, rgbOf(next.color), next.uv, settings.indexed)\n }\n\n if (snapshot) {\n for (const [material, acc] of target.accs) {\n const before = snapshot.get(material) ?? { v: 0, i: 0 }\n if (acc.vertices === before.v) continue\n acc.ranges.push({\n name: node.name as string,\n ...(node.tags ? { tags: node.tags } : {}),\n vertexStart: before.v,\n vertexCount: acc.vertices - before.v,\n indexStart: before.i,\n indexCount: acc.indices.length - before.i,\n })\n }\n }\n }\n\n const drawInstanced = (node: ShapeNode, parentWorld: Matrix4 | null, inherited: Inherited, path: string): void => {\n const collector: Target = { part: inherited.target.part, accs: new Map() }\n const { instances, ...single } = node as ShapeNode & { instances: NonNullable<ShapeNode['instances']> }\n const before = parts.length\n visit(single as ShapeNode, null, { ...inherited, target: collector }, path)\n if (parts.length !== before) throw new Error(`game-shapes: an instanced node cannot hold parts (${path})`)\n const matrices = new Float32Array(instances.length * 16)\n const hasColors = instances.some((instance) => instance.color !== undefined)\n const colors = hasColors ? new Float32Array(instances.length * 3) : undefined\n instances.forEach((instance, index) => {\n const local = matrixOf(instance)\n const m = local ? (parentWorld ? multiply(parentWorld, local) : local) : parentWorld ?? identity4()\n matrices.set(m, index * 16)\n if (colors) colors.set(colorChannels(colorHex(instance.color), space ?? 'srgb'), index * 3)\n })\n for (const acc of collector.accs.values()) {\n const batch = finish(acc, settings.indexed, false)\n instanced.push({\n material: acc.material,\n part: collector.part,\n ...(node.name !== undefined ? { name: node.name } : {}),\n geometry: { type: 'BufferGeometry', parameters: {}, positions: batch.positions, normals: batch.normals, uvs: batch.uvs, ...(batch.indices ? { indices: batch.indices } : {}), groups: [] },\n matrices: matrices.slice(),\n ...(colors ? { colors: colors.slice() } : {}),\n count: instances.length,\n })\n }\n }\n\n visit(schema.root, null, { material: rootMaterial, color: 0xffffff, uv: IDENTITY_UV, target: root }, 'root')\n\n for (const group of autoGroups.values()) {\n const template = buildPrimitive(group.node, level)\n const n = group.matrices.length / 16\n const rgb = colorChannels(group.color, space ?? 'srgb')\n const colors = new Float32Array(n * 3)\n for (let i = 0; i < n; i++) colors.set(rgb, i * 3)\n instanced.push({\n material: group.material,\n part: null,\n geometry: { type: template.type, parameters: template.parameters, positions: template.positions.slice(), normals: template.normals.slice(), uvs: template.uvs.slice(), ...(template.indices ? { indices: template.indices.slice() } : {}), groups: template.groups.map((g) => ({ ...g })) },\n matrices: new Float32Array(group.matrices),\n ...(space ? { colors } : {}),\n count: n,\n })\n }\n\n const batches: ShapeBatch[] = []\n for (const target of targets) for (const acc of target.accs.values()) if (acc.vertices > 0 && (!settings.indexed || acc.indices.length > 0)) batches.push(finish(acc, settings.indexed, space !== null))\n return { level: { distance: level.distance, detail: level.detail, batches, instanced }, parts, points, primitives }\n}\n\n/**\n * Turns a shape into buffers: one batch per (part, material) per level, baked; instanced nodes as instance batches; parts with their pivots;\n * points. Pure: the same schema and options give the same bytes, here or in a worker.\n */\nexport function generate(schema: ShapeSchema, options: GenerateOptions = {}): ShapeBuffers {\n if (options.validate !== false) assertValidShape(schema)\n const settings: Settings = {\n colors: options.colors ?? 'linear',\n indexed: options.indexed ?? true,\n ...(options.materials ? { materials: new Set(options.materials) } : {}),\n ...(options.fallbackMaterial !== undefined ? { fallback: options.fallbackMaterial } : {}),\n ...(options.materialAlias ? { alias: options.materialAlias } : {}),\n seed: options.seed ?? 0,\n ...(options.generators ? { generators: options.generators } : {}),\n ...(options.instancing ? { autoMin: Math.max(2, options.instancing.minCount) } : {}),\n }\n const specs: LevelSpec[] = [{ distance: 0, detail: 1, index: 0 }, ...(schema.lod ?? []).map((rule, index) => ({ ...rule, index: index + 1 }))]\n const wanted = options.levels ? specs.filter((spec) => options.levels!.includes(spec.index)) : specs\n let parts: ShapePart[] = []\n let points: ShapePoint[] = []\n let primitives = 0\n const levels: ShapeLevel[] = []\n for (const spec of wanted) {\n const result = runLevel(schema, settings, spec)\n if (spec.index === 0 || levels.length === 0) {\n parts = result.parts\n points = result.points\n primitives = result.primitives\n }\n levels.push(result.level)\n }\n const first = levels[0]\n const vertices = first ? first.batches.reduce((sum, batch) => sum + batch.positions.length / 3, 0) : 0\n const triangles = first\n ? first.batches.reduce((sum, batch) => sum + (batch.indices ? batch.indices.length : batch.positions.length / 3) / 3, 0) +\n first.instanced.reduce((sum, batch) => sum + ((batch.geometry.indices ? batch.geometry.indices.length : batch.geometry.positions.length / 3) / 3) * batch.count, 0)\n : 0\n return {\n key: options.key === false ? '' : options.key ?? shapeKey(schema, options),\n ...(schema.name !== undefined ? { name: schema.name } : {}),\n levels,\n parts,\n points,\n ...(schema.materials ? { materials: schema.materials } : {}),\n ...(schema.cullDistance !== undefined ? { cullDistance: schema.cullDistance } : {}),\n stats: { vertices, triangles, batches: first ? first.batches.length : 0, instances: first ? first.instanced.reduce((sum, batch) => sum + batch.count, 0) : 0, primitives },\n }\n}\n","import { normalMatrix, transformPoint } from './math'\nimport type { InstancedBatch, PrimitiveBuffers, ShapeBatch, ShapeBuffers } from './types'\n\n/** One piece for `mergeTransformed`: arrays (any may be missing) and the matrix that takes them into the merged space. */\nexport interface TransformedPiece {\n readonly positions: ArrayLike<number>\n readonly normals?: ArrayLike<number>\n readonly uvs?: ArrayLike<number>\n readonly indices?: ArrayLike<number> | null\n /** Column-major 4 x 4. */\n readonly matrix: readonly number[]\n}\n\nexport interface MergedArrays {\n readonly positions: Float32Array\n readonly normals: Float32Array\n readonly uvs: Float32Array\n}\n\n/**\n * Joins pieces into one non-indexed set of arrays, each piece de-indexed, its missing normals and uvs zero-filled, its positions by\n * `Vector3.applyMatrix4` and its normals by the normal matrix and normalised: what three's `toNonIndexed` + `applyMatrix4` + a join do,\n * bit for bit (the port of `mergeByMaterial`).\n */\nexport function mergeTransformed(pieces: readonly TransformedPiece[]): MergedArrays {\n let total = 0\n for (const piece of pieces) total += piece.indices ? piece.indices.length : piece.positions.length / 3\n const positions = new Float32Array(total * 3)\n const normals = new Float32Array(total * 3)\n const uvs = new Float32Array(total * 2)\n let at = 0\n for (const piece of pieces) {\n const e = piece.matrix\n const nm = normalMatrix(e)\n const count = piece.indices ? piece.indices.length : piece.positions.length / 3\n // de-index into Float32 first, as toNonIndexed does, then transform the stored values\n const p = new Float32Array(count * 3)\n const n = new Float32Array(count * 3)\n for (let k = 0; k < count; k++) {\n const i = piece.indices ? (piece.indices[k] as number) : k\n for (let c = 0; c < 3; c++) {\n p[k * 3 + c] = piece.positions[i * 3 + c] as number\n if (piece.normals) n[k * 3 + c] = piece.normals[i * 3 + c] as number\n }\n if (piece.uvs) {\n uvs[(at + k) * 2] = piece.uvs[i * 2] as number\n uvs[(at + k) * 2 + 1] = piece.uvs[i * 2 + 1] as number\n }\n }\n for (let k = 0; k < count; k++) {\n const q = transformPoint(e, p[k * 3] as number, p[k * 3 + 1] as number, p[k * 3 + 2] as number)\n positions[(at + k) * 3] = q[0]\n positions[(at + k) * 3 + 1] = q[1]\n positions[(at + k) * 3 + 2] = q[2]\n const x = n[k * 3] as number\n const y = n[k * 3 + 1] as number\n const z = n[k * 3 + 2] as number\n const vx = nm[0]! * x + nm[3]! * y + nm[6]! * z\n const vy = nm[1]! * x + nm[4]! * y + nm[7]! * z\n const vz = nm[2]! * x + nm[5]! * y + nm[8]! * z\n const s = 1 / (Math.sqrt(vx * vx + vy * vy + vz * vz) || 1)\n normals[(at + k) * 3] = vx * s\n normals[(at + k) * 3 + 1] = vy * s\n normals[(at + k) * 3 + 2] = vz * s\n }\n at += count\n }\n return { positions, normals, uvs }\n}\n\nconst primitiveArrays = (p: PrimitiveBuffers): ArrayBuffer[] => [p.positions, p.normals, p.uvs, ...(p.indices ? [p.indices] : [])].map((a) => a.buffer as ArrayBuffer)\nconst batchArrays = (b: ShapeBatch): ArrayBuffer[] => [b.positions, b.normals, b.uvs, ...(b.colors ? [b.colors] : []), ...(b.indices ? [b.indices] : [])].map((a) => a.buffer as ArrayBuffer)\nconst instancedArrays = (b: InstancedBatch): ArrayBuffer[] => [...primitiveArrays(b.geometry), b.matrices.buffer as ArrayBuffer, ...(b.colors ? [b.colors.buffer as ArrayBuffer] : [])]\n\n/** Every `ArrayBuffer` of a result, for `postMessage(buffers, transferablesOf(buffers))`. */\nexport function transferablesOf(buffers: ShapeBuffers): ArrayBuffer[] {\n const out = new Set<ArrayBuffer>()\n for (const level of buffers.levels) {\n for (const batch of level.batches) for (const a of batchArrays(batch)) out.add(a)\n for (const batch of level.instanced) for (const a of instancedArrays(batch)) out.add(a)\n }\n return [...out]\n}\n\nconst copyPrimitive = (p: PrimitiveBuffers): PrimitiveBuffers => ({\n ...p,\n positions: p.positions.slice(),\n normals: p.normals.slice(),\n uvs: p.uvs.slice(),\n ...(p.indices ? { indices: p.indices.slice() } : {}),\n groups: p.groups.map((g) => ({ ...g })),\n})\n\n/** A deep copy whose arrays are its own (cached results are shared and read-only; copy before deforming). */\nexport function cloneBuffers(buffers: ShapeBuffers): ShapeBuffers {\n return {\n ...buffers,\n levels: buffers.levels.map((level) => ({\n ...level,\n batches: level.batches.map((b) => ({\n ...b,\n positions: b.positions.slice(),\n normals: b.normals.slice(),\n uvs: b.uvs.slice(),\n ...(b.colors ? { colors: b.colors.slice() } : {}),\n ...(b.indices ? { indices: b.indices.slice() } : {}),\n ranges: b.ranges.map((r) => ({ ...r })),\n bounds: { min: [...b.bounds.min], max: [...b.bounds.max] },\n })),\n instanced: level.instanced.map((b) => ({ ...b, geometry: copyPrimitive(b.geometry), matrices: b.matrices.slice(), ...(b.colors ? { colors: b.colors.slice() } : {}) })),\n })),\n }\n}\n\n/** Bytes held by the arrays of a result (what the cache counts). */\nexport function byteSizeOf(buffers: ShapeBuffers): number {\n return transferablesOf(buffers).reduce((sum, buffer) => sum + buffer.byteLength, 0)\n}\n","import { generate } from './generate'\nimport { transferablesOf } from './merge'\nimport type { GenerateOptions, ShapeBuffers, ShapeGenerator, ShapeSchema } from './types'\n\n/** A job the pool posts: `options` without `generators` (functions do not cross threads; register them in the worker script). */\nexport interface ShapeJob {\n readonly id: number\n readonly schema: ShapeSchema\n readonly options?: Omit<GenerateOptions, 'generators'>\n}\n\nexport type ShapeReply = { readonly id: number; readonly ok: true; readonly buffers: ShapeBuffers } | { readonly id: number; readonly ok: false; readonly error: string }\n\n/** What a worker scope looks like: `self` in a browser worker, a `worker_threads` `parentPort` wrapper in Node, or an in-thread fake. */\nexport interface WorkerScopeLike {\n onmessage: ((event: { data: unknown }) => void) | null\n postMessage(message: unknown, transfer?: ArrayBuffer[]): void\n}\n\nexport interface ShapeWorkerOptions {\n /** Generators of the `custom` nodes, the same ones the main thread registers. */\n readonly generators?: Readonly<Record<string, ShapeGenerator>>\n /** Transfer the arrays back (default true: zero copy, the worker keeps nothing). */\n readonly transfer?: boolean\n}\n\n/**\n * The worker side of `createShapePool`: answers each job with `generate(schema, options)`, transferring every array.\n *\n * ```ts\n * // shape-worker.ts\n * import { installShapeWorker } from '@adatechnology/game-shapes/worker'\n * installShapeWorker(self as never, { generators: myGenerators })\n * ```\n */\nexport function installShapeWorker(scope: WorkerScopeLike, options: ShapeWorkerOptions = {}): void {\n const transfer = options.transfer !== false\n scope.onmessage = (event) => {\n const job = event.data as ShapeJob\n try {\n const buffers = generate(job.schema, { ...(job.options ?? {}), ...(options.generators ? { generators: options.generators } : {}) })\n const reply: ShapeReply = { id: job.id, ok: true, buffers }\n scope.postMessage(reply, transfer ? transferablesOf(buffers) : [])\n } catch (error) {\n const reply: ShapeReply = { id: job.id, ok: false, error: error instanceof Error ? error.message : String(error) }\n scope.postMessage(reply)\n }\n }\n}\n","import type { PrimitiveBuffers, ShapeBatch } from '@adatechnology/game-shapes'\nimport type * as THREE_NS from 'three'\n\nexport type Three = typeof THREE_NS\n\nexport interface ToGeometryOptions {\n /** Copy the arrays into the attributes (default true). Without a copy the geometry shares the buffers (a cached result is read-only: do not deform it). */\n readonly copy?: boolean\n}\n\n/** The order in which three's generator of each type sets its attributes (toJSON and attribute iteration keep it). */\nconst UV_BEFORE_NORMAL = new Set(['LatheGeometry', 'ExtrudeGeometry'])\n/** Types whose constructor sets the index before the attributes. */\nconst INDEX_FIRST = new Set(['BoxGeometry', 'CylinderGeometry', 'ConeGeometry', 'SphereGeometry', 'PlaneGeometry', 'CircleGeometry', 'RingGeometry', 'LatheGeometry', 'TorusGeometry'])\n\nconst isPrimitive = (value: PrimitiveBuffers | ShapeBatch): value is PrimitiveBuffers => typeof (value as PrimitiveBuffers).type === 'string'\n\n/** Three's own parameters object for a type (lathe points as `Vector2`). */\nfunction threeParameters(THREE: Three, p: PrimitiveBuffers): Record<string, unknown> {\n if (p.type === 'LatheGeometry') {\n const points = (p.parameters.points as Array<{ x: number; y: number }>).map(({ x, y }) => new THREE.Vector2(x, y))\n return { ...p.parameters, points }\n }\n return { ...p.parameters }\n}\n\n/**\n * A `BufferGeometry` from game-shapes buffers. A primitive becomes an instance of the three class it reproduces (`type`, `parameters`, prototype:\n * `instanceof THREE.CylinderGeometry`, `clone()` and `toJSON()` behave as three's), with the same attributes, index and groups. A batch gets\n * `position`, `normal`, `uv`, `color` (when present) and its index.\n */\nexport function toGeometry(THREE: Three, source: PrimitiveBuffers | ShapeBatch, options: ToGeometryOptions = {}): THREE_NS.BufferGeometry {\n const copy = options.copy !== false\n const primitive = isPrimitive(source) ? source : null\n const ThreeClass = primitive && primitive.type !== 'BufferGeometry' ? ((THREE as unknown as Record<string, unknown>)[primitive.type] as (new () => THREE_NS.BufferGeometry) | undefined) : undefined\n // the BufferGeometry constructor only, with the prototype of the class it stands for\n const geometry = (ThreeClass ? Reflect.construct(THREE.BufferGeometry, [], ThreeClass) : new THREE.BufferGeometry()) as THREE_NS.BufferGeometry & { parameters?: Record<string, unknown> }\n if (primitive && ThreeClass) {\n Object.assign(geometry, { type: primitive.type, parameters: threeParameters(THREE, primitive) })\n }\n const attribute = (array: Float32Array, size: number): THREE_NS.BufferAttribute => (copy ? new THREE.Float32BufferAttribute(array, size) : new THREE.BufferAttribute(array, size))\n const index = source.indices\n const setIndex = (): void => {\n if (!index) return\n geometry.setIndex(copy ? (index instanceof Uint32Array ? new THREE.Uint32BufferAttribute(index, 1) : new THREE.Uint16BufferAttribute(index, 1)) : new THREE.BufferAttribute(index, 1))\n }\n const type = primitive?.type ?? 'BufferGeometry'\n if (INDEX_FIRST.has(type)) setIndex()\n geometry.setAttribute('position', attribute(source.positions, 3))\n if (UV_BEFORE_NORMAL.has(type)) {\n geometry.setAttribute('uv', attribute(source.uvs, 2))\n geometry.setAttribute('normal', attribute(source.normals, 3))\n } else {\n geometry.setAttribute('normal', attribute(source.normals, 3))\n geometry.setAttribute('uv', attribute(source.uvs, 2))\n }\n if (!primitive && (source as ShapeBatch).colors) geometry.setAttribute('color', attribute((source as ShapeBatch).colors as Float32Array, 3))\n if (!INDEX_FIRST.has(type)) setIndex()\n if (primitive) for (const group of primitive.groups) geometry.addGroup(group.start, group.count, group.materialIndex)\n return geometry\n}\n","import { box, circle, cone, cylinder, extrude, lathe, plane, ring, sphere, torus } from '@adatechnology/game-shapes'\nimport type { BevelSpec, PrimitiveBuffers, PrimitiveNode, ShapeOutline, Vec2 } from '@adatechnology/game-shapes'\nimport { buildPrimitive } from '@adatechnology/game-shapes'\nimport type * as THREE_NS from 'three'\n\nimport { toGeometry } from './geometry'\nimport type { Three } from './geometry'\n\n/** The geometry constructors `shapeGeometries` replaces. */\nexport const SHAPE_GEOMETRY_TYPES = ['BoxGeometry', 'CylinderGeometry', 'ConeGeometry', 'SphereGeometry', 'PlaneGeometry', 'CircleGeometry', 'RingGeometry', 'LatheGeometry', 'TorusGeometry', 'ExtrudeGeometry'] as const\n\ntype Curve = { isLineCurve?: boolean; v1?: { x: number; y: number }; v2?: { x: number; y: number } }\ntype PathLike = { curves: Curve[]; autoClose?: boolean; holes?: PathLike[] }\n\n/** The point list of a path made only of contiguous `LineCurve`s (what `moveTo` + `lineTo` builds), or null. */\nfunction linePoints(path: PathLike): Vec2[] | null {\n if (path.autoClose || path.curves.length === 0) return null\n const points: Vec2[] = []\n for (const [index, curve] of path.curves.entries()) {\n if (!curve.isLineCurve || !curve.v1 || !curve.v2) return null\n if (index === 0) points.push([curve.v1.x, curve.v1.y])\n else {\n const last = points[points.length - 1] as Vec2\n if (last[0] !== curve.v1.x || last[1] !== curve.v1.y) return null\n }\n points.push([curve.v2.x, curve.v2.y])\n }\n return points\n}\n\ntype ExtrudeOptions = { depth?: number; steps?: number; bevelEnabled?: boolean; bevelThickness?: number; bevelSize?: number; bevelOffset?: number; bevelSegments?: number; extrudePath?: unknown; UVGenerator?: unknown; curveSegments?: number }\n\n/** An extrusion game-shapes can make exactly: one straight-edged shape, no path, the world uvs. */\nfunction extrudeOf(shapes: unknown, options: ExtrudeOptions = {}): PrimitiveBuffers | null {\n if (Array.isArray(shapes) || !shapes || options.extrudePath !== undefined || options.UVGenerator !== undefined) return null\n const shape = shapes as PathLike\n const outer = linePoints(shape)\n if (!outer) return null\n const holes: Vec2[][] = []\n for (const hole of shape.holes ?? []) {\n const points = linePoints(hole)\n if (!points) return null\n holes.push(points)\n }\n const outline: ShapeOutline = holes.length ? { outer, holes } : { outer }\n const bevel: false | BevelSpec =\n options.bevelEnabled === false\n ? false\n : {\n ...(options.bevelThickness !== undefined ? { thickness: options.bevelThickness } : {}),\n ...(options.bevelSize !== undefined ? { size: options.bevelSize } : {}),\n ...(options.bevelOffset !== undefined ? { offset: options.bevelOffset } : {}),\n ...(options.bevelSegments !== undefined ? { segments: options.bevelSegments } : {}),\n }\n return extrude(outline, options.depth, options.steps, bevel)\n}\n\nexport interface ShapeGeometriesOptions {\n /** Go through the template cache of game-shapes (default true): the same primitive is generated once per process. */\n readonly cache?: boolean\n}\n\nconst namespaces = new WeakMap<object, Map<string, Three>>()\n/** The namespaces this module made: wrapping one again gives it back (a package handing its `T` to another). */\nconst shims = new WeakSet<object>()\n\n/**\n * A three namespace whose `BoxGeometry`, `CylinderGeometry`, `ConeGeometry`, `SphereGeometry`, `PlaneGeometry`, `CircleGeometry`, `RingGeometry`,\n * `LatheGeometry`, `TorusGeometry` and (straight-edged) `ExtrudeGeometry` are made by game-shapes, bit-identical to three's and instances of three's\n * classes; everything else is three's own. Hand it to code ported from the teams as `T`, so it keeps reading `new T.CylinderGeometry(...)`.\n * An extrusion with curves, several shapes, a path or a custom uv generator falls back to three.\n */\nexport function shapeGeometries(THREE: Three, options: ShapeGeometriesOptions = {}): Three {\n if (shims.has(THREE)) return THREE\n const cache = options.cache !== false\n const key = cache ? 'cache' : 'nocache'\n let byKey = namespaces.get(THREE)\n if (!byKey) {\n byKey = new Map()\n namespaces.set(THREE, byKey)\n }\n const existing = byKey.get(key)\n if (existing) return existing\n const made = (p: PrimitiveBuffers): THREE_NS.BufferGeometry => toGeometry(THREE, p)\n const viaCache = (node: PrimitiveNode, direct: () => PrimitiveBuffers): PrimitiveBuffers => (cache ? buildPrimitive(node) : direct())\n const defined = <T extends object>(o: T): T => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined)) as T\n const constructors: Record<(typeof SHAPE_GEOMETRY_TYPES)[number], (...args: any[]) => THREE_NS.BufferGeometry> = {\n BoxGeometry: (width?: number, height?: number, depth?: number, ws = 1, hs = 1, ds = 1) =>\n made(viaCache({ kind: 'box', size: [width ?? 1, height ?? 1, depth ?? 1], segments: [ws, hs, ds] }, () => box(width, height, depth, ws, hs, ds))),\n CylinderGeometry: (radiusTop?: number, radiusBottom?: number, height?: number, radialSegments?: number, heightSegments?: number, openEnded?: boolean, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'cylinder', ...defined({ radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }) }, () => cylinder(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))),\n ConeGeometry: (radius?: number, height?: number, radialSegments?: number, heightSegments?: number, openEnded?: boolean, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'cone', ...defined({ radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }) }, () => cone(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))),\n SphereGeometry: (radius?: number, widthSegments?: number, heightSegments?: number, phiStart?: number, phiLength?: number, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'sphere', ...defined({ radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength }) }, () => sphere(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength))),\n PlaneGeometry: (width?: number, height?: number, widthSegments?: number, heightSegments?: number) =>\n made(viaCache({ kind: 'plane', ...defined({ width, height, widthSegments, heightSegments }) }, () => plane(width, height, widthSegments, heightSegments))),\n CircleGeometry: (radius?: number, segments?: number, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'circle', ...defined({ radius, segments, thetaStart, thetaLength }) }, () => circle(radius, segments, thetaStart, thetaLength))),\n RingGeometry: (innerRadius?: number, outerRadius?: number, thetaSegments?: number, phiSegments?: number, thetaStart?: number, thetaLength?: number) =>\n made(viaCache({ kind: 'ring', ...defined({ innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength }) }, () => ring(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength))),\n LatheGeometry: (points?: Array<{ x: number; y: number }>, segments?: number, phiStart?: number, phiLength?: number) => {\n if (!points) return new THREE.LatheGeometry(undefined, segments, phiStart, phiLength)\n const profile = points.map((p) => [p.x, p.y] as const)\n return made(viaCache({ kind: 'lathe', points: profile, ...defined({ segments, phiStart, phiLength }) }, () => lathe(profile, segments, phiStart, phiLength)))\n },\n TorusGeometry: (radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, arc?: number) =>\n made(viaCache({ kind: 'torus', ...defined({ radius, tube, radialSegments, tubularSegments, arc }) }, () => torus(radius, tube, radialSegments, tubularSegments, arc))),\n ExtrudeGeometry: (shapes?: unknown, extrudeOptions?: ExtrudeOptions) => {\n const buffers = shapes === undefined ? null : extrudeOf(shapes, extrudeOptions)\n if (!buffers) return new THREE.ExtrudeGeometry(shapes as THREE_NS.Shape, extrudeOptions as THREE_NS.ExtrudeGeometryOptions)\n const geometry = toGeometry(THREE, buffers) as THREE_NS.BufferGeometry & { parameters: unknown }\n geometry.parameters = { shapes, options: extrudeOptions ?? {} }\n return geometry\n },\n }\n const namespace: Record<string, unknown> = { ...(THREE as unknown as Record<string, unknown>) }\n for (const type of SHAPE_GEOMETRY_TYPES) {\n const make = constructors[type]\n // callable with `new` (the returned object wins), and `instanceof` checks three's prototype\n const Constructor = function (this: unknown, ...args: unknown[]) {\n return make(...args)\n } as unknown as { prototype: unknown }\n Constructor.prototype = (THREE as unknown as Record<string, { prototype: unknown }>)[type]!.prototype\n Object.defineProperty(Constructor, 'name', { value: type })\n namespace[type] = Constructor\n }\n const result = namespace as unknown as Three\n byKey.set(key, result)\n shims.add(result)\n return result\n}\n","import { colorHex } from '@adatechnology/game-shapes'\nimport type { MaterialHint, ShapeBuffers, ShapeLevel, ShapePart, ShapePoint } from '@adatechnology/game-shapes'\nimport type * as THREE_NS from 'three'\n\nimport { toGeometry } from './geometry'\nimport type { Three } from './geometry'\n\n/** A `MeshStandardMaterial` per material id from the schema's hints (vertex colours on unless the hint says otherwise). */\nexport function createMaterials(THREE: Three, hints: Readonly<Record<string, MaterialHint>> = {}, ids: Iterable<string> = []): Record<string, THREE_NS.Material> {\n const out: Record<string, THREE_NS.Material> = {}\n const all = new Set([...Object.keys(hints), ...ids])\n for (const id of all) {\n const hint = hints[id] ?? {}\n const parameters: THREE_NS.MeshStandardMaterialParameters = { vertexColors: hint.vertexColors ?? true }\n if (hint.color !== undefined) parameters.color = colorHex(hint.color)\n if (hint.roughness !== undefined) parameters.roughness = hint.roughness\n if (hint.metalness !== undefined) parameters.metalness = hint.metalness\n if (hint.opacity !== undefined) parameters.opacity = hint.opacity\n if (hint.transparent !== undefined) parameters.transparent = hint.transparent\n if (hint.emissive !== undefined) parameters.emissive = colorHex(hint.emissive)\n if (hint.emissiveIntensity !== undefined) parameters.emissiveIntensity = hint.emissiveIntensity\n if (hint.flatShading !== undefined) parameters.flatShading = hint.flatShading\n if (hint.depthWrite !== undefined) parameters.depthWrite = hint.depthWrite\n if (hint.side !== undefined) parameters.side = hint.side === 'double' ? THREE.DoubleSide : hint.side === 'back' ? THREE.BackSide : THREE.FrontSide\n const material = new THREE.MeshStandardMaterial(parameters)\n material.name = id\n out[id] = material\n }\n return out\n}\n\nexport interface ToObjectOptions {\n /** Materials by id; missing ids get one from the schema hints (`createMaterials`). */\n readonly materials?: Readonly<Record<string, THREE_NS.Material>>\n /** The material of one draw (wins over `materials`): per material id and part (`null` for the static body). */\n readonly materialFor?: (material: string, part: string | null) => THREE_NS.Material | undefined\n /** Cast and receive shadows (default true). */\n readonly shadows?: boolean\n /** Copy the arrays into the attributes (default true; false shares them, read-only). */\n readonly copy?: boolean\n /** Name of the root. */\n readonly name?: string\n}\n\nexport interface ShapeObject {\n /** A `Group`, or a `LOD` when the shape has levels or a cull distance. */\n readonly object: THREE_NS.Object3D\n /** The level 0 group (the root itself without LOD). */\n readonly near: THREE_NS.Group\n /** Part groups of level 0 by id, at their pivots; animate these. */\n readonly parts: Record<string, THREE_NS.Group>\n readonly meshes: THREE_NS.Mesh[]\n readonly instanced: THREE_NS.InstancedMesh[]\n readonly points: readonly ShapePoint[]\n readonly materials: Record<string, THREE_NS.Material>\n}\n\nfunction placePart(THREE: Three, group: THREE_NS.Group, part: ShapePart): void {\n if (part.matrix && part.position === undefined && part.rotation === undefined && part.scale === undefined && part.heading === undefined) {\n new THREE.Matrix4().fromArray(part.matrix as number[]).decompose(group.position, group.quaternion, group.scale)\n return\n }\n if (part.position) group.position.set(part.position[0], part.position[1], part.position[2])\n if (part.heading !== undefined) group.rotation.y = part.heading\n else if (part.rotation) group.rotation.set(part.rotation[0], part.rotation[1], part.rotation[2], part.rotationOrder ?? 'XYZ')\n if (part.scale !== undefined) {\n if (typeof part.scale === 'number') group.scale.setScalar(part.scale)\n else group.scale.set(part.scale[0], part.scale[1], part.scale[2])\n }\n group.updateMatrix()\n}\n\n/**\n * The three objects of a shape: one mesh per batch (`static:<material>` or `part:<id>`, `userData.material`, `userData.part`), part groups at their\n * pivots, an `InstancedMesh` per instanced batch, and a `LOD` (levels at their distances, nothing from `cullDistance`) when there are levels.\n */\nexport function toObject3D(THREE: Three, buffers: ShapeBuffers, options: ToObjectOptions = {}): ShapeObject {\n const shadows = options.shadows !== false\n const ids = new Set<string>()\n for (const level of buffers.levels) {\n for (const b of level.batches) ids.add(b.material)\n for (const b of level.instanced) ids.add(b.material)\n }\n const made = createMaterials(THREE, buffers.materials, [...ids].filter((id) => !options.materials?.[id]))\n const materials: Record<string, THREE_NS.Material> = { ...made, ...(options.materials ?? {}) }\n const materialOf = (id: string, part: string | null): THREE_NS.Material => options.materialFor?.(id, part) ?? (materials[id] as THREE_NS.Material)\n const meshes: THREE_NS.Mesh[] = []\n const instanced: THREE_NS.InstancedMesh[] = []\n\n const build = (level: ShapeLevel, withParts: boolean): { group: THREE_NS.Group; parts: Record<string, THREE_NS.Group> } => {\n const group = new THREE.Group()\n group.name = options.name ?? buffers.name ?? 'shape'\n const parts: Record<string, THREE_NS.Group> = {}\n if (withParts) {\n for (const part of buffers.parts) {\n const g = new THREE.Group()\n g.name = `part:${part.id}`\n g.userData.part = part.id\n placePart(THREE, g, part)\n parts[part.id] = g\n }\n }\n const into = (part: string | null): THREE_NS.Object3D => (part !== null && parts[part]) || group\n for (const batch of level.batches) {\n const mesh = new THREE.Mesh(toGeometry(THREE, batch, { copy: options.copy !== false }), materialOf(batch.material, batch.part))\n mesh.geometry.computeBoundingSphere()\n mesh.geometry.computeBoundingBox()\n mesh.name = batch.part === null ? `static:${batch.material}` : `part:${batch.part}`\n if (batch.part !== null) mesh.userData.part = batch.part\n mesh.userData.material = batch.material\n if (batch.ranges.length) mesh.userData.ranges = batch.ranges\n mesh.castShadow = shadows\n mesh.receiveShadow = shadows\n into(batch.part).add(mesh)\n meshes.push(mesh)\n }\n for (const batch of level.instanced) {\n const mesh = new THREE.InstancedMesh(toGeometry(THREE, batch.geometry, { copy: options.copy !== false }), materialOf(batch.material, batch.part), batch.count)\n mesh.instanceMatrix.array.set(batch.matrices)\n mesh.instanceMatrix.needsUpdate = true\n if (batch.colors) mesh.instanceColor = new THREE.InstancedBufferAttribute(batch.colors.slice(), 3)\n mesh.name = `instanced:${batch.name ?? batch.material}`\n mesh.userData.material = batch.material\n if (batch.part !== null) mesh.userData.part = batch.part\n mesh.castShadow = shadows\n mesh.receiveShadow = shadows\n mesh.computeBoundingSphere()\n into(batch.part).add(mesh)\n instanced.push(mesh)\n }\n for (const part of Object.values(parts)) group.add(part)\n return { group, parts }\n }\n\n const levels = buffers.levels\n const first = build(levels[0] ?? { distance: 0, detail: 1, batches: [], instanced: [] }, true)\n let object: THREE_NS.Object3D = first.group\n if (levels.length > 1 || buffers.cullDistance !== undefined) {\n const lod = new THREE.LOD()\n lod.name = first.group.name\n lod.addLevel(first.group, 0)\n for (const level of levels.slice(1)) lod.addLevel(build(level, false).group, level.distance)\n if (buffers.cullDistance !== undefined) lod.addLevel(new THREE.Group(), buffers.cullDistance)\n object = lod\n }\n object.userData.points = buffers.points\n return { object, near: first.group, parts: first.parts, meshes, instanced, points: buffers.points, materials }\n}\n","import { mergeTransformed } from '@adatechnology/game-shapes'\nimport type { TransformedPiece } from '@adatechnology/game-shapes'\nimport type * as THREE_NS from 'three'\n\nimport type { Three } from './geometry'\n\nconst isVisible = (object: THREE_NS.Object3D): boolean => {\n for (let node: THREE_NS.Object3D | null = object; node; node = node.parent) if (!node.visible) return false\n return true\n}\n\n/** A plain, non-interleaved, not normalised Float32 attribute: what the core merge reads directly. */\nconst plain = (attribute: THREE_NS.BufferAttribute | THREE_NS.InterleavedBufferAttribute | undefined): attribute is THREE_NS.BufferAttribute =>\n attribute !== undefined && !(attribute as THREE_NS.InterleavedBufferAttribute).isInterleavedBufferAttribute && attribute.array instanceof Float32Array && !attribute.normalized\n\n/** Arrays of a geometry the core merge can take as they are; for anything else, the arrays three's own `toNonIndexed` makes (then not indexed). */\nfunction piece(geometry: THREE_NS.BufferGeometry, matrix: THREE_NS.Matrix4): TransformedPiece {\n const position = geometry.getAttribute('position')\n const normal = geometry.getAttribute('normal')\n const uv = geometry.getAttribute('uv')\n const ok = plain(position) && (normal === undefined || plain(normal)) && (uv === undefined || plain(uv)) && position.itemSize === 3 && (uv === undefined || uv.itemSize === 2)\n if (ok) {\n return { positions: position.array, ...(normal ? { normals: normal.array } : {}), ...(uv ? { uvs: uv.array } : {}), indices: geometry.index ? geometry.index.array : null, matrix: matrix.elements }\n }\n const flat = geometry.index ? geometry.toNonIndexed() : geometry\n const read = (name: string, size: number): Float32Array | undefined => {\n const attribute = flat.getAttribute(name)\n if (!attribute) return undefined\n const out = new Float32Array(attribute.count * size)\n for (let i = 0; i < attribute.count; i++) for (let c = 0; c < size; c++) out[i * size + c] = c === 0 ? attribute.getX(i) : c === 1 ? attribute.getY(i) : attribute.getZ(i)\n return out\n }\n const positions = read('position', 3) as Float32Array\n const normals = read('normal', 3)\n const uvs = read('uv', 2)\n if (flat !== geometry) flat.dispose()\n return { positions, ...(normals ? { normals } : {}), ...(uvs ? { uvs } : {}), indices: null, matrix: matrix.elements }\n}\n\n/**\n * Every visible mesh under `root` (whose world matrix must be up to date), baked into the space of `space` and joined by material: one non-indexed\n * mesh per material (position, normal, uv), no shadow cast. The bake is game-shapes' `mergeTransformed`, bit-identical to three's\n * `toNonIndexed` + `applyMatrix4` + join, so the result is the one `game-props3d`'s `mergeByMaterial` always gave.\n */\nexport function mergeByMaterial(THREE: Three, root: THREE_NS.Object3D, space: THREE_NS.Object3D): THREE_NS.Mesh[] {\n const toSpace = space.matrixWorld.clone().invert()\n const byMaterial = new Map<THREE_NS.Material, TransformedPiece[]>()\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh || Array.isArray(mesh.material) || !isVisible(mesh)) return\n const list = byMaterial.get(mesh.material) ?? []\n list.push(piece(mesh.geometry, new THREE.Matrix4().multiplyMatrices(toSpace, mesh.matrixWorld)))\n byMaterial.set(mesh.material, list)\n })\n return [...byMaterial].map(([material, pieces]) => {\n const merged = mergeTransformed(pieces)\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(merged.positions, 3))\n geometry.setAttribute('normal', new THREE.BufferAttribute(merged.normals, 3))\n geometry.setAttribute('uv', new THREE.BufferAttribute(merged.uvs, 2))\n const mesh = new THREE.Mesh(geometry, material)\n mesh.castShadow = false\n mesh.receiveShadow = true\n return mesh\n })\n}\n","import type { Condition, DamageMaterial, PartKind } from './types'\n\n/** Keys of the material table. A piece / mesh refers to a key; `MaterialIds` maps it to a destruction SDK material id. */\nexport type MaterialKey = 'wood' | 'woodDry' | 'foliage' | 'flowers' | 'fruit' | 'pot' | 'soil' | 'cactus'\nexport type MaterialIds = Record<MaterialKey, string>\n\n/**\n * Default mapping to the common destruction SDK material ids (snake_case `MaterialId` strings, see game-destruction).\n * Nothing is imported from that package: these are plain strings, override any of them with the `materialIds` option.\n */\nexport const DEFAULT_MATERIAL_IDS: Readonly<MaterialIds> = Object.freeze({\n wood: 'green_wood',\n woodDry: 'wood_soft',\n foliage: 'foliage',\n flowers: 'foliage',\n fruit: 'flesh_fruit',\n pot: 'ceramic',\n soil: 'soil',\n cactus: 'cactus',\n})\n\nexport function resolveMaterialIds(overrides?: Partial<MaterialIds>): MaterialIds {\n return { ...DEFAULT_MATERIAL_IDS, ...(overrides ?? {}) }\n}\n\n/** Material key of a whole mesh part (wood of a dry / dead plant is dry wood; the cactus body and spines are 'cactus'). */\nexport function materialKeyForPart(part: PartKind, meshMaterial: DamageMaterial, condition: Condition = 'healthy'): MaterialKey {\n switch (part) {\n case 'wood':\n return condition === 'dry' || condition === 'dead' ? 'woodDry' : 'wood'\n case 'foliage':\n return meshMaterial === 'cactus' ? 'cactus' : 'foliage'\n case 'flowers':\n return 'flowers'\n case 'fruit':\n return 'fruit'\n default:\n return 'cactus'\n }\n}\n","/** FNV-1a 32-bit string hash. */\nexport function hashString(s: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n}\n\n/** Mix two uint32 values into one. */\nexport function hashMix(a: number, b: number): number {\n let h = (a ^ Math.imul(b, 0x9e3779b1)) >>> 0\n h = Math.imul(h ^ (h >>> 16), 0x85ebca6b)\n h = Math.imul(h ^ (h >>> 13), 0xc2b2ae35)\n return (h ^ (h >>> 16)) >>> 0\n}\n\nexport function toSeed(seed: number | string | undefined): number {\n if (seed === undefined) return 1\n if (typeof seed === 'string') return hashString(seed)\n return seed >>> 0 || 1\n}\n\n/** mulberry32 PRNG with small helpers. Never uses Math.random. */\nexport class Rng {\n private s: number\n constructor(seed: number) {\n this.s = seed >>> 0\n }\n next(): number {\n this.s = (this.s + 0x6d2b79f5) >>> 0\n let t = this.s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n range(a: number, b: number): number {\n return a + (b - a) * this.next()\n }\n int(a: number, b: number): number {\n return Math.floor(this.range(a, b + 1))\n }\n chance(p: number): boolean {\n return this.next() < p\n }\n sign(): number {\n return this.next() < 0.5 ? -1 : 1\n }\n pick<T>(arr: readonly T[]): T {\n return arr[Math.min(arr.length - 1, Math.floor(this.next() * arr.length))]\n }\n /** approx gaussian (sum of 3 uniforms), mean 0, roughly -1..1 */\n gauss(): number {\n return (this.next() + this.next() + this.next()) / 1.5 - 1\n }\n /** independent child generator derived from this one's seed and a label / index */\n fork(label: number | string): Rng {\n return new Rng(hashMix(this.s, typeof label === 'string' ? hashString(label) : label + 1))\n }\n /** a fresh uint32 derived without advancing structure-dependent streams */\n seed(): number {\n return Math.floor(this.next() * 4294967296) >>> 0\n }\n}\n\nexport function createRng(seed: number | string | undefined): Rng {\n return new Rng(toSeed(seed))\n}\n","import type { Vec3 } from './types'\n\nexport const TAU = Math.PI * 2\nexport const add = (a: Vec3, b: Vec3): Vec3 => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]\nexport const sub = (a: Vec3, b: Vec3): Vec3 => [a[0] - b[0], a[1] - b[1], a[2] - b[2]]\nexport const mul = (a: Vec3, s: number): Vec3 => [a[0] * s, a[1] * s, a[2] * s]\nexport const dot = (a: Vec3, b: Vec3): number => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\nexport const cross = (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]\nexport const len = (a: Vec3): number => Math.hypot(a[0], a[1], a[2])\nexport const dist = (a: Vec3, b: Vec3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2])\nexport const norm = (a: Vec3): Vec3 => {\n const l = len(a)\n return l < 1e-9 ? [0, 1, 0] : [a[0] / l, a[1] / l, a[2] / l]\n}\nexport const lerp = (a: number, b: number, t: number): number => a + (b - a) * t\nexport const lerp3 = (a: Vec3, b: Vec3, t: number): Vec3 => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t]\nexport const clamp = (v: number, a: number, b: number): number => (v < a ? a : v > b ? b : v)\nexport const smooth = (t: number): number => t * t * (3 - 2 * t)\n\n/** Rotate v around a unit axis by angle (Rodrigues). */\nexport function rotAxis(v: Vec3, axis: Vec3, ang: number): Vec3 {\n const c = Math.cos(ang)\n const s = Math.sin(ang)\n const k = cross(axis, v)\n const d = dot(axis, v) * (1 - c)\n return [v[0] * c + k[0] * s + axis[0] * d, v[1] * c + k[1] * s + axis[1] * d, v[2] * c + k[2] * s + axis[2] * d]\n}\nexport const rotY = (v: Vec3, a: number): Vec3 => {\n const c = Math.cos(a)\n const s = Math.sin(a)\n return [v[0] * c + v[2] * s, v[1], -v[0] * s + v[2] * c]\n}\n\n/** Any unit vector perpendicular to n. */\nexport function perp(n: Vec3): Vec3 {\n const a: Vec3 = Math.abs(n[1]) < 0.95 ? [0, 1, 0] : [1, 0, 0]\n return norm(cross(a, n))\n}\n\n/** Direction from azimuth (around +y, 0 = +x) and elevation (0 = horizontal, pi/2 = up). */\nexport function dirFromAngles(az: number, el: number): Vec3 {\n const c = Math.cos(el)\n return [Math.cos(az) * c, Math.sin(el), Math.sin(az) * c]\n}\n\n/** Local frame: world = o + x*lx + y*ly + z*lz. y is the \"axis\" direction. */\nexport interface Frame {\n o: Vec3\n x: Vec3\n y: Vec3\n z: Vec3\n}\nexport function frameFromAxis(o: Vec3, axis: Vec3, twist = 0): Frame {\n const y = norm(axis)\n let x = perp(y)\n if (twist) x = rotAxis(x, y, twist)\n const z = norm(cross(x, y))\n return { o, x, y, z }\n}\nexport function toWorld(f: Frame, l: Vec3): Vec3 {\n return [\n f.o[0] + f.x[0] * l[0] + f.y[0] * l[1] + f.z[0] * l[2],\n f.o[1] + f.x[1] * l[0] + f.y[1] * l[1] + f.z[1] * l[2],\n f.o[2] + f.x[2] * l[0] + f.y[2] * l[1] + f.z[2] * l[2],\n ]\n}\nexport function dirToWorld(f: Frame, l: Vec3): Vec3 {\n return [\n f.x[0] * l[0] + f.y[0] * l[1] + f.z[0] * l[2],\n f.x[1] * l[0] + f.y[1] * l[1] + f.z[1] * l[2],\n f.x[2] * l[0] + f.y[2] * l[1] + f.z[2] * l[2],\n ]\n}\n\n/** Catmull-Rom through points, `n` samples per span (including end points). */\nexport function catmull(pts: Vec3[], perSpan: number): Vec3[] {\n if (pts.length < 3 || perSpan <= 1) return pts.slice()\n const out: Vec3[] = []\n for (let i = 0; i < pts.length - 1; i++) {\n const p0 = pts[Math.max(0, i - 1)]\n const p1 = pts[i]\n const p2 = pts[i + 1]\n const p3 = pts[Math.min(pts.length - 1, i + 2)]\n for (let k = 0; k < perSpan; k++) {\n const t = k / perSpan\n const t2 = t * t\n const t3 = t2 * t\n const p: Vec3 = [0, 0, 0]\n for (let c = 0; c < 3; c++) {\n p[c] = 0.5 * (2 * p1[c] + (-p0[c] + p2[c]) * t + (2 * p0[c] - 5 * p1[c] + 4 * p2[c] - p3[c]) * t2 + (-p0[c] + 3 * p1[c] - 3 * p2[c] + p3[c]) * t3)\n }\n out.push(p)\n }\n }\n out.push(pts[pts.length - 1])\n return out\n}\n\n/** Point and tangent on a polyline at t in 0..1 (by index fraction). */\nexport function sampleLine(pts: Vec3[], t: number): { p: Vec3; d: Vec3 } {\n const f = clamp(t, 0, 1) * (pts.length - 1)\n const i = Math.min(pts.length - 2, Math.floor(f))\n const u = f - i\n return { p: lerp3(pts[i], pts[i + 1], u), d: norm(sub(pts[i + 1], pts[i])) }\n}\n","import type { Vec3, Condition } from './types'\nimport type { Rng } from './rng'\nimport { clamp, lerp3 } from './math'\n\n/** 0xRRGGBB -> sRGB triplet 0..1. All colors in this package are handled as sRGB triplets until MeshData is built (then linear). */\nexport function rgb(hex: number): Vec3 {\n return [((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255]\n}\n\nexport function toHsv(c: Vec3): Vec3 {\n const [r, g, b] = c\n const mx = Math.max(r, g, b)\n const mn = Math.min(r, g, b)\n const d = mx - mn\n let h = 0\n if (d > 1e-6) {\n if (mx === r) h = ((g - b) / d) % 6\n else if (mx === g) h = (b - r) / d + 2\n else h = (r - g) / d + 4\n h /= 6\n if (h < 0) h += 1\n }\n return [h, mx < 1e-6 ? 0 : d / mx, mx]\n}\n\nexport function fromHsv(h: number, s: number, v: number): Vec3 {\n h = ((h % 1) + 1) % 1\n const i = Math.floor(h * 6)\n const f = h * 6 - i\n const p = v * (1 - s)\n const q = v * (1 - f * s)\n const t = v * (1 - (1 - f) * s)\n switch (i % 6) {\n case 0:\n return [v, t, p]\n case 1:\n return [q, v, p]\n case 2:\n return [p, v, t]\n case 3:\n return [p, q, v]\n case 4:\n return [t, p, v]\n default:\n return [v, p, q]\n }\n}\n\nexport const shade = (c: Vec3, f: number): Vec3 => [clamp(c[0] * f, 0, 1), clamp(c[1] * f, 0, 1), clamp(c[2] * f, 0, 1)]\nexport const mix = (a: Vec3, b: Vec3, t: number): Vec3 => lerp3(a, b, t)\n\n/** Hue / value / saturation jitter (amounts are max deltas). */\nexport function jitter(c: Vec3, rng: Rng, hue = 0.02, val = 0.08, sat = 0.06): Vec3 {\n const [h, s, v] = toHsv(c)\n return fromHsv(h + rng.gauss() * hue, clamp(s + rng.gauss() * sat, 0, 1), clamp(v * (1 + rng.gauss() * val), 0, 1))\n}\n\n/** Warm the hue toward yellow and darken the top (used for lit tips). */\nexport function lighten(c: Vec3, amt: number): Vec3 {\n const [h, s, v] = toHsv(c)\n return fromHsv(h - amt * 0.03, clamp(s - amt * 0.12, 0, 1), clamp(v + amt * 0.35, 0, 1))\n}\n\nexport function srgbToLinear(v: number): number {\n return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4)\n}\n\nexport function linearToSrgb(v: number): number {\n return v <= 0.0031308 ? v * 12.92 : 1.055 * Math.pow(v, 1 / 2.4) - 0.055\n}\n\nconst DRY: Vec3 = [0.66, 0.56, 0.22]\nconst DEAD: Vec3 = [0.4, 0.35, 0.27]\nconst PALE: Vec3 = [0.74, 0.7, 0.5]\n\n/** Tint a leaf / green-tissue color by condition. */\nexport function tintGreen(c: Vec3, condition: Condition): Vec3 {\n switch (condition) {\n case 'dry':\n return mix(c, DRY, 0.55)\n case 'dead':\n return mix(c, DEAD, 0.85)\n case 'overgrown': {\n const [h, s, v] = toHsv(c)\n return fromHsv(h - 0.004, clamp(s * 1.08, 0, 1), v * 0.9)\n }\n default:\n return c\n }\n}\n\n/** Tint a succulent / cactus body color by condition (dead = pale and bleached). */\nexport function tintFlesh(c: Vec3, condition: Condition): Vec3 {\n switch (condition) {\n case 'dry':\n return mix(c, [0.62, 0.6, 0.34], 0.4)\n case 'dead':\n return mix(c, PALE, 0.8)\n case 'overgrown':\n return shade(c, 0.95)\n default:\n return c\n }\n}\n","import type { DamageMaterial, MeshData, PartKind, Vec3 } from '../types'\nimport { linearToSrgb, srgbToLinear } from '../color'\n\ntype ColorArg = Vec3\n\n/** Accumulates triangles with per-vertex color / sway. Colors are given as sRGB and converted to linear in `build`. */\nexport class MeshBuilder {\n pos: number[] = []\n nor: number[] = []\n col: number[] = []\n sway: number[] = []\n idx: number[] = []\n /** piece tag of every triangle (see Ctx.piece); '' = untagged */\n triTag: string[] = []\n /** tag given to the triangles emitted from now on */\n tag = ''\n /** centerlines of the tubes drawn so far with the piece tag they were drawn under (see `tube`), for piece geometry */\n tubes: { tag: string; path: Vec3[]; radii: number[] }[] = []\n /** after `build`: contiguous triangle-index ranges per tag, in index units (3 per triangle) */\n ranges: { tag: string; indexStart: number; indexCount: number }[] = []\n\n get triangleCount(): number {\n return this.idx.length / 3\n }\n get vertexCount(): number {\n return this.pos.length / 3\n }\n\n vert(p: Vec3, n: Vec3, c: ColorArg, s: number): number {\n const i = this.pos.length / 3\n this.pos.push(p[0], p[1], p[2])\n this.nor.push(n[0], n[1], n[2])\n this.col.push(c[0], c[1], c[2])\n this.sway.push(s < 0 ? 0 : s > 1 ? 1 : s)\n return i\n }\n tri(a: number, b: number, c: number): void {\n this.idx.push(a, b, c)\n this.triTag.push(this.tag)\n }\n\n /**\n * Flat shaded triangle. If `hint` is given the face is wound so that its normal faces that direction.\n * Colors / sway are per vertex (gradients across the face are kept).\n */\n flatTri(p0: Vec3, p1: Vec3, p2: Vec3, c0: ColorArg, c1: ColorArg, c2: ColorArg, s0: number, s1: number, s2: number, hint?: Vec3): void {\n const ux = p1[0] - p0[0]\n const uy = p1[1] - p0[1]\n const uz = p1[2] - p0[2]\n const vx = p2[0] - p0[0]\n const vy = p2[1] - p0[1]\n const vz = p2[2] - p0[2]\n let nx = uy * vz - uz * vy\n let ny = uz * vx - ux * vz\n let nz = ux * vy - uy * vx\n const l = Math.hypot(nx, ny, nz)\n if (l < 1e-12) return\n nx /= l\n ny /= l\n nz /= l\n if (hint && nx * hint[0] + ny * hint[1] + nz * hint[2] < 0) {\n // flip winding\n const n: Vec3 = [-nx, -ny, -nz]\n const a = this.vert(p0, n, c0, s0)\n const b = this.vert(p2, n, c2, s2)\n const c = this.vert(p1, n, c1, s1)\n this.tri(a, b, c)\n return\n }\n const n: Vec3 = [nx, ny, nz]\n const a = this.vert(p0, n, c0, s0)\n const b = this.vert(p1, n, c1, s1)\n const c = this.vert(p2, n, c2, s2)\n this.tri(a, b, c)\n }\n\n /** Flat triangle with a single color and sway. */\n flat(p0: Vec3, p1: Vec3, p2: Vec3, c: ColorArg, s: number, hint?: Vec3): void {\n this.flatTri(p0, p1, p2, c, c, c, s, s, s, hint)\n }\n\n /** Flat quad split along p0-p2. */\n flatQuad(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, c0: ColorArg, c1: ColorArg, c2: ColorArg, c3: ColorArg, s0: number, s1: number, s2: number, s3: number, hint?: Vec3): void {\n this.flatTri(p0, p1, p2, c0, c1, c2, s0, s1, s2, hint)\n this.flatTri(p0, p2, p3, c0, c2, c3, s0, s2, s3, hint)\n }\n\n /** Append already-built (linear) mesh data with a y-rotation, scale and translation. */\n appendMesh(m: MeshData, tx: number, ty: number, tz: number, ry = 0, scale = 1, tagOf?: (triangle: number) => string): void {\n const base = this.pos.length / 3\n const c = Math.cos(ry)\n const s = Math.sin(ry)\n const n = m.positions.length / 3\n for (let i = 0; i < n; i++) {\n const x = m.positions[i * 3] * scale\n const y = m.positions[i * 3 + 1] * scale\n const z = m.positions[i * 3 + 2] * scale\n this.pos.push(x * c + z * s + tx, y + ty, -x * s + z * c + tz)\n const nx = m.normals[i * 3]\n const nz = m.normals[i * 3 + 2]\n this.nor.push(nx * c + nz * s, m.normals[i * 3 + 1], -nx * s + nz * c)\n this.col.push(linearToSrgb(m.colors[i * 3]), linearToSrgb(m.colors[i * 3 + 1]), linearToSrgb(m.colors[i * 3 + 2]))\n this.sway.push(m.sway[i])\n }\n for (let i = 0; i < m.indices.length; i++) this.idx.push(m.indices[i] + base)\n for (let t = 0; t < m.indices.length / 3; t++) this.triTag.push(tagOf ? tagOf(t) : this.tag)\n }\n\n /** Make the triangles of every tag contiguous (stable, tags ordered by first appearance) and fill `ranges`. */\n private groupTriangles(): void {\n const nTri = this.idx.length / 3\n const order: string[] = []\n const count = new Map<string, number>()\n for (let t = 0; t < nTri; t++) {\n const tg = this.triTag[t]\n const c = count.get(tg)\n if (c === undefined) {\n order.push(tg)\n count.set(tg, 1)\n } else count.set(tg, c + 1)\n }\n // already contiguous?\n let contiguous = true\n const seen = new Set<string>()\n for (let t = 0; t < nTri && contiguous; t++) {\n const tg = this.triTag[t]\n if (t > 0 && tg === this.triTag[t - 1]) continue\n if (seen.has(tg)) contiguous = false\n seen.add(tg)\n }\n if (!contiguous) {\n const start = new Map<string, number>()\n let acc = 0\n for (const tg of order) {\n start.set(tg, acc)\n acc += count.get(tg)!\n }\n const idx = new Array<number>(this.idx.length)\n const tags = new Array<string>(nTri)\n for (let t = 0; t < nTri; t++) {\n const tg = this.triTag[t]\n const o = start.get(tg)!\n start.set(tg, o + 1)\n idx[o * 3] = this.idx[t * 3]\n idx[o * 3 + 1] = this.idx[t * 3 + 1]\n idx[o * 3 + 2] = this.idx[t * 3 + 2]\n tags[o] = tg\n }\n this.idx = idx\n this.triTag = tags\n }\n this.ranges = []\n let acc = 0\n for (const tg of order) {\n const c = count.get(tg)!\n this.ranges.push({ tag: tg, indexStart: acc * 3, indexCount: c * 3 })\n acc += c\n }\n }\n\n build(kind: PartKind, material: DamageMaterial): MeshData | undefined {\n if (this.idx.length === 0) return undefined\n this.groupTriangles()\n const n = this.pos.length / 3\n const colors = new Float32Array(n * 3)\n for (let i = 0; i < n * 3; i++) colors[i] = srgbToLinear(this.col[i])\n return {\n positions: new Float32Array(this.pos),\n normals: new Float32Array(this.nor),\n colors,\n sway: new Float32Array(this.sway),\n indices: new Uint32Array(this.idx),\n triangleCount: this.idx.length / 3,\n kind,\n material,\n }\n }\n}\n","import type { CrownShape, Vec3 } from '../types'\nimport type { Rng } from '../rng'\nimport { add, catmull, clamp, dirFromAngles, lerp, mul, norm, perp, rotAxis, cross, sub, TAU } from '../math'\n\nexport interface Branch {\n /** control points (smooth with catmull for rendering) */\n pts: Vec3[]\n radii: number[]\n level: number\n broken?: boolean\n}\nexport interface Tip {\n p: Vec3\n dir: Vec3\n /** relative size 0.7..1.3 */\n size: number\n level: number\n seed: number\n /** random 0..1 used to decide whether the tip keeps its leaves in dry / winter conditions */\n keep: number\n /** extra random 0..1 */\n roll: number\n}\nexport interface TreeShape {\n trunk: Branch\n branches: Branch[]\n tips: Tip[]\n /** center of the crown (for shading) */\n crown: Vec3\n trunkTopY: number\n}\n\nexport interface GrowParams {\n height: number\n trunkRadius: number\n crownRadius: number\n shape: CrownShape\n levels: number\n trunkFraction: number\n gnarl: number\n /** number of primary branches */\n primary: number\n lean: number\n /** 'bare' trees show twisted limbs, with broken stubs */\n bare?: boolean\n}\n\nfunction jitterDir(rng: Rng, d: Vec3, amt: number): Vec3 {\n return norm([d[0] + rng.gauss() * amt, d[1] + rng.gauss() * amt * 0.6, d[2] + rng.gauss() * amt])\n}\n\nfunction branchPath(rng: Rng, start: Vec3, dir0: Vec3, length: number, steps: number, upBias: number, droop: number, gnarl: number): Vec3[] {\n const pts: Vec3[] = [start]\n let d = dir0\n let p = start\n for (let i = 0; i < steps; i++) {\n const f = (i + 1) / steps\n d = norm(add(jitterDir(rng, d, gnarl), [0, upBias / steps - droop * f * f * 0.9, 0]))\n p = add(p, mul(d, length / steps))\n pts.push(p)\n }\n return pts\n}\n\nfunction taper(n: number, r0: number, r1: number): number[] {\n const out: number[] = []\n for (let i = 0; i < n; i++) out.push(lerp(r0, r1, Math.pow(i / (n - 1), 0.85)))\n return out\n}\n\n/** Grow the skeleton of a tree: trunk, nested branches and leaf-clump anchors. Consumes the same random numbers at every LOD. */\nexport function growTree(rng: Rng, p: GrowParams): TreeShape {\n const H = p.height\n const trunkTop = H * (p.shape === 'columnar' ? 0.97 : 0.93)\n const clearY = H * p.trunkFraction\n // trunk centerline\n const n = 7\n const ctrl: Vec3[] = []\n let ox = 0\n let oz = 0\n const lx = Math.cos(rng.range(0, TAU))\n const lz = Math.sin(rng.range(0, TAU))\n for (let i = 0; i < n; i++) {\n const f = i / (n - 1)\n if (i > 0) {\n ox += rng.gauss() * p.gnarl * H * 0.025\n oz += rng.gauss() * p.gnarl * H * 0.025\n }\n ctrl.push([ox + lx * p.lean * H * f * f, trunkTop * f, oz + lz * p.lean * H * f * f])\n }\n const tpts = catmull(ctrl, 3)\n const tr: number[] = []\n for (let i = 0; i < tpts.length; i++) {\n const f = i / (tpts.length - 1)\n tr.push(p.trunkRadius * (1 - 0.62 * f) * (1 + 0.5 * Math.exp(-f * 22)) * (f > 0.9 ? 0.85 : 1))\n }\n const trunk: Branch = { pts: tpts, radii: tr, level: 0 }\n const trunkAt = (y: number): { pos: Vec3; r: number } => {\n const f = Math.min(1, Math.max(0, y / trunkTop)) * (tpts.length - 1)\n const i = Math.min(tpts.length - 2, Math.floor(f))\n const u = f - i\n return { pos: [lerp(tpts[i][0], tpts[i + 1][0], u), lerp(tpts[i][1], tpts[i + 1][1], u), lerp(tpts[i][2], tpts[i + 1][2], u)], r: lerp(tr[i], tr[i + 1], u) }\n }\n\n const branches: Branch[] = []\n const tips: Tip[] = []\n const baseAz = rng.range(0, TAU)\n const golden = 2.399963\n const pushTip = (pos: Vec3, dir: Vec3, level: number, size: number): void => {\n tips.push({ p: pos, dir, size, level, seed: rng.seed(), keep: rng.next(), roll: rng.next() })\n }\n\n const grow = (start: Vec3, dir: Vec3, length: number, r0: number, level: number, fracStart: number, shapeUp: number, droop: number): void => {\n const steps = level === 1 ? 5 : 4\n const pts = branchPath(rng, start, dir, length, steps, shapeUp, droop, p.gnarl * 0.18)\n let radii = taper(pts.length, r0, Math.max(r0 * 0.22, 0.006))\n let broken = false\n if (p.bare && level >= 2 && rng.chance(0.3)) {\n // broken stub: cut short, blunt end\n pts.length = Math.max(2, Math.ceil(pts.length * rng.range(0.45, 0.7)))\n radii = radii.slice(0, pts.length)\n radii[radii.length - 1] = radii[radii.length - 2] * 0.7\n broken = true\n }\n branches.push({ pts: catmull(pts, 2), radii: catmull(radii.map((r) => [r, 0, 0] as Vec3), 2).map((v) => v[0]), level, broken })\n const last = pts[pts.length - 1]\n const lastDir = norm(sub(last, pts[pts.length - 2]))\n if (level >= p.levels || broken) {\n if (!broken) pushTip(last, lastDir, level, rng.range(0.85, 1.2))\n else rng.next()\n } else {\n // continue the branch with a tip and spawn children\n const kids = level === 1 ? rng.int(2, 3) : 2\n for (let k = 0; k < kids; k++) {\n const t = rng.range(0.4, 0.92) * (kids === 1 ? 1 : 1)\n const idx = Math.min(pts.length - 2, Math.floor(t * (pts.length - 1)))\n const u = t * (pts.length - 1) - idx\n const pos: Vec3 = [lerp(pts[idx][0], pts[idx + 1][0], u), lerp(pts[idx][1], pts[idx + 1][1], u), lerp(pts[idx][2], pts[idx + 1][2], u)]\n const pd = norm(sub(pts[idx + 1], pts[idx]))\n const axis = norm(cross(pd, perp(pd)))\n const rot = rotAxis(pd, rotAxis(axis, pd, rng.range(0, TAU)), rng.range(0.45, 0.95) * rng.sign())\n const cdir = norm(add(rot, [0, 0.25, 0]))\n grow(pos, cdir, length * rng.range(0.5, 0.68) * (1 - t * 0.35), radii[idx] * 0.62, level + 1, fracStart, shapeUp, droop)\n }\n if (!p.bare) pushTip(last, lastDir, level, rng.range(0.9, 1.2))\n else rng.next()\n }\n }\n\n for (let i = 0; i < p.primary; i++) {\n const f = p.primary === 1 ? 0 : i / (p.primary - 1)\n const y = lerp(clearY, trunkTop * 0.82, Math.pow(f, 0.9)) + rng.range(-0.04, 0.04) * H\n const { pos, r } = trunkAt(y)\n const az = baseAz + i * golden + rng.range(-0.25, 0.25)\n const hf = clamp((y - clearY) / Math.max(0.01, trunkTop - clearY), 0, 1)\n let el: number\n let lenK: number\n let up: number\n let droop = 0\n switch (p.shape) {\n case 'spreading':\n el = lerp(0.5, 0.18, 1 - hf) * (0.9 + rng.next() * 0.3)\n lenK = lerp(1.15, 0.75, hf)\n up = 0.25\n break\n case 'columnar':\n el = lerp(1.15, 1.35, hf)\n lenK = lerp(0.85, 0.5, hf)\n up = 0.25\n break\n case 'weeping':\n el = lerp(0.95, 0.6, 1 - hf)\n lenK = lerp(1.15, 0.7, hf)\n up = 0.5\n droop = 1.8\n break\n default:\n el = lerp(1.05, 0.62, 1 - hf) + rng.range(-0.1, 0.1)\n lenK = lerp(1.1, 0.7, Math.pow(hf, 1.3))\n up = 0.35\n }\n const dir = dirFromAngles(az, el)\n const start = add(pos, mul(norm([dir[0], 0, dir[2]]), r * 0.5))\n grow(start, dir, p.crownRadius * lenK * rng.range(0.85, 1.1), r * rng.range(0.4, 0.55), 1, f, up, droop)\n }\n // leader clump at the top\n const topPos = tpts[tpts.length - 1]\n pushTip(add(topPos, [0, H * 0.02, 0]), [0, 1, 0], 0, p.shape === 'columnar' ? 1.1 : 1.0)\n\n // crown center\n let cx = 0\n let cy = 0\n let cz = 0\n for (const t of tips) {\n cx += t.p[0]\n cy += t.p[1]\n cz += t.p[2]\n }\n const m = Math.max(1, tips.length)\n return { trunk, branches, tips, crown: [cx / m, cy / m - H * 0.04, cz / m], trunkTopY: trunkTop }\n}\n\n/**\n * Rescale branches and tips (not the trunk) so the crown reaches `height` and `reach` once clumps of radius `clumpR` sit on the tips.\n * Keeps the proportions honest whatever the random growth did.\n */\nexport function fitTree(tree: TreeShape, height: number, reach: number, clumpR: number, clearY: number, tipFilter?: (t: Tip) => boolean): void {\n let maxY = clearY + 0.01\n let maxR = 0.01\n for (const t of tree.tips) {\n if (tipFilter && !tipFilter(t)) continue\n maxY = Math.max(maxY, t.p[1])\n maxR = Math.max(maxR, Math.hypot(t.p[0], t.p[2]))\n }\n const sx = clamp((reach - clumpR * 0.7) / Math.max(0.1, maxR), 0.35, 1.8)\n const sy = clamp((height - clumpR * 0.55 - clearY) / Math.max(0.1, maxY - clearY), 0.4, 1.6)\n const f = (p: Vec3): void => {\n p[0] *= sx\n p[2] *= sx\n if (p[1] > clearY) p[1] = clearY + (p[1] - clearY) * sy\n }\n for (const b of tree.branches) for (const p of b.pts) f(p)\n for (const t of tree.tips) f(t.p)\n tree.crown = [tree.crown[0] * sx, clearY + (tree.crown[1] - clearY) * sy, tree.crown[2] * sx]\n}\n","import type { Vec3 } from '../types'\nimport { add, cross, mul, norm, perp, sub, TAU, dot } from '../math'\nimport type { MeshBuilder } from './builder'\n\nexport interface TubeOptions {\n sides: number\n /** radius per path point */\n radii: number[]\n /** color by position along the path (0..1) and angle fraction around (0..1) */\n color: (t: number, a: number) => Vec3\n /** wind sway by position along the path */\n sway: (t: number) => number\n /** close the far end: 'point' adds a short rounded tip, 'flat' a flat cap, 'none' leaves it open */\n end?: 'point' | 'flat' | 'none'\n /** smooth radial normals (default true) or flat faces */\n smooth?: boolean\n /** radius jitter per ring vertex for a hand-cut look, 0..0.3 */\n rough?: (ring: number, i: number) => number\n}\n\n/** Frames along a polyline by parallel transport. */\nexport function pathFrames(path: Vec3[]): { t: Vec3; n: Vec3; b: Vec3 }[] {\n const out: { t: Vec3; n: Vec3; b: Vec3 }[] = []\n let n: Vec3 | undefined\n for (let i = 0; i < path.length; i++) {\n const a = path[Math.max(0, i - 1)]\n const c = path[Math.min(path.length - 1, i + 1)]\n const tan = norm(sub(c, a))\n if (!n) n = perp(tan)\n else {\n // project previous normal onto the plane perpendicular to the new tangent\n n = sub(n, mul(tan, dot(n, tan)))\n n = norm(n)\n }\n out.push({ t: tan, n, b: norm(cross(tan, n)) })\n }\n return out\n}\n\n/** Tapered tube along a polyline. Returns the ring start indices so callers can attach things. */\nexport function tube(b: MeshBuilder, path: Vec3[], o: TubeOptions): void {\n const n = path.length\n if (n < 2) return\n b.tubes.push({ tag: b.tag, path, radii: o.radii })\n const frames = pathFrames(path)\n const S = o.sides\n const smooth = o.smooth !== false\n const rings: { p: Vec3; nr: Vec3; c: Vec3 }[][] = []\n for (let k = 0; k < n; k++) {\n const f = frames[k]\n const r = o.radii[k]\n const t = k / (n - 1)\n const ring: { p: Vec3; nr: Vec3; c: Vec3 }[] = []\n for (let i = 0; i < S; i++) {\n const a = (i / S) * TAU\n const ca = Math.cos(a)\n const sa = Math.sin(a)\n const dir: Vec3 = [f.n[0] * ca + f.b[0] * sa, f.n[1] * ca + f.b[1] * sa, f.n[2] * ca + f.b[2] * sa]\n const rr = r * (1 + (o.rough ? o.rough(k, i) : 0))\n ring.push({ p: add(path[k], mul(dir, rr)), nr: dir, c: o.color(t, i / S) })\n }\n rings.push(ring)\n }\n const sw = (k: number): number => o.sway(k / (n - 1))\n if (smooth) {\n const base: number[] = []\n for (let k = 0; k < n; k++) {\n base.push(b.vertexCount)\n for (let i = 0; i < S; i++) b.vert(rings[k][i].p, rings[k][i].nr, rings[k][i].c, sw(k))\n }\n for (let k = 0; k < n - 1; k++) {\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n const a0 = base[k] + i\n const a1 = base[k] + j\n const b0 = base[k + 1] + i\n const b1 = base[k + 1] + j\n b.tri(a0, a1, b0)\n b.tri(a1, b1, b0)\n }\n }\n } else {\n for (let k = 0; k < n - 1; k++) {\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n const hint = add(rings[k][i].nr, rings[k][j].nr)\n b.flatQuad(\n rings[k][i].p, rings[k + 1][i].p, rings[k + 1][j].p, rings[k][j].p,\n rings[k][i].c, rings[k + 1][i].c, rings[k + 1][j].c, rings[k][j].c,\n sw(k), sw(k + 1), sw(k + 1), sw(k), hint,\n )\n }\n }\n }\n const end = o.end ?? 'point'\n const last = n - 1\n if (end === 'point') {\n const tip = add(path[last], mul(frames[last].t, Math.max(o.radii[last] * 1.2, 0.005)))\n const tc = rings[last][0].c\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n b.flatTri(rings[last][i].p, rings[last][j].p, tip, rings[last][i].c, rings[last][j].c, tc, sw(last), sw(last), sw(last), add(rings[last][i].nr, frames[last].t))\n }\n } else if (end === 'flat') {\n const tc = rings[last][0].c\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n b.flatTri(rings[last][i].p, rings[last][j].p, path[last], rings[last][i].c, rings[last][j].c, tc, sw(last), sw(last), sw(last), frames[last].t)\n }\n }\n}\n\nexport interface RibbedOptions {\n ribs: number\n /** ridge radius per path point */\n radii: number[]\n /** valley radius as a fraction of the ridge radius */\n valley: number\n color: (t: number, ridge: boolean, rib: number) => Vec3\n sway: (t: number) => number\n /** extra rings that round off the end (dome) */\n dome?: number\n /** wobble of ridge radius for organic look (per ring, per rib) */\n rough?: (ring: number, rib: number) => number\n}\n\nexport interface RibbedInfo {\n /** ridge world positions per ring and rib (for attaching spines) */\n ridges: { p: Vec3; n: Vec3; t: number; rib: number; ring: number }[]\n end: Vec3\n}\n\n/** Ribbed column (cactus): 2*ribs vertices per ring alternating ridge and valley, flat shaded. */\nexport function ribbedTube(b: MeshBuilder, path: Vec3[], o: RibbedOptions): RibbedInfo {\n b.tubes.push({ tag: b.tag, path, radii: o.radii })\n const frames = pathFrames(path)\n const pts = path.slice()\n const radii = o.radii.slice()\n const fr = frames.slice()\n const domeN = o.dome ?? 0\n const lastR = o.radii[o.radii.length - 1]\n const lastF = frames[frames.length - 1]\n const lastP = path[path.length - 1]\n for (let j = 1; j <= domeN; j++) {\n const a = (j / (domeN + 1)) * (Math.PI / 2)\n pts.push(add(lastP, mul(lastF.t, lastR * Math.sin(a) * 0.9)))\n radii.push(lastR * Math.cos(a))\n fr.push(lastF)\n }\n const apex = add(lastP, mul(lastF.t, lastR * (domeN > 0 ? 0.95 : 0.2)))\n const S = o.ribs * 2\n const N = pts.length\n const rings: { p: Vec3; nr: Vec3; c: Vec3 }[][] = []\n const info: RibbedInfo = { ridges: [], end: apex }\n const swayAt = (k: number): number => o.sway(k / (N - 1))\n for (let k = 0; k < N; k++) {\n const f = fr[k]\n const ring: { p: Vec3; nr: Vec3; c: Vec3 }[] = []\n for (let i = 0; i < S; i++) {\n const ridge = i % 2 === 0\n const rib = i >> 1\n const a = (i / S) * TAU\n const dir: Vec3 = [f.n[0] * Math.cos(a) + f.b[0] * Math.sin(a), f.n[1] * Math.cos(a) + f.b[1] * Math.sin(a), f.n[2] * Math.cos(a) + f.b[2] * Math.sin(a)]\n const wob = o.rough ? o.rough(k, rib) : 0\n const rr = radii[k] * (ridge ? 1 + wob : o.valley)\n const p = add(pts[k], mul(dir, rr))\n const c = o.color(Math.min(1, k / (path.length - 1)), ridge, rib)\n ring.push({ p, nr: dir, c })\n if (ridge && k < path.length) info.ridges.push({ p, n: dir, t: k / (path.length - 1), rib, ring: k })\n }\n rings.push(ring)\n }\n for (let k = 0; k < N - 1; k++) {\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n const hint = add(rings[k][i].nr, rings[k][j].nr)\n b.flatQuad(\n rings[k][i].p, rings[k + 1][i].p, rings[k + 1][j].p, rings[k][j].p,\n rings[k][i].c, rings[k + 1][i].c, rings[k + 1][j].c, rings[k][j].c,\n swayAt(k), swayAt(k + 1), swayAt(k + 1), swayAt(k), hint,\n )\n }\n }\n const lastRing = rings[N - 1]\n for (let i = 0; i < S; i++) {\n const j = (i + 1) % S\n b.flatTri(lastRing[i].p, lastRing[j].p, apex, lastRing[i].c, lastRing[j].c, lastRing[0].c, swayAt(N - 1), swayAt(N - 1), swayAt(N - 1), add(lastRing[i].nr, lastF.t))\n }\n return info\n}\n","import type { Lod, Vec3 } from '../types'\nimport { clamp } from '../math'\nimport { shade, mix } from '../color'\nimport type { MeshBuilder } from './builder'\nimport { tube } from './tube'\nimport type { Branch } from './branches'\n\n/** Bark color function: vertical bands, angular ribs, darker toward the ground, lighter young tips. */\nexport function barkColor(base: Vec3, level: number, seed = 0): (t: number, a: number) => Vec3 {\n const lightTip: Vec3 = shade(base, 1.18)\n return (t, a) => {\n const band = 0.93 + 0.07 * Math.sin(t * (level === 0 ? 38 : 16) + seed)\n const rib = 0.92 + 0.08 * Math.cos(a * Math.PI * 2 * 3 + seed * 1.7 + t * 2.2)\n let k = band * rib\n if (level === 0) k *= 0.8 + 0.2 * clamp(t * 7, 0, 1)\n const c = shade(base, k * 1.5)\n return level === 0 ? c : mix(c, lightTip, clamp(t * 0.8, 0, 1) * 0.5)\n }\n}\n\n/** Draw a branch / trunk as a tapered tube, thinning the path by lod. */\nexport function drawBranch(b: MeshBuilder, br: Branch, bark: Vec3, lod: Lod, seed = 0): void {\n const maxLevel = lod === 0 ? 99 : lod === 1 ? 2 : 1\n if (br.level > maxLevel) return\n const stride = lod === 0 ? (br.level >= 1 ? 2 : 1) : lod === 1 ? (br.level >= 1 ? 3 : 2) : br.level === 0 ? 4 : 3\n const pts: Vec3[] = []\n const radii: number[] = []\n for (let i = 0; i < br.pts.length; i += stride) {\n pts.push(br.pts[i])\n radii.push(br.radii[i])\n }\n if ((br.pts.length - 1) % stride !== 0) {\n pts.push(br.pts[br.pts.length - 1])\n radii.push(br.radii[br.radii.length - 1])\n }\n if (pts.length < 2) return\n const sides = br.level === 0 ? (lod === 0 ? 8 : lod === 1 ? 6 : 4) : br.level === 1 ? (lod === 0 ? 5 : 3) : lod === 0 ? 4 : 3\n const lv = br.level\n tube(b, pts, {\n sides,\n radii,\n color: barkColor(bark, lv, seed),\n sway: (t) => (lv === 0 ? 0.03 * t : clamp(0.06 * lv + 0.22 * t, 0, 0.5)),\n end: br.broken ? 'flat' : 'point',\n })\n}\n","import type { Vec3 } from '../types'\nimport { norm } from '../math'\n\nexport interface IcoTemplate {\n verts: Vec3[]\n faces: [number, number, number][]\n}\n\nconst cache = new Map<number, IcoTemplate>()\n\n/** Unit icosphere template: detail 0 = 20 faces, 1 = 80, 2 = 320. */\nexport function icoTemplate(detail: number): IcoTemplate {\n const hit = cache.get(detail)\n if (hit) return hit\n const t = (1 + Math.sqrt(5)) / 2\n const verts: Vec3[] = [\n [-1, t, 0], [1, t, 0], [-1, -t, 0], [1, -t, 0],\n [0, -1, t], [0, 1, t], [0, -1, -t], [0, 1, -t],\n [t, 0, -1], [t, 0, 1], [-t, 0, -1], [-t, 0, 1],\n ].map((v) => norm(v as Vec3))\n let faces: [number, number, number][] = [\n [0, 11, 5], [0, 5, 1], [0, 1, 7], [0, 7, 10], [0, 10, 11],\n [1, 5, 9], [5, 11, 4], [11, 10, 2], [10, 7, 6], [7, 1, 8],\n [3, 9, 4], [3, 4, 2], [3, 2, 6], [3, 6, 8], [3, 8, 9],\n [4, 9, 5], [2, 4, 11], [6, 2, 10], [8, 6, 7], [9, 8, 1],\n ]\n for (let d = 0; d < detail; d++) {\n const mid = new Map<string, number>()\n const midpoint = (a: number, b: number): number => {\n const key = a < b ? a + '_' + b : b + '_' + a\n const h = mid.get(key)\n if (h !== undefined) return h\n const va = verts[a]\n const vb = verts[b]\n verts.push(norm([(va[0] + vb[0]) / 2, (va[1] + vb[1]) / 2, (va[2] + vb[2]) / 2]))\n mid.set(key, verts.length - 1)\n return verts.length - 1\n }\n const next: [number, number, number][] = []\n for (const [a, b, c] of faces) {\n const ab = midpoint(a, b)\n const bc = midpoint(b, c)\n const ca = midpoint(c, a)\n next.push([a, ab, ca], [b, bc, ab], [c, ca, bc], [ab, bc, ca])\n }\n faces = next\n }\n const res = { verts, faces }\n cache.set(detail, res)\n return res\n}\n","import type { Vec3 } from '../types'\nimport { add, cross, mul, norm, dot } from '../math'\nimport { mix, shade } from '../color'\nimport type { MeshBuilder } from './builder'\n\nexport interface LeafOptions {\n /** tip droop as a fraction of length, along -up (default 0.18) */\n curl?: number\n /** midrib lift as a fraction of half-width (default 0.5): leaves are folded, never flat cards */\n fold?: number\n /** rows along the length; 2 = 4 triangles, 3 = 8, ... (default 2) */\n rows?: number\n /** width at the base as a fraction of the max width (default 0) */\n baseWidth?: number\n /** sway at the base and at the tip */\n swayBase: number\n swayTip: number\n /** peak of the width profile along the length 0..1 (default 0.38) */\n peak?: number\n /** rounder tip: profile exponent (default 1) */\n round?: number\n /** edge darkening factor for the leaf edges (default 0.92) */\n edge?: number\n /** width multiplier of the edge vertices per row and side (tears / notches); <1 pulls the edge in */\n tear?: (row: number, side: -1 | 1) => number\n}\n\n/**\n * Folded, slightly drooping leaf (bent strip with a midrib). `up` is the direction the upper face looks to.\n * 4 triangles with rows = 2.\n */\nexport function leaf(b: MeshBuilder, base: Vec3, dir: Vec3, up: Vec3, length: number, width: number, c0: Vec3, c1: Vec3, o: LeafOptions): void {\n const d = norm(dir)\n let right = cross(d, up)\n if (dot(right, right) < 1e-6) right = cross(d, [1, 0, 0])\n right = norm(right)\n const n2 = norm(cross(right, d))\n const rows = o.rows ?? 2\n const curl = o.curl ?? 0.18\n const fold = o.fold ?? 0.5\n const peak = o.peak ?? 0.38\n const round = o.round ?? 1\n const edgeK = o.edge ?? 0.92\n const bw = o.baseWidth ?? 0\n type Row = { c: Vec3; w: number; col: Vec3; s: number }\n const rr: Row[] = []\n for (let i = 0; i <= rows; i++) {\n const t = i / rows\n let w: number\n if (t < peak) w = bw + (1 - bw) * Math.sin((t / peak) * Math.PI * 0.5)\n else w = Math.pow(Math.cos(((t - peak) / (1 - peak)) * Math.PI * 0.5), round)\n w *= width * 0.5\n const centre = add(add(base, mul(d, length * t)), mul(n2, -length * curl * t * t))\n rr.push({ c: centre, w: i === rows ? 0 : w, col: mix(c0, c1, t), s: o.swayBase + (o.swayTip - o.swayBase) * t })\n }\n const verts = rr.map((r, i) => {\n const hasWidth = r.w > 1e-6\n const edgeC = shade(r.col, edgeK)\n const lift = r.w * fold\n const mid = add(r.c, mul(n2, hasWidth ? lift : 0))\n const tl = o.tear ? o.tear(i, -1) : 1\n const tr = o.tear ? o.tear(i, 1) : 1\n const L = hasWidth ? add(add(r.c, mul(right, -r.w * tl)), mul(n2, -r.w * 0.12)) : r.c\n const R = hasWidth ? add(add(r.c, mul(right, r.w * tr)), mul(n2, -r.w * 0.12)) : r.c\n return { L, M: mid, R, c: r.col, e: edgeC, s: r.s, w: r.w, i }\n })\n for (let i = 0; i < rows; i++) {\n const a = verts[i]\n const z = verts[i + 1]\n const aw = a.w > 1e-6\n const zw = z.w > 1e-6\n if (!aw && zw) {\n b.flatTri(a.M, z.L, z.M, a.c, z.e, z.c, a.s, z.s, z.s, n2)\n b.flatTri(a.M, z.M, z.R, a.c, z.c, z.e, a.s, z.s, z.s, n2)\n } else if (aw && !zw) {\n b.flatTri(a.L, z.M, a.M, a.e, z.c, a.c, a.s, z.s, a.s, n2)\n b.flatTri(a.M, z.M, a.R, a.c, z.c, a.e, a.s, z.s, a.s, n2)\n } else if (aw && zw) {\n b.flatQuad(a.L, z.L, z.M, a.M, a.e, z.e, z.c, a.c, a.s, z.s, z.s, a.s, n2)\n b.flatQuad(a.M, z.M, z.R, a.R, a.c, z.c, z.e, a.e, a.s, z.s, z.s, a.s, n2)\n }\n }\n}\n\n\n/** Cheap leaflet / pinna: 2 triangles with a slight fold. */\nexport function kite(b: MeshBuilder, base: Vec3, dir: Vec3, up: Vec3, length: number, width: number, c0: Vec3, c1: Vec3, sway0: number, sway1: number, lift = 0.35): void {\n const d = norm(dir)\n let right = cross(d, up)\n if (dot(right, right) < 1e-6) right = cross(d, [1, 0, 0])\n right = norm(right)\n const n2 = norm(cross(right, d))\n const m = add(base, mul(d, length * 0.4))\n const hw = width * 0.5\n const L = add(add(m, mul(right, -hw)), mul(n2, hw * lift))\n const R = add(add(m, mul(right, hw)), mul(n2, hw * lift))\n const T = add(add(base, mul(d, length)), mul(n2, -length * 0.08))\n const cm = mix(c0, c1, 0.4)\n b.flatTri(base, L, R, c0, cm, cm, sway0, sway0 + (sway1 - sway0) * 0.4, sway0 + (sway1 - sway0) * 0.4, n2)\n b.flatTri(L, T, R, cm, c1, cm, sway0 + (sway1 - sway0) * 0.4, sway1, sway0 + (sway1 - sway0) * 0.4, n2)\n}\n","import type { Vec3 } from '../types'\nimport { add, mul, norm, sub, dot, clamp, smooth, lerp, dist, type Frame, toWorld } from '../math'\nimport { jitter, lighten, mix, shade } from '../color'\nimport { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\nimport { icoTemplate } from './ico'\nimport { leaf } from './leaf'\n\nexport interface ShellVertex {\n p: Vec3\n /** unit direction from the shell center (local space) */\n dir: Vec3\n /** 0 at the bottom, 1 at the top */\n h: number\n}\n\nexport interface ShellOptions {\n center: Vec3\n /** radii along local x / y / z */\n radii: Vec3\n frame?: Frame\n detail: 0 | 1 | 2\n rng?: Rng\n /** radial noise amplitude (fraction of radius) */\n noise: number\n /** squash of the lower part (0 none .. 1 flat bottom) */\n flatBottom?: number\n color: (v: ShellVertex) => Vec3\n sway: (v: ShellVertex) => number\n}\n\n/** Faceted, noisy, flat shaded ellipsoid shell. Returns the displaced vertices. */\nexport function icoShell(b: MeshBuilder, o: ShellOptions): ShellVertex[] {\n const tpl = icoTemplate(o.detail)\n const verts: ShellVertex[] = tpl.verts.map((u) => {\n let r = 1 + (o.rng && o.noise ? o.rng.gauss() * o.noise : 0)\n let y = u[1]\n if (o.flatBottom && y < 0) y *= 1 - o.flatBottom * 0.7 * Math.min(1, -y * 1.4)\n r = Math.max(0.5, r)\n const l: Vec3 = [u[0] * o.radii[0] * r, y * o.radii[1] * r, u[2] * o.radii[2] * r]\n const p = o.frame ? toWorld(o.frame, l) : add(o.center, l)\n return { p, dir: u, h: clamp((u[1] + 1) / 2, 0, 1) }\n })\n const origin = o.frame ? o.frame.o : o.center\n const colors = verts.map((v) => o.color(v))\n const sways = verts.map((v) => o.sway(v))\n for (const [a, bb, c] of tpl.faces) {\n const hint = sub(add(add(verts[a].p, verts[bb].p), verts[c].p), mul(origin, 3))\n b.flatTri(verts[a].p, verts[bb].p, verts[c].p, colors[a], colors[bb], colors[c], sways[a], sways[bb], sways[c], hint)\n }\n return verts\n}\n\nexport interface ClumpOptions {\n center: Vec3\n radius: number\n /** vertical radius ratio (default 0.78) */\n squash?: number\n detail: 0 | 1 | 2\n seed: number\n /** base leaf color (sRGB) */\n base: Vec3\n /** crown center: vertices facing away from it are brighter, facing it darker */\n crown?: Vec3\n /** accent color mixed on top (flowers / new growth), 0..1 amount */\n accent?: { color: Vec3; amount: number }\n /** leaves poking out of the surface: count (LOD0 only) and length */\n leaves?: { count: number; length: number; width?: number }\n /** sway multiplier (trees move little, shrubs more) */\n swayK: number\n noise?: number\n flatBottom?: number\n /** minimum brightness at the bottom (default 0.5) */\n ao?: number\n}\n\n/** Leaf clump: deformed low poly shell with gradient colors and optional small leaves on the surface. */\nexport function clump(b: MeshBuilder, o: ClumpOptions): void {\n const rng = new Rng(o.seed)\n const base = jitter(o.base, rng, 0.015, 0.07, 0.05)\n const crown = o.crown\n const ao = o.ao ?? 0.5\n const accent = o.accent\n const sq = o.squash ?? 0.78\n icoShell(b, {\n center: o.center,\n radii: [o.radius, o.radius * sq, o.radius],\n detail: o.detail,\n rng,\n noise: o.noise ?? 0.2,\n flatBottom: o.flatBottom ?? 0.5,\n color: (v) => {\n const tHeight = smooth(v.h)\n let k = lerp(ao, 1.04, tHeight)\n if (crown) {\n const out = norm(sub(v.p, crown))\n const f = dot(out, norm(sub(v.p, o.center)))\n k *= lerp(0.8, 1.06, clamp((f + 1) / 2, 0, 1))\n }\n let c = shade(base, k)\n if (v.h > 0.62) c = mix(c, lighten(base, 1), clamp((v.h - 0.62) * 1.7, 0, 0.6))\n c = shade(c, 0.94 + ((Math.sin(v.p[0] * 91.7 + v.p[1] * 53.3 + v.p[2] * 37.1) + 1) / 2) * 0.12)\n if (accent && accent.amount > 0) {\n const m = clamp(accent.amount * (0.35 + v.h * 0.9), 0, 1)\n c = mix(c, shade(accent.color, 0.7 + 0.35 * tHeight), m)\n }\n return c\n },\n sway: (v) => o.swayK * (0.45 + 0.55 * v.h),\n })\n}\n\n/** Surface leaves for a clump, emitted separately so callers can skip them at lower LODs. */\nexport function clumpLeaves(b: MeshBuilder, o: ClumpOptions): void {\n if (!o.leaves || o.leaves.count <= 0) return\n const rng = new Rng(o.seed ^ 0x9e3779b9)\n const base = jitter(o.base, new Rng(o.seed), 0.015, 0.07, 0.05)\n const sq = o.squash ?? 0.78\n for (let i = 0; i < o.leaves.count; i++) {\n // direction biased to the upper / outer half\n const a = rng.range(0, Math.PI * 2)\n const y = rng.range(-0.25, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [o.center[0] + d[0] * o.radius * 0.92, o.center[1] + d[1] * o.radius * sq * 0.92, o.center[2] + d[2] * o.radius * 0.92]\n let out = d\n if (o.crown) out = norm(add(d, mul(norm(sub(p, o.crown)), 0.6)))\n // leaves lie on the surface like shingles, pointing up-and-out, with the tips lifted off the shell\n let t: Vec3 = sub([0, 1, 0], mul(out, out[1]))\n if (dot(t, t) < 0.05) t = [Math.cos(a + 1.3), 0, Math.sin(a + 1.3)]\n const dir = norm(add(mul(norm(t), 0.8), mul(out, 0.22)))\n const k = lerp(o.ao ?? 0.5, 1.1, clamp((y + 0.4) / 1.4, 0, 1))\n const c0 = shade(base, Math.max(0.6, k * 0.9))\n const c1 = lighten(shade(base, Math.min(1.1, k)), 0.9)\n const len = o.leaves.length * rng.range(0.8, 1.25)\n const start = sub(p, mul(out, len * 0.05))\n leaf(b, start, dir, out, len, o.leaves.width ?? len * 0.8, c0, c1, { swayBase: o.swayK * 0.8, swayTip: Math.min(1, o.swayK * 1.4), curl: 0.06, fold: 0.12, round: 0.8, peak: 0.45 })\n }\n}\n\n/** Greedily merge points with radii into at most k groups (used by the far LOD). */\nexport function mergeAnchors<T extends { p: Vec3; r: number }>(items: T[], k: number): { p: Vec3; r: number; members: T[] }[] {\n if (items.length <= k) return items.map((i) => ({ p: i.p, r: i.r, members: [i] }))\n const seeds: T[] = [items.reduce((a, b2) => (b2.r > a.r ? b2 : a), items[0])]\n while (seeds.length < k) {\n let best: T | undefined\n let bd = -1\n for (const it of items) {\n let md = Infinity\n for (const s of seeds) md = Math.min(md, dist(it.p, s.p))\n if (md > bd) {\n bd = md\n best = it\n }\n }\n seeds.push(best as T)\n }\n const groups = seeds.map((s) => ({ s, members: [] as T[] }))\n for (const it of items) {\n let bi = 0\n let bd = Infinity\n for (let i = 0; i < seeds.length; i++) {\n const d = dist(it.p, seeds[i].p)\n if (d < bd) {\n bd = d\n bi = i\n }\n }\n groups[bi].members.push(it)\n }\n return groups\n .filter((g) => g.members.length > 0)\n .map((g) => {\n let cx = 0\n let cy = 0\n let cz = 0\n let w = 0\n for (const m of g.members) {\n cx += m.p[0] * m.r\n cy += m.p[1] * m.r\n cz += m.p[2] * m.r\n w += m.r\n }\n const p: Vec3 = [cx / w, cy / w, cz / w]\n let r = 0\n for (const m of g.members) r = Math.max(r, dist(p, m.p) + m.r * 0.85)\n return { p, r, members: g.members }\n })\n}\n\n/** Tiny faceted blob (8 triangles) for small fruit / buds. */\nexport function octa(b: MeshBuilder, center: Vec3, radii: Vec3, color: (h: number) => Vec3, sway: number): void {\n const pts: Vec3[] = [\n [radii[0], 0, 0], [0, 0, radii[2]], [-radii[0], 0, 0], [0, 0, -radii[2]],\n ].map((p) => add(center, [p[0], p[1] + 0.0, p[2]] as Vec3))\n const top: Vec3 = add(center, [0, radii[1], 0])\n const bot: Vec3 = add(center, [0, -radii[1], 0])\n for (let i = 0; i < 4; i++) {\n const a = pts[i]\n const c = pts[(i + 1) % 4]\n const out = sub(add(a, c), mul(center, 2))\n b.flatTri(a, c, top, color(0.5), color(0.5), color(1), sway, sway, sway, add(out, [0, 1, 0]))\n b.flatTri(c, a, bot, color(0.5), color(0.5), color(0), sway, sway, sway, add(out, [0, -1, 0]))\n }\n}\n","import type { Lod, Vec3 } from '../types'\nimport { add, frameFromAxis, mul, norm, TAU, toWorld, dirToWorld, type Frame, lerp } from '../math'\nimport { shade, lighten, mix, jitter } from '../color'\nimport type { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\nimport { leaf } from './leaf'\nimport { icoShell } from './shell'\nimport { tube } from './tube'\n\n/** Small flat flower (default 5 petals) lying on a surface, normal pointing out. */\nexport function blossom(b: MeshBuilder, center: Vec3, normal: Vec3, size: number, color: Vec3, heart: Vec3, sway: number, petals = 5, twist = 0): void {\n const f = frameFromAxis(center, normal, twist)\n const peak = toWorld(f, [0, size * 0.3, 0])\n for (let i = 0; i < petals; i++) {\n const a0 = (i / petals) * TAU\n const a1 = ((i + 1) / petals) * TAU\n const am = (a0 + a1) / 2\n const p0 = toWorld(f, [Math.cos(a0) * size * 0.75, 0, Math.sin(a0) * size * 0.75])\n const p1 = toWorld(f, [Math.cos(a1) * size * 0.75, 0, Math.sin(a1) * size * 0.75])\n const pm = toWorld(f, [Math.cos(am) * size * 1.1, size * 0.08, Math.sin(am) * size * 1.1])\n const c = i % 2 ? shade(color, 0.93) : color\n b.flatTri(peak, p0, pm, heart, c, lighten(c, 0.4), sway, sway, sway, normal)\n b.flatTri(peak, pm, p1, heart, lighten(c, 0.4), c, sway, sway, sway, normal)\n }\n}\n\nexport type FlowerKind = 'daisy' | 'sunflower' | 'rose' | 'tulip' | 'hibiscus' | 'cluster' | 'lily' | 'bird_of_paradise' | 'trumpet' | 'passion' | 'bract' | 'bell' | 'pompom' | 'florets'\n\nexport interface HeadOptions {\n kind: FlowerKind\n center: Vec3\n /** direction the flower faces (stem tip direction) */\n axis: Vec3\n /** head radius in meters */\n size: number\n colors: Vec3[]\n centerColor: Vec3\n rng: Rng\n lod: Lod\n sway: number\n twist?: number\n}\n\ninterface PetalOpts {\n angle: number\n r0: number\n elev: number\n length: number\n width: number\n c0: Vec3\n c1: Vec3\n curl: number\n rows?: number\n face?: 'axis' | 'radial'\n fold?: number\n peak?: number\n round?: number\n swayK: number\n}\n\nfunction petal(b: MeshBuilder, f: Frame, o: PetalOpts): void {\n const ca = Math.cos(o.angle)\n const sa = Math.sin(o.angle)\n const ce = Math.cos(o.elev)\n const se = Math.sin(o.elev)\n const baseL: Vec3 = [ca * o.r0, 0, sa * o.r0]\n const dirL: Vec3 = [ca * ce, se, sa * ce]\n const faceL: Vec3 = o.face === 'radial' ? [ca, 0, sa] : [0, 1, 0]\n leaf(b, toWorld(f, baseL), dirToWorld(f, dirL), dirToWorld(f, faceL), o.length, o.width, o.c0, o.c1, {\n rows: o.rows ?? 2,\n curl: o.curl,\n fold: o.fold ?? 0.25,\n swayBase: o.swayK,\n swayTip: o.swayK,\n peak: o.peak ?? 0.55,\n round: o.round ?? 0.8,\n edge: 0.96,\n })\n}\n\nfunction dome(b: MeshBuilder, f: Frame, radius: number, height: number, c0: Vec3, c1: Vec3, sway: number, detail: 0 | 1 = 0): void {\n icoShell(b, {\n center: f.o,\n frame: f,\n radii: [radius, height, radius],\n detail,\n noise: 0,\n color: (v) => mix(c0, c1, Math.max(0, v.h - 0.2) * 1.2),\n sway: () => sway,\n })\n}\n\n/** A flower head built from folded petals (no flat cards). Sizes are in meters. */\nexport function flowerHead(b: MeshBuilder, o: HeadOptions): void {\n const f = frameFromAxis(o.center, o.axis, o.twist ?? o.rng.range(0, TAU))\n const s = o.size\n const rng = o.rng\n const col = (i: number): Vec3 => o.colors[i % o.colors.length]\n const sw = o.sway\n const heart = o.centerColor\n if (o.lod === 2 && o.kind !== 'cluster' && o.kind !== 'bird_of_paradise') {\n blossom(b, o.center, o.axis, s * 1.2, col(0), heart, sw, 4, o.twist ?? 0)\n return\n }\n switch (o.kind) {\n case 'daisy': {\n const n = o.lod === 0 ? 12 : o.lod === 1 ? 8 : 5\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.005, 0.03, 0.02)\n petal(b, f, { angle: (i / n) * TAU + rng.range(-0.05, 0.05), r0: s * 0.18, elev: 0.12 + rng.range(-0.05, 0.08), length: s * 0.95, width: s * 0.42 * (12 / n) ** 0.5, c0: shade(c, 0.88), c1: lighten(c, 0.2), curl: -0.08, swayK: sw })\n }\n dome(b, f, s * 0.3, s * 0.2, shade(heart, 0.75), lighten(heart, 0.5), sw)\n break\n }\n case 'sunflower': {\n const n = o.lod === 0 ? 14 : o.lod === 1 ? 10 : 6\n for (let layer = 0; layer < 2; layer++) {\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.006, 0.04, 0.03)\n petal(b, f, { angle: ((i + layer * 0.5) / n) * TAU, r0: s * 0.5, elev: layer ? 0.02 : 0.2, length: s * 0.62, width: s * 0.3, c0: shade(c, 0.85), c1: lighten(c, 0.18), curl: -0.1 + layer * 0.12, swayK: sw, peak: 0.45 })\n }\n if (o.lod > 0) break\n }\n dome(b, f, s * 0.58, s * 0.2, shade(heart, 0.6), shade(mix(heart, [0.55, 0.38, 0.12], 0.5), 1.2), sw, o.lod === 0 ? 1 : 0)\n break\n }\n case 'rose': {\n const layers = o.lod === 0 ? [{ n: 5, r: 0.55, e: 0.5, k: 1 }, { n: 5, r: 0.38, e: 0.85, k: 0.82 }, { n: 4, r: 0.22, e: 1.15, k: 0.62 }, { n: 3, r: 0.1, e: 1.4, k: 0.42 }] : [{ n: 5, r: 0.5, e: 0.7, k: 1 }, { n: 4, r: 0.25, e: 1.2, k: 0.6 }]\n layers.forEach((L, li) => {\n for (let i = 0; i < L.n; i++) {\n const base = col(i)\n const c = jitter(base, rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / L.n) * TAU + li * 0.9 + rng.range(-0.1, 0.1), r0: s * L.r * 0.5, elev: L.e, length: s * (0.75 + L.r * 0.5), width: s * (0.85 - li * 0.1), c0: shade(c, 0.5 * L.k + 0.35), c1: lighten(shade(c, 0.95), 0.3), curl: 0.12, face: 'radial', swayK: sw, peak: 0.6, rows: 2, fold: 0.1 })\n }\n })\n break\n }\n case 'tulip': {\n const n = o.lod === 2 ? 4 : 6\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n const inner = i % 2\n petal(b, f, { angle: (i / n) * TAU + (inner ? 0.5 : 0), r0: s * (inner ? 0.2 : 0.35), elev: inner ? 1.35 : 1.15, length: s * (inner ? 1.7 : 1.9), width: s * 1.05, c0: shade(c, 0.78), c1: lighten(c, 0.22), curl: 0.28, face: 'radial', rows: o.lod === 0 ? 3 : 2, swayK: sw, peak: 0.45 })\n }\n break\n }\n case 'hibiscus': {\n const n = 5\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / n) * TAU + rng.range(-0.08, 0.08), r0: s * 0.04, elev: 0.5, length: s * 1.2, width: s * 1.15, c0: shade(mix(c, [0.35, 0.02, 0.05], 0.7), 0.9), c1: lighten(c, 0.2), curl: -0.05, rows: o.lod === 0 ? 3 : 2, swayK: sw, peak: 0.55, round: 0.6, fold: 0.15 })\n }\n if (o.lod < 2) {\n const tip = toWorld(f, [0, s * 1.0, 0])\n tube(b, [f.o, add(f.o, mul(f.y, s * 0.5)), tip], { sides: 3, radii: [s * 0.05, s * 0.04, s * 0.03], color: () => [0.95, 0.75, 0.3], sway: () => sw, end: 'none' })\n if (o.lod === 0) {\n dome(b, { ...f, o: tip }, s * 0.14, s * 0.08, [0.95, 0.78, 0.2], [1, 0.9, 0.4], sw)\n for (let i = 0; i < 3; i++) {\n const a = (i / 3) * TAU\n dome(b, { ...f, o: toWorld(f, [Math.cos(a) * s * 0.2, s * 0.85, Math.sin(a) * s * 0.2]) }, s * 0.06, s * 0.05, [0.95, 0.5, 0.15], [1, 0.8, 0.3], sw)\n }\n }\n }\n break\n }\n case 'cluster': {\n const detail: 0 | 1 = o.lod === 0 ? 1 : 0\n icoShell(b, {\n center: o.center,\n radii: [s, s * 0.85, s],\n detail,\n rng,\n noise: 0.12,\n color: (v) => {\n const h = (Math.sin(v.p[0] * 131 + v.p[1] * 71 + v.p[2] * 97) + 1) / 2\n const c = mix(col(0), col(1 % o.colors.length), h)\n return shade(c, lerp(0.7, 1.1, v.h))\n },\n sway: () => sw,\n })\n break\n }\n case 'lily': {\n const n = 6\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / n) * TAU + (i % 2 ? 0.2 : 0), r0: s * 0.06, elev: 0.55, length: s * 1.25, width: s * 0.55, c0: shade(mix(c, [0.2, 0.4, 0.1], 0.35), 0.85), c1: lighten(c, 0.2), curl: -0.28, rows: o.lod === 0 ? 3 : 2, swayK: sw, peak: 0.5, fold: 0.3 })\n }\n if (o.lod === 0) {\n for (let i = 0; i < 3; i++) {\n const a = (i / 3) * TAU + 0.4\n const p1 = toWorld(f, [Math.cos(a) * s * 0.25, s * 0.55, Math.sin(a) * s * 0.25])\n tube(b, [f.o, p1], { sides: 3, radii: [s * 0.02, s * 0.015], color: () => [0.9, 0.9, 0.7], sway: () => sw, end: 'none' })\n dome(b, { ...f, o: p1 }, s * 0.06, s * 0.04, [0.8, 0.35, 0.1], [0.95, 0.55, 0.15], sw)\n }\n }\n break\n }\n case 'bird_of_paradise': {\n const green: Vec3 = [0.3, 0.5, 0.25]\n const red: Vec3 = [0.7, 0.15, 0.15]\n // boat shaped bract, then the orange and blue petals standing from it\n leaf(b, o.center, norm(add(f.x, mul(f.y, 0.5))), f.y, s * 1.5, s * 0.5, shade(green, 0.7), red, { rows: 2, curl: -0.15, fold: 0.6, swayBase: sw, swayTip: sw, peak: 0.45 })\n for (let i = 0; i < (o.lod === 2 ? 2 : 3); i++) {\n const c = col(0)\n const a = (i - 1) * 0.35\n const dir = norm(add(mul(f.y, 0.75), add(mul(f.x, 0.55 + Math.abs(a) * 0.1), mul(f.z, a))))\n leaf(b, add(o.center, mul(f.y, s * 0.15)), dir, f.z, s * 1.2, s * 0.32, shade(c, 0.85), lighten(c, 0.2), { rows: 2, curl: 0.2, fold: 0.35, swayBase: sw, swayTip: sw, peak: 0.4 })\n }\n if (o.lod < 2) {\n const c2 = col(1 % o.colors.length)\n for (let i = 0; i < 2; i++) {\n const dir = norm(add(mul(f.y, 0.4), add(mul(f.x, 0.8), mul(f.z, i ? 0.2 : -0.2))))\n leaf(b, add(o.center, mul(f.y, s * 0.1)), dir, f.z, s * 1.1, s * 0.22, shade(c2, 0.8), c2, { rows: 2, curl: 0.1, fold: 0.35, swayBase: sw, swayTip: sw, peak: 0.4 })\n }\n }\n break\n }\n case 'trumpet': {\n const n = o.lod === 0 ? 8 : 6\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / n) * TAU, r0: s * 0.08, elev: 0.75, length: s * 1.3, width: s * 0.38, c0: shade(c, 0.85), c1: c, curl: -0.1, rows: 2, swayK: sw, peak: 0.45 })\n }\n dome(b, f, s * 0.2, s * 0.15, shade(heart, 0.8), heart, sw)\n break\n }\n case 'passion': {\n const n = o.lod === 0 ? 10 : 6\n for (let i = 0; i < n; i++) {\n const c = col(i % 2)\n petal(b, f, { angle: (i / n) * TAU, r0: s * 0.1, elev: 0.1, length: s * 0.95, width: s * 0.4, c0: shade(c, 0.9), c1: lighten(c, 0.1), curl: -0.05, rows: 2, swayK: sw, peak: 0.5 })\n }\n if (o.lod < 2) {\n const cor = o.colors[o.colors.length - 1]\n for (let i = 0; i < (o.lod === 0 ? 12 : 6); i++) {\n petal(b, f, { angle: (i / (o.lod === 0 ? 12 : 6)) * TAU, r0: s * 0.12, elev: 0.5, length: s * 0.45, width: s * 0.1, c0: shade(cor, 0.7), c1: lighten(cor, 0.3), curl: -0.2, rows: 2, swayK: sw })\n }\n dome(b, { ...f, o: add(f.o, mul(f.y, s * 0.25)) }, s * 0.12, s * 0.12, [0.45, 0.55, 0.2], [0.7, 0.8, 0.35], sw)\n }\n break\n }\n case 'bract': {\n // bougainvillea: three papery heart-shaped bracts around a tiny white flower\n const n = 3\n for (let i = 0; i < n; i++) {\n const c = jitter(col(i), rng, 0.008, 0.06, 0.03)\n petal(b, f, { angle: (i / n) * TAU + rng.range(0, 0.5), r0: s * 0.05, elev: 0.5, length: s * 1.1, width: s * 1.0, c0: shade(c, 0.85), c1: lighten(c, 0.2), curl: -0.1, rows: 2, swayK: sw, peak: 0.55, round: 0.6 })\n }\n break\n }\n case 'pompom': {\n // marigold: ruffled little ball, faceted, orange with yellow streaks, on a green calyx\n const c0 = col(0)\n const c1 = col(1 % o.colors.length)\n const ctr = add(o.center, mul(o.axis, s * 0.55))\n icoShell(b, {\n center: ctr,\n radii: [s, s * 0.82, s],\n detail: 0,\n rng,\n noise: 0.13,\n color: (v) => {\n const h = (Math.sin(v.p[0] * 311 + v.p[1] * 177 + v.p[2] * 233) + 1) / 2\n return shade(mix(c0, c1, h), lerp(0.72, 1.12, v.h))\n },\n sway: () => sw,\n })\n dome(b, { ...f, o: add(o.center, mul(o.axis, s * 0.05)) }, s * 0.5, s * 0.35, [0.2, 0.4, 0.15], [0.3, 0.5, 0.2], sw)\n break\n }\n case 'florets': {\n // hydrangea: a ball of many small four-petal florets over a dark core\n const n = o.lod === 0 ? 34 : 20\n const R = s\n const ctr = add(o.center, mul(o.axis, R * 0.75))\n icoShell(b, { center: ctr, radii: [R * 0.84, R * 0.8, R * 0.84], detail: 0, noise: 0, color: (v) => shade(mix(col(0), [0.15, 0.3, 0.2], 0.55), 0.65 + v.h * 0.3), sway: () => sw })\n const w = R * 0.34 * Math.sqrt(34 / n)\n for (let i = 0; i < n; i++) {\n const y = 1 - (i + 0.5) * (2 / n)\n const r = Math.sqrt(Math.max(0, 1 - y * y))\n const a = i * 2.399963\n const d: Vec3 = norm([Math.cos(a) * r, y, Math.sin(a) * r])\n const fr = frameFromAxis(add(ctr, mul(d, R * 0.97)), d, a)\n const c = jitter(col(i), rng, 0.01, 0.07, 0.05)\n const base = shade(c, lerp(0.7, 1.08, (y + 1) / 2))\n const tip = lighten(base, 0.35)\n const pk = toWorld(fr, [0, w * 0.35, 0])\n const ps: Vec3[] = [toWorld(fr, [w, 0, 0]), toWorld(fr, [0, 0, w]), toWorld(fr, [-w, 0, 0]), toWorld(fr, [0, 0, -w])]\n for (let k = 0; k < 4; k++) {\n const q = ps[k]\n const q2 = ps[(k + 1) % 4]\n b.flatTri(pk, q, q2, tip, base, base, sw, sw, sw, d)\n }\n }\n break\n }\n case 'bell': {\n // drooping bell (fuchsia / abutilon like): 5 petals hanging, narrow at the stem\n for (let i = 0; i < 5; i++) {\n const c = jitter(col(i), rng, 0.004, 0.03, 0.02)\n petal(b, f, { angle: (i / 5) * TAU, r0: s * 0.05, elev: 0.5, length: s * 1.1, width: s * 0.8, c0: shade(c, 0.8), c1: lighten(c, 0.15), curl: 0.2, rows: 2, face: 'radial', swayK: sw, peak: 0.6 })\n }\n break\n }\n }\n}\n","import type { Vec3 } from '../types'\nimport type { Ctx } from '../ctx'\nimport type { Branch } from '../geometry/branches'\n\n/** Maximum number of separate main branches a tree is split into (more are merged into the last). */\nexport const MAX_MAIN_BRANCHES = 6\n\nexport interface CrownAnchor {\n /** crown piece id that the foliage near `points` goes to */\n crownId: string\n branchId: string\n points: Vec3[]\n}\n\n/**\n * Draw the trunk and every branch as separate wood pieces: 'trunk', then 'branch0'..'branch5' (a main branch, i.e. level 1, with all\n * the branches that grow from it). `draw(branch, index)` draws one branch (index -1 is the trunk).\n * Returns the anchors that `splitCrown` uses to hand foliage to the nearest main branch.\n */\nexport function drawTreeWood(ctx: Ctx, tree: { trunk: Branch; branches: Branch[] }, draw: (br: Branch, index: number) => void): CrownAnchor[] {\n ctx.piece('trunk', 'trunk')\n draw(tree.trunk, -1)\n const top = tree.trunk.pts[tree.trunk.pts.length - 1]\n const anchors: CrownAnchor[] = [{ crownId: 'crown', branchId: 'trunk', points: [top] }]\n let main = -1\n let current: CrownAnchor | undefined\n for (let i = 0; i < tree.branches.length; i++) {\n const br = tree.branches[i]\n if (br.level <= 1) {\n main++\n const k = Math.min(main, MAX_MAIN_BRANCHES - 1)\n const id = `branch${k}`\n ctx.piece(id, 'branch', 'trunk', br.pts[0])\n current = anchors.find((a) => a.branchId === id)\n if (!current) {\n current = { crownId: `crown${k}`, branchId: id, points: [] }\n anchors.push(current)\n }\n }\n if (current) current.points.push(br.pts[br.pts.length - 1])\n draw(br, i)\n }\n ctx.piece('trunk', 'trunk')\n return anchors\n}\n\n/**\n * Relabel the foliage / flower triangles tagged 'crown' so each goes to the crown of the nearest main branch (by triangle center\n * to the nearest branch end). Call after the crown geometry was emitted.\n */\nexport function splitCrown(ctx: Ctx, anchors: CrownAnchor[]): void {\n if (anchors.length <= 1) {\n return\n }\n for (const b of [ctx.foliage, ctx.flowers, ctx.wood]) {\n const nTri = b.idx.length / 3\n for (let t = 0; t < nTri; t++) {\n if (b.triTag[t] !== 'crown') continue\n let cx = 0\n let cy = 0\n let cz = 0\n for (let k = 0; k < 3; k++) {\n const v = b.idx[t * 3 + k] * 3\n cx += b.pos[v]\n cy += b.pos[v + 1]\n cz += b.pos[v + 2]\n }\n cx /= 3\n cy /= 3\n cz /= 3\n let best = anchors[0]\n let bd = Infinity\n for (const a of anchors) {\n for (const p of a.points) {\n const d = (p[0] - cx) ** 2 + (p[1] - cy) ** 2 + (p[2] - cz) ** 2\n if (d < bd) {\n bd = d\n best = a\n }\n }\n }\n b.triTag[t] = best.crownId\n if (!ctx.pieceMeta.has(best.crownId)) ctx.pieceMeta.set(best.crownId, { kind: 'crown', parent: best.branchId })\n }\n }\n}\n","import type { Vec3 } from '../types'\nimport type { Ctx } from '../ctx'\nimport { mix, tintGreen } from '../color'\nimport { clamp } from '../math'\n\nconst AUTUMN: Vec3[] = [\n [0.86, 0.56, 0.12],\n [0.8, 0.32, 0.1],\n [0.92, 0.76, 0.2],\n [0.66, 0.3, 0.1],\n]\nconst WINTER_LEAF: Vec3 = [0.45, 0.34, 0.2]\n\n/** Condition + season tint for leaf-like green tissue. `roll` (0..1) varies the autumn color per clump. */\nexport function leafTint(ctx: Ctx, c: Vec3, deciduous: boolean, roll: number): Vec3 {\n let out = tintGreen(c, ctx.condition)\n if (deciduous) {\n if (ctx.season === 'autumn') out = mix(out, AUTUMN[Math.floor(roll * AUTUMN.length) % AUTUMN.length], 0.8)\n else if (ctx.season === 'winter') out = mix(out, WINTER_LEAF, 0.8)\n }\n return out\n}\n\n/** Share of leaf tips kept (0..1+) by condition and season. */\nexport function leafAmount(ctx: Ctx, deciduous: boolean): number {\n let a = 1\n switch (ctx.condition) {\n case 'dry':\n a = 0.72\n break\n case 'dead':\n a = 0\n break\n case 'overgrown':\n a = 1.15\n break\n }\n if (deciduous) {\n if (ctx.season === 'winter') a *= 0.1\n else if (ctx.season === 'autumn') a *= 0.85\n }\n return clamp(a, 0, 1.3)\n}\n\nexport function inSeason(ctx: Ctx, seasons: readonly string[] | undefined): boolean {\n return (seasons ?? ['spring', 'summer']).includes(ctx.season)\n}\n","import type { DeadTreeSpec } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { rgb, shade, mix } from '../color'\nimport { growTree } from '../geometry/branches'\nimport { drawBranch } from '../geometry/wood'\nimport { drawTreeWood } from './pieces'\n\n/** Bare, twisted tree with broken stubs. Also used for the `dead` condition of broadleaf trees. */\nexport function generateDeadTree(spec: DeadTreeSpec, ctx: Ctx, fromTree = false): ArchResult {\n const height = spec.height ?? 5\n const trunkRadius = spec.trunkRadius ?? 0.2\n const crownRadius = spec.crownRadius ?? height * 0.38\n const base = fromTree ? mix(rgb(spec.barkColor ?? 0x6b4b34), [0.42, 0.39, 0.34], 0.7) : rgb(spec.barkColor ?? 0x6c6458)\n const bark = shade(base, 0.95)\n const tree = growTree(ctx.rng, {\n height,\n trunkRadius,\n crownRadius,\n shape: 'spreading',\n levels: spec.branchLevels ?? 3,\n trunkFraction: 0.33,\n gnarl: 1.1,\n primary: 5,\n lean: 0.1,\n bare: true,\n })\n drawTreeWood(ctx, tree, (br, i) => drawBranch(ctx.wood, br, bark, ctx.lod, i < 0 ? 1 : i * 0.5))\n return { collider: { kind: 'cylinder', radius: trunkRadius * 1.1, height: height * 0.5 }, bendable: false }\n}\n","import type { BroadleafTreeSpec, CrownStyle, Vec3 } from '../types'\nimport type { Ctx } from '../ctx'\nimport { Rng } from '../rng'\nimport { add, clamp, dist, lerp, mul, norm, TAU } from '../math'\nimport { mix, shade } from '../color'\nimport { clump, clumpLeaves } from '../geometry/shell'\nimport { tube } from '../geometry/tube'\nimport { barkColor } from '../geometry/wood'\nimport { leaf } from '../geometry/leaf'\nimport { growTree, type Branch, type GrowParams, type Tip, type TreeShape } from '../geometry/branches'\nimport { catmull } from '../math'\n\nexport interface StyleGroup {\n p: Vec3\n r: number\n sq: number\n}\n\nexport interface StyleEnv {\n ctx: Ctx\n spec: BroadleafTreeSpec\n tree: TreeShape\n vis: Tip[]\n H: number\n R: number\n clearY: number\n /** leaf / bloom color of a clump */\n colorFor: (tip: Tip) => { base: Vec3; accent?: { color: Vec3; amount: number } }\n grow: number\n bark: Vec3\n keep: number\n bloomOn: boolean\n}\n\ninterface Anchor {\n p: Vec3\n r: number\n sq: number\n tip: Tip\n tone: number\n}\n\n/** Weeping willow skeleton: short trunk forking into arching limbs that rise, then fall toward the ground. */\nexport function willowTree(rng: Rng, p: GrowParams): TreeShape {\n const base = growTree(rng, { ...p, height: p.height * 0.56, primary: 1, levels: 1, shape: 'round' })\n const H = p.height\n const trunk = base.trunk\n const top = trunk.pts[trunk.pts.length - 1]\n const branches: Branch[] = []\n const tips: Tip[] = []\n const n = 8\n for (let i = 0; i < n; i++) {\n const az = (i / n) * TAU + rng.range(-0.25, 0.25)\n const y0 = top[1] * rng.range(0.72, 0.98)\n // the trunk position at that height (trunk pts are dense and monotonic in y)\n let tp = top\n for (const q of trunk.pts) if (q[1] >= y0) { tp = q; break }\n const L = p.crownRadius * rng.range(0.85, 1.1)\n const G = H * rng.range(0.15, 0.22)\n const k2 = 6.25 * G\n const pts: Vec3[] = []\n for (let k = 0; k <= 7; k++) {\n const t = k / 7\n const d = L * Math.pow(t, 0.85)\n const wob = Math.sin(t * 5 + i) * 0.12\n pts.push([tp[0] + Math.cos(az + wob) * d, y0 + 0.8 * k2 * t - k2 * t * t, tp[2] + Math.sin(az + wob) * d])\n }\n const sm = catmull(pts, 2)\n const r0 = trunk.radii[Math.floor(trunk.radii.length * 0.85)] * rng.range(0.4, 0.5)\n const radii = sm.map((_, k) => Math.max(0.012, r0 * (1 - 0.85 * (k / (sm.length - 1)))))\n branches.push({ pts: sm, radii, level: 1 })\n // twig forks\n for (let q = 0; q < 2; q++) {\n const t = rng.range(0.4, 0.7)\n const bi = Math.floor(t * (sm.length - 1))\n const s0 = sm[bi]\n const az2 = az + rng.range(0.5, 1) * (q ? 1 : -1)\n const pp: Vec3[] = [s0]\n for (let k = 1; k <= 4; k++) pp.push([s0[0] + Math.cos(az2) * L * 0.12 * k, s0[1] + (k < 2 ? 0.1 : -0.25 * k) * H * 0.04 - k * 0.15, s0[2] + Math.sin(az2) * L * 0.12 * k])\n branches.push({ pts: catmull(pp, 2), radii: catmull(pp.map((_, k) => [r0 * 0.4 * (1 - k * 0.2), 0, 0] as Vec3), 2).map((v) => Math.max(0.008, v[0])), level: 2 })\n }\n for (const t of [0.3, 0.55, 0.8]) {\n const q = sm[Math.floor(t * (sm.length - 1))]\n tips.push({ p: q, dir: [0, 1, 0], size: rng.range(0.8, 1.2), level: 1, seed: rng.seed(), keep: rng.next(), roll: rng.next() })\n }\n }\n tips.push({ p: [top[0], top[1] + 0.4, top[2]], dir: [0, 1, 0], size: 1, level: 0, seed: rng.seed(), keep: 0, roll: 0.5 })\n return { trunk, branches, tips, crown: [top[0], top[1] + G0(H), top[2]], trunkTopY: top[1] }\n}\nconst G0 = (H: number): number => H * 0.12\n\n/** Skeleton parameters per style: how the branches grow under the crown. */\nexport function styleSkeleton(style: CrownStyle): { shape: 'round' | 'spreading' | 'weeping'; primary: number; trunkFraction: number; levels: number; gnarl: number; lean: number } {\n switch (style) {\n case 'dome':\n return { shape: 'spreading', primary: 6, trunkFraction: 0.34, levels: 3, gnarl: 0.5, lean: 0.02 }\n case 'umbrella':\n return { shape: 'spreading', primary: 7, trunkFraction: 0.46, levels: 2, gnarl: 0.55, lean: 0.03 }\n case 'lumpy':\n return { shape: 'round', primary: 5, trunkFraction: 0.3, levels: 3, gnarl: 0.95, lean: 0.05 }\n case 'sphere':\n return { shape: 'round', primary: 4, trunkFraction: 0.5, levels: 2, gnarl: 0.3, lean: 0.01 }\n case 'willow':\n return { shape: 'weeping', primary: 7, trunkFraction: 0.28, levels: 2, gnarl: 0.5, lean: 0.03 }\n case 'sparse_high':\n return { shape: 'round', primary: 4, trunkFraction: 0.58, levels: 3, gnarl: 0.9, lean: 0.07 }\n default:\n return { shape: 'round', primary: 5, trunkFraction: 0.32, levels: 3, gnarl: 0.55, lean: 0.03 }\n }\n}\n\nconst fakeTip = (r: Rng, level = 1): Tip => ({ p: [0, 0, 0], dir: [0, 1, 0], size: 1, level, seed: r.seed(), keep: r.next(), roll: r.next() })\n\nfunction pickSpread(tips: Tip[], rad: number, max: number, minY: number): Tip[] {\n const out: Tip[] = []\n const sorted = tips.filter((t) => t.p[1] >= minY).sort((a, b) => b.level - a.level || a.keep - b.keep)\n for (const t of sorted) {\n if (out.length >= max) break\n if (out.every((o) => dist(o.p, t.p) > rad * 1.05)) out.push(t)\n }\n return out\n}\n\nfunction buildAnchors(style: CrownStyle, env: StyleEnv, rng: Rng): Anchor[] {\n const { H, R, tree, vis } = env\n const size = env.spec.clumpSize ?? 1\n const top = tree.trunk.pts[tree.trunk.pts.length - 1]\n const cx = tree.crown[0] * 0.3 + top[0] * 0.7\n const cz = tree.crown[2] * 0.3 + top[2] * 0.7\n const out: Anchor[] = []\n const add1 = (p: Vec3, r: number, sq: number, tip?: Tip, tone = 1): void => {\n out.push({ p, r, sq, tip: tip ?? fakeTip(rng), tone })\n }\n switch (style) {\n case 'sphere': {\n // clipped ball made of lumps (never one smooth sphere)\n const rs = Math.min(R, (H - env.clearY) * 0.5)\n const cy = H - rs\n add1([top[0], cy, top[2]], rs * 0.66, 1, vis[0])\n const ringN = 7\n for (let i = 0; i < ringN; i++) {\n const a = (i / ringN) * TAU + rng.range(0, 0.4)\n const lift = i % 2 ? 0.22 : -0.1\n add1([top[0] + Math.cos(a) * rs * 0.52, cy + rs * lift, top[2] + Math.sin(a) * rs * 0.52], rs * 0.5, 0.95, undefined, 1 - (i % 3) * 0.05)\n }\n add1([top[0] + rs * 0.12, cy + rs * 0.5, top[2]], rs * 0.46, 0.95, undefined, 1.05)\n add1([top[0], cy - rs * 0.45, top[2]], rs * 0.44, 0.85, undefined, 0.92)\n break\n }\n case 'dome':\n case 'cloud': {\n const cloud = style === 'cloud'\n const y0 = cloud ? Math.min(env.clearY * 0.7, Math.max(0.7, H * 0.2)) : env.clearY * 0.66\n const n = cloud ? 9 : 11\n const rr = R * (cloud ? 0.5 : 0.4) * size\n for (let i = 0; i < n; i++) {\n const u = (i + 0.5) / n\n const ang = i * 2.399963\n const rad = Math.min(R - rr * 0.95, Math.sqrt(u) * R * (cloud ? 0.78 : 0.9))\n const hh = Math.pow(Math.max(0.04, 1 - (rad / R) ** 2), cloud ? 0.6 : 0.42)\n const r = rr * (1.12 - 0.3 * u) * rng.range(0.9, 1.08)\n const sq = cloud ? 0.92 : 0.7\n const depth = cloud ? (i % 3 === 0 ? 1 : 0.35 + 0.65 * ((i * 0.618034) % 1)) : 0.3 + 0.7 * ((i * 0.618034) % 1)\n const y = y0 + r * sq + hh * (H - y0 - r * sq * 2) * (cloud ? 0.95 : 0.96) * depth\n add1([cx + Math.cos(ang) * rad, y, cz + Math.sin(ang) * rad], r, sq, undefined, 1 - u * 0.1)\n }\n break\n }\n case 'umbrella': {\n const sq = 0.36\n const r0 = R * 0.4 * size\n const yTop = H - r0 * sq\n add1([cx, yTop, cz], r0 * 0.95, sq)\n const rings: [number, number][] = [[6, 0.36], [10, 0.7], [12, 1.0]]\n for (const [cnt, f] of rings) {\n for (let i = 0; i < cnt; i++) {\n const ang = (i / cnt) * TAU + f * 2 + rng.range(-0.15, 0.15)\n const rad = Math.min(R - r0 * 0.7, R * f) * rng.range(0.92, 1.05)\n const r = r0 * rng.range(0.85, 1.1) * (1 - f * 0.12)\n add1([cx + Math.cos(ang) * rad, yTop - (rad / R) * H * 0.07 - rng.range(0, 0.25), cz + Math.sin(ang) * rad], r, sq, undefined, 1)\n }\n }\n break\n }\n case 'lumpy': {\n const r = R * 0.3 * size\n const picks = pickSpread(vis, r * 1.5, 15, env.clearY + 0.05 * H)\n for (const t of picks) add1(add(t.p, [0, r * 0.45, 0]), r * t.size * rng.range(0.85, 1.15), 0.7, t, rng.range(0.9, 1.1))\n break\n }\n case 'sparse_high': {\n const r = R * 0.3 * size\n const picks = pickSpread(vis, r * 0.9, 8, env.clearY)\n for (const t of picks) add1(add(t.p, [0, r * 0.25, 0]), r * t.size * rng.range(0.75, 1.15), 0.68, t, 1)\n // irregular fill around the upper trunk\n const yTop = H - r * 0.5\n for (let i = 0; i < 9; i++) {\n const ang = rng.range(0, TAU)\n const rad = R * rng.range(0.2, 1.0)\n const y = lerp(env.clearY + (H - env.clearY) * 0.2, yTop, rng.next())\n add1([cx + Math.cos(ang) * rad, y, cz + Math.sin(ang) * rad], r * rng.range(0.55, 0.9), 0.66, undefined, rng.range(0.9, 1.05))\n }\n break\n }\n case 'willow': {\n const r = R * 0.24 * size\n const picks = pickSpread(vis, r * 1.2, 9, env.clearY)\n for (const t of picks) add1(add(t.p, [0, r * 0.2, 0]), r * t.size, 0.5, t, 1)\n break\n }\n default:\n break\n }\n return out\n}\n\n/** Hanging curtain strips (willow / eucalyptus) from points along the branches. */\nfunction hangStrips(env: StyleEnv, rng: Rng, base: Vec3, opts: { perBranch: number; minLen: number; maxLen: number; toGround: boolean; width: number; light: Vec3 }): void {\n const { ctx, tree } = env\n const lodK = ctx.pick(1, 0.45, 0.18)\n for (const br of tree.branches) {\n if (br.level < 1) continue\n const n = Math.max(1, Math.round(opts.perBranch * lodK * (br.level === 1 ? 1 : 0.8)))\n for (let k = 0; k < n; k++) {\n const t = lerp(0.45, 1, (k + rng.next() * 0.7) / n)\n const idx = Math.min(br.pts.length - 2, Math.floor(t * (br.pts.length - 1)))\n const u = t * (br.pts.length - 1) - idx\n const p: Vec3 = [lerp(br.pts[idx][0], br.pts[idx + 1][0], u), lerp(br.pts[idx][1], br.pts[idx + 1][1], u), lerp(br.pts[idx][2], br.pts[idx + 1][2], u)]\n const len = opts.toGround ? Math.max(opts.minLen, (p[1] - 0.2 - rng.range(0, 0.9)) * rng.range(0.85, 1)) : rng.range(opts.minLen, opts.maxLen)\n const out = norm([p[0], 0, p[2]])\n const w = opts.width * (ctx.lod === 2 ? 2.2 : 1) * rng.range(0.8, 1.2)\n const g0 = shade(base, 0.78)\n const g1 = mix(base, opts.light, 0.55)\n const reps = ctx.lod === 0 ? 2 : 1\n for (let q = 0; q < reps; q++) {\n const off: Vec3 = [-out[2] * w * q * 0.9, 0, out[0] * w * q * 0.9]\n leaf(ctx.foliage, add(p, off), [out[0] * 0.12, -1, out[2] * 0.12], out, len * rng.range(0.9, 1), w, g0, g1, { rows: ctx.lod === 0 ? 3 : 2, curl: 0.04, fold: 0.2, baseWidth: 0.7, swayBase: 0.35, swayTip: 1, peak: 0.2, round: 1.4 })\n }\n }\n }\n}\n\n/** Foliage of a styled crown; returns the clump list so blossoms / fruit can sit on it. */\nexport function styledCrown(style: CrownStyle, env: StyleEnv): StyleGroup[] {\n const { ctx } = env\n const rng = new Rng((env.vis[0]?.seed ?? 1) ^ 0x51ed27)\n let anchors = buildAnchors(style, env, rng)\n const overgrown = ctx.condition === 'overgrown' ? 1.14 : 1\n // condition / season: drop some clumps (dry, bare), never the first\n anchors = anchors.filter((a, i) => i === 0 || a.tip.keep < env.keep)\n if (ctx.lod === 2 && anchors.length > 7) anchors = anchors.filter((_, i) => i % 2 === 0 || i === 1)\n if (ctx.lod === 1 && anchors.length > 6 && style !== 'sphere') anchors = anchors.filter((_, i) => i % 3 !== 2)\n const groups: StyleGroup[] = []\n const bigSphere = false\n for (const a of anchors) {\n const { base: b0, accent } = env.colorFor(a.tip)\n const base = shade(b0, clamp(a.tone * (0.9 + a.tip.roll * 0.2), 0.7, 1.15))\n const r = a.r * overgrown\n const detail = (ctx.lod === 0 ? (bigSphere ? 2 : 1) : ctx.lod === 1 ? (bigSphere ? 1 : 0) : 0) as 0 | 1 | 2\n const leaves =\n ctx.lod === 0 && !bigSphere && style !== 'willow' && style !== 'umbrella' && style !== 'sparse_high' ? { count: Math.round((4 + r * 2) * (ctx.condition === 'dry' ? 0.5 : 1)), length: r * 0.4, width: r * 0.32 } : undefined\n const o = {\n center: a.p,\n radius: r,\n squash: a.sq,\n detail,\n seed: a.tip.seed,\n base,\n crown: env.tree.crown,\n accent,\n leaves,\n swayK: 0.3,\n noise: bigSphere ? 0.015 : style === 'lumpy' || style === 'sparse_high' ? 0.2 : 0.13,\n flatBottom: style === 'umbrella' || style === 'dome' ? 0.75 : 0.5,\n ao: env.bloomOn && env.spec.bloom?.replacesLeaves ? 0.78 : style === 'dome' ? 0.45 : 0.55,\n }\n if (ctx.lod >= 1 && style !== 'willow') {\n // mid LOD: several small low-subdivision lumps per clump instead of one big faceted icosahedron\n const sr = new Rng(a.tip.seed ^ 0x2545f491)\n const subs = 2\n for (let k = 0; k < subs; k++) {\n const ang = (k / subs) * TAU + sr.range(0, 1)\n const off = r * (ctx.lod === 2 ? 0.42 : 0.5)\n const sub = { ...o, radius: r * (ctx.lod === 2 ? 0.74 : 0.62), seed: a.tip.seed + k * 977, center: [a.p[0] + Math.cos(ang) * off, a.p[1] + r * a.sq * sr.range(0, 0.35), a.p[2] + Math.sin(ang) * off] as Vec3 }\n clump(ctx.foliage, sub)\n }\n } else {\n clump(ctx.foliage, o)\n }\n if (ctx.lod === 0) clumpLeaves(ctx.foliage, o)\n groups.push({ p: a.p, r, sq: a.sq })\n if (style === 'sparse_high' && a.tip.p[0] === 0 && a.tip.p[1] === 0 && ctx.lod < 2) {\n // twig linking a free clump to the trunk\n const tp = env.tree.trunk.pts\n let q = tp[tp.length - 1]\n for (const pt of tp) if (pt[1] >= a.p[1] - r * 1.4) { q = pt; break }\n const mid: Vec3 = [(q[0] + a.p[0]) / 2, (q[1] + a.p[1]) / 2 - r * 0.2 + 0.15, (q[2] + a.p[2]) / 2]\n const end: Vec3 = [a.p[0], a.p[1] - r * a.sq * 0.4, a.p[2]]\n tube(ctx.wood, catmull([q, mid, end], 2), { sides: 4, radii: [0.07, 0.06, 0.05, 0.04, 0.03, 0.02, 0.012].slice(0, 5), color: barkColor(env.bark, 1), sway: (t) => 0.1 + 0.3 * t, end: 'point' })\n }\n }\n if (style === 'willow' && ctx.lod < 3) {\n const base = env.colorFor(env.vis[0] ?? fakeTip(rng)).base\n hangStrips(env, rng, base, { perBranch: 7, minLen: 1.2, maxLen: 9, toGround: true, width: env.R * 0.07, light: [0.78, 0.84, 0.4] })\n } else if (style === 'sparse_high') {\n const base = env.colorFor(env.vis[0] ?? fakeTip(rng)).base\n hangStrips(env, rng, base, { perBranch: 2, minLen: env.H * 0.07, maxLen: env.H * 0.13, toGround: false, width: env.R * 0.06, light: [0.7, 0.78, 0.55] })\n }\n void mul\n return groups\n}\n","import type { BroadleafTreeSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { Rng } from '../rng'\nimport { add, clamp, dist, lerp, mul, norm, TAU } from '../math'\nimport { jitter, mix, rgb, shade } from '../color'\nimport { fitTree, growTree, type Tip } from '../geometry/branches'\nimport { drawBranch } from '../geometry/wood'\nimport { clump, clumpLeaves, mergeAnchors, icoShell, octa } from '../geometry/shell'\nimport { blossom } from '../geometry/flower'\nimport { leaf } from '../geometry/leaf'\nimport { tube } from '../geometry/tube'\nimport { drawTreeWood, splitCrown } from './pieces'\nimport { inSeason, leafAmount, leafTint } from './shared'\nimport { generateDeadTree } from './dead-tree'\nimport { styleSkeleton, styledCrown, willowTree, type StyleGroup } from './tree-styles'\n\nconst DEFAULT_LEAF = [0x4d9a43, 0x5aa84a, 0x428a3e]\n\nexport function generateBroadleafTree(spec: BroadleafTreeSpec, ctx: Ctx): ArchResult {\n const height = spec.height ?? 6\n const trunkRadius = spec.trunkRadius ?? height * 0.04\n const crownRadius = spec.crownRadius ?? height * 0.42\n const shape = spec.crownShape ?? 'round'\n const bark = rgb(spec.barkColor ?? 0x8a6a4c)\n if (ctx.condition === 'dead') {\n return generateDeadTree({ archetype: 'dead_tree', height, trunkRadius, crownRadius, barkColor: spec.barkColor, branchLevels: spec.branchLevels }, ctx, true)\n }\n const style = spec.crownStyle\n const sk = style ? styleSkeleton(style) : undefined\n const trunkFraction = spec.trunkFraction ?? sk?.trunkFraction ?? (shape === 'spreading' ? 0.36 : shape === 'columnar' ? 0.22 : shape === 'weeping' ? 0.3 : 0.4)\n const levels = spec.branchLevels ?? sk?.levels ?? 3\n const rng = ctx.rng\n const growFn = style === 'willow' ? willowTree : growTree\n const tree = growFn(rng, {\n height,\n trunkRadius,\n crownRadius,\n shape: sk?.shape ?? shape,\n levels,\n trunkFraction,\n gnarl: sk?.gnarl ?? (spec.leafShape === 'sparse' ? 0.9 : 0.55),\n primary: sk?.primary ?? (shape === 'columnar' ? 5 : shape === 'spreading' ? 5 : 4),\n lean: sk?.lean ?? (spec.leafShape === 'sparse' ? 0.08 : 0.03),\n })\n const deciduous = spec.deciduous ?? false\n const bloom = spec.bloom\n const bloomOn = !!bloom && inSeason(ctx, bloom.seasons)\n const replaces = bloomOn && !!bloom?.replacesLeaves\n const palette = (spec.leafColor ?? DEFAULT_LEAF).map(rgb)\n const amount = leafAmount(ctx, deciduous && !replaces)\n const baseKeep = spec.density ?? 1\n\n\n // visible tips\n const keepThreshold = clamp(amount * baseKeep, 0, 1.3)\n const visible: Tip[] = tree.tips.filter((t, i) => i === 0 || t.keep < keepThreshold || t.level === 0)\n const sparse = spec.leafShape === 'sparse'\n const nT = Math.max(1, visible.length)\n const rK = clamp(2.3 / Math.sqrt(nT), 0.36, 0.8) * (sparse ? 0.62 : 1) * (spec.clipped ? 1.1 : 1)\n const grow = ctx.condition === 'overgrown' ? 1.14 : 1\n const reachK = shape === 'spreading' ? 1.08 : shape === 'columnar' ? 0.62 : 1\n const styleReach = style === 'dome' || style === 'umbrella' ? 0.95 : style === 'sphere' ? 0.5 : style === 'sparse_high' ? 0.85 : style === 'willow' ? 1 : 0.9\n const styleClumpR = style ? crownRadius * 0.28 : crownRadius * rK * grow\n if (style !== 'willow') fitTree(tree, height, style ? crownRadius * styleReach : crownRadius * reachK, styleClumpR, height * trunkFraction * 0.95)\n if (style && style !== 'sparse_high' && style !== 'willow') {\n // the leader must not poke out of the crown\n const yMax = style === 'sphere' ? height * 0.62 : height * 0.8\n const tpts = tree.trunk.pts\n let keepN = tpts.findIndex((q) => q[1] > yMax)\n if (keepN < 0) keepN = tpts.length\n keepN = Math.max(3, keepN)\n tree.trunk = { ...tree.trunk, pts: tpts.slice(0, keepN), radii: tree.trunk.radii.slice(0, keepN) }\n }\n // wood\n const anchors = drawTreeWood(ctx, tree, (br, i) => drawBranch(ctx.wood, br, bark, ctx.lod, i < 0 ? 0 : i * 0.37))\n ctx.piece('crown', 'crown', 'trunk')\n const colorFor = (tip: Tip): { base: Vec3; accent?: { color: Vec3; amount: number } } => {\n const pc = palette[Math.floor(tip.roll * palette.length) % palette.length]\n let base = leafTint(ctx, pc, deciduous, tip.roll)\n if (bloomOn && bloom) {\n const bc = rgb(bloom.colors[Math.floor(((tip.seed >>> 8) % 1000) / 1000 * bloom.colors.length)])\n const density = bloom.density ?? (replaces ? 1 : 0.85)\n if (replaces && tip.roll > density) return { base }\n if (replaces) base = mix(bc, shade(bc, 0.8), tip.roll * 0.5)\n else return { base, accent: { color: bc, amount: density * 0.8 } }\n }\n return { base }\n }\n\n let groups: { p: Vec3; r: number; sq?: number }[]\n const squash = shape === 'spreading' ? 0.55 : shape === 'weeping' ? 1.35 : shape === 'columnar' ? 1.05 : 0.78\n if (style) {\n groups = styledCrown(style, { ctx, spec, tree, vis: visible, H: height, R: crownRadius, clearY: height * trunkFraction * 0.95, colorFor, grow, bark, keep: keepThreshold, bloomOn }) as StyleGroup[]\n } else {\n const anchors = visible.map((t) => {\n const r = crownRadius * rK * t.size * grow\n const lift = shape === 'weeping' ? -0.1 : 0.35\n const center = add(add(t.p, mul(t.dir, r * 0.25)), [0, r * lift, 0])\n return { p: center, r, tip: t }\n })\n // inner fill clumps halfway along the main limbs so the crown reads as one mass\n if (!sparse) {\n for (let bi = 0; bi < tree.branches.length; bi++) {\n const br = tree.branches[bi]\n if (br.level !== 1) continue\n const r2 = new Rng(Math.floor(br.radii[0] * 1e6) ^ (bi * 7919))\n const mid = br.pts[Math.floor(br.pts.length * 0.55)]\n const roll = r2.next()\n if (roll > keepThreshold) continue\n const r = crownRadius * rK * 0.95 * grow\n anchors.push({ p: add(mid, [0, r * 0.35, 0]), r, tip: { p: mid, dir: [0, 1, 0], size: 1, level: 1, seed: r2.seed(), keep: roll, roll: r2.next() } })\n }\n }\n\n const crown = tree.crown\n const kGroups = ctx.pick(clamp(Math.round(anchors.length * 0.26), 5, 7), clamp(Math.round(anchors.length * 0.26), 5, 7), 6)\n const lg = (sparse && ctx.lod < 2) || anchors.length <= kGroups ? anchors.map((an) => ({ p: an.p, r: an.r, members: [an] })) : mergeAnchors(anchors, kGroups)\n groups = lg\n for (const g of lg) {\n const t0 = g.members[0].tip\n const { base, accent } = colorFor(t0)\n const rMain = ctx.lod === 2 ? g.r : g.members.length > 1 ? g.r * 0.95 : g.r\n const leaves = ctx.lod === 0 && !sparse ? { count: Math.round((6 + rMain * 3) * (ctx.condition === 'dry' ? 0.5 : 1)), length: rMain * 0.34, width: rMain * 0.28 } : undefined\n const o = {\n center: g.p,\n radius: rMain,\n squash,\n detail: (ctx.lod === 0 ? (sparse ? 1 : 2) : ctx.lod === 1 ? 1 : 0) as 0 | 1 | 2,\n seed: t0.seed,\n base,\n crown,\n accent,\n leaves,\n swayK: 0.3,\n noise: ctx.lod === 0 ? (sparse ? 0.3 : 0.17) : 0.14,\n flatBottom: shape === 'weeping' ? 0.1 : 0.5,\n ao: 0.5,\n }\n clump(ctx.foliage, o)\n if (ctx.lod === 0) clumpLeaves(ctx.foliage, o)\n if (ctx.lod < 2 && g.members.length > 1) {\n // satellites on the members that are farthest from the group center: lumpy, layered silhouette\n const sorted = g.members.slice().sort((m1, m2) => dist(m2.p, g.p) - dist(m1.p, g.p)).slice(0, ctx.condition === 'dry' ? 1 : 2)\n for (const m of sorted) {\n const so = { ...o, center: m.p, radius: m.r * 0.78, seed: m.tip.seed, detail: (ctx.lod === 0 ? 1 : 0) as 0 | 1, leaves: ctx.lod === 0 && !sparse ? { count: 3, length: m.r * 0.3, width: m.r * 0.25 } : undefined }\n clump(ctx.foliage, so)\n if (ctx.lod === 0) clumpLeaves(ctx.foliage, so)\n }\n }\n if (ctx.condition === 'overgrown' && ctx.lod < 2) {\n const r2 = new Rng(t0.seed ^ 0x1234)\n clump(ctx.foliage, { ...o, center: add(g.p, [r2.range(-0.4, 0.4) * g.r, g.r * r2.range(0.2, 0.5), r2.range(-0.4, 0.4) * g.r]), radius: g.r * 0.7, seed: t0.seed ^ 0x77, leaves: undefined, detail: 1 })\n }\n if ((shape === 'weeping' || sparse) && ctx.lod < 2) {\n const r2 = new Rng(t0.seed ^ 0x5151)\n const n = ctx.lod === 0 ? (sparse ? 7 : 10) : sparse ? 3 : 4\n for (let i = 0; i < n; i++) {\n const ang = r2.range(0, TAU)\n const rr = g.r * r2.range(0.3, 0.95)\n const top: Vec3 = [g.p[0] + Math.cos(ang) * rr, g.p[1] - g.r * 0.2, g.p[2] + Math.sin(ang) * rr]\n const hang = g.r * r2.range(1.4, 2.4) * (sparse ? 1.3 : 1)\n const g0 = shade(base, 0.75)\n const g1 = mix(base, [0.78, 0.82, 0.4], 0.35)\n leaf(ctx.foliage, top, [0.1 * Math.cos(ang), -1, 0.1 * Math.sin(ang)], [Math.cos(ang), 0.2, Math.sin(ang)], hang, g.r * 0.3, g0, g1, { rows: 2, curl: 0.05, fold: 0.3, swayBase: 0.4, swayTip: 1, peak: 0.25 })\n }\n }\n }\n\n }\n\n // blossoms scattered on the crown surface (LOD0 only)\n if (bloomOn && bloom && ctx.lod === 0) {\n const r2 = new Rng(Math.floor(height * 1000) + 77)\n for (const a of groups) {\n const n = replaces ? 6 : 5\n for (let i = 0; i < n; i++) {\n const ang = r2.range(0, TAU)\n const y = r2.range(0.1, 1)\n const rr = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(ang) * rr, y, Math.sin(ang) * rr]\n const p: Vec3 = [a.p[0] + d[0] * a.r * 1.0, a.p[1] + d[1] * a.r * (a.sq ?? squash) * 1.0, a.p[2] + d[2] * a.r * 1.0]\n const bc = rgb(r2.pick(bloom.colors))\n blossom(ctx.flowers, p, norm(d), a.r * 0.2, shade(bc, 1.05), jitter(bc, r2, 0.01, 0.05), 0.5, 4, r2.range(0, TAU))\n }\n }\n }\n\n splitCrown(ctx, anchors)\n\n // fruit\n if (spec.fruit && ctx.condition !== 'dry') {\n const f = spec.fruit\n const count = Math.round(f.count * ctx.pick(1, 0.3, 0))\n const r2 = new Rng(Math.floor(height * 733) + 5)\n const fr = f.radius ?? 0.07\n if (f.onTrunk) {\n const mains = tree.branches.filter((b2) => b2.level === 1)\n for (let i = 0; i < count; i++) {\n // ~45% on the trunk, the rest on the main limbs\n const onBranch = mains.length > 0 && r2.next() > 0.45\n const br = onBranch ? mains[r2.int(0, mains.length - 1)] : tree.trunk\n const tpts = br.pts\n const u = onBranch ? r2.range(0.05, 0.75) : r2.range(0.03, Math.min(0.7, (trunkFraction * 1.05) / 0.93))\n const idx = Math.min(tpts.length - 2, Math.floor(u * (tpts.length - 1)))\n const k = u * (tpts.length - 1) - idx\n const pos: Vec3 = [lerp(tpts[idx][0], tpts[idx + 1][0], k), lerp(tpts[idx][1], tpts[idx + 1][1], k), lerp(tpts[idx][2], tpts[idx + 1][2], k)]\n const rad = lerp(br.radii[idx], br.radii[idx + 1], k)\n const ang = r2.range(0, TAU)\n const c = rgb(r2.pick(f.colors))\n const out: Vec3 = [Math.cos(ang), r2.range(-0.3, 0.5), Math.sin(ang)]\n const center = add(pos, mul(norm(out), rad + fr * 0.4))\n const rr = fr * r2.range(0.8, 1.2)\n ctx.fruitItem(() => octa(ctx.fruit, center, [rr, rr, rr], (h) => shade(c, 0.75 + h * 0.6), 0))\n }\n } else {\n for (let i = 0; i < count; i++) {\n const a = groups[i % groups.length]\n const ang = r2.range(0, TAU)\n const rr = a.r * r2.range(0.45, 0.9)\n const depth = Math.sqrt(Math.max(0, 1 - (rr / a.r) ** 2)) * 0.8\n const top: Vec3 = [a.p[0] + Math.cos(ang) * rr, a.p[1] - a.r * (a.sq ?? squash) * depth * 0.9, a.p[2] + Math.sin(ang) * rr]\n const c = rgb(r2.pick(f.colors))\n const s = fr * r2.range(0.9, 1.15)\n const drop = s * 3.2\n const centre: Vec3 = [top[0], top[1] - drop - s * 0.6, top[2]]\n ctx.fruitItem(() => {\n tube(ctx.wood, [top, [top[0], top[1] - drop * 0.8, top[2]]], { sides: 3, radii: [0.008, 0.008], color: () => [0.3, 0.4, 0.2], sway: () => 0.5, end: 'none' })\n if (s < 0.06) octa(ctx.fruit, centre, [s * 0.85, s * 1.2, s * 0.85], (h) => shade(c, 0.7 + h * 0.45), 0.4)\n else icoShell(ctx.fruit, { center: centre, radii: [s * 0.85, s * 1.2, s * 0.85], detail: 0, rng: r2, noise: 0.04, color: (v) => shade(c, 0.7 + v.h * 0.45), sway: () => 0.4 })\n })\n }\n }\n }\n\n return {\n collider: { kind: 'cylinder', radius: trunkRadius * 1.1, height: height * Math.max(0.35, trunkFraction) },\n bendable: false,\n }\n}\n","import type { FlowerPlantSpec, FlowerType, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { add, catmull, dirFromAngles, mul, norm, sampleLine, TAU, lerp } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen } from '../color'\nimport { tube } from '../geometry/tube'\nimport { leaf } from '../geometry/leaf'\nimport { blossom, flowerHead, type FlowerKind } from '../geometry/flower'\nimport { clump } from '../geometry/shell'\n\ninterface TypeDef {\n height: number\n size: number\n stems: number\n colors: number[]\n center: number\n kind: FlowerKind\n leaf: { style: 'lance' | 'heart' | 'strap' | 'compound' | 'broad'; len: number; width: number; along: number; basal: number }\n woody?: boolean\n tilt?: number\n /** upright, nearly vertical stems */\n straight?: boolean\n /** flower heads per stem (default 1) */\n heads?: number\n bushy?: boolean\n hmin?: number\n /** leafy mound the flowers sit on instead of free stems (radius / height as multiples of the plant height) */\n mound?: { r: number; h: number; heads: number; leaf: number }\n}\n\nconst TYPES: Record<FlowerType, TypeDef> = {\n daisy: { height: 0.38, size: 0.05, stems: 6, colors: [0xfbfaf2], center: 0xf0b820, kind: 'daisy', leaf: { style: 'lance', len: 0.16, width: 0.05, along: 2, basal: 4 } },\n sunflower: { height: 1.7, size: 0.2, stems: 3, colors: [0xf4c21a], center: 0x4a2c14, kind: 'sunflower', leaf: { style: 'heart', len: 0.3, width: 0.24, along: 5, basal: 3 }, tilt: 0.5 },\n rose: { height: 0.85, size: 0.062, stems: 7, colors: [0xd0243a], center: 0xe8c040, kind: 'rose', leaf: { style: 'compound', len: 0.12, width: 0.07, along: 4, basal: 2 }, woody: true },\n tulip: { height: 0.42, size: 0.042, stems: 7, colors: [0xe03a52], center: 0x303030, kind: 'tulip', leaf: { style: 'strap', len: 0.3, width: 0.085, along: 0, basal: 3 }, straight: true },\n pompom: { height: 0.34, size: 0.019, stems: 8, colors: [0xf08a1a, 0xf5b020], center: 0x305020, kind: 'pompom', leaf: { style: 'lance', len: 0.11, width: 0.04, along: 5, basal: 3 }, bushy: true, heads: 2 },\n hydrangea: { height: 0.95, size: 0.07, stems: 5, mound: { r: 0.46, h: 0.78, heads: 5, leaf: 0.15 }, colors: [0x5a84d8, 0x8aa8e8, 0x9a90e0], center: 0x405080, kind: 'florets', leaf: { style: 'broad', len: 0.26, width: 0.19, along: 9, basal: 4 }, bushy: true },\n hibiscus: { height: 0.9, size: 0.1, stems: 3, colors: [0xe02a3a], center: 0xe8c040, kind: 'hibiscus', leaf: { style: 'heart', len: 0.18, width: 0.12, along: 4, basal: 2 }, woody: true },\n cluster: { height: 0.8, size: 0.15, stems: 4, colors: [0x5a84d8, 0x8aa8e8], center: 0x405080, kind: 'cluster', leaf: { style: 'broad', len: 0.26, width: 0.2, along: 4, basal: 2 } },\n lily: { height: 0.85, size: 0.09, stems: 3, colors: [0xfffaf0], center: 0xe08a20, kind: 'lily', leaf: { style: 'lance', len: 0.22, width: 0.04, along: 5, basal: 2 } },\n bird_of_paradise: { height: 1.3, size: 0.14, stems: 3, colors: [0xf08a20, 0x4a5ad0], center: 0x303030, kind: 'bird_of_paradise', leaf: { style: 'broad', len: 0.55, width: 0.2, along: 0, basal: 6 } },\n}\n\nexport function generateFlowerPlant(spec: FlowerPlantSpec, ctx: Ctx): ArchResult {\n const type = spec.flowerType ?? 'daisy'\n const def = TYPES[type]\n const rng = ctx.rng\n const over = ctx.condition === 'overgrown'\n const height = (spec.height ?? def.height) * (over ? 1.15 : 1)\n const stemCount = Math.max(ctx.lod === 2 ? 2 : 1, Math.round((spec.stemCount ?? def.stems) * (over ? 1.4 : 1) * (ctx.lod === 2 ? 0.45 : 1)))\n const colors = (spec.petalColors ?? def.colors).map(rgb)\n const heart = rgb(spec.centerColor ?? def.center)\n const leafBase = tintGreen(rgb(spec.leafColor ?? 0x3f8a3a), ctx.condition)\n const stemBase = tintGreen(rgb(spec.leafColor ? spec.leafColor : 0x4a8a3a), ctx.condition)\n const size = (spec.flowerSize ?? def.size) * 1.25\n const spreading = !!spec.spreading\n const mnd = spreading ? { r: 1.15, h: 0.62, heads: 0, leaf: 0.075 } : def.mound\n const isMound = !!mnd\n const bushy = !!spec.bushy || def.woody === true || def.bushy === true\n const dead = ctx.condition === 'dead'\n const dry = ctx.condition === 'dry'\n const bloomShare = dead ? 0 : (ctx.season === 'winter' ? 0.35 : 1) * (dry ? 0.5 : 1)\n const stemBuilder = def.woody ? ctx.wood : ctx.foliage\n const stemColor: Vec3 = def.woody ? mix(rgb(0x5a6a30), tintGreen(rgb(0x6b5030), ctx.condition), 0.4) : shade(stemBase, 0.9)\n const sides = ctx.pick(4, 3, 3)\n const leafRows = ctx.pick(2, 2, 2)\n const swayHead = 0.85\n\n const stemsData: { base: Vec3; tip: Vec3; path: Vec3[]; ang: number }[] = []\n for (let i = 0; i < stemCount; i++) {\n const ang = (i / stemCount) * TAU + rng.range(-0.4, 0.4)\n const r0 = spreading ? rng.range(0.02, 0.06) : rng.range(0.0, 0.09) * Math.sqrt(height)\n const base: Vec3 = [Math.cos(ang) * r0, 0, Math.sin(ang) * r0]\n const h = height * (def.hmin ? rng.range(def.hmin, 1.0) : rng.range(0.72, 1.08))\n const lean = spreading ? height * 1.1 * rng.range(0.7, 1.25) : def.straight ? h * rng.range(0.0, 0.05) : h * rng.range(0.08, bushy ? 0.4 : 0.22)\n const la = ang + rng.range(-0.5, 0.5)\n let tip: Vec3 = spreading ? [base[0] + Math.cos(la) * lean, h * 0.5, base[2] + Math.sin(la) * lean] : [base[0] + Math.cos(la) * lean, h, base[2] + Math.sin(la) * lean]\n if (dry) tip = [tip[0] * 1.4, tip[1] * 0.8, tip[2] * 1.4]\n if (dead) tip = [tip[0] * 2.2, tip[1] * 0.45, tip[2] * 2.2]\n const mid: Vec3 = spreading ? [lerp(base[0], tip[0], 0.5), h * 1.0, lerp(base[2], tip[2], 0.5)] : [lerp(base[0], tip[0], 0.3), tip[1] * 0.55, lerp(base[2], tip[2], 0.3)]\n const ctrl: Vec3[] = [base, mid, tip]\n const path = ctx.lod === 2 ? [base, tip] : catmull(ctrl, ctx.pick(3, 2, 1))\n stemsData.push({ base, tip, path, ang })\n }\n\n const moundR = height * (mnd?.r ?? 1)\n const moundH = height * (mnd?.h ?? 1)\n const mLeaf = mnd?.leaf ?? 0.08\n const mLeafC = dead ? mix(leafBase, [0.42, 0.32, 0.2], 0.8) : dry ? mix(leafBase, [0.55, 0.48, 0.22], 0.5) : leafBase\n const blobs: { c: Vec3; r: number; sq: number }[] = []\n if (isMound) {\n if (spreading) blobs.push({ c: [0, moundH * 0.42, 0], r: moundR, sq: (moundH / moundR) * 0.95 })\n else {\n // leafy bush: a ring of rounded leaf clumps around a taller one\n const nb = ctx.pick(6, 5, 4)\n for (let i = 0; i < nb; i++) {\n const a = i * 2.2 + 0.4\n const ring = i === 0 ? 0 : moundR * 0.5\n blobs.push({ c: [Math.cos(a) * ring, moundH * (i === 0 ? 0.55 : 0.28 + 0.07 * (i % 3)), Math.sin(a) * ring], r: moundR * (i === 0 ? 0.62 : 0.52), sq: 0.95 })\n }\n }\n for (const bl of blobs) clump(ctx.foliage, { center: bl.c, radius: bl.r, squash: bl.sq, detail: ctx.pick(1, 1, 0) as 0 | 1, seed: rng.seed(), base: dead ? mix(leafBase, [0.42, 0.32, 0.2], 0.7) : dry ? mix(leafBase, [0.55, 0.48, 0.22], 0.45) : mix(leafBase, [0.25, 0.55, 0.22], 0.25), swayK: 0.3, noise: 0.16, flatBottom: 0.8, ao: 0.5 })\n const nl = ctx.pick(spreading ? 60 : 66, spreading ? 26 : 30, 0)\n for (let i = 0; i < nl; i++) {\n const bl = blobs[i % blobs.length]\n const a = rng.range(0, TAU)\n const y = rng.range(0.05, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [bl.c[0] + d[0] * bl.r * 0.92, bl.c[1] + d[1] * bl.r * bl.sq * 0.92, bl.c[2] + d[2] * bl.r * 0.92]\n const out = norm([d[0], d[1] * 0.8 + 0.3, d[2]])\n leaf(ctx.foliage, p, norm([-d[2] * 0.3 + out[0], out[1] * 0.4 + 0.2, d[0] * 0.3 + out[2]]), out, mLeaf, mLeaf * 0.68, shade(mLeafC, 0.7), mix(mLeafC, [0.6, 0.8, 0.3], dead ? 0 : 0.2), { rows: 2, curl: 0.2, fold: 0.4, swayBase: 0.2, swayTip: 0.6, peak: 0.45, round: 0.7 })\n }\n }\n const radius = isMound ? 0.0001 : Math.max(0.004, height * 0.014) * (def.woody ? 1.2 : 1)\n for (const st of isMound ? [] : stemsData) {\n const n = st.path.length\n tube(stemBuilder, st.path, {\n sides,\n radii: st.path.map((_, k) => radius * (1 - 0.35 * (k / (n - 1)))),\n color: (t) => mix(shade(stemColor, 0.8), stemColor, t),\n sway: (t) => 0.15 + 0.8 * t * t,\n end: 'none',\n smooth: true,\n })\n }\n\n const leafC0 = shade(leafBase, 0.68)\n const leafC1 = mix(leafBase, [0.55, 0.75, 0.25], 0.25)\n const L = def.leaf\n const lscale = height / def.height\n const makeLeaf = (pos: Vec3, azimuth: number, elev: number, lenK: number): void => {\n let len = L.len * lscale * lenK * (over ? 1.2 : 1)\n let wid = L.width * lscale * lenK\n if (spreading) {\n len = 0.07 * lenK * (over ? 1.2 : 1)\n wid = 0.045 * lenK\n }\n const dir = dirFromAngles(azimuth, elev)\n const c0 = jitter(leafC0, rng, 0.01, 0.06, 0.04)\n const c1 = jitter(leafC1, rng, 0.01, 0.06, 0.04)\n switch (L.style) {\n case 'strap':\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len * 1.2, wid, c0, c1, { rows: ctx.pick(3, 2, 2), curl: 0.35, fold: 0.5, swayBase: 0.2, swayTip: 0.9, peak: 0.3, round: 1.4 })\n break\n case 'heart':\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len, wid, c0, c1, { rows: leafRows, curl: 0.3, fold: 0.4, swayBase: 0.3, swayTip: 0.9, peak: 0.3, round: 0.55, baseWidth: 0.25 })\n break\n case 'broad':\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len, wid, c0, c1, { rows: ctx.pick(3, 2, 2), curl: 0.25, fold: 0.5, swayBase: 0.3, swayTip: 0.9, peak: 0.45, round: 0.7 })\n break\n case 'compound': {\n const side = ctx.lod === 2 ? 0 : 2\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len, wid, c0, c1, { rows: 2, curl: 0.2, fold: 0.4, swayBase: 0.3, swayTip: 0.9, peak: 0.45 })\n for (let k = 0; k < side; k++) {\n const d2 = dirFromAngles(azimuth + (k ? 0.7 : -0.7), elev * 0.8)\n leaf(ctx.foliage, add(pos, mul(dir, len * 0.4)), d2, [0, 1, 0], len * 0.8, wid * 0.9, c0, c1, { rows: 2, curl: 0.2, fold: 0.4, swayBase: 0.3, swayTip: 0.9, peak: 0.45 })\n }\n break\n }\n default:\n leaf(ctx.foliage, pos, dir, [0, 1, 0], len, wid, c0, c1, { rows: leafRows, curl: 0.25, fold: 0.5, swayBase: 0.25, swayTip: 0.9, peak: 0.4 })\n }\n }\n // basal leaves\n const basal = Math.round(L.basal * (bushy ? 1.5 : 1) * ctx.pick(1, 0.6, 0.35) * (over ? 1.4 : 1) * (dead ? 0.4 : 1))\n const basalN = isMound ? 0 : basal * Math.max(1, Math.round(stemCount / 3))\n for (let i = 0; i < basalN; i++) {\n const a = rng.range(0, TAU)\n const rr = spreading ? rng.range(0.02, 0.5) : rng.range(0, 0.07)\n const pos: Vec3 = [Math.cos(a) * rr, 0.01, Math.sin(a) * rr]\n makeLeaf(pos, a, spreading ? rng.range(0.15, 0.5) : rng.range(0.5, 1.0), rng.range(0.7, 1.2))\n }\n // leaves along the stems\n if (L.along > 0 && !dead && !isMound) {\n const per = Math.max(1, Math.round(L.along * ctx.pick(1, 0.5, 0)))\n for (const st of stemsData) {\n for (let k = 0; k < per; k++) {\n const t = lerp(0.15, 0.75, (k + rng.range(0, 0.6)) / per)\n const s = sampleLine(st.path, t)\n makeLeaf(s.p, st.ang + k * 2.4 + rng.range(-0.4, 0.4), rng.range(0.2, 0.9), lerp(1.05, 0.65, t) * rng.range(0.85, 1.15))\n }\n }\n }\n\n // flower heads\n const multi = colors.length > 1 && type !== 'cluster' && type !== 'bird_of_paradise'\n for (let i = 0; i < stemsData.length; i++) {\n const st = stemsData[i]\n if (rng.next() > bloomShare) {\n rng.next()\n continue\n }\n const tipDir = norm([st.tip[0] - st.path[st.path.length - 2][0], st.tip[1] - st.path[st.path.length - 2][1], st.tip[2] - st.path[st.path.length - 2][2]])\n let axis = tipDir\n if (def.tilt) axis = norm(add(tipDir, [Math.cos(st.ang) * def.tilt, -0.1, Math.sin(st.ang) * def.tilt]))\n if (type === 'tulip' || type === 'rose' || type === 'lily') axis = norm(add(axis, [0, 0.8, 0]))\n let hc = multi ? [colors[i % colors.length]] : colors\n if (dry) hc = hc.map((c) => mix(c, [0.55, 0.42, 0.25], 0.5))\n const sz = size * rng.range(0.85, 1.15)\n if (def.mound) {\n // heads sitting on the leafy mound\n if (i >= def.mound.heads) continue\n const a = i * 2.4 + rng.range(-0.3, 0.3)\n const bl = blobs[i % blobs.length]\n const y = i === 0 ? 1 : rng.range(0.6, 0.95)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [bl.c[0] + d[0] * bl.r * 0.9, bl.c[1] + d[1] * bl.r * bl.sq * 0.95, bl.c[2] + d[2] * bl.r * 0.9]\n flowerHead(ctx.flowers, { kind: def.kind, center: p, axis: norm([d[0] * 0.5, 1, d[2] * 0.5]), size: sz * rng.range(0.9, 1.1), colors: hc, centerColor: heart, rng: rng.fork(i), lod: ctx.lod, sway: swayHead })\n } else if (spreading) {\n // five-petal flowers sitting on top of the mound\n const nb = ctx.pick(2, 1, 1) + (i % 3 === 0 ? 1 : 0)\n for (let k = 0; k < nb; k++) {\n const a = rng.range(0, TAU)\n const y = rng.range(0.35, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [d[0] * moundR * 0.9, moundH * 0.42 + d[1] * moundH * 0.9, d[2] * moundR * 0.9]\n const nrm = norm([d[0] * 0.5, 0.9 + d[1] * 0.3, d[2] * 0.5])\n blossom(ctx.flowers, add(p, mul(nrm, 0.012)), nrm, sz * rng.range(0.85, 1.1), hc[0], heart, 0.7, ctx.pick(5, 5, 4), rng.range(0, TAU))\n }\n } else if (def.heads && def.heads > 1) {\n const nh = Math.max(1, Math.round(def.heads * ctx.pick(1, 0.7, 0.4)))\n for (let k = 0; k < nh; k++) {\n const s = sampleLine(st.path, k === 0 ? 1 : rng.range(0.55, 0.92))\n const ax = norm([Math.cos(st.ang + k) * 0.5 * (k ? 1 : 0.3), 1, Math.sin(st.ang + k) * 0.5 * (k ? 1 : 0.3)])\n flowerHead(ctx.flowers, { kind: def.kind, center: s.p, axis: ax, size: sz * (k === 0 ? 1 : 0.85), colors: hc, centerColor: heart, rng: rng.fork(i * 7 + k), lod: k === 0 ? ctx.lod : (Math.max(ctx.lod, 1) as 0 | 1 | 2), sway: swayHead })\n }\n } else {\n flowerHead(ctx.flowers, { kind: def.kind, center: add(st.tip, mul(axis, def.kind === 'rose' ? 0 : 0.0)), axis, size: sz, colors: hc, centerColor: heart, rng: rng.fork(i), lod: ctx.lod, sway: swayHead })\n }\n }\n\n return { collider: null, bendable: true }\n}\n\n","import type { Vec3 } from '../types'\nimport { add, mul } from '../math'\nimport { mix } from '../color'\nimport type { MeshBuilder } from './builder'\n\nexport interface BladeOptions {\n /** segments (tris = 2 * segs - 1) */\n segs: number\n /** horizontal lean 0..1.2 (fraction of height the tip is displaced) */\n lean: number\n /** curvature exponent of the lean (higher = straighter at the base) */\n bend?: number\n swayMax: number\n /** twist of the ribbon around the blade axis in radians */\n twist?: number\n}\n\n/** Curved tapered grass blade (a ribbon facing outward, not crossed planes). `az` is the direction the blade leans toward. */\nexport function blade(b: MeshBuilder, base: Vec3, az: number, height: number, width: number, c0: Vec3, c1: Vec3, o: BladeOptions): Vec3 {\n const dx = Math.cos(az)\n const dz = Math.sin(az)\n const bend = o.bend ?? 1.7\n const tw = o.twist ?? 0\n const side: Vec3 = [-dz * Math.cos(tw), Math.sin(tw), dx * Math.cos(tw)]\n const pts: Vec3[] = []\n for (let i = 0; i <= o.segs; i++) {\n const t = i / o.segs\n const h = height * (1 - 0.18 * t * t)\n const off = o.lean * height * Math.pow(t, bend)\n pts.push([base[0] + dx * off, base[1] + h * t, base[2] + dz * off])\n }\n const nrm: Vec3 = [dx, 0.2, dz]\n for (let i = 0; i < o.segs; i++) {\n const t0 = i / o.segs\n const t1 = (i + 1) / o.segs\n const w0 = width * 0.5 * (1 - Math.pow(t0, 1.3) * 0.9)\n const w1 = width * 0.5 * (1 - Math.pow(t1, 1.3) * 0.9) * (i + 1 === o.segs ? 0 : 1)\n const a = add(pts[i], mul(side, -w0))\n const bb = add(pts[i], mul(side, w0))\n const cA = mix(c0, c1, t0)\n const cB = mix(c0, c1, t1)\n const s0 = o.swayMax * Math.pow(t0, 1.4)\n const s1 = o.swayMax * Math.pow(t1, 1.4)\n if (i + 1 === o.segs) {\n b.flatTri(a, bb, pts[i + 1], cA, cA, cB, s0, s0, s1, nrm)\n } else {\n const c = add(pts[i + 1], mul(side, w1))\n const d = add(pts[i + 1], mul(side, -w1))\n b.flatQuad(a, bb, c, d, cA, cA, cB, cB, s0, s0, s1, s1, nrm)\n }\n }\n return pts[pts.length - 1]\n}\n","import type { GrassTuftSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, mul, dirFromAngles } from '../math'\nimport { jitter, rgb, shade, tintGreen, mix, lighten } from '../color'\nimport { blade } from '../geometry/blade'\nimport { tube } from '../geometry/tube'\nimport { icoShell } from '../geometry/shell'\n\nexport function generateGrassTuft(spec: GrassTuftSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const over = ctx.condition === 'overgrown'\n const count = Math.round((spec.count ?? 34) * (spec.seedHeads ? 0.75 : 1) * (spec.umbrellaHeads ? 0.2 : 1) * (over ? 1.4 : 1) * ctx.pick(1, 0.55, 0.22))\n const height = (spec.height ?? 0.35) * (over ? 1.3 : 1)\n const bladeH = spec.umbrellaHeads ? height * 0.35 : height\n const radius = spec.radius ?? height * 0.45\n let base = rgb(spec.color ?? 0x6aa646)\n base = tintGreen(base, ctx.condition)\n const dry = ctx.condition === 'dry' || ctx.condition === 'dead'\n const c0 = shade(base, 0.5)\n const c1 = mix(lighten(base, 0.8), [0.85, 0.85, 0.45], dry ? 0.2 : 0.18)\n const segs = ctx.pick(3, 2, 1)\n const wid = Math.max(0.018, height * ctx.pick(0.13, 0.16, 0.2))\n for (let i = 0; i < count; i++) {\n const a = rng.range(0, TAU)\n const d0 = rng.range(0, radius * 0.35)\n const p: Vec3 = [Math.cos(a) * d0, 0, Math.sin(a) * d0]\n const h = bladeH * rng.range(0.55, 1.15) * (1 - d0 / (radius * 1.8))\n // colour variation: some blades yellower, some darker\n const v = rng.next()\n const tone = v < 0.2 ? mix(c1, [0.78, 0.78, 0.32], 0.45) : v > 0.8 ? shade(c1, 0.8) : c1\n const col0 = jitter(v > 0.8 ? shade(c0, 0.85) : c0, rng, 0.012, 0.12, 0.06)\n const col1 = jitter(tone, rng, 0.02, 0.12, 0.07)\n blade(ctx.foliage, p, a + rng.range(-0.3, 0.3), h, wid * rng.range(0.8, 1.35), col0, col1, { segs, lean: rng.range(0.22, 0.7), swayMax: 1, twist: rng.range(-0.4, 0.4) })\n }\n if (spec.umbrellaHeads) {\n // papyrus: bare triangular stems, each topped by an umbrella of thin arching rays\n const ns = Math.max(3, Math.round((spec.count ?? 18) * 0.36 * ctx.pick(1, 0.6, 0.35)))\n const ray = ctx.pick(11, 7, 4)\n const gc = shade(base, 0.9)\n for (let i = 0; i < ns; i++) {\n const a = rng.range(0, TAU)\n const d0 = rng.range(0, radius * 0.6)\n const b0: Vec3 = [Math.cos(a) * d0, 0, Math.sin(a) * d0]\n const h = height * rng.range(0.85, 1.2)\n const la = rng.range(0, TAU)\n const lean = h * rng.range(0.03, 0.12) * (1 + d0 / radius)\n const top: Vec3 = [b0[0] + Math.cos(la) * lean, h, b0[2] + Math.sin(la) * lean]\n const mid: Vec3 = [b0[0] + Math.cos(la) * lean * 0.3, h * 0.5, b0[2] + Math.sin(la) * lean * 0.3]\n tube(ctx.foliage, [b0, mid, top], { sides: 3, radii: [height * 0.011, height * 0.009, height * 0.007], color: (t) => mix(shade(gc, 0.75), lighten(gc, 0.5), t), sway: (t) => 0.3 + 0.7 * t * t, end: 'none' })\n for (let k = 0; k < ray; k++) {\n const ra = (k / ray) * TAU + rng.range(-0.2, 0.2)\n const len = height * rng.range(0.2, 0.3)\n const dx = Math.cos(ra)\n const dz = Math.sin(ra)\n const p1: Vec3 = [top[0] + dx * len * 0.5, top[1] + len * 0.22, top[2] + dz * len * 0.5]\n const p2: Vec3 = [top[0] + dx * len, top[1] - len * 0.18, top[2] + dz * len]\n tube(ctx.foliage, [top, p1, p2], { sides: 3, radii: [height * 0.005, height * 0.004, height * 0.0025], color: (t) => mix(shade(gc, 1.05), lighten(gc, 0.9), t), sway: (t) => 0.6 + 0.4 * t, end: 'none' })\n }\n if (ctx.lod < 2) {\n // tuft of bracts under the umbrella\n icoShell(ctx.foliage, { center: [top[0], top[1] - 0.01, top[2]], radii: [height * 0.025, height * 0.018, height * 0.025], detail: 0, rng, noise: 0.1, color: (v) => shade(lighten(gc, 0.6), 0.8 + v.h * 0.3), sway: () => 0.9 })\n }\n }\n }\n if (spec.seedHeads && ctx.condition !== 'dead') {\n const seed = rgb(spec.seedColor ?? 0xd8c98a)\n const n = Math.max(2, Math.round(count / 7))\n for (let i = 0; i < n; i++) {\n const a = rng.range(0, TAU)\n const d0 = rng.range(0, radius * 0.3)\n const base0: Vec3 = [Math.cos(a) * d0, 0, Math.sin(a) * d0]\n const h = height * rng.range(1.5, 2.0)\n const lean = rng.range(0.1, 0.3)\n const dir = dirFromAngles(a, 1.3)\n const mid = add(base0, add(mul([dir[0], 0, dir[2]], h * lean * 0.5), [0, h * 0.55, 0]))\n const tip = add(base0, add(mul([dir[0], 0, dir[2]], h * lean), [0, h, 0]))\n tube(ctx.foliage, [base0, mid, tip], { sides: 3, radii: [height * 0.012, height * 0.009, height * 0.007], color: (t) => mix(c0, seed, t * 0.9), sway: (t) => 0.4 + 0.6 * t, end: 'none' })\n if (ctx.lod < 2) {\n const head = h * 0.22\n const hc = jitter(seed, rng, 0.01, 0.08, 0.05)\n icoShell(ctx.flowers, { center: add(tip, [dir[0] * head * 0.2, head * 0.35, dir[2] * head * 0.2]), radii: [height * 0.035, head * 0.55, height * 0.035], detail: 0, rng, noise: 0.1, color: (v) => shade(hc, 0.8 + v.h * 0.4), sway: () => 1 })\n }\n }\n }\n return { collider: null, bendable: true }\n}\n","import type { FernSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, cross, dirFromAngles, mul, norm, lerp } from '../math'\nimport { jitter, rgb, shade, tintGreen, mix } from '../color'\nimport { leaf, kite } from '../geometry/leaf'\n\nexport function generateFern(spec: FernSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const over = ctx.condition === 'overgrown'\n const n = Math.round((spec.frondCount ?? 11) * (ctx.condition === 'dead' ? 0.6 : 1) * (over ? 1.3 : 1) * ctx.pick(1, 0.7, 0.35))\n const L0 = (spec.frondLength ?? 0.7) * (over ? 1.15 : 1)\n const base = tintGreen(rgb(spec.color ?? 0x468f3c), ctx.condition)\n const c0 = shade(base, 0.62)\n const c1 = mix(shade(base, 1.12), [0.7, 0.85, 0.3], 0.15)\n const pairs = ctx.pick(11, 6, 0)\n for (let i = 0; i < n; i++) {\n const az = (i / n) * TAU + rng.range(-0.3, 0.3)\n const L = L0 * rng.range(0.7, 1.1) * (i % 3 === 0 ? 1.1 : 0.85)\n const e0 = rng.range(0.5, 1.15) * (i % 2 ? 0.8 : 1.1)\n const droop = rng.range(0.45, 0.9) * (ctx.condition === 'dry' ? 1.3 : 1)\n const horiz = dirFromAngles(az, 0)\n const pts: Vec3[] = []\n const segs = 6\n for (let k = 0; k <= segs; k++) {\n const t = k / segs\n pts.push([horiz[0] * L * t * Math.cos(e0) * 0.9 + 0.0, 0.04 + L * t * Math.sin(e0) - L * t * t * droop, horiz[2] * L * t * Math.cos(e0) * 0.9])\n }\n if (ctx.lod === 2) {\n leaf(ctx.foliage, pts[0], norm([pts[4][0] - pts[0][0], pts[4][1] - pts[0][1], pts[4][2] - pts[0][2]]), [0, 1, 0], L * 1.0, L * 0.34, c0, c1, { rows: 3, curl: 0.5, fold: 0.2, swayBase: 0.2, swayTip: 1, peak: 0.4, round: 1.3 })\n continue\n }\n // rachis as a thin ribbon\n for (let k = 0; k < segs; k++) {\n const a = pts[k]\n const bq = pts[k + 1]\n const d = norm([bq[0] - a[0], bq[1] - a[1], bq[2] - a[2]])\n const side = norm(cross(d, [0, 1, 0]))\n const w = L * 0.012 * (1 - k / segs)\n const t0 = k / segs\n const t1 = (k + 1) / segs\n const rc0 = shade(c0, 0.8 + 0.2 * t0)\n const rc1 = shade(c0, 0.8 + 0.2 * t1)\n ctx.foliage.flatQuad(add(a, mul(side, -w)), add(a, mul(side, w)), add(bq, mul(side, w * 0.8)), add(bq, mul(side, -w * 0.8)), rc0, rc0, rc1, rc1, 0.2 + 0.7 * t0, 0.2 + 0.7 * t0, 0.2 + 0.7 * t1, 0.2 + 0.7 * t1, [0, 1, 0])\n }\n if (pairs === 0) continue\n for (let k = 0; k < pairs; k++) {\n const t = lerp(0.1, 0.97, k / (pairs - 1))\n const f = t * segs\n const idx = Math.min(segs - 1, Math.floor(f))\n const u = f - idx\n const p: Vec3 = [lerp(pts[idx][0], pts[idx + 1][0], u), lerp(pts[idx][1], pts[idx + 1][1], u), lerp(pts[idx][2], pts[idx + 1][2], u)]\n const d = norm([pts[idx + 1][0] - pts[idx][0], pts[idx + 1][1] - pts[idx][1], pts[idx + 1][2] - pts[idx][2]])\n const side = norm(cross(d, [0, 1, 0]))\n const len = L * 0.2 * Math.sin(Math.PI * Math.min(1, t * 0.9 + 0.12)) * (0.8 + rng.next() * 0.3)\n const col0 = jitter(c0, rng, 0.01, 0.06, 0.04)\n const col1 = jitter(c1, rng, 0.01, 0.06, 0.04)\n for (const s of [-1, 1]) {\n const dir = norm(add(add(mul(side, s * 0.95), mul(d, 0.6)), [0, -0.28, 0]))\n kite(ctx.foliage, p, dir, [0, 1, 0], len, len * 0.5, col0, col1, 0.3 + 0.6 * t, 0.4 + 0.6 * t)\n }\n }\n }\n return { collider: null, bendable: true }\n}\n","import type { Vec3 } from '../types'\nimport { add, cross, dot, mul, norm } from '../math'\nimport { shade } from '../color'\nimport type { MeshBuilder } from './builder'\n\nexport interface FleshyLeafOptions {\n rows: number\n profile: 'blade' | 'sword' | 'aloe' | 'spoon'\n /** half thickness as a fraction of the half width at the ridge */\n thick: number\n /** tip droop as a fraction of length (along -up) */\n curl: number\n /** emit the underside (keel) as well */\n lower: boolean\n swayBase: number\n swayTip: number\n /** per row color: t along the length -> ridge color; edges use `edge` */\n color: (t: number) => Vec3\n edge: (t: number) => Vec3\n /** teeth along the edges: count per side, color, size as fraction of width */\n teeth?: { count: number; color: Vec3; size: number }\n /** terminal spine color */\n spine?: Vec3\n}\n\nfunction widthAt(profile: FleshyLeafOptions['profile'], t: number): number {\n switch (profile) {\n case 'blade': // agave: widest near 30%, long taper\n return t < 0.3 ? Math.pow(Math.sin((t / 0.3) * Math.PI * 0.5), 0.6) : Math.pow(1 - (t - 0.3) / 0.7, 0.85)\n case 'sword': // sansevieria: parallel sides, pointed tip\n return Math.min(1, Math.sin(Math.min(1, t * 6 + 0.15) * Math.PI * 0.5)) * (t > 0.82 ? Math.pow(1 - (t - 0.82) / 0.18, 0.8) : 1)\n case 'aloe': // triangular\n return t < 0.08 ? 0.75 + t * 3 : Math.pow(1 - (t - 0.08) / 0.92, 0.8)\n case 'spoon': // echeveria\n return Math.pow(Math.sin(Math.PI * Math.pow(Math.min(1, t * 0.97 + 0.03), 0.65)), 0.75)\n }\n}\n\n/** Thick leaf with a ridge on top and a keel below (ridge / edges / keel per row). Tip points along `dir`. */\nexport function fleshyLeaf(b: MeshBuilder, base: Vec3, dir: Vec3, up: Vec3, length: number, width: number, o: FleshyLeafOptions): void {\n const d = norm(dir)\n let right = cross(d, up)\n if (dot(right, right) < 1e-6) right = cross(d, [1, 0, 0])\n right = norm(right)\n const n2 = norm(cross(right, d))\n const R = o.rows\n type Row = { L: Vec3; T: Vec3; R: Vec3; K: Vec3; c: Vec3; e: Vec3; s: number; w: number; ctr: Vec3 }\n const rows: Row[] = []\n for (let i = 0; i <= R; i++) {\n const t = i / R\n const w = (i === R ? 0 : widthAt(o.profile, t)) * width * 0.5\n const centre = add(add(base, mul(d, length * t)), mul(n2, -length * o.curl * t * t))\n const th = w * o.thick\n const ridge = add(centre, mul(n2, th))\n const c = o.color(t)\n const e = o.edge(t)\n const sw = o.swayBase + (o.swayTip - o.swayBase) * t\n rows.push({\n L: add(centre, mul(right, -w)),\n T: ridge,\n R: add(centre, mul(right, w)),\n K: add(centre, mul(n2, -th * 0.8)),\n c,\n e,\n s: sw,\n w,\n ctr: centre,\n })\n }\n for (let i = 0; i < R; i++) {\n const a = rows[i]\n const z = rows[i + 1]\n const aw = a.w > 1e-6\n const zw = z.w > 1e-6\n if (!aw && zw) {\n b.flatTri(a.T, z.L, z.T, a.c, z.e, z.c, a.s, z.s, z.s, n2)\n b.flatTri(a.T, z.T, z.R, a.c, z.c, z.e, a.s, z.s, z.s, n2)\n if (o.lower) {\n b.flatTri(a.T, z.K, z.L, shade(a.c, 0.7), shade(z.c, 0.6), shade(z.e, 0.7), a.s, z.s, z.s, mul(n2, -1))\n b.flatTri(a.T, z.R, z.K, shade(a.c, 0.7), shade(z.e, 0.7), shade(z.c, 0.6), a.s, z.s, z.s, mul(n2, -1))\n }\n } else if (aw && !zw) {\n b.flatTri(a.L, z.T, a.T, a.e, z.c, a.c, a.s, z.s, a.s, n2)\n b.flatTri(a.T, z.T, a.R, a.c, z.c, a.e, a.s, z.s, a.s, n2)\n if (o.lower) {\n b.flatTri(a.L, a.K, z.T, shade(a.e, 0.7), shade(a.c, 0.6), z.c, a.s, a.s, z.s, mul(n2, -1))\n b.flatTri(a.K, a.R, z.T, shade(a.c, 0.6), shade(a.e, 0.7), z.c, a.s, a.s, z.s, mul(n2, -1))\n }\n } else if (aw && zw) {\n b.flatQuad(a.L, z.L, z.T, a.T, a.e, z.e, z.c, a.c, a.s, z.s, z.s, a.s, n2)\n b.flatQuad(a.T, z.T, z.R, a.R, a.c, z.c, z.e, a.e, a.s, z.s, z.s, a.s, n2)\n if (o.lower) {\n b.flatQuad(a.L, a.K, z.K, z.L, shade(a.e, 0.7), shade(a.c, 0.55), shade(z.c, 0.55), shade(z.e, 0.7), a.s, a.s, z.s, z.s, mul(n2, -1))\n b.flatQuad(a.K, a.R, z.R, z.K, shade(a.c, 0.55), shade(a.e, 0.7), shade(z.e, 0.7), shade(z.c, 0.55), a.s, a.s, z.s, z.s, mul(n2, -1))\n }\n }\n }\n if (o.teeth && o.teeth.count > 0) {\n const { count, color, size } = o.teeth\n for (let k = 0; k < count; k++) {\n const t0 = 0.12 + (0.7 * k) / count\n const t1 = t0 + 0.05\n const i0 = Math.min(R, Math.round(t0 * R))\n const i1 = Math.min(R, Math.max(i0 + 1, Math.round(t1 * R)))\n for (const sd of [-1, 1]) {\n const e0 = sd < 0 ? rows[i0].L : rows[i0].R\n const e1 = sd < 0 ? rows[i1].L : rows[i1].R\n const out = mul(right, sd * width * size)\n const tip = add(add(mul(add(e0, e1), 0.5), out), mul(d, length * 0.02))\n b.flatTri(e0, tip, e1, color, shade(color, 1.3), color, rows[i0].s, rows[i0].s, rows[i1].s, add(out, n2))\n }\n }\n }\n if (o.spine) {\n const last = rows[R]\n const prev = rows[R - 1]\n const tip = add(last.ctr, mul(d, length * 0.06))\n const hw = Math.max(prev.w * 0.12, width * 0.02)\n b.flatTri(add(prev.ctr, mul(right, -hw)), add(prev.ctr, mul(right, hw)), tip, o.spine, o.spine, shade(o.spine, 1.4), last.s, last.s, last.s, n2)\n b.flatTri(add(prev.ctr, mul(right, -hw)), tip, add(prev.ctr, mul(right, hw)), o.spine, shade(o.spine, 1.4), o.spine, last.s, last.s, last.s, mul(n2, -1))\n }\n}\n\n","import type { RosetteSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, dirFromAngles, lerp, mul } from '../math'\nimport { jitter, mix, rgb, shade, tintFlesh, lighten } from '../color'\nimport { fleshyLeaf } from '../geometry/succulent'\nimport { tube } from '../geometry/tube'\nimport { icoShell } from '../geometry/shell'\n\nexport function generateRosette(spec: RosetteSpec, ctx: Ctx): ArchResult {\n const form = spec.form ?? 'agave'\n const rng = ctx.rng\n const over = ctx.condition === 'overgrown'\n switch (form) {\n case 'sword': {\n const h = (spec.height ?? 0.8) * (over ? 1.2 : 1)\n const n = Math.round((spec.leafCount ?? 9) * (over ? 1.3 : 1) * ctx.pick(1, 0.7, 0.55))\n const base = tintFlesh(rgb(spec.color ?? 0x3f7a45), ctx.condition)\n const edgeC = tintFlesh(rgb(spec.edgeColor ?? 0xc9c24a), ctx.condition)\n const dark = shade(base, 0.6)\n const light = mix(base, [0.62, 0.78, 0.6], 0.45)\n for (let i = 0; i < n; i++) {\n const az = (i / n) * TAU * 1.0 + rng.range(-0.3, 0.3)\n const el = rng.range(1.2, 1.5)\n const len = h * rng.range(0.55, 1.0) * (ctx.condition === 'dead' ? 0.6 : 1)\n const ring = rng.range(0, 0.08)\n const base0: Vec3 = [Math.cos(az) * ring, 0.0, Math.sin(az) * ring]\n const band = rng.range(0, TAU)\n fleshyLeaf(ctx.foliage, base0, dirFromAngles(az, el), dirFromAngles(az + Math.PI, 0.2), len, h * 0.16 * rng.range(0.85, 1.15), {\n rows: ctx.pick(7, 4, 2),\n profile: 'sword',\n thick: 0.25,\n curl: rng.range(0.03, ctx.condition === 'dry' ? 0.3 : 0.12),\n lower: false,\n swayBase: 0,\n swayTip: 0.5,\n color: (t) => mix(dark, light, 0.5 + 0.5 * Math.sin(t * 22 + band)),\n edge: (t) => mix(edgeC, shade(edgeC, 0.8), 0.5 + 0.5 * Math.sin(t * 22 + band)),\n })\n }\n break\n }\n case 'aloe': {\n const h = (spec.height ?? 0.55) * (over ? 1.2 : 1)\n const n = Math.round((spec.leafCount ?? 12) * ctx.pick(1, 0.7, 0.5))\n const base = tintFlesh(rgb(spec.color ?? 0x6f9f6a), ctx.condition)\n const edge = rgb(spec.edgeColor ?? 0xe8e0c8)\n for (let i = 0; i < n; i++) {\n const ring = i < n * 0.4 ? 0 : i < n * 0.75 ? 1 : 2\n const az = i * 2.4 + rng.range(-0.2, 0.2)\n const el = [1.15, 0.85, 0.55][ring] + rng.range(-0.1, 0.1)\n const len = h * [0.75, 0.95, 0.85][ring] * rng.range(0.9, 1.1)\n const c = jitter(base, rng, 0.01, 0.06, 0.04)\n fleshyLeaf(ctx.foliage, [0, 0.02, 0], dirFromAngles(az, el), [0, 1, 0], len, h * 0.26, {\n rows: ctx.pick(3, 2, 2),\n profile: 'aloe',\n thick: 0.45,\n curl: 0.28,\n lower: ctx.lod === 0,\n swayBase: 0,\n swayTip: 0.5,\n color: (t) => mix(shade(c, 0.62), lighten(c, 0.5), t),\n edge: (t) => mix(shade(c, 0.5), shade(c, 0.95), t),\n teeth: ctx.lod === 0 ? { count: 5, color: edge, size: 0.07 } : undefined,\n })\n }\n if (spec.bloom && ctx.condition !== 'dead' && ctx.lod < 2) {\n const bc = rgb(spec.bloom.color)\n const stalkH = h * 1.5\n const tip: Vec3 = [0.04, stalkH, 0.02]\n tube(ctx.foliage, [[0, 0.1, 0], [0.02, stalkH * 0.5, 0.0], tip], { sides: 4, radii: [0.012, 0.01, 0.007], color: () => [0.45, 0.55, 0.3], sway: (t) => 0.3 + 0.6 * t, end: 'point' })\n for (let k = 0; k < 9; k++) {\n const t = 0.62 + (0.38 * k) / 9\n const y = lerp(0.1, stalkH, t)\n const a = k * 2.3\n const p: Vec3 = [lerp(0, 0.04, t) + Math.cos(a) * 0.012, y, lerp(0, 0.02, t) + Math.sin(a) * 0.012]\n const dir = dirFromAngles(a, -0.8)\n icoShell(ctx.flowers, { center: add(p, mul(dir, 0.03)), radii: [0.014, 0.04, 0.014], detail: 0, noise: 0, rng, color: (v) => mix(shade(bc, 0.8), lighten(bc, 0.4), v.h), sway: () => 0.9 })\n }\n }\n break\n }\n case 'echeveria': {\n const h = spec.height ?? 0.14\n const base = tintFlesh(rgb(spec.color ?? 0x8fb0a0), ctx.condition)\n const tipC = rgb(spec.edgeColor ?? 0xd88aa0)\n const rings = ctx.pick([5, 7, 9, 11], [5, 8, 10], [6, 9])\n rings.forEach((cnt, r) => {\n for (let i = 0; i < cnt; i++) {\n const az = (i / cnt) * TAU + r * 0.45 + rng.range(-0.1, 0.1)\n const el = [1.35, 1.0, 0.65, 0.35][Math.min(r, 3)]\n const len = h * [0.5, 0.65, 0.8, 0.9][Math.min(r, 3)]\n const c = jitter(base, rng, 0.008, 0.05, 0.04)\n fleshyLeaf(ctx.foliage, [0, 0.01 + r * 0.004, 0], dirFromAngles(az, el), [0, 1, 0], len, h * 0.42, {\n rows: ctx.pick(3, 2, 2),\n profile: 'spoon',\n thick: 0.6,\n curl: 0.25,\n lower: ctx.lod === 0,\n swayBase: 0,\n swayTip: 0.15,\n color: (t) => mix(shade(c, 0.7), mix(lighten(c, 0.4), tipC, 0.5), Math.pow(t, 2)),\n edge: (t) => mix(shade(c, 0.6), tipC, Math.pow(t, 1.5) * 0.9),\n })\n }\n })\n break\n }\n default: {\n // agave\n const h = (spec.height ?? 0.9) * (over ? 1.15 : 1)\n const n = Math.round((spec.leafCount ?? 20) * ctx.pick(1, 0.7, 0.55))\n const base = tintFlesh(rgb(spec.color ?? 0x5f9a8a), ctx.condition)\n const tooth = rgb(spec.edgeColor ?? 0x5a3a2a)\n for (let i = 0; i < n; i++) {\n const f = i / n\n const az = i * 2.399963 + rng.range(-0.15, 0.15)\n const el = lerp(1.35, 0.3, Math.pow(f, 0.8)) + rng.range(-0.06, 0.06)\n const len = h * lerp(0.55, 1, Math.pow(f, 0.6)) * rng.range(0.92, 1.08)\n const c = jitter(base, rng, 0.012, 0.06, 0.04)\n fleshyLeaf(ctx.foliage, [0, 0.03, 0], dirFromAngles(az, el), [0, 1, 0], len, len * 0.3, {\n rows: ctx.pick(3, 2, 2),\n profile: 'blade',\n thick: 0.5,\n curl: lerp(0.12, 0.3, f),\n lower: ctx.lod === 0,\n swayBase: 0,\n swayTip: 0.25,\n color: (t) => mix(shade(c, 0.6), mix(lighten(c, 0.6), [0.7, 0.8, 0.6], 0.25), Math.pow(t, 0.9)),\n edge: (t) => mix(shade(c, 0.5), shade(c, 1.0), t * 0.8),\n teeth: ctx.lod === 0 && f > 0.35 ? { count: 4, color: tooth, size: 0.05 } : undefined,\n spine: ctx.lod < 2 ? tooth : undefined,\n })\n }\n break\n }\n }\n return { collider: null, bendable: true }\n}\n","import type { Vec3 } from '../types'\nimport { add, cross, mul, norm, perp } from '../math'\nimport { shade } from '../color'\nimport type { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\n\n/** Tuft of thin radial spines at an areole: each spine is one thin triangle. */\nexport function spineTuft(b: MeshBuilder, p: Vec3, n: Vec3, count: number, length: number, color: Vec3, rng: Rng, sway = 0): void {\n const nn = norm(n)\n const t1 = perp(nn)\n const t2 = norm(cross(nn, t1))\n const w = length * 0.07\n for (let i = 0; i < count; i++) {\n const a = (i / count) * Math.PI * 2 + rng.range(0, 0.6)\n const spread = i === 0 ? 0 : 0.55\n const dir = norm(add(mul(nn, 1), add(mul(t1, Math.cos(a) * spread), mul(t2, Math.sin(a) * spread))))\n const tip = add(p, mul(dir, length * rng.range(0.75, 1.1)))\n const side = mul(norm(cross(dir, nn)), w)\n const left = add(p, side)\n const right = add(p, mul(side, -1))\n b.flatTri(left, right, tip, shade(color, 0.8), shade(color, 0.8), color, sway, sway, sway, nn)\n }\n}\n\n/** Tiny dark areole base under a tuft (single triangle). */\nexport function areole(b: MeshBuilder, p: Vec3, n: Vec3, size: number, color: Vec3, sway = 0): void {\n const nn = norm(n)\n const t1 = mul(perp(nn), size)\n const t2 = mul(norm(cross(nn, perp(nn))), size)\n const c = add(p, mul(nn, size * 0.1))\n b.flatTri(add(c, t1), add(c, add(mul(t1, -0.5), t2)), add(c, add(mul(t1, -0.5), mul(t2, -1))), color, color, color, sway, sway, sway, nn)\n}\n","import type { ColumnarCactusSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, catmull, dirFromAngles, lerp, mul, norm } from '../math'\nimport { mix, rgb, shade, tintFlesh, lighten } from '../color'\nimport { ribbedTube } from '../geometry/tube'\nimport { spineTuft, areole } from '../geometry/spines'\nimport { flowerHead } from '../geometry/flower'\n\nexport function generateColumnarCactus(spec: ColumnarCactusSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const srng = rng.fork('spines')\n const dead = ctx.condition === 'dead'\n const dry = ctx.condition === 'dry'\n const over = ctx.condition === 'overgrown'\n const H = (spec.height ?? 3.2) * (over ? 1.1 : 1)\n const R = spec.radius ?? H * 0.055\n const ribsFull = spec.ribs ?? 10\n const ribs = ctx.pick(ribsFull, Math.max(6, Math.round(ribsFull * 0.7)), Math.min(5, ribsFull))\n const style = spec.armStyle ?? 'candelabra'\n const armsSpec = spec.arms ?? [2, 4]\n const arms = (Array.isArray(armsSpec) ? rng.int(armsSpec[0], armsSpec[1]) : armsSpec) + (over ? 1 : 0)\n const base = tintFlesh(rgb(spec.color ?? 0x5f9a78), ctx.condition)\n const spineC = rgb(spec.spineColor ?? 0xe6dcb4)\n const slump = dead ? 0.22 : dry ? 0.05 : 0\n const rings = ctx.pick(1, 0.7, 0.45)\n const domeSteps = ctx.pick(2, 1, 1)\n const spineOn = ctx.lod === 0 && ctx.condition !== 'dead' ? 1 : ctx.lod === 0 ? 0.5 : 0\n\n const bodyColor = (t: number, ridge: boolean, rib: number): Vec3 => {\n let k = ridge ? 1.05 : 0.7\n if (rib % 2 === 0) k *= 1.04\n const c = shade(base, k * (0.78 + 0.28 * Math.min(1, t * 1.4)))\n return mix(c, lighten(base, 0.8), Math.max(0, t - 0.8) * 1.4 * (ridge ? 1 : 0.5))\n }\n const info: { tipPos: Vec3; tipDir: Vec3; r: number }[] = []\n\n const column = (path: Vec3[], radiusAt: (t: number) => number, seedK: number, withSpines: boolean): void => {\n const radii = path.map((_, i) => radiusAt(i / (path.length - 1)))\n const res = ribbedTube(ctx.foliage, path, {\n ribs,\n radii,\n valley: 0.74,\n dome: domeSteps,\n color: (t, ridge, rib) => bodyColor(t, ridge, rib + seedK),\n sway: () => 0,\n rough: (ring, rib) => Math.sin(ring * 1.7 + rib * 2.3 + seedK) * 0.03,\n })\n const last = path[path.length - 1]\n const prev = path[path.length - 2]\n info.push({ tipPos: add(last, mul(norm([last[0] - prev[0], last[1] - prev[1], last[2] - prev[2]]), radii[radii.length - 1] * 0.9)), tipDir: norm([last[0] - prev[0], last[1] - prev[1], last[2] - prev[2]]), r: radii[radii.length - 1] })\n if (withSpines && spineOn > 0) {\n for (const rd of res.ridges) {\n if (rd.ring === 0 || rd.ring % 3 !== 1) continue\n if (srng.next() > spineOn) continue\n areole(ctx.spines, rd.p, rd.n, R * 0.09, [0.25, 0.2, 0.15])\n spineTuft(ctx.spines, rd.p, add(rd.n, [0, 0.15, 0]), 3, R * 0.55, spineC, srng)\n }\n }\n }\n\n // main trunk (slightly sinuous, slumped when dead)\n const nCtrl = 5\n const ctrl: Vec3[] = []\n const lean = rng.range(-0.04, 0.04) * H\n for (let i = 0; i < nCtrl; i++) {\n const t = i / (nCtrl - 1)\n ctrl.push([lean * t + slump * H * t * t, H * t, Math.sin(t * 3 + rng.range(0, 1)) * 0.015 * H])\n }\n const mainPath = catmull(ctrl, Math.max(1, Math.round(2 * rings)))\n const mainR = (t: number): number => R * (1 + 0.35 * Math.exp(-t * 18)) * (1 - 0.08 * t) * (t > 0.92 ? 1 - (t - 0.92) * 1.5 : 1)\n column(mainPath, mainR, 0, true)\n const at = (t: number): { p: Vec3; r: number } => {\n const f = t * (mainPath.length - 1)\n const i = Math.min(mainPath.length - 2, Math.floor(f))\n const u = f - i\n return { p: [lerp(mainPath[i][0], mainPath[i + 1][0], u), lerp(mainPath[i][1], mainPath[i + 1][1], u), lerp(mainPath[i][2], mainPath[i + 1][2], u)], r: mainR(t) }\n }\n\n // arms\n for (let a = 0; a < arms; a++) {\n const az = (a / arms) * TAU + rng.range(-0.5, 0.5)\n const out = dirFromAngles(az, 0)\n let t0: number\n let outLen: number\n let upLen: number\n let rise: number\n switch (style) {\n case 'saguaro':\n t0 = rng.range(0.35, 0.6)\n outLen = H * rng.range(0.12, 0.2)\n upLen = H * rng.range(0.25, 0.4)\n rise = 0.1\n break\n case 'sprawl':\n t0 = rng.range(0.02, 0.2)\n outLen = H * rng.range(0.3, 0.6)\n upLen = H * rng.range(0.25, 0.5)\n rise = 0.35\n break\n default:\n t0 = rng.range(0.45, 0.75)\n outLen = H * rng.range(0.08, 0.15)\n upLen = H * rng.range(0.28, 0.42)\n rise = 0.25\n }\n const s = at(t0)\n const start = add(s.p, mul(out, s.r * 0.3))\n const p1 = add(start, add(mul(out, outLen * 0.7), [0, outLen * rise, 0]))\n const p2 = add(start, add(mul(out, outLen), [0, outLen * rise + upLen * 0.18, 0]))\n let p3 = add(p2, add(mul(out, outLen * 0.15), [0, upLen, 0]))\n if (dead) p3 = add(p2, add(mul(out, upLen * 0.7), [0, upLen * 0.25, 0]))\n ctx.piece(`arm${a}`, 'arm', 'stem', start)\n const armPath = catmull([start, p1, p2, p3], Math.max(1, Math.round(2 * rings)))\n const ar = s.r * (style === 'sprawl' ? 0.9 : 0.72)\n column(armPath, (t) => ar * (t > 0.9 ? 1 - (t - 0.9) * 1.6 : 1) * (t < 0.12 ? 0.85 + t * 1.2 : 1), a + 1, true)\n }\n\n ctx.piece('stem', 'stem')\n const frng = rng.fork('flowers')\n // flowers (night bloom, white trumpets) at the tips\n if (spec.flowers && !dead && ctx.lod < 2) {\n const fc = rgb(spec.flowers.color)\n const count = spec.flowers.count ?? 1\n for (let i = 0; i < info.length; i++) {\n for (let k = 0; k < count; k++) {\n if (frng.next() > 0.8) continue\n const tip = info[i]\n const ax = norm(add(tip.tipDir, [rng.range(-0.5, 0.5), 0.2, rng.range(-0.5, 0.5)]))\n flowerHead(ctx.flowers, { kind: 'trumpet', center: add(tip.tipPos, mul(tip.tipDir, -tip.r * 0.3)), axis: ax, size: R * 1.5, colors: [fc, shade(fc, 0.92)], centerColor: [0.95, 0.85, 0.4], rng: rng.fork(i * 7 + k), lod: ctx.lod, sway: 0 })\n }\n }\n }\n return { collider: { kind: 'cylinder', radius: R * 1.1, height: H * 0.9 }, bendable: false, thorny: true, foliageMaterial: 'cactus' }\n}\n","import type { PaddleCactusSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { add, mul, norm, rotAxis, TAU } from '../math'\nimport { jitter, mix, rgb, shade, tintFlesh, lighten } from '../color'\nimport { icoShell } from '../geometry/shell'\nimport { spineTuft } from '../geometry/spines'\nimport { blossom } from '../geometry/flower'\nimport { frameFromAxis, type Frame } from '../math'\n\ninterface Pad {\n center: Vec3\n dir: Vec3\n /** width axis */\n x: Vec3\n /** thickness axis */\n z: Vec3\n w: number\n l: number\n gen: number\n index: number\n parent?: number\n start: Vec3\n}\n\nexport function generatePaddleCactus(spec: PaddleCactusSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const dead = ctx.condition === 'dead'\n const over = ctx.condition === 'overgrown'\n const gens = (spec.generations ?? 3) + (over ? 1 : 0)\n const padL = (spec.padSize ?? 0.34) * (over ? 1.1 : 1)\n const base = tintFlesh(rgb(spec.color ?? 0x6c9f62), ctx.condition)\n const spineC = rgb(0xe9dfb8)\n const pads: Pad[] = []\n const frng = rng.fork('decor')\n\n const mkFrame = (dir: Vec3, twist: number): { x: Vec3; z: Vec3 } => {\n const f = frameFromAxis([0, 0, 0], dir, twist)\n return { x: f.x, z: f.z }\n }\n const addPad = (start: Vec3, dir: Vec3, scale: number, gen: number, twist: number, parent?: Pad): Pad => {\n const l = padL * scale * rng.range(0.9, 1.1)\n const w = l * rng.range(0.62, 0.78)\n const d = norm(dir)\n const { x, z } = mkFrame(d, twist)\n const p: Pad = { center: add(start, mul(d, l * 0.46)), dir: d, x, z, w, l, gen, index: pads.length, parent: parent?.index, start }\n pads.push(p)\n return p\n }\n const root = addPad([0, 0, 0], [rng.range(-0.15, 0.15), 1, rng.range(-0.15, 0.15)], 1.15, 0, rng.range(0, TAU))\n let frontier: Pad[] = [root]\n for (let g = 1; g < gens; g++) {\n const next: Pad[] = []\n for (const p of frontier) {\n const kids = g === 1 ? rng.int(2, 3) : rng.int(1, 3)\n for (let k = 0; k < kids; k++) {\n // attach near the upper edge; tilt sideways around the pad's thickness axis, with a little twist\n const side = kids === 1 ? rng.sign() : (k / (kids - 1)) * 2 - 1\n const ang = side * rng.range(0.5, 0.95)\n let nd = rotAxis(p.dir, p.z, ang)\n nd = rotAxis(nd, p.dir, rng.range(-0.4, 0.4))\n nd = norm(add(nd, [0, 0.25, 0]))\n if (dead) nd = norm(add(nd, [0, -0.7, 0]))\n const start = add(add(p.center, mul(p.dir, p.l * 0.42)), mul(p.x, side * p.w * 0.28))\n next.push(addPad(start, nd, 0.86 - g * 0.04, g, rng.range(0, TAU), p))\n }\n }\n frontier = next\n }\n const maxGen = ctx.lod === 2 ? 1 : 99\n const detail = (ctx.lod === 0 ? 1 : 0) as 0 | 1\n for (const p of pads) {\n if (p.gen > maxGen) continue\n ctx.piece(`pad${p.index}`, 'pad', p.parent === undefined ? undefined : `pad${p.parent}`, p.start)\n ctx.pieceGeom(`pad${p.index}`, { radius: p.l * 0.085, length: p.l, axis: p.dir, base: p.start })\n const frame: Frame = { o: p.center, x: p.x, y: p.dir, z: p.z }\n const c = jitter(base, rng.fork(p.gen * 31 + Math.floor(p.l * 1000)), 0.012, 0.05, 0.04)\n icoShell(ctx.foliage, {\n center: p.center,\n frame,\n radii: [p.w * 0.5, p.l * 0.5, p.l * 0.085],\n detail,\n rng: rng.fork(Math.floor(p.l * 997) + p.gen),\n noise: 0.04,\n color: (v) => {\n const edge = 1 - Math.abs(v.dir[2])\n let k = 0.72 + 0.34 * v.h\n k *= 0.9 + 0.2 * edge\n const col = shade(c, k)\n return p.gen === 0 ? mix(col, shade(c, 0.6), Math.max(0, 0.5 - v.h) * 0.8) : mix(col, lighten(c, 0.5), Math.max(0, v.h - 0.8))\n },\n sway: () => 0,\n })\n if (ctx.lod === 0 && ctx.condition !== 'dead') {\n // areole tufts on both faces\n const n = 12\n for (let i = 0; i < n; i++) {\n const u = ((i % 4) + 0.5 + (Math.floor(i / 4) % 2) * 0.5) / 4.2 - 0.5\n const v = (Math.floor(i / 4) + 0.5) / 3 - 0.5\n const face = i % 2 ? 1 : -1\n const px = u * p.w * 0.78\n const py = v * p.l * 0.8\n const pz = face * p.l * 0.085 * Math.sqrt(Math.max(0, 1 - (px / (p.w * 0.5)) ** 2 - (py / (p.l * 0.5)) ** 2)) * 1.04\n const pos = add(add(add(p.center, mul(p.x, px)), mul(p.dir, py)), mul(p.z, pz))\n const nrm = add(mul(p.z, face), [0, 0.1, 0])\n spineTuft(ctx.spines, pos, nrm, 3, p.l * 0.1, spineC, frng)\n }\n }\n }\n // fruit and flowers on the rim of the outer pads\n const outer = pads.filter((p) => p.gen >= gens - 1 || p.gen >= 2)\n if (spec.fruit && !dead && ctx.lod < 2) {\n const fc = rgb(spec.fruit.color)\n for (let i = 0; i < spec.fruit.count; i++) {\n const p = outer[i % Math.max(1, outer.length)] ?? root\n const side = frng.sign()\n const pos = add(add(p.center, mul(p.dir, p.l * 0.5 * 0.92)), mul(p.x, side * p.w * frng.range(0, 0.28)))\n const r = padL * 0.1\n ctx.fruitItem(() => icoShell(ctx.fruit, { center: add(pos, mul(p.z, r * 0.2)), radii: [r * 0.8, r * 1.15, r * 0.8], detail: 0, rng: frng, noise: 0.05, color: (v) => mix(shade(fc, 0.7), lighten(fc, 0.4), v.h), sway: () => 0 }))\n }\n }\n if (spec.flowers && !dead && ctx.lod === 0) {\n const fc = rgb(spec.flowers.color)\n for (let i = 0; i < spec.flowers.count; i++) {\n const p = outer[(i * 3 + 1) % Math.max(1, outer.length)] ?? root\n ctx.piece(`pad${p.index}`, 'pad', p.parent === undefined ? undefined : `pad${p.parent}`, p.start)\n const pos = add(add(p.center, mul(p.dir, p.l * 0.5 * 0.9)), mul(p.x, frng.range(-0.25, 0.25) * p.w))\n blossom(ctx.flowers, add(pos, mul(p.z, p.l * 0.04)), norm(add(p.dir, mul(p.z, 0.5))), padL * 0.16, fc, [0.9, 0.5, 0.2], 0, 6, frng.range(0, TAU))\n }\n }\n return { collider: { kind: 'cylinder', radius: padL * 0.12, height: padL * 1.2 }, bendable: false, thorny: true, foliageMaterial: 'cactus' }\n}\n","import type { GlobeCactusSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, norm } from '../math'\nimport { mix, rgb, shade, tintFlesh, lighten } from '../color'\nimport { ribbedTube } from '../geometry/tube'\nimport { spineTuft, areole } from '../geometry/spines'\nimport { icoShell } from '../geometry/shell'\nimport { blossom } from '../geometry/flower'\n\nexport function generateGlobeCactus(spec: GlobeCactusSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const srng = rng.fork('spines')\n const R = (spec.radius ?? 0.28) * (ctx.condition === 'overgrown' ? 1.1 : 1)\n const H = spec.height ?? R * 2.0\n const ribs = spec.ribs ?? 13\n const base = tintFlesh(rgb(spec.color ?? 0x5c9a58), ctx.condition)\n const spineC = rgb(spec.spineColor ?? 0xf0d890)\n const rings = ctx.pick(7, 5, 3)\n const path: Vec3[] = []\n const radii: number[] = []\n for (let i = 0; i < rings; i++) {\n const t = i / (rings - 1)\n path.push([0, H * 0.9 * t, 0])\n // barrel profile: narrow at the soil line, full at 45%, rounding in at the top\n radii.push(R * (0.55 + 0.45 * Math.sin(Math.min(1, t * 1.2 + 0.1) * Math.PI * 0.62) ** 0.7) * (t > 0.85 ? 1 - (t - 0.85) * 1.2 : 1))\n }\n const res = ribbedTube(ctx.foliage, path, {\n ribs,\n radii,\n valley: 0.7,\n dome: ctx.pick(2, 1, 1),\n color: (t, ridge, rib) => {\n const k = (ridge ? 1.08 : 0.68) * (0.75 + 0.3 * t) * (rib % 2 ? 0.97 : 1.03)\n return shade(base, k)\n },\n sway: () => 0,\n rough: (ring, rib) => Math.sin(ring * 2.1 + rib * 1.3) * 0.02,\n })\n if (ctx.lod === 0) {\n for (const rd of res.ridges) {\n if (rd.ring === 0 || rd.t > 0.9) continue\n areole(ctx.spines, rd.p, rd.n, R * 0.08, [0.3, 0.25, 0.18])\n spineTuft(ctx.spines, rd.p, add(rd.n, [0, 0.1, 0]), 5, R * 0.42, spineC, srng)\n }\n }\n const topY = H * 0.9 + R * 0.2\n if (spec.cephalium && ctx.lod < 2) {\n // cap of the crown cactus: red hairy dome with white bristles\n const cc = rgb(spec.cephalium.color)\n const capR = radii[radii.length - 1] * 0.95 + R * 0.12\n icoShell(ctx.fruit, {\n center: [0, H * 0.9 + R * 0.02, 0],\n radii: [capR, R * 0.45, capR],\n detail: ctx.pick(1, 0, 0) as 0 | 1,\n rng: srng,\n noise: 0.08,\n color: (v) => mix(shade(cc, 0.7), mix(lighten(cc, 0.3), [0.95, 0.9, 0.85], 0.35), v.h),\n sway: () => 0,\n })\n if (ctx.lod === 0) {\n for (let i = 0; i < 14; i++) {\n const a = srng.range(0, TAU)\n const rr = Math.sqrt(srng.next()) * capR * 0.8\n const y = H * 0.9 + R * 0.02 + R * 0.45 * Math.sqrt(Math.max(0, 1 - (rr / capR) ** 2))\n spineTuft(ctx.spines, [Math.cos(a) * rr, y, Math.sin(a) * rr], [0, 1, 0], 3, R * 0.22, [0.96, 0.9, 0.8], srng)\n }\n for (let i = 0; i < 3; i++) {\n const a = i * 2.1\n const rr = capR * 0.3\n blossom(ctx.flowers, [Math.cos(a) * rr, H * 0.9 + R * 0.48, Math.sin(a) * rr], [0, 1, 0], R * 0.14, [0.95, 0.4, 0.6], [1, 0.9, 0.5], 0, 5, a)\n }\n }\n } else if (spec.flowers && ctx.condition !== 'dead' && ctx.lod < 2) {\n const fc = rgb(spec.flowers.color)\n const n = spec.flowers.count ?? 6\n for (let i = 0; i < n; i++) {\n const a = (i / n) * TAU\n const rr = radii[radii.length - 1] * 0.62\n const p: Vec3 = [Math.cos(a) * rr, topY - R * 0.1, Math.sin(a) * rr]\n blossom(ctx.flowers, p, norm([Math.cos(a) * 0.4, 1, Math.sin(a) * 0.4]), R * 0.22, fc, [0.95, 0.8, 0.3], 0, 8, a)\n }\n }\n return { collider: { kind: 'cylinder', radius: R * 1.0, height: H }, bendable: false, thorny: true, foliageMaterial: 'cactus' }\n}\n","import type { Lod, Vec3 } from '../types'\nimport { add, cross, dirFromAngles, lerp, mul, norm } from '../math'\nimport { shade, mix, jitter } from '../color'\nimport type { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\nimport { kite, leaf } from './leaf'\n\nexport interface PinnateOptions {\n origin: Vec3\n az: number\n /** elevation of the rachis at the base (radians) */\n elev: number\n length: number\n /** gravity droop: fraction of the length lost at the tip */\n droop: number\n /** leaflet length as a fraction of the frond length */\n leafletLen: number\n /** leaflet pairs at lod 0 */\n pairs: number\n c0: Vec3\n c1: Vec3\n lod: Lod\n rng: Rng\n /** sway at base / tip */\n swayBase: number\n swayTip: number\n /** how much leaflets hang down (V shape), default 0.45 */\n hang?: number\n /** leaflet width as a fraction of its length (default 0.2) */\n leafletWidth?: number\n}\n\n/** Curved rachis with leaflets on both sides (palm / date / areca frond). Returns the tip. */\nexport function pinnateFrond(b: MeshBuilder, o: PinnateOptions): Vec3 {\n const horiz = dirFromAngles(o.az, 0)\n const segs = o.lod === 0 ? 8 : o.lod === 1 ? 5 : 4\n const pts: Vec3[] = []\n const ce = Math.cos(o.elev)\n const se = Math.sin(o.elev)\n for (let k = 0; k <= segs; k++) {\n const t = k / segs\n pts.push([o.origin[0] + horiz[0] * o.length * t * ce, o.origin[1] + o.length * (t * se - o.droop * t * t), o.origin[2] + horiz[2] * o.length * t * ce])\n }\n const sideV = norm(cross(horiz, [0, 1, 0]))\n if (o.lod === 2) {\n // one narrow arched strip that droops along the rachis\n const mid = pts[Math.floor(segs / 2)]\n const d0 = norm([mid[0] - o.origin[0], mid[1] - o.origin[1] + 0.001, mid[2] - o.origin[2]])\n leaf(b, o.origin, d0, [0, 1, 0], o.length * 1.02, o.length * 0.15, shade(o.c0, 0.95), o.c1, { rows: 3, curl: o.droop * 1.1, fold: 0.6, swayBase: o.swayBase, swayTip: o.swayTip, peak: 0.4, round: 1.1, baseWidth: 0.1 })\n return pts[segs]\n }\n // rachis ribbon\n for (let k = 0; k < segs; k++) {\n const a = pts[k]\n const bq = pts[k + 1]\n const w = o.length * 0.012 * (1 - 0.7 * (k / segs))\n const t0 = k / segs\n const t1 = (k + 1) / segs\n const s0 = lerp(o.swayBase, o.swayTip, t0)\n const s1 = lerp(o.swayBase, o.swayTip, t1)\n const rc = shade(o.c0, 0.75)\n b.flatQuad(add(a, mul(sideV, -w)), add(a, mul(sideV, w)), add(bq, mul(sideV, w * 0.8)), add(bq, mul(sideV, -w * 0.8)), rc, rc, shade(o.c0, 0.9), shade(o.c0, 0.9), s0, s0, s1, s1, [0, 1, 0])\n }\n const pairs = o.lod === 0 ? o.pairs : Math.min(9, Math.max(5, Math.round(o.pairs * 0.6)))\n const hang = o.hang ?? 0.45\n const lw = o.leafletWidth ?? 0.2\n for (let k = 0; k < pairs; k++) {\n const t = lerp(0.14, 0.98, k / Math.max(1, pairs - 1))\n const f = t * segs\n const idx = Math.min(segs - 1, Math.floor(f))\n const u = f - idx\n const p: Vec3 = [lerp(pts[idx][0], pts[idx + 1][0], u), lerp(pts[idx][1], pts[idx + 1][1], u), lerp(pts[idx][2], pts[idx + 1][2], u)]\n const d = norm([pts[idx + 1][0] - pts[idx][0], pts[idx + 1][1] - pts[idx][1], pts[idx + 1][2] - pts[idx][2]])\n const prof = Math.sin(Math.PI * Math.min(1, 0.12 + t * 0.85)) ** 0.85\n const len = o.length * o.leafletLen * prof * (o.lod === 0 ? 1 : 1.5) * (0.9 + o.rng.next() * 0.2)\n const sw = lerp(o.swayBase, o.swayTip, t)\n const cc0 = jitter(o.c0, o.rng, 0.008, 0.05, 0.03)\n const cc1 = jitter(o.c1, o.rng, 0.008, 0.05, 0.03)\n for (const s of [-1, 1]) {\n const dir = norm(add(add(mul(sideV, s * 0.85), mul(d, 0.6)), [0, -hang, 0]))\n kite(b, p, dir, [0, 1, 0], len, len * lw * (o.lod === 0 ? 1 : 2.3), mix(cc0, cc1, 0.1), cc1, sw, Math.min(1, sw + 0.1))\n }\n }\n return pts[segs]\n}\n","import type { PalmSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, catmull, dirFromAngles, lerp, mul, norm } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { tube } from '../geometry/tube'\nimport { pinnateFrond } from '../geometry/fronds'\nimport { leaf } from '../geometry/leaf'\nimport { icoShell } from '../geometry/shell'\n\ninterface Defaults {\n height: number\n trunkRadius: number\n frondCount: number\n frondLength: number\n leaf: number\n trunk: number\n lean: number\n}\nconst DEF: Record<NonNullable<PalmSpec['variant']>, Defaults> = {\n coconut: { height: 7, trunkRadius: 0.17, frondCount: 18, frondLength: 2.7, leaf: 0x4e9a3c, trunk: 0xa08a68, lean: 0.2 },\n royal: { height: 11, trunkRadius: 0.27, frondCount: 13, frondLength: 3.8, leaf: 0x4a9a3c, trunk: 0xbab4a4, lean: 0.01 },\n fan: { height: 3.2, trunkRadius: 0.2, frondCount: 16, frondLength: 1.5, leaf: 0x5a9a44, trunk: 0x7a5c3c, lean: 0.03 },\n areca: { height: 2.6, trunkRadius: 0.03, frondCount: 5, frondLength: 1.5, leaf: 0x78ae3e, trunk: 0x9aa860, lean: 0.25 },\n date: { height: 6, trunkRadius: 0.24, frondCount: 20, frondLength: 3, leaf: 0x6a9a58, trunk: 0x8a6a48, lean: 0.05 },\n}\n\nexport function generatePalm(spec: PalmSpec, ctx: Ctx): ArchResult {\n const variant = spec.variant ?? 'coconut'\n const d = DEF[variant]\n const rng = ctx.rng\n const dead = ctx.condition === 'dead'\n const dry = ctx.condition === 'dry'\n const over = ctx.condition === 'overgrown'\n const H = (spec.height ?? d.height) * (over ? 1.08 : 1)\n const R = spec.trunkRadius ?? d.trunkRadius\n const trunkC = rgb(spec.trunkColor ?? d.trunk)\n const leafBase = tintGreen(rgb(spec.leafColor ?? d.leaf), ctx.condition)\n const lean = (spec.lean ?? d.lean) * (dead ? 1.4 : 1)\n const stems = variant === 'areca' || (variant === 'fan' && (spec.stems ?? 1) > 1) ? (spec.stems ?? 6) : 1\n const clump = stems > 1\n const frondN = Math.round((spec.frondCount ?? d.frondCount) * (dead ? 0.5 : dry ? 0.75 : over ? 1.2 : 1))\n const frondL = (spec.frondLength ?? d.frondLength) * (over ? 1.1 : 1)\n const c0 = shade(leafBase, 0.62)\n const c1 = mix(shade(leafBase, 1.12), [0.7, 0.85, 0.35], 0.12)\n const deadC = [0.45, 0.36, 0.22] as Vec3\n const crowns: { p: Vec3; r: number }[] = []\n\n const buildStem = (si: number, stemH: number, stemR: number, stemLean: number, az: number): void => {\n const trunkId = si === 0 ? 'trunk' : `stem${si}`\n ctx.piece(trunkId, si === 0 ? 'trunk' : 'stem')\n const srng = rng.fork(si * 101 + 7)\n const nPts = Math.max(4, Math.round(stemH / (clump ? 0.35 : 0.2)))\n const ctrl: Vec3[] = []\n const wob = srng.range(0, TAU)\n for (let i = 0; i <= 4; i++) {\n const t = i / 4\n const off = stemLean * stemH * (variant === 'coconut' ? 0.35 * t + 0.65 * t * t : t * t) + Math.sin(t * 3 + wob) * (variant === 'coconut' ? 0.045 : 0.02) * stemH\n ctrl.push([Math.cos(az) * off, stemH * t, Math.sin(az) * off])\n }\n const full = catmull(ctrl, Math.max(1, Math.round(nPts / 4)))\n const stride = ctx.pick(1, 2, Math.max(1, Math.floor(full.length / 3)))\n const path: Vec3[] = []\n for (let i = 0; i < full.length; i += stride) path.push(full[i])\n if ((full.length - 1) % stride !== 0) path.push(full[full.length - 1])\n const scars = variant === 'areca' ? 4 : variant === 'royal' ? 2.5 : 3.2\n const radii = path.map((_, i) => {\n const t = i / (path.length - 1)\n let r = stemR * (variant === 'royal' ? 1.02 + 0.18 * Math.sin(Math.min(1, t * 1.4) * Math.PI) - 0.28 * t : 1.0 - 0.22 * t)\n r *= 1 + 0.5 * Math.exp(-t * (variant === 'royal' ? 16 : 22))\n const ringPhase = Math.cos(t * stemH * scars * TAU)\n r *= 1 + (ctx.lod === 0 ? 0.045 : 0.02) * ringPhase\n return r\n })\n const sides = ctx.pick(clump ? 5 : 8, clump ? 4 : 6, 4)\n tube(ctx.wood, path, {\n sides,\n radii,\n color: (t, a) => {\n const ring = 0.84 + 0.16 * Math.cos(t * stemH * scars * TAU)\n const stripe = 0.94 + 0.06 * Math.cos(a * TAU * 3 + t * 4)\n let c = shade(trunkC, ring * stripe * (0.78 + 0.22 * Math.min(1, t * 6)))\n if (variant === 'royal') c = mix(c, [0.62, 0.62, 0.55], 0.25)\n if (dead) c = mix(c, [0.4, 0.37, 0.32], 0.5)\n return c\n },\n sway: (t) => 0.05 * t * t,\n end: 'flat',\n })\n const top = path[path.length - 1]\n let crownTop: Vec3 = top\n if (variant === 'royal') {\n // smooth green crownshaft\n const shaft: Vec3[] = [top, add(top, [0, 0.5, 0]), add(top, [0.0, 1.25, 0])]\n const shaftC = mix(leafBase, [0.55, 0.75, 0.3], 0.3)\n tube(ctx.wood, shaft, { sides: ctx.pick(7, 5, 4), radii: [stemR * 0.9, stemR * 0.95, stemR * 0.7], color: (t) => shade(shaftC, 0.8 + 0.3 * t), sway: () => 0.05, end: 'flat' })\n crownTop = add(top, [0, 1.25, 0])\n } else if (variant !== 'areca') {\n icoShell(ctx.wood, { center: add(top, [0, stemR * 0.7, 0]), radii: [stemR * 1.35, stemR * 1.0, stemR * 1.35], detail: 0, rng: srng, noise: 0.06, color: (v) => shade(mix(trunkC, [0.35, 0.45, 0.2], 0.55), 0.7 + v.h * 0.5), sway: () => 0.05 })\n crownTop = add(top, [0, stemR * 0.9, 0])\n }\n crowns.push({ p: crownTop, r: frondL })\n ctx.piece(si === 0 ? 'crown' : `crown${si}`, 'crown', trunkId)\n\n const n = clump ? Math.max(3, Math.round(frondN)) : frondN\n for (let i = 0; i < n; i++) {\n if (ctx.lod === 2 && variant === 'fan' && i % 2 === 1) continue\n const f = srng.fork(i)\n const ring = i % 3\n const az2 = (i / n) * TAU * 1.0 + f.range(-0.2, 0.2) + si\n let elev: number\n let droop: number\n if (variant === 'royal') {\n elev = [1.1, 0.65, 0.2][ring] + f.range(-0.1, 0.1)\n droop = [0.35, 0.65, 1.0][ring]\n } else if (variant === 'date') {\n elev = [1.15, 0.8, 0.45][ring] + f.range(-0.08, 0.08)\n droop = [0.3, 0.5, 0.75][ring]\n } else if (variant === 'areca') {\n elev = [1.1, 0.8, 0.5][ring] + f.range(-0.1, 0.1)\n droop = [0.45, 0.8, 1.1][ring]\n } else if (variant === 'fan') {\n elev = [1.3, 0.95, 0.6][ring] + f.range(-0.1, 0.1)\n droop = [0.25, 0.35, 0.5][ring]\n } else {\n elev = [1.15, 0.75, 0.38][ring] + f.range(-0.1, 0.1)\n droop = [0.45, 0.78, 1.1][ring]\n }\n if (dead) {\n elev = elev * 0.4 - 0.3\n droop *= 1.4\n }\n if (dry) droop *= 1.15\n const len = frondL * f.range(0.85, 1.1) * (ring === 2 ? 0.92 : 1)\n const colA = dead ? mix(c0, deadC, 0.8) : c0\n const colB = dead ? mix(c1, deadC, 0.7) : ring === 2 && dry ? mix(c1, deadC, 0.4) : c1\n if (variant === 'fan') {\n fanFrond(ctx, f, crownTop, az2, elev, len, droop, colA, colB)\n } else {\n pinnateFrond(ctx.foliage, {\n origin: crownTop,\n az: az2,\n elev,\n length: len,\n droop,\n leafletLen: variant === 'areca' ? 0.24 : variant === 'date' ? 0.2 : variant === 'coconut' ? 0.25 : 0.24,\n pairs: variant === 'areca' ? 10 : variant === 'royal' ? 26 : variant === 'coconut' ? 28 : 18,\n c0: colA,\n c1: colB,\n lod: ctx.lod,\n rng: f,\n swayBase: 0.25,\n swayTip: 1,\n hang: variant === 'date' ? 0.2 : variant === 'royal' ? 0.5 : variant === 'coconut' ? 0.8 : 0.45,\n leafletWidth: variant === 'date' ? 0.12 : variant === 'coconut' ? 0.13 : 0.2,\n })\n }\n }\n // fruit cluster\n if (spec.fruit && !dead && ctx.lod < 2) {\n const fc = rgb(spec.fruit.color)\n const fr = spec.fruit.radius ?? (variant === 'coconut' ? 0.1 : 0.03)\n const count = Math.round(spec.fruit.count * (ctx.lod === 0 ? 1 : 0.5))\n for (let i = 0; i < count; i++) {\n const a = (i / count) * TAU + srng.range(0, 1)\n const rr = stemR * 1.3 + fr * 0.8\n const p: Vec3 = [crownTop[0] + Math.cos(a) * rr, crownTop[1] - fr * (0.6 + srng.range(0, 1.4)) - 0.05, crownTop[2] + Math.sin(a) * rr]\n ctx.fruitItem(() => icoShell(ctx.fruit, { center: p, radii: [fr, fr * 1.15, fr], detail: 0, rng: srng, noise: 0.04, color: (v) => mix(shade(fc, 0.6), lighten(fc, 0.3), v.h), sway: () => 0.1 }))\n }\n }\n }\n\n if (!clump) {\n buildStem(0, H, R, lean, rng.range(0, TAU))\n } else {\n for (let i = 0; i < stems; i++) {\n const az = (i / stems) * TAU + rng.range(-0.4, 0.4)\n const hh = H * rng.range(0.62, 1.0)\n buildStem(i, hh, R * rng.range(0.85, 1.1), (spec.lean ?? d.lean) * rng.range(0.6, 1.3), az)\n }\n }\n const maxR = crowns.reduce((m, c) => Math.max(m, Math.hypot(c.p[0], c.p[2])), 0)\n return clump\n ? { collider: { kind: 'cylinder', radius: Math.max(0.15, maxR * 0.5 + R * 2), height: H * 0.5 }, bendable: true }\n : { collider: { kind: 'cylinder', radius: R * 1.15, height: H * 0.85 }, bendable: false }\n}\n\n/** Palmate frond: long petiole ending in a round, ribbed fan of folded segments whose tips droop. */\nfunction fanFrond(ctx: Ctx, rng: import('../rng').Rng, origin: Vec3, az: number, elev: number, len: number, droop: number, c0: Vec3, c1: Vec3): void {\n const horiz = dirFromAngles(az, 0)\n const petL = len * 0.82\n const pe = Math.max(0.15, elev)\n const tipPet: Vec3 = [origin[0] + horiz[0] * petL * Math.cos(pe) * 0.8, origin[1] + petL * (Math.sin(pe) * 0.9 - droop * 0.12), origin[2] + horiz[2] * petL * Math.cos(pe) * 0.8]\n const mid: Vec3 = [lerp(origin[0], tipPet[0], 0.5), lerp(origin[1], tipPet[1], 0.5) + petL * 0.06, lerp(origin[2], tipPet[2], 0.5)]\n tube(ctx.foliage, [origin, mid, tipPet], { sides: 3, radii: [len * 0.02, len * 0.015, len * 0.011], color: (t) => shade(mix(c0, [0.55, 0.5, 0.25], 0.35), 0.85 + 0.2 * t), sway: (t) => 0.1 + 0.5 * t, end: 'none' })\n const segs: number = ctx.pick(len < 1.3 ? 9 : 15, 7, 4)\n const span = 3.7\n const bR = len * 0.46\n const tilt = Math.min(1.1, pe) * 0.65\n const A: Vec3 = norm([horiz[0] * Math.cos(tilt), Math.sin(tilt) * 0.95, horiz[2] * Math.cos(tilt)])\n const B: Vec3 = [-horiz[2], 0, horiz[0]]\n for (let i = 0; i < segs; i++) {\n const u = segs === 1 ? 0 : i / (segs - 1) - 0.5\n const th = u * span\n const dir = norm(add(add(mul(A, Math.cos(th)), mul(B, Math.sin(th))), [0, 0.02 - Math.abs(u) * 0.12, 0]))\n const cc = jitter(mix(c0, c1, 0.45), rng, 0.01, 0.07, 0.05)\n const w = ((bR * (span / segs)) * 0.75) / 0.78 + 0.02\n leaf(ctx.foliage, tipPet, dir, [0, 1, 0], bR * (0.92 + 0.08 * Math.cos(th)), w, shade(cc, 0.7), lighten(c1, 0.95), { rows: ctx.pick(3, 2, 2), curl: 0.22 + Math.abs(u) * 0.14, fold: 0.5, swayBase: 0.35, swayTip: 1, peak: 0.82, round: 0.45, baseWidth: 0.04 })\n }\n}\n","import type { BananaSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, catmull, dirFromAngles, mul, norm } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { tube } from '../geometry/tube'\nimport { leaf } from '../geometry/leaf'\nimport { icoShell } from '../geometry/shell'\n\nexport function generateBanana(spec: BananaSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const dead = ctx.condition === 'dead'\n const dry = ctx.condition === 'dry'\n const over = ctx.condition === 'overgrown'\n const H = (spec.height ?? 3.6) * (over ? 1.12 : 1)\n const stemH = H * 0.5\n const R = H * 0.04\n const leafBase = tintGreen(rgb(spec.leafColor ?? 0x66a83e), ctx.condition)\n const nLeaves = Math.round((spec.leafCount ?? 8) * (dead ? 0.5 : over ? 1.2 : 1))\n const tornShare = spec.torn ?? (dry ? 0.9 : 0.5)\n const stemC = mix(rgb(0x9cb86a), tintGreen(rgb(0x9cb86a), ctx.condition), 1)\n\n // pseudostem: leaf sheaths read as bands and flares\n const ctrl: Vec3[] = []\n const lean = rng.range(-0.05, 0.05)\n for (let i = 0; i <= 4; i++) {\n const t = i / 4\n ctrl.push([lean * stemH * t * t, stemH * t, Math.sin(t * 2.5) * 0.02])\n }\n const full = catmull(ctrl, ctx.pick(5, 3, 1))\n const radii = full.map((_, i) => {\n const t = i / (full.length - 1)\n return R * (1 - 0.3 * t) * (1 + 0.45 * Math.exp(-t * 14)) * (1 + 0.04 * Math.cos(t * 26))\n })\n tube(ctx.wood, full, {\n sides: ctx.pick(9, 6, 5),\n radii,\n color: (t, a) => {\n const sheath = 0.86 + 0.14 * Math.cos(t * 26)\n const stripe = 0.93 + 0.07 * Math.cos(a * TAU * 4)\n let c = shade(stemC, sheath * stripe * (0.7 + 0.3 * Math.min(1, t * 5)))\n c = mix(c, [0.55, 0.4, 0.22], Math.max(0, 0.18 - t) * 2.2)\n if (dead) c = mix(c, [0.45, 0.36, 0.22], 0.7)\n return c\n },\n sway: (t) => 0.04 * t,\n end: 'flat',\n })\n const top = full[full.length - 1]\n ctx.piece('crown', 'crown', 'trunk')\n\n // leaves\n const rows = ctx.pick(9, 6, 3)\n for (let i = 0; i < nLeaves; i++) {\n const f = rng.fork(i)\n const ring = i % 3\n const az = (i / nLeaves) * TAU * 1.0 + f.range(-0.25, 0.25)\n const L = H * f.range(0.55, 0.72) * (ring === 2 ? 0.85 : 1)\n const el = [1.15, 0.8, 0.45][ring] + f.range(-0.12, 0.12)\n const horiz = dirFromAngles(az, 0)\n // petiole: a short stalk before the blade\n const petL = L * 0.18\n const pEnd: Vec3 = [top[0] + horiz[0] * petL * Math.cos(el), top[1] + petL * Math.sin(el), top[2] + horiz[2] * petL * Math.cos(el)]\n tube(ctx.foliage, [top, pEnd], { sides: 3, radii: [R * 0.22, R * 0.15], color: () => shade(leafBase, 0.85), sway: () => 0.2, end: 'none' })\n const torn = f.next() < tornShare || dead\n const c0 = dead ? mix(leafBase, [0.4, 0.32, 0.2], 0.85) : jitter(shade(leafBase, 0.7), f, 0.01, 0.06, 0.04)\n const c1 = dead ? mix(leafBase, [0.5, 0.42, 0.25], 0.8) : mix(jitter(lighten(leafBase, 0.5), f, 0.012, 0.06, 0.04), [0.75, 0.85, 0.35], 0.15)\n const tearSeed = f.range(0, 10)\n leaf(ctx.foliage, pEnd, norm([horiz[0] * Math.cos(el), Math.sin(el), horiz[2] * Math.cos(el)]), [0, 1, 0], L, L * 0.34, c0, c1, {\n rows,\n curl: [0.55, 0.7, 0.8][ring] * (dry ? 1.2 : 1),\n fold: 0.35,\n swayBase: 0.25,\n swayTip: 1,\n peak: 0.45,\n round: 0.5,\n baseWidth: 0.12,\n tear: torn ? (row, side) => (row % 2 === 1 && row > 1 && row < rows ? 0.35 + 0.35 * Math.abs(Math.sin(tearSeed + row * 1.3 + side)) : 1) : undefined,\n })\n }\n\n // bunch and bud\n if (spec.bunch && !dead && ctx.lod < 2) {\n const out = dirFromAngles(rng.range(0, TAU), 0)\n const stalk: Vec3[] = [add(top, [0, -0.05, 0]), add(top, add(mul(out, R * 1.6), [0, -0.2, 0])), add(top, add(mul(out, R * 2.2), [0, -0.7, 0])), add(top, add(mul(out, R * 2.1), [0, -1.1, 0]))]\n const sp = catmull(stalk, 2)\n tube(ctx.wood, sp, { sides: 4, radii: sp.map(() => R * 0.2), color: () => [0.35, 0.45, 0.2], sway: (t) => 0.15 + 0.3 * t, end: 'none' })\n const hands = ctx.pick(5, 3, 0)\n const fingers = ctx.pick(7, 4, 0)\n const green = rgb(0x86b04a)\n const yellow = rgb(0xc8c24a)\n const frng = rng.fork('bunch')\n ctx.fruitItem(() => {\n for (let h = 0; h < hands; h++) {\n const t = 0.45 + (0.5 * h) / Math.max(1, hands - 1)\n const idx = Math.min(sp.length - 1, Math.floor(t * (sp.length - 1)))\n const base = sp[idx]\n const ha = h * 1.9\n for (let k = 0; k < fingers; k++) {\n const a = ha + (k / fingers) * 2.4 - 1.2\n const dirOut = dirFromAngles(a, -0.9)\n const fl = 0.16\n const center = add(base, add(mul(dirOut, fl * 0.55 + R * 0.35), [0, -0.02, 0]))\n icoShell(ctx.fruit, {\n center,\n radii: [0.026, fl * 0.55, 0.026],\n detail: 0,\n rng: frng,\n noise: 0.04,\n color: (v) => mix(shade(green, 0.75), mix(green, yellow, 0.3), v.h),\n sway: () => 0.2,\n })\n }\n }\n })\n if (spec.bud) {\n const end = sp[sp.length - 1]\n const bc = rgb(0x7a2a62)\n icoShell(ctx.flowers, { center: add(end, [0, -0.17, 0]), radii: [0.08, 0.18, 0.08], detail: ctx.pick(1, 0, 0) as 0 | 1, rng: frng, noise: 0.05, color: (v) => mix(shade(bc, 0.6), lighten(bc, 0.5), v.h), sway: () => 0.3 })\n }\n } else if (spec.bud && !dead && ctx.lod < 2) {\n const bc = rgb(0x7a2a62)\n icoShell(ctx.flowers, { center: add(top, [0.1, 0.15, 0]), radii: [0.08, 0.18, 0.08], detail: 0, rng: rng.fork('bud'), noise: 0.05, color: (v) => mix(shade(bc, 0.6), lighten(bc, 0.5), v.h), sway: () => 0.3 })\n }\n return { collider: { kind: 'cylinder', radius: R * 1.05, height: stemH * 0.9 }, bendable: true }\n}\n","import type { Vec3 } from '../types'\nimport { add, mul, norm, lerp } from '../math'\nimport { shade } from '../color'\nimport type { Rng } from '../rng'\nimport type { MeshBuilder } from './builder'\n\nexport interface BoxShellOptions {\n center: Vec3\n /** full size x, y, z */\n size: Vec3\n /** grid cells along x, y, z (a single number applies to all three) */\n grid: number | [number, number, number]\n /** 0 = sharp box .. 1 = ellipsoid (pulls edges and corners in) */\n round: number\n rng: Rng\n /** displacement amplitude as a fraction of the smallest dimension (smooth 3D value noise) */\n noise: number\n /** noise frequency in cycles per meter (default 1.8 / smallest dimension) */\n freq?: number\n /** per-face colour jitter (0..1, default 0.1) */\n jitter?: number\n color: (p: Vec3, h: number, n: Vec3) => Vec3\n sway: (h: number) => number\n}\n\nfunction hash3(x: number, y: number, z: number, s: number): number {\n let h = (x * 374761393 + y * 668265263 + z * 2147483647 + s * 1274126177) | 0\n h = Math.imul(h ^ (h >>> 13), 1274126177)\n return ((h ^ (h >>> 16)) >>> 0) / 4294967296\n}\n\n/** Smooth 3D value noise in -1..1. */\nexport function valueNoise3(x: number, y: number, z: number, seed: number): number {\n const xi = Math.floor(x)\n const yi = Math.floor(y)\n const zi = Math.floor(z)\n const fx = x - xi\n const fy = y - yi\n const fz = z - zi\n const sx = fx * fx * (3 - 2 * fx)\n const sy = fy * fy * (3 - 2 * fy)\n const sz = fz * fz * (3 - 2 * fz)\n const n = (a: number, b: number, c: number): number => hash3(xi + a, yi + b, zi + c, seed)\n const x00 = lerp(n(0, 0, 0), n(1, 0, 0), sx)\n const x10 = lerp(n(0, 1, 0), n(1, 1, 0), sx)\n const x01 = lerp(n(0, 0, 1), n(1, 0, 1), sx)\n const x11 = lerp(n(0, 1, 1), n(1, 1, 1), sx)\n return lerp(lerp(x00, x10, sy), lerp(x01, x11, sy), sz) * 2 - 1\n}\n\n/**\n * Clipped hedge section: one subdivided box (bottom face omitted) whose vertices are pushed along their outward\n * direction by smooth value noise, with edges and corners pulled in. Flat shaded, per-face colour jitter.\n */\nexport function boxShell(b: MeshBuilder, o: BoxShellOptions): void {\n const [gx, gy, gz] = typeof o.grid === 'number' ? [o.grid, o.grid, o.grid] : o.grid\n const hx = o.size[0] / 2\n const hy = o.size[1] / 2\n const hz = o.size[2] / 2\n const minDim = Math.min(o.size[0], o.size[1], o.size[2])\n const amp = o.noise * minDim\n const freq = o.freq ?? 1.8 / minDim\n const seed = Math.floor(o.rng.next() * 1e6)\n const jit = o.jitter ?? 0.1\n const faces: { n: Vec3; u: Vec3; v: Vec3; cu: number; cv: number }[] = [\n { n: [1, 0, 0], u: [0, 0, 1], v: [0, 1, 0], cu: gz, cv: gy },\n { n: [-1, 0, 0], u: [0, 1, 0], v: [0, 0, 1], cu: gy, cv: gz },\n { n: [0, 0, 1], u: [1, 0, 0], v: [0, 1, 0], cu: gx, cv: gy },\n { n: [0, 0, -1], u: [0, 1, 0], v: [1, 0, 0], cu: gy, cv: gx },\n { n: [0, 1, 0], u: [0, 0, 1], v: [1, 0, 0], cu: gz, cv: gx },\n ]\n // shared grid vertices keyed by quantized cube coordinate so faces stay welded\n const cache = new Map<string, Vec3>()\n const vertex = (c: Vec3): Vec3 => {\n const key = c.map((x) => Math.round(x * 1000)).join(',')\n const hit = cache.get(key)\n if (hit) return hit\n const m = Math.max(Math.abs(c[0]), Math.abs(c[1]), Math.abs(c[2]))\n const s = norm(c)\n const sphere: Vec3 = [s[0] * m, s[1] * m, s[2] * m]\n const q: Vec3 = [lerp(c[0], sphere[0], o.round), lerp(c[1], sphere[1], o.round), lerp(c[2], sphere[2], o.round)]\n const base: Vec3 = [o.center[0] + q[0] * hx, o.center[1] + q[1] * hy, o.center[2] + q[2] * hz]\n const nz = valueNoise3(base[0] * freq, base[1] * freq, base[2] * freq, seed) * 0.75 + valueNoise3(base[0] * freq * 2.3, base[1] * freq * 2.3, base[2] * freq * 2.3, seed + 7) * 0.25\n const out = norm([q[0] / Math.max(hx, 1e-6), q[1] / Math.max(hy, 1e-6), q[2] / Math.max(hz, 1e-6)])\n const p: Vec3 = add(base, mul(out, nz * amp))\n cache.set(key, p)\n return p\n }\n let fi = 0\n for (const f of faces) {\n for (let i = 0; i < f.cu; i++) {\n for (let j = 0; j < f.cv; j++) {\n const u0 = (i / f.cu) * 2 - 1\n const u1 = ((i + 1) / f.cu) * 2 - 1\n const v0 = (j / f.cv) * 2 - 1\n const v1 = ((j + 1) / f.cv) * 2 - 1\n const corner = (u: number, v: number): Vec3 => add(add(mul(f.n, 1), mul(f.u, u)), mul(f.v, v))\n const ps = [vertex(corner(u0, v0)), vertex(corner(u1, v0)), vertex(corner(u1, v1)), vertex(corner(u0, v1))]\n const hs = ps.map((p) => (p[1] - (o.center[1] - hy)) / o.size[1])\n const fj = 1 - jit + 2 * jit * hash3(fi++, i, j, seed)\n const cs = ps.map((p, k) => shade(o.color(p, hs[k], f.n), fj))\n b.flatQuad(ps[0], ps[1], ps[2], ps[3], cs[0], cs[1], cs[2], cs[3], o.sway(hs[0]), o.sway(hs[1]), o.sway(hs[2]), o.sway(hs[3]), add(f.n, [0, 0, 0]))\n }\n }\n }\n}\n","import type { ShrubSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, clamp, lerp, mul, norm } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { Rng } from '../rng'\nimport { tube } from '../geometry/tube'\nimport { clump, clumpLeaves } from '../geometry/shell'\nimport { boxShell } from '../geometry/boxshell'\nimport { blossom, flowerHead, type FlowerKind } from '../geometry/flower'\nimport { leaf } from '../geometry/leaf'\nimport { leafAmount } from './shared'\n\nconst DEFAULT_LEAF = [0x3f8a3a, 0x4a9a42, 0x357a38]\n\nexport function generateShrub(spec: ShrubSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const shape = spec.shape ?? 'round'\n const over = ctx.condition === 'overgrown'\n const dead = ctx.condition === 'dead'\n const R = (spec.radius ?? 0.6) * (over ? 1.2 : 1)\n const H = (spec.height ?? (shape === 'hedge' ? 1.1 : R * 1.5)) * (over ? 1.15 : 1)\n const density = (spec.density ?? 1) * leafAmount(ctx, false)\n const palette = (spec.leafColor ?? DEFAULT_LEAF).map((c) => tintGreen(rgb(c), ctx.condition))\n const stemC = rgb(spec.stemColor ?? 0x6a4c34)\n const flowers = spec.flowers && !dead && !(ctx.season === 'winter' && rng.fork('w').next() < 0.5)\n const variegation = spec.variegation?.map(rgb)\n const lsize = spec.leafSize ?? 1\n\n const flowerDots = (center: Vec3, rx: number, ry: number, rz: number, count: number, frng: Rng, crown: Vec3): void => {\n if (!spec.flowers) return\n const fl = spec.flowers\n const colors = fl.colors.map(rgb)\n const size = (fl.size ?? 0.045) * (shape === 'hedge' ? 1 : 1)\n const style = fl.style ?? 'dots'\n for (let i = 0; i < count; i++) {\n const a = frng.range(0, TAU)\n const y = frng.range(0.05, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [center[0] + d[0] * rx * 1.0, center[1] + d[1] * ry * 1.0, center[2] + d[2] * rz * 1.0]\n const n = norm(add(d, mul(norm([p[0] - crown[0], p[1] - crown[1], p[2] - crown[2]]), 0.5)))\n const c = frng.pick(colors)\n if (style === 'dots') {\n blossom(ctx.flowers, add(p, mul(n, size * 0.2)), n, size, shade(c, 1.05), jitter(c, frng, 0.01, 0.05), 0.6, ctx.pick(5, 4, 3), frng.range(0, TAU))\n } else if (style === 'clusters') {\n flowerHead(ctx.flowers, { kind: 'bract', center: add(p, mul(n, size * 0.2)), axis: n, size: size * 1.4, colors, centerColor: [1, 1, 1], rng: frng.fork(i), lod: ctx.lod, sway: 0.6 })\n } else {\n flowerHead(ctx.flowers, { kind: (style === 'hibiscus' ? 'hibiscus' : 'bell') as FlowerKind, center: add(p, mul(n, size * 0.1)), axis: n, size: size * 1.6, colors, centerColor: [1, 0.85, 0.3], rng: frng.fork(i), lod: ctx.lod, sway: 0.6 })\n }\n }\n }\n\n if (shape === 'hedge') {\n const length = spec.length ?? 2.4\n const width = spec.width ?? Math.max(0.6, H * 0.6)\n const sections = Math.max(1, Math.round(length / (width * 1.1)))\n const secLen = length / sections\n const grid: [number, number, number] = ctx.lod === 0 ? [6, 4, 4] : ctx.lod === 1 ? [4, 3, 3] : [3, 2, 2]\n const base = dead ? mix(palette[0], [0.42, 0.33, 0.22], 0.65) : ctx.condition === 'dry' ? mix(palette[0], [0.5, 0.45, 0.22], 0.35) : palette[0]\n for (let i = 0; i < sections; i++) {\n const sr = rng.fork(i * 17 + 3)\n const cx = -length / 2 + secLen * (i + 0.5)\n const h = H * sr.range(0.96, 1.04)\n const seed = sr.seed()\n const sect = new Rng(seed)\n const c = jitter(base, sect, 0.01, 0.05, 0.04)\n boxShell(ctx.foliage, {\n center: [cx, h * 0.5, 0],\n size: [secLen * 1.04, h, width],\n grid,\n round: 0.42,\n rng: sect,\n noise: 0.12,\n freq: 3 / Math.min(secLen, h, width),\n jitter: 0.12,\n color: (p, hh, n) => {\n let k = lerp(0.7, 1.15, clamp(hh, 0, 1)) * (0.88 + 0.24 * ((Math.sin(p[0] * 47.3 + p[1] * 31.7 + p[2] * 53.9) + 1) / 2))\n if (n[1] > 0.5) k *= 1.08\n return mix(shade(c, k), lighten(c, 0.6), clamp((hh - 0.9) * 4, 0, 0.5))\n },\n sway: (hh) => 0.3 * hh,\n })\n if (ctx.lod === 0) {\n // leaf flecks poking from the clipped surface\n const lc0 = shade(c, 0.75)\n const lc1 = lighten(c, 0.9)\n for (let k = 0; k < 14; k++) {\n const onTop = k % 3 !== 0\n const px = cx + sr.range(-secLen / 2, secLen / 2)\n const pz = sr.range(-width / 2, width / 2) * 0.9\n const pos: Vec3 = onTop ? [px, h * 0.98, pz] : [px, sr.range(0.3, 0.9) * h, (pz > 0 ? 1 : -1) * width * 0.5]\n const n: Vec3 = onTop ? [sr.range(-0.3, 0.3), 1, sr.range(-0.3, 0.3)] : [0, 0.3, pz > 0 ? 1 : -1]\n leaf(ctx.foliage, pos, norm(add(n, [sr.range(-0.4, 0.4), 0, sr.range(-0.4, 0.4)])), n, 0.1 * lsize, 0.08 * lsize, lc0, lc1, { curl: 0.2, swayBase: 0.3, swayTip: 0.5 })\n }\n }\n if (flowers) flowerDots([cx, h * 0.5, 0], secLen * 0.5, h * 0.5, width * 0.5, ctx.pick(8, 5, 0) * Math.round((spec.flowers?.count ?? 10) / 10), sr.fork('f'), [cx, h * 0.3, 0])\n }\n return { collider: null, bendable: true }\n }\n\n // round / loose: multi stem bush with clumps\n const crownC: Vec3 = [0, H * 0.5, 0]\n const nStems = ctx.pick(6, 4, 3)\n const nClumps = Math.max(3, Math.round(ctx.pick(9, 10, 4) * clamp(density, 0.3, 1.4) * (shape === 'loose' ? 0.9 : 1)))\n const anchors: { p: Vec3; r: number; seed: number }[] = []\n for (let i = 0; i < nClumps; i++) {\n const f = rng.fork(i + 1)\n const a = (i / nClumps) * TAU * 1.0 + f.range(-0.5, 0.5)\n const layer = i % 3\n const rr = R * (layer === 0 ? f.range(0.0, 0.35) : f.range(0.45, 0.8)) * (shape === 'loose' ? 1.15 : 1)\n const y = H * (layer === 0 ? f.range(0.55, 0.8) : layer === 1 ? f.range(0.35, 0.55) : f.range(0.22, 0.4))\n anchors.push({ p: [Math.cos(a) * rr, y, Math.sin(a) * rr], r: R * f.range(0.42, 0.62) * (shape === 'loose' ? 0.9 : 1) * (ctx.lod === 1 ? 0.8 : 1), seed: f.seed() })\n }\n // stems from the ground to the lower clumps\n for (let i = 0; i < nStems; i++) {\n const a = anchors[i % anchors.length]\n const base: Vec3 = [a.p[0] * 0.12, 0, a.p[2] * 0.12]\n const mid: Vec3 = [a.p[0] * 0.5, a.p[1] * 0.5, a.p[2] * 0.5]\n tube(ctx.wood, [base, mid, [a.p[0] * 0.85, a.p[1] * 0.85, a.p[2] * 0.85]], { sides: ctx.pick(5, 4, 3), radii: [R * 0.05, R * 0.04, R * 0.025], color: (t) => shade(stemC, 0.7 + 0.4 * t), sway: (t) => 0.1 + 0.3 * t, end: 'point' })\n }\n anchors.forEach((a, idx) => {\n const crn = idx % 2 === 0\n const base = variegation && crn ? variegation[idx % variegation.length] : palette[idx % palette.length]\n const o = {\n center: a.p,\n radius: a.r,\n squash: shape === 'loose' ? 0.85 : 0.8,\n detail: (ctx.lod === 0 ? 1 : 0) as 0 | 1,\n seed: a.seed,\n base: dead ? mix(base, [0.4, 0.35, 0.27], 0.6) : base,\n crown: crownC,\n leaves: ctx.lod === 0 ? { count: 6 + Math.round(a.r * 8), length: a.r * 0.5 * lsize, width: a.r * 0.4 * lsize } : ctx.lod === 1 ? { count: 2 + Math.round(a.r * 3), length: a.r * 0.55 * lsize, width: a.r * 0.45 * lsize } : undefined,\n swayK: 0.7,\n noise: shape === 'loose' ? 0.3 : 0.2,\n flatBottom: 0.6,\n ao: 0.45,\n }\n clump(ctx.foliage, o)\n if (ctx.lod < 2) clumpLeaves(ctx.foliage, o)\n })\n if (variegation && ctx.lod < 2) {\n // colorful croton leaves: broad leaves in the variegation palette all over the surface\n const vr = rng.fork('vari')\n const n = ctx.pick(36, 14, 0)\n for (let i = 0; i < n; i++) {\n const a = vr.range(0, TAU)\n const y = vr.range(0.15, 1)\n const r = Math.sqrt(1 - y * y)\n const d: Vec3 = [Math.cos(a) * r, y, Math.sin(a) * r]\n const p: Vec3 = [d[0] * R * 0.8, H * 0.5 + d[1] * H * 0.42, d[2] * R * 0.8]\n const c = vr.pick(variegation)\n leaf(ctx.foliage, p, norm(add(mul(d, 0.4), [0, 0.8, 0])), d, 0.17 * lsize, 0.1 * lsize, shade(c, 0.75), lighten(c, 0.3), { rows: 2, curl: 0.25, fold: 0.5, swayBase: 0.6, swayTip: 0.9, peak: 0.45 })\n }\n }\n if (flowers && spec.flowers) {\n const fr = rng.fork('flowers')\n const count = Math.round((spec.flowers.count ?? 24) * ctx.pick(1, 0.5, 0))\n flowerDots([0, H * 0.5, 0], R * 1.0, H * 0.52, R * 1.0, count, fr, crownC)\n }\n return { collider: null, bendable: true }\n}\n","import type { ConiferSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU, add, catmull, dirFromAngles, lerp, mul } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { tube } from '../geometry/tube'\nimport { leaf } from '../geometry/leaf'\nimport { barkColor } from '../geometry/wood'\n\nexport function generateConifer(spec: ConiferSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const shape = spec.shape ?? 'cone'\n const dead = ctx.condition === 'dead'\n const over = ctx.condition === 'overgrown'\n const H = (spec.height ?? (shape === 'candelabra' ? 14 : 9)) * (over ? 1.08 : 1)\n const R = spec.radius ?? H * (shape === 'candelabra' ? 0.2 : 0.24)\n const trunkR = spec.trunkRadius ?? H * 0.02\n const leafBase = tintGreen(rgb(spec.leafColor ?? (shape === 'candelabra' ? 0x3d6e3a : 0x2f6e3a)), ctx.condition)\n const bark = rgb(spec.barkColor ?? (shape === 'candelabra' ? 0x6a5442 : 0x6b4b34))\n const tiers = spec.tiers ?? (shape === 'candelabra' ? 6 : 9)\n const lean = rng.range(-0.02, 0.02) * H\n const trunkTop = shape === 'candelabra' ? H : H * 0.96\n const ctrl: Vec3[] = []\n for (let i = 0; i <= 4; i++) {\n const t = i / 4\n ctrl.push([lean * t * t, trunkTop * t, Math.sin(t * 3 + 1) * 0.01 * H])\n }\n const tp = catmull(ctrl, ctx.pick(3, 2, 1))\n const tr = tp.map((_, i) => {\n const t = i / (tp.length - 1)\n return trunkR * (1 - 0.7 * t) * (1 + 0.5 * Math.exp(-t * 20))\n })\n tube(ctx.wood, tp, { sides: ctx.pick(8, 6, 4), radii: tr, color: barkColor(bark, 0), sway: () => 0.02, end: 'point' })\n ctx.piece('crown', 'crown', 'trunk')\n\n if (shape === 'cone') {\n const foliage = ctx.foliage\n const K = ctx.pick(10, 8, 6)\n const startY = H * (dead ? 0.35 : 0.14)\n for (let i = 0; i < tiers; i++) {\n const f = tiers === 1 ? 0 : i / (tiers - 1)\n const y = lerp(startY, H * 0.9, f)\n const tierH = (H * 0.9 - startY) / tiers * 1.9\n const r = R * lerp(1, 0.14, Math.pow(f, 0.95)) * (1 + (i % 2) * 0.06)\n const col = jitter(leafBase, rng.fork(i), 0.012, 0.06, 0.04)\n const lightTop = mix(lighten(col, 1.0), [0.75, 0.88, 0.5], 0.2)\n const dark = shade(col, 0.62)\n const apex: Vec3 = [lean * (y / H) ** 2, y + tierH * 0.55, 0]\n const innerR = r * 0.32\n const ring = (rad: number, yy: number, k: number, ph: number): Vec3 => [apex[0] + Math.cos((k / K) * TAU + ph) * rad, yy, Math.sin((k / K) * TAU + ph) * rad]\n const tphase = i * 0.7\n for (let k = 0; k < K; k++) {\n const jag = k % 2 === 0 ? 1 : 0.78\n const a0 = ring(innerR, y + tierH * 0.12, k, tphase)\n const a1 = ring(innerR, y + tierH * 0.12, k + 1, tphase)\n const o0 = ring(r * jag, y - tierH * 0.42, k, tphase)\n const o1 = ring(r * (k % 2 === 0 ? 0.78 : 1), y - tierH * 0.42, k + 1, tphase)\n const sw = 0.25 + 0.35 * (1 - f)\n // top surface\n foliage.flat(apex, a1, a0, shade(lightTop, 0.85), 0.2, [0, 1, 0])\n foliage.flatTri(a0, a1, o1, mix(col, lightTop, 0.2), mix(col, lightTop, 0.2), lightTop, 0.2, 0.2, sw, [0, 1, 0])\n foliage.flatTri(a0, o1, o0, mix(col, lightTop, 0.2), lightTop, lightTop, 0.2, sw, sw, [0, 1, 0])\n // underside, dark\n foliage.flatTri(a0, o0, o1, dark, shade(dark, 1.1), shade(dark, 1.1), 0.2, sw, sw, [0, -1, 0])\n foliage.flatTri(a0, o1, a1, dark, shade(dark, 1.1), dark, 0.2, sw, 0.2, [0, -1, 0])\n }\n if (ctx.lod === 0) {\n // drooping branchlets poking out of the skirt\n const nb = 8\n for (let k = 0; k < nb; k++) {\n const ang = (k / nb) * TAU + tphase * 0.5 + rng.fork(i * 9 + k).range(0, 0.5)\n const d = dirFromAngles(ang, -0.35)\n leaf(foliage, [apex[0] + Math.cos(ang) * r * 0.55, y - tierH * 0.2, apex[2] + Math.sin(ang) * r * 0.55], d, [0, 1, 0], r * 0.55, r * 0.22, shade(col, 0.7), lightTop, { rows: 2, curl: 0.45, fold: 0.5, swayBase: 0.3, swayTip: 0.7, peak: 0.4 })\n }\n }\n }\n } else {\n // candelabra (araucaria): whorls of upturned branches carrying thick needle sleeves\n const whorls = Math.max(3, Math.min(tiers, ctx.pick(5, 4, 3)))\n const perWhorl = ctx.pick(8, 6, 5)\n for (let w = 0; w < whorls; w++) {\n const f = whorls === 1 ? 1 : w / (whorls - 1)\n const y = lerp(H * 0.66, H * 0.9, f)\n const len = R * lerp(1.15, 0.6, f)\n const topY = H * lerp(0.93, 1.0, f)\n for (let k = 0; k < perWhorl; k++) {\n const fr = rng.fork(w * 31 + k)\n const az = (k / perWhorl) * TAU + w * 0.9 + fr.range(-0.2, 0.2)\n const out = dirFromAngles(az, 0)\n const start: Vec3 = [lean * (y / H) ** 2, y, 0]\n const rise = Math.max(0.5, topY - y)\n const p1 = add(start, add(mul(out, len * 0.4), [0, rise * 0.02, 0]))\n const p2 = add(start, add(mul(out, len * 0.75), [0, rise * 0.22, 0]))\n const p3 = add(start, add(mul(out, len * 1.0), [0, rise * 0.95, 0]))\n const path = catmull([start, p1, p2, p3], ctx.pick(2, 1, 1))\n const n = path.length\n if (ctx.lod < 2) tube(ctx.wood, path, { sides: ctx.pick(4, 3, 3), radii: path.map((_, i) => trunkR * 0.35 * (1 - 0.6 * (i / (n - 1)))), color: barkColor(bark, 1), sway: (t) => 0.1 + 0.2 * t, end: 'none' })\n const col = jitter(leafBase, fr, 0.012, 0.08, 0.05)\n const sleeve = path.slice(Math.floor(n * 0.2))\n const sr = Math.max(0.12, R * 0.085 * lerp(1, 0.85, f))\n tube(ctx.foliage, sleeve, {\n sides: ctx.pick(6, 5, 4),\n radii: sleeve.map((_, i) => sr * (0.55 + 0.45 * Math.sin(Math.min(1, (i + 0.5) / (sleeve.length - 0.5)) * Math.PI * 0.9 + 0.3))),\n color: (t, a) => mix(shade(col, 0.55), lighten(col, 0.7), clamp01(0.4 * t + 0.6 * (0.5 + 0.5 * Math.sin(a * TAU)))),\n sway: (t) => 0.2 + 0.4 * t,\n end: 'point',\n smooth: false,\n rough: ctx.lod === 0 ? (_r, i) => (i % 2 ? 0.28 : -0.12) : undefined,\n })\n }\n }\n // leader tuft\n tube(ctx.foliage, [[lean, H * 0.93, 0], [lean, H * 1.02, 0]], { sides: 5, radii: [R * 0.07, R * 0.03], color: () => shade(leafBase, 0.9), sway: () => 0.2, end: 'point' })\n }\n return { collider: { kind: 'cylinder', radius: trunkR * 1.2, height: H * 0.6 }, bendable: false }\n}\n\nconst clamp01 = (v: number): number => (v < 0 ? 0 : v > 1 ? 1 : v)\n","import type { VineSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { add, catmull, lerp, mul, norm, sampleLine, TAU, sub, cross } from '../math'\nimport { jitter, mix, rgb, shade, tintGreen, lighten } from '../color'\nimport { tube } from '../geometry/tube'\nimport { leaf } from '../geometry/leaf'\nimport { flowerHead } from '../geometry/flower'\n\n/** Climbing plant along a host polyline or a wall rectangle in the xy plane facing +z. */\nexport function generateVine(spec: VineSpec, ctx: Ctx): ArchResult {\n const rng = ctx.rng\n const dead = ctx.condition === 'dead'\n const over = ctx.condition === 'overgrown'\n const host = spec.host ?? { wall: { width: 2.5, height: 2.2 } }\n const base = tintGreen(rgb(spec.leafColor ?? 0x3f8a3a), ctx.condition)\n const stemC = rgb(spec.stemColor ?? 0x5a4630)\n const lsize = spec.leafSize ?? 1\n const density = (spec.density ?? 1) * (over ? 1.5 : 1) * (dead ? 0.15 : ctx.condition === 'dry' ? 0.6 : 1)\n const c0 = shade(base, 0.65)\n const c1 = mix(lighten(base, 0.5), [0.7, 0.85, 0.4], 0.1)\n\n const stems: Vec3[][] = []\n if ('path' in host) {\n const pts = host.path\n const nStems = 2\n for (let s = 0; s < nStems; s++) {\n const off = rng.range(0.02, 0.06)\n const wob = rng.range(0, TAU)\n const path = pts.map((p, i) => add(p, [Math.sin(i * 1.7 + wob + s * 2) * off, Math.cos(i * 1.3 + wob) * off, Math.sin(i * 0.9 + s) * off]))\n stems.push(catmull(path, ctx.pick(2, 1, 1)))\n }\n } else {\n const W = host.wall.width\n const Hh = host.wall.height\n const n = Math.max(2, Math.round(W / 0.7))\n for (let i = 0; i < n; i++) {\n const x0 = -W / 2 + (W * (i + 0.5)) / n + rng.range(-0.1, 0.1)\n const topY = Hh * rng.range(0.55, 0.98) * (over ? 1 : 0.92)\n const ctrl: Vec3[] = [[x0, 0, 0.03]]\n let x = x0\n for (let k = 1; k <= 5; k++) {\n x += rng.range(-0.18, 0.18)\n ctrl.push([clamp(x, -W / 2, W / 2), (topY * k) / 5, 0.03 + rng.range(0, 0.02)])\n }\n const main = catmull(ctrl, ctx.pick(2, 1, 1))\n stems.push(main)\n // side branches spreading across the wall\n const nb = Math.round(rng.range(2, 3.5) * (over ? 1.4 : 1))\n for (let b = 0; b < nb; b++) {\n const t = rng.range(0.25, 0.85)\n const s = sampleLine(main, t)\n const dir = rng.sign()\n const len = W * rng.range(0.18, 0.4)\n const end: Vec3 = [clamp(s.p[0] + dir * len, -W / 2, W / 2), Math.min(Hh, s.p[1] + rng.range(0.05, 0.35)), 0.035]\n const mid: Vec3 = [lerp(s.p[0], end[0], 0.5), lerp(s.p[1], end[1], 0.5) + rng.range(-0.08, 0.08), 0.04]\n stems.push(catmull([s.p, mid, end], ctx.pick(2, 1, 1)))\n }\n }\n }\n // draw stems and leaves\n const flowers = spec.flowers && !dead\n for (let si = 0; si < stems.length; si++) {\n const st = stems[si]\n const n = st.length\n tube(ctx.wood, st, { sides: 3, radii: st.map((_, i) => (si < 3 ? 0.014 : 0.009) * (1 - 0.5 * (i / (n - 1)))), color: (t) => shade(stemC, 0.8 + 0.4 * t), sway: (t) => 0.1 + 0.3 * t, end: 'point' })\n const spacing = 0.16 / Math.max(0.2, density)\n let length = 0\n for (let i = 1; i < n; i++) length += Math.hypot(...(sub(st[i], st[i - 1]) as Vec3))\n const count = Math.max(0, Math.round((length / spacing) * ctx.pick(1, 0.4, 0.2)))\n const lrng = rng.fork(si + 100)\n for (let k = 0; k < count; k++) {\n const t = (k + lrng.range(0.1, 0.9)) / count\n const s = sampleLine(st, t)\n const side = k % 2 ? 1 : -1\n const hostNormal: Vec3 = 'path' in host ? norm(cross(s.d, [0, 1, 0.01])) : [0, 0, 1]\n const lateral = norm(cross(hostNormal, s.d))\n const dir = norm(add(add(mul(lateral, side * 0.9), mul(s.d, lrng.range(0.0, 0.5))), mul(hostNormal, 0.35)))\n const len = 0.17 * lsize * lrng.range(0.8, 1.3)\n const cc0 = jitter(c0, lrng, 0.012, 0.07, 0.04)\n const cc1 = jitter(c1, lrng, 0.012, 0.07, 0.04)\n leaf(ctx.foliage, add(s.p, mul(hostNormal, 0.01)), dir, hostNormal, len, len * 0.9, dead ? [0.4, 0.34, 0.24] : cc0, dead ? [0.5, 0.42, 0.28] : cc1, { rows: 2, curl: 0.15, fold: 0.4, swayBase: 0.3, swayTip: 0.8, peak: 0.4, round: 0.6, baseWidth: 0.2 })\n if (flowers && spec.flowers && lrng.next() < (0.16 * (spec.flowers.count ?? 12)) / 12 * ctx.pick(1, 0.6, 0)) {\n const cols = spec.flowers.colors.map(rgb)\n const sz = spec.flowers.style === 'passion' ? 0.06 : 0.055\n flowerHead(ctx.flowers, {\n kind: spec.flowers.style === 'passion' ? 'passion' : 'bract',\n center: add(s.p, mul(hostNormal, 0.05)),\n axis: norm(add(hostNormal, [lrng.range(-0.3, 0.3), 0.2, lrng.range(-0.3, 0.3)])),\n size: sz * lrng.range(0.9, 1.3),\n colors: cols,\n centerColor: [1, 1, 1],\n rng: lrng.fork(k),\n lod: ctx.lod,\n sway: 0.6,\n })\n }\n }\n }\n return { collider: null, bendable: true }\n}\n\nconst clamp = (v: number, a: number, b: number): number => (v < a ? a : v > b ? b : v)\n","import type { PartKind, PottedSpec, Vec3 } from '../types'\nimport type { ArchResult, Ctx } from '../ctx'\nimport { TAU } from '../math'\nimport { jitter, rgb, shade } from '../color'\nimport { tube } from '../geometry/tube'\nimport { generate } from '../generate'\n\n/** Plant in a pot: pot shell, soil disc, then the wrapped plant generated at the same lod / condition / season. */\nexport function generatePotted(spec: PottedSpec, ctx: Ctx): ArchResult {\n const pot = spec.pot ?? {}\n const shape = pot.shape ?? 'terracotta'\n const R = pot.radius ?? 0.2\n const h = pot.height ?? R * 1.6\n const col = rgb(pot.color ?? (shape === 'cachepot' ? 0xe8e2d4 : shape === 'cylinder' ? 0x6a6e72 : 0xb5603c))\n const sides = ctx.pick(shape === 'square' ? 4 : 12, shape === 'square' ? 4 : 8, shape === 'square' ? 4 : 5)\n const prof: { y: number; r: number }[] = []\n switch (shape) {\n case 'terracotta':\n prof.push({ y: 0, r: R * 0.62 }, { y: h * 0.1, r: R * 0.66 }, { y: h * 0.7, r: R * 0.92 }, { y: h * 0.78, r: R * 1.06 }, { y: h * 0.95, r: R * 1.08 }, { y: h * 0.98, r: R * 0.96 })\n break\n case 'cylinder':\n prof.push({ y: 0, r: R * 0.97 }, { y: h * 0.04, r: R }, { y: h * 0.92, r: R }, { y: h * 0.97, r: R * 1.03 }, { y: h * 0.98, r: R * 0.94 })\n break\n case 'square':\n prof.push({ y: 0, r: R * 1.0 }, { y: h * 0.92, r: R * 1.2 }, { y: h * 0.97, r: R * 1.24 }, { y: h * 0.98, r: R * 1.12 })\n break\n default: // cachepot\n prof.push({ y: 0, r: R * 0.8 }, { y: h * 0.12, r: R * 0.95 }, { y: h * 0.55, r: R * 1.12 }, { y: h * 0.88, r: R * 1.04 }, { y: h * 0.95, r: R * 1.06 }, { y: h * 0.98, r: R * 0.95 })\n }\n ctx.piece('pot', 'pot')\n const path: Vec3[] = prof.map((p) => [0, p.y, 0])\n tube(ctx.wood, path, {\n sides,\n radii: prof.map((p) => p.r),\n color: (t, a) => {\n const c = jitter(col, ctx.rng.fork(1), 0.004, 0.02, 0.02)\n const k = 0.7 + 0.35 * t + 0.04 * Math.cos(a * TAU * 2)\n return t > 0.93 ? shade(c, 1.12) : shade(c, k)\n },\n sway: () => 0,\n end: 'none',\n smooth: shape !== 'square',\n })\n // soil disc\n ctx.piece('soil', 'soil', 'pot')\n const soilY = h * 0.93\n const soil: Vec3 = [0.22, 0.15, 0.1]\n const rim = (prof[prof.length - 2]?.r ?? R) * 0.96\n for (let i = 0; i < sides; i++) {\n const a0 = (i / sides) * TAU\n const a1 = ((i + 1) / sides) * TAU\n ctx.wood.flatTri([0, soilY, 0], [Math.cos(a1) * rim, soilY, Math.sin(a1) * rim], [Math.cos(a0) * rim, soilY, Math.sin(a0) * rim], shade(soil, 0.9), soil, soil, 0, 0, 0, [0, 1, 0])\n }\n // inner plant\n const inner = generate(spec.plant, { seed: ctx.rng.fork('plant').seed(), lod: ctx.lod, condition: ctx.condition, season: ctx.season })\n const yOff = soilY - 0.02\n const tagsOf = (part: PartKind): ((t: number) => string) | undefined => {\n const mesh = inner.parts[part]\n if (!mesh) return undefined\n const tags = new Array<string>(mesh.triangleCount).fill('')\n for (const pc of inner.pieces) {\n if (pc.part !== part) continue\n if (!ctx.pieceMeta.has(pc.id)) ctx.pieceMeta.set(pc.id, { kind: pc.kind, parent: pc.parent, pivot: [pc.pivot[0], pc.pivot[1] + yOff, pc.pivot[2]], ...(pc.radius === undefined || pc.length === undefined || !pc.axis || !pc.base ? {} : { geom: { radius: pc.radius, length: pc.length, axis: pc.axis, base: [pc.base[0], pc.base[1] + yOff, pc.base[2]] as Vec3 } }) })\n for (let t = pc.indexStart / 3; t < (pc.indexStart + pc.indexCount) / 3; t++) tags[t] = pc.id\n }\n return (t) => tags[t]\n }\n if (inner.parts.wood) ctx.wood.appendMesh(inner.parts.wood, 0, yOff, 0, 0, 1, tagsOf('wood'))\n if (inner.parts.spines) ctx.spines.appendMesh(inner.parts.spines, 0, yOff, 0, 0, 1, tagsOf('spines'))\n if (inner.parts.foliage) ctx.foliage.appendMesh(inner.parts.foliage, 0, yOff, 0, 0, 1, tagsOf('foliage'))\n if (inner.parts.flowers) ctx.flowers.appendMesh(inner.parts.flowers, 0, yOff, 0, 0, 1, tagsOf('flowers'))\n if (inner.parts.fruit) ctx.fruit.appendMesh(inner.parts.fruit, 0, yOff, 0, 0, 1, tagsOf('fruit'))\n return {\n collider: { kind: 'cylinder', radius: Math.max(R * 1.1, 0.1), height: h },\n bendable: inner.bendable,\n thorny: inner.thorny,\n foliageMaterial: inner.parts.foliage?.material,\n }\n}\n","import type { Condition, GenerateOptions, Lod, PartKind, PieceGeometry, PieceKind, PlantMesh, PlantPiece, PlantSpec, Season, Vec3 } from './types'\nimport { materialKeyForPart, type MaterialKey } from './destruction'\nimport { Rng, toSeed } from './rng'\nimport { MeshBuilder } from './geometry/builder'\nimport type { ArchResult, Ctx, PieceMeta } from './ctx'\nimport { generateBroadleafTree } from './archetypes/broadleaf-tree'\nimport { generateDeadTree } from './archetypes/dead-tree'\nimport { generateFlowerPlant } from './archetypes/flower-plant'\nimport { generateGrassTuft } from './archetypes/grass-tuft'\nimport { generateFern } from './archetypes/fern'\nimport { generateRosette } from './archetypes/rosette'\nimport { generateColumnarCactus } from './archetypes/cactus-columnar'\nimport { generatePaddleCactus } from './archetypes/cactus-paddle'\nimport { generateGlobeCactus } from './archetypes/cactus-globe'\nimport { generatePalm } from './archetypes/palm'\nimport { generateBanana } from './archetypes/banana'\nimport { generateShrub } from './archetypes/shrub'\nimport { generateConifer } from './archetypes/conifer'\nimport { generateVine } from './archetypes/vine'\nimport { generatePotted } from './archetypes/potted'\n\ntype Gen = (spec: any, ctx: Ctx) => ArchResult\n\n/** Registry of archetype generators. Filled in by each archetype module through `GENERATORS`. */\nexport const GENERATORS: Record<string, Gen> = {\n broadleaf_tree: generateBroadleafTree,\n dead_tree: generateDeadTree,\n flower_plant: generateFlowerPlant,\n grass_tuft: generateGrassTuft,\n fern: generateFern,\n rosette: generateRosette,\n columnar_cactus: generateColumnarCactus,\n paddle_cactus: generatePaddleCactus,\n globe_cactus: generateGlobeCactus,\n palm: generatePalm,\n banana: generateBanana,\n shrub: generateShrub,\n conifer: generateConifer,\n vine: generateVine,\n potted: generatePotted,\n}\n\nexport function archetypes(): string[] {\n return Object.keys(GENERATORS)\n}\n\n/** Build a plant. Deterministic: same spec + seed + lod + condition + season => identical arrays. */\nexport function generate(spec: PlantSpec, opts: GenerateOptions = {}): PlantMesh {\n const gen = GENERATORS[spec.archetype]\n if (!gen) throw new Error(`game-vegetation: unknown archetype \"${(spec as { archetype: string }).archetype}\"`)\n const seed = toSeed(opts.seed)\n const lod: Lod = opts.lod ?? 0\n const condition: Condition = opts.condition ?? 'healthy'\n const season: Season = opts.season ?? 'spring'\n const scale = opts.scale ?? 1\n const pieceMeta = new Map<string, PieceMeta>()\n const treeLike = spec.archetype === 'broadleaf_tree' || spec.archetype === 'dead_tree' || spec.archetype === 'palm' || spec.archetype === 'conifer' || spec.archetype === 'banana'\n const rootId = treeLike ? 'trunk' : 'stem'\n let fruitCount = 0\n const ctx: Ctx = {\n pieceMeta,\n piece(id, kind, parent, pivot) {\n if (!pieceMeta.has(id)) pieceMeta.set(id, { kind, parent, pivot })\n ctx.wood.tag = id\n ctx.foliage.tag = id\n ctx.flowers.tag = id\n ctx.spines.tag = id\n },\n pieceGeom(id, geom) {\n const m = pieceMeta.get(id)\n if (m) m.geom = geom\n },\n fruitItem(draw) {\n const id = `fruit${fruitCount++}`\n pieceMeta.set(id, { kind: 'fruit', parent: undefined })\n const saved = [ctx.wood.tag, ctx.foliage.tag, ctx.flowers.tag, ctx.spines.tag, ctx.fruit.tag]\n ctx.wood.tag = id\n ctx.foliage.tag = id\n ctx.flowers.tag = id\n ctx.spines.tag = id\n ctx.fruit.tag = id\n draw()\n ;[ctx.wood.tag, ctx.foliage.tag, ctx.flowers.tag, ctx.spines.tag, ctx.fruit.tag] = saved\n },\n rng: new Rng(seed),\n lod,\n condition,\n season,\n wood: new MeshBuilder(),\n foliage: new MeshBuilder(),\n flowers: new MeshBuilder(),\n fruit: new MeshBuilder(),\n spines: new MeshBuilder(),\n pick: (a, b, c) => (lod === 0 ? a : lod === 1 ? b : c),\n }\n ctx.piece(rootId, treeLike ? 'trunk' : 'stem')\n ctx.fruit.tag = 'fruit'\n if (!pieceMeta.has('fruit')) pieceMeta.set('fruit', { kind: 'fruit', parent: undefined })\n const res = gen(spec, ctx)\n if (fruitCount > MAX_FRUIT_PIECES) clusterFruit(ctx, fruitCount)\n const parts: PlantMesh['parts'] = {\n wood: ctx.wood.build('wood', 'wood'),\n foliage: ctx.foliage.build('foliage', res.foliageMaterial ?? 'foliage'),\n flowers: ctx.flowers.build('flowers', 'foliage'),\n fruit: ctx.fruit.build('fruit', 'foliage'),\n spines: ctx.spines.build('spines', 'cactus'),\n }\n const builders = { wood: ctx.wood, foliage: ctx.foliage, flowers: ctx.flowers, fruit: ctx.fruit, spines: ctx.spines }\n let radius = 0\n let height = 0\n let tris = 0\n for (const key of Object.keys(parts) as (keyof typeof parts)[]) {\n const m = parts[key]\n if (!m) {\n delete parts[key]\n continue\n }\n tris += m.triangleCount\n const pos = m.positions\n for (let i = 0; i < pos.length; i += 3) {\n if (scale !== 1) {\n pos[i] *= scale\n pos[i + 1] *= scale\n pos[i + 2] *= scale\n }\n if (pos[i + 1] < 0) pos[i + 1] = 0\n const r = Math.hypot(pos[i], pos[i + 2])\n if (r > radius) radius = r\n if (pos[i + 1] > height) height = pos[i + 1]\n }\n }\n const pieces = buildPieces(parts, builders, pieceMeta, rootId, condition, scale)\n const collider = res.collider ? { kind: 'cylinder' as const, radius: res.collider.radius * scale, height: res.collider.height * scale } : null\n return {\n parts,\n pieces,\n bounds: { radius, height },\n collider,\n bendable: res.bendable,\n thorny: !!res.thorny,\n seed,\n species: opts.species ?? spec.archetype,\n lod,\n triangleCount: tris,\n condition,\n }\n}\n\n/** A plant has at most this many fruit pieces; more fruit is grouped into small clusters by proximity. */\nexport const MAX_FRUIT_PIECES = 24\n\n/** Group the fruit pieces `fruit0..n-1` into MAX_FRUIT_PIECES clusters (farthest-point seeds, nearest seed wins) and relabel their triangles. */\nfunction clusterFruit(ctx: Ctx, n: number): void {\n const builders = [ctx.wood, ctx.foliage, ctx.flowers, ctx.fruit, ctx.spines]\n const sum = new Map<string, [number, number, number, number]>()\n for (const b of builders) {\n for (let t = 0; t < b.triTag.length; t++) {\n const tg = b.triTag[t]\n if (!/^fruit\\d+$/.test(tg)) continue\n const s = sum.get(tg) ?? [0, 0, 0, 0]\n for (let k = 0; k < 3; k++) {\n const v = b.idx[t * 3 + k] * 3\n s[0] += b.pos[v]\n s[1] += b.pos[v + 1]\n s[2] += b.pos[v + 2]\n s[3]++\n }\n sum.set(tg, s)\n }\n }\n const centers: Vec3[] = []\n for (let i = 0; i < n; i++) {\n const s = sum.get(`fruit${i}`) ?? [0, 0, 0, 1]\n centers.push([s[0] / s[3], s[1] / s[3], s[2] / s[3]])\n }\n const d2 = (a: Vec3, b: Vec3): number => (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2\n const seeds = [0]\n const near = centers.map((c) => d2(c, centers[0]))\n while (seeds.length < MAX_FRUIT_PIECES) {\n let best = 0\n for (let i = 1; i < n; i++) if (near[i] > near[best]) best = i\n seeds.push(best)\n for (let i = 0; i < n; i++) near[i] = Math.min(near[i], d2(centers[i], centers[best]))\n }\n const cluster = centers.map((c) => {\n let bi = 0\n let bd = Infinity\n for (let k = 0; k < seeds.length; k++) {\n const d = d2(c, centers[seeds[k]])\n if (d < bd) {\n bd = d\n bi = k\n }\n }\n return bi\n })\n for (const b of builders) {\n for (let t = 0; t < b.triTag.length; t++) {\n const m = /^fruit(\\d+)$/.exec(b.triTag[t])\n if (m) b.triTag[t] = `fruit${cluster[Number(m[1])]}`\n }\n }\n for (let i = 0; i < n; i++) ctx.pieceMeta.delete(`fruit${i}`)\n for (let k = 0; k < MAX_FRUIT_PIECES; k++) ctx.pieceMeta.set(`fruit${k}`, { kind: 'fruit', parent: undefined })\n}\n\nconst PART_ORDER: PartKind[] = ['wood', 'foliage', 'flowers', 'fruit', 'spines']\n\n/** Pieces made of a straight-ish wood tube: they get a radius, length, axis and base. */\nconst WOOD_KINDS: ReadonlySet<PieceKind> = new Set<PieceKind>(['trunk', 'branch', 'stem', 'arm', 'pad'])\n/** The radius is measured away from the root flare (first 15 % of the length) and the tip taper (after 60 %). */\nconst FLARE_SKIP = 0.15\nconst BODY_END = 0.6\n\n/**\n * The straight-tube fit of a wood piece, in plant space (scaled): the mean radius of the body of its tube, its length along the centreline, the direction from its first to its last point\n * and the first point. An archetype that set `pieceGeom` wins. Returns `undefined` when no tube was drawn under the tag.\n */\nfunction pieceGeometry(tag: string, m: PieceMeta, builders: Record<PartKind, MeshBuilder>, scale: number): PieceGeometry | undefined {\n if (m.geom) {\n const g = m.geom\n return { radius: g.radius * scale, length: g.length * scale, axis: [...g.axis] as Vec3, base: [g.base[0] * scale, g.base[1] * scale, g.base[2] * scale] }\n }\n let tube: MeshBuilder['tubes'][number] | undefined\n for (const part of PART_ORDER) {\n tube = builders[part].tubes.find((t) => t.tag === tag)\n if (tube) break\n }\n if (!tube || tube.path.length < 2) return undefined\n const { path, radii } = tube\n const seg: number[] = []\n let total = 0\n for (let i = 1; i < path.length; i++) {\n const l = Math.hypot(path[i][0] - path[i - 1][0], path[i][1] - path[i - 1][1], path[i][2] - path[i - 1][2])\n seg.push(l)\n total += l\n }\n if (total <= 0) return undefined\n let wsum = 0\n let rsum = 0\n let all = 0\n let acc = 0\n for (let i = 0; i < seg.length; i++) {\n const r = (radii[i] + radii[i + 1]) / 2\n all += r * seg[i]\n const mid = acc + seg[i] / 2\n if (mid >= total * FLARE_SKIP && mid <= total * BODY_END) {\n rsum += r * seg[i]\n wsum += seg[i]\n }\n acc += seg[i]\n }\n const radius = wsum > 0 ? rsum / wsum : all / total\n const a = path[0]\n const b = path[path.length - 1]\n const d = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]) || 1\n return { radius: radius * scale, length: total * scale, axis: [(b[0] - a[0]) / d, (b[1] - a[1]) / d, (b[2] - a[2]) / d], base: [a[0] * scale, a[1] * scale, a[2] * scale] }\n}\n\n/** Turn the builders' tag ranges into pieces with ids, materials, pivots and bounds (positions already scaled). */\nfunction buildPieces(parts: PlantMesh['parts'], builders: Record<PartKind, MeshBuilder>, meta: Map<string, PieceMeta>, rootId: string, condition: Condition, scale: number): PlantPiece[] {\n const primary = new Map<string, PartKind>()\n for (const part of PART_ORDER) {\n if (!parts[part]) continue\n for (const r of builders[part].ranges) if (!primary.has(r.tag || rootId)) primary.set(r.tag || rootId, part)\n }\n if (parts.fruit) for (const r of builders.fruit.ranges) if (meta.get(r.tag || rootId)?.kind === 'fruit') primary.set(r.tag, 'fruit')\n // bounds of every tag over all its parts, to hang each fruit on the nearest non-fruit piece\n const tagBox = new Map<string, { min: Vec3; max: Vec3 }>()\n for (const part of PART_ORDER) {\n const mesh = parts[part]\n if (!mesh) continue\n for (const r of builders[part].ranges) {\n const tag = r.tag || rootId\n let box = tagBox.get(tag)\n if (!box) tagBox.set(tag, (box = { min: [Infinity, Infinity, Infinity], max: [-Infinity, -Infinity, -Infinity] }))\n for (let i = r.indexStart; i < r.indexStart + r.indexCount; i++) {\n const v = mesh.indices[i] * 3\n for (let a = 0; a < 3; a++) {\n const c = mesh.positions[v + a]\n if (c < box.min[a]) box.min[a] = c\n if (c > box.max[a]) box.max[a] = c\n }\n }\n }\n }\n const fruitHang = new Map<string, { parent?: string; pivot: Vec3 }>()\n const PRIORITY: Partial<Record<PieceKind, number>> = { branch: 0, pad: 0, arm: 0, stem: 1, trunk: 1, crown: 2 }\n for (const [tag, box] of tagBox) {\n if (meta.get(tag)?.kind !== 'fruit') continue\n const cx = (box.min[0] + box.max[0]) / 2\n const cy = (box.min[1] + box.max[1]) / 2\n const cz = (box.min[2] + box.max[2]) / 2\n let parent: string | undefined\n let pbox: { min: Vec3; max: Vec3 } | undefined\n let bd = Infinity\n let bp = 9\n for (const [ptag, pb] of tagBox) {\n const pk = meta.get(ptag)?.kind\n if (pk === undefined || PRIORITY[pk] === undefined) continue\n let d = 0\n const p = [cx, cy, cz]\n for (let a = 0; a < 3; a++) {\n const o = p[a] < pb.min[a] ? pb.min[a] - p[a] : p[a] > pb.max[a] ? p[a] - pb.max[a] : 0\n d += o * o\n }\n const pr = PRIORITY[pk]!\n if (d < bd - 1e-9 || (Math.abs(d - bd) <= 1e-9 && pr < bp)) {\n bd = d\n bp = pr\n parent = ptag\n pbox = pb\n }\n }\n // pivot: the point of the fruit's bounds nearest to the middle of what it hangs from (a stalk top, a trunk / pad side)\n const pc = pbox ? [(pbox.min[0] + pbox.max[0]) / 2, (pbox.min[1] + pbox.max[1]) / 2, (pbox.min[2] + pbox.max[2]) / 2] : [cx, box.max[1], cz]\n const pivot: Vec3 = [Math.min(box.max[0], Math.max(box.min[0], pc[0])), Math.min(box.max[1], Math.max(box.min[1], pc[1])), Math.min(box.max[2], Math.max(box.min[2], pc[2]))]\n fruitHang.set(tag, { parent, pivot })\n }\n const idOf = (tag: string, part: PartKind): string => (primary.get(tag) === part ? tag : `${tag}:${part}`)\n const out: PlantPiece[] = []\n for (const part of PART_ORDER) {\n const mesh = parts[part]\n if (!mesh) continue\n for (const r of builders[part].ranges) {\n const tag = r.tag || rootId\n const m = meta.get(tag) ?? { kind: 'stem' as const }\n const min: Vec3 = [Infinity, Infinity, Infinity]\n const max: Vec3 = [-Infinity, -Infinity, -Infinity]\n for (let i = r.indexStart; i < r.indexStart + r.indexCount; i++) {\n const v = mesh.indices[i] * 3\n for (let a = 0; a < 3; a++) {\n const c = mesh.positions[v + a]\n if (c < min[a]) min[a] = c\n if (c > max[a]) max[a] = c\n }\n }\n let pivot: Vec3\n const hang = fruitHang.get(tag)\n if (hang) pivot = hang.pivot\n else if (m.pivot) pivot = [m.pivot[0] * scale, Math.max(0, m.pivot[1] * scale), m.pivot[2] * scale]\n else if (m.kind === 'crown' || m.kind === 'fruit') pivot = [(min[0] + max[0]) / 2, (min[1] + max[1]) / 2, (min[2] + max[2]) / 2]\n else pivot = [(min[0] + max[0]) / 2, min[1], (min[2] + max[2]) / 2]\n if (m.kind === 'trunk' || m.kind === 'stem' || m.kind === 'pot' || m.kind === 'soil') pivot = [0, min[1], 0]\n let material: MaterialKey = materialKeyForPart(part, mesh.material, condition)\n if (m.kind === 'pot') material = 'pot'\n else if (m.kind === 'soil') material = 'soil'\n const parentTag = hang ? hang.parent : m.parent\n const parentId = parentTag !== undefined && primary.has(parentTag) ? idOf(parentTag, primary.get(parentTag)!) : undefined\n const geom = WOOD_KINDS.has(m.kind) ? pieceGeometry(tag, m, builders, scale) : undefined\n out.push({\n id: idOf(tag, part),\n kind: m.kind,\n material,\n ...(parentId === undefined ? {} : { parent: parentId }),\n part,\n indexStart: r.indexStart,\n indexCount: r.indexCount,\n pivot,\n bounds: { min, max },\n ...(geom ?? {}),\n })\n }\n }\n return out\n}\n","import type { Condition, GenerateOptions, Lod, MeshData, PartKind, PieceKind, Placement, PlantMesh, PlantSpec, Season, Vec3 } from './types'\nimport type { MaterialKey } from './destruction'\nimport { generate } from './generate'\nimport { MeshBuilder } from './geometry/builder'\nimport { hashMix, toSeed } from './rng'\n\nexport interface LotColliderData {\n x: number\n z: number\n r: number\n h: number\n damage?: 'thorns'\n}\n\n/** One separable piece of a plant inside the merged lot meshes. */\nexport interface LotPiece {\n id: string\n kind: PieceKind\n parent?: string\n /** the plant part the piece comes from */\n part: PartKind\n /** which merged mesh holds it (spines go to 'wood', fruit to 'flowers') */\n mesh: 'wood' | 'foliage' | 'flowers'\n /** triangle index range in `lot.meshes[mesh].indices` (a multiple of 3) */\n indexStart: number\n indexCount: number\n /** key of the destruction material table (see MaterialIds) */\n material: MaterialKey\n /** wood pieces: the straight-tube fit, as in `PlantPiece` */\n radius?: number\n length?: number\n axis?: Vec3\n base?: Vec3\n}\nexport interface LotPlantPieces {\n /** index into the `placements` array given to buildLot */\n plantIndex: number\n species: string\n x: number\n z: number\n ry: number\n scale: number\n lod: Lod\n pieces: LotPiece[]\n /** what is needed to regenerate the same plant as a separable object (see extractPlant) */\n spec: PlantSpec\n generateOptions: GenerateOptions\n}\n\nexport interface Lot {\n meshes: { wood?: MeshData; foliage?: MeshData; flowers?: MeshData }\n /** trunks only; foliage, flowers and grass never collide */\n colliders: LotColliderData[]\n triangleCount: number\n plantCount: number\n /** grass tufts left out to meet the triangle budget */\n thinnedCount: number\n /** plants kept at LOD0, LOD1 and LOD2 */\n lodCounts: [number, number, number]\n /** condition the lot was built with (default 'healthy') */\n condition?: Condition\n /** one entry per plant that made it into the meshes (thinned grass is absent), see extractPlant / hideLotPlant */\n pieceTable: LotPlantPieces[]\n}\n\nexport interface BuildLotOptions {\n seed?: number | string\n /** 'game' uses LOD1 for every plant; 'high' uses `lod` (default 0) */\n quality: 'high' | 'game'\n lod?: Lod\n condition?: Condition\n season?: Season\n /**\n * LOD used for small plants (grass tufts, small flowers, ferns...) so a yard full of them stays cheap.\n * Default: 2 in 'game' quality, `lod` (0 unless set) in 'high' quality. Set it equal to the main LOD to disable.\n */\n smallPlantsLod?: Lod\n /** plants not taller than this (meters, after placement scale) count as small (default 0.7) */\n smallPlantMaxHeight?: number\n /**\n * Soft triangle cap for the whole lot. When the plants exceed it: some grass tufts are left out first, then small\n * plants, then shrubs / hedges, and only then trees and palms are switched to LOD2 (smallest first) until the lot fits. Default: 20000 in 'game' quality, unlimited in 'high' quality.\n */\n triangleBudget?: number\n}\n\n/**\n * Merge every plant of an area into at most 3 meshes (wood + spines, foliage, flowers + fruit), with every vertex\n * already transformed by its placement (x, z, ry, scale). Engine agnostic.\n */\nexport function buildLot(placements: Placement[], resolveSpec: (id: string) => PlantSpec, opts: BuildLotOptions): Lot {\n const lod: Lod = opts.quality === 'game' ? 1 : (opts.lod ?? 0)\n const smallLod: Lod = opts.smallPlantsLod ?? (opts.quality === 'game' ? 2 : lod)\n const smallMax = opts.smallPlantMaxHeight ?? 0.8\n const budget = opts.triangleBudget ?? (opts.quality === 'game' ? 20000 : Infinity)\n const base = toSeed(opts.seed)\n const wood = new MeshBuilder()\n const foliage = new MeshBuilder()\n const flowers = new MeshBuilder()\n const colliders: LotColliderData[] = []\n const cache = new Map<string, PlantSpec>()\n const entries: { p: Placement; plant: PlantMesh; go: GenerateOptions; spec: PlantSpec; dropped?: boolean }[] = []\n let total = 0\n for (const p of placements) {\n let spec = cache.get(p.species)\n if (!spec) {\n spec = resolveSpec(p.species)\n cache.set(p.species, spec)\n }\n const go: GenerateOptions = { seed: hashMix(base, p.seed), lod, condition: opts.condition, season: opts.season }\n let plant: PlantMesh | undefined\n if (smallLod !== lod) {\n // small plants (judged by the cheap version) use the cheap LOD\n const cheap = generate(spec, { ...go, lod: smallLod })\n if (cheap.bounds.height * p.scale <= smallMax) plant = cheap\n }\n plant ??= generate(spec, go)\n total += plant.triangleCount\n entries.push({ p, plant, go, spec })\n }\n let thinned = 0\n if (total > budget) {\n const kindOf = (e: (typeof entries)[number]): number => {\n const a = e.spec.archetype\n if (a === 'grass_tuft' && e.plant.bounds.height * e.p.scale < 1) return 0\n if (a === 'broadleaf_tree' || a === 'conifer' || a === 'dead_tree' || a === 'palm' || a === 'banana') return 3\n return e.plant.bounds.height * e.p.scale <= smallMax ? 1 : 2\n }\n const cost = (e: (typeof entries)[number]): number => e.plant.triangleCount\n // 1) thin out grass tufts and weeds (a deterministic share, in hash order): they are tiny\n const grass = entries.filter((e) => kindOf(e) === 0).sort((a, b) => hashMix(a.p.seed, 7) - hashMix(b.p.seed, 7))\n const keepMin = Math.ceil(grass.length * 0.2)\n for (let i = 0; i < grass.length - keepMin && total > budget; i++) {\n total -= cost(grass[i])\n grass[i].dropped = true\n thinned++\n }\n // 2..4) small plants, then shrubs / hedges / the rest, then trees and palms: drop to LOD2, smallest first\n for (const kind of [1, 2, 3]) {\n const group = entries.filter((e) => !e.dropped && kindOf(e) === kind && e.plant.lod < 2).sort((a, b) => a.plant.bounds.height * a.p.scale - b.plant.bounds.height * b.p.scale)\n for (const e of group) {\n if (total <= budget) break\n const cheap = generate(e.spec, { ...e.go, lod: 2 })\n total += cheap.triangleCount - e.plant.triangleCount\n e.plant = cheap\n }\n }\n }\n const lodCounts: [number, number, number] = [0, 0, 0]\n const kept: { plantIndex: number; e: (typeof entries)[number] }[] = []\n for (let pi = 0; pi < entries.length; pi++) {\n const e = entries[pi]\n const { p, plant, dropped } = e\n if (dropped) continue\n kept.push({ plantIndex: pi, e })\n lodCounts[plant.lod]++\n const { parts } = plant\n // every triangle is tagged \"<plantIndex>|<piece id>\" so the merged builders report the piece ranges\n const tagsOf = (part: PartKind): ((t: number) => string) | undefined => {\n const mesh = parts[part]\n if (!mesh) return undefined\n const tags = new Array<string>(mesh.triangleCount).fill('')\n for (const pc of plant.pieces) {\n if (pc.part !== part) continue\n for (let t = pc.indexStart / 3; t < (pc.indexStart + pc.indexCount) / 3; t++) tags[t] = `${pi}|${pc.id}`\n }\n return (t) => tags[t]\n }\n if (parts.wood) wood.appendMesh(parts.wood, p.x, 0, p.z, p.ry, p.scale, tagsOf('wood'))\n if (parts.spines) wood.appendMesh(parts.spines, p.x, 0, p.z, p.ry, p.scale, tagsOf('spines'))\n if (parts.foliage) foliage.appendMesh(parts.foliage, p.x, 0, p.z, p.ry, p.scale, tagsOf('foliage'))\n if (parts.flowers) flowers.appendMesh(parts.flowers, p.x, 0, p.z, p.ry, p.scale, tagsOf('flowers'))\n if (parts.fruit) flowers.appendMesh(parts.fruit, p.x, 0, p.z, p.ry, p.scale, tagsOf('fruit'))\n if (plant.collider) {\n const c: LotColliderData = { x: p.x, z: p.z, r: plant.collider.radius * p.scale, h: plant.collider.height * p.scale }\n if (plant.thorny) c.damage = 'thorns'\n colliders.push(c)\n }\n }\n const meshes: Lot['meshes'] = {\n wood: wood.build('wood', 'wood'),\n foliage: foliage.build('foliage', 'foliage'),\n flowers: flowers.build('flowers', 'foliage'),\n }\n for (const k of Object.keys(meshes) as (keyof Lot['meshes'])[]) if (!meshes[k]) delete meshes[k]\n const rangeOf = new Map<string, { mesh: 'wood' | 'foliage' | 'flowers'; indexStart: number; indexCount: number }>()\n for (const [mesh, b] of [['wood', wood], ['foliage', foliage], ['flowers', flowers]] as const) {\n for (const r of b.ranges) if (r.tag) rangeOf.set(r.tag, { mesh, indexStart: r.indexStart, indexCount: r.indexCount })\n }\n const pieceTable: LotPlantPieces[] = kept.map(({ plantIndex, e }) => ({\n plantIndex,\n species: e.p.species,\n x: e.p.x,\n z: e.p.z,\n ry: e.p.ry,\n scale: e.p.scale,\n lod: e.plant.lod,\n spec: e.spec,\n generateOptions: { ...e.go, lod: e.plant.lod },\n pieces: e.plant.pieces.map((pc) => {\n const r = rangeOf.get(`${plantIndex}|${pc.id}`)!\n return { id: pc.id, kind: pc.kind, ...(pc.parent === undefined ? {} : { parent: pc.parent }), part: pc.part, mesh: r.mesh, indexStart: r.indexStart, indexCount: r.indexCount, material: pc.material, ...(pc.radius === undefined ? {} : { radius: pc.radius, length: pc.length, axis: pc.axis, base: pc.base }) }\n }),\n }))\n const triangleCount = (meshes.wood?.triangleCount ?? 0) + (meshes.foliage?.triangleCount ?? 0) + (meshes.flowers?.triangleCount ?? 0)\n return { meshes, colliders, triangleCount, plantCount: placements.length, thinnedCount: thinned, lodCounts, condition: opts.condition ?? 'healthy', pieceTable }\n}\n\nexport interface ExtractedPlant {\n /** the plant regenerated with the exact options used in the lot (same LOD, same seed): identical geometry, plus its pieces */\n plant: PlantMesh\n /** where the plant stood in the lot: build the separable object with position (x, 0, z), rotation.y = ry and scale */\n placement: { species: string; x: number; z: number; ry: number; scale: number }\n /** the index ranges the plant occupies in the merged meshes */\n ranges: LotPiece[]\n}\n\nfunction entryOf(lot: Lot, plantIndex: number): LotPlantPieces {\n const e = lot.pieceTable.find((t) => t.plantIndex === plantIndex)\n if (!e) throw new Error(`game-vegetation: plant ${plantIndex} is not in the lot (thinned out or out of range)`)\n return e\n}\n\n/**\n * Get a plant of the lot back as a stand-alone `PlantMesh` (with `pieces`) plus its placement, to spawn a separable version\n * (`createPlantObject(THREE, plant, mats, { separable: true })`) when the merged plant gets hit. Does not touch the lot.\n */\nexport function extractPlant(lot: Lot, plantIndex: number): ExtractedPlant {\n const e = entryOf(lot, plantIndex)\n return {\n plant: generate(e.spec, { ...e.generateOptions, species: e.species }),\n placement: { species: e.species, x: e.x, z: e.z, ry: e.ry, scale: e.scale },\n ranges: e.pieces,\n }\n}\n\n/**\n * Make a plant of the lot invisible by zeroing its index ranges in the merged meshes (degenerate triangles). Idempotent.\n * The indices array is shared with the three BufferGeometry, so set `geometry.index.needsUpdate = true` afterwards\n * (`removeLotPlant` in game-vegetation/three does that). Returns the ranges that were cleared.\n */\nexport function hideLotPlant(lot: Lot, plantIndex: number): LotPiece[] {\n const e = entryOf(lot, plantIndex)\n for (const r of e.pieces) {\n const m = lot.meshes[r.mesh]\n if (m) m.indices.fill(0, r.indexStart, r.indexStart + r.indexCount)\n }\n return e.pieces\n}\n","import type { Placement } from './types'\nimport { Rng, hashMix, toSeed } from './rng'\nimport { TAU, clamp } from './math'\n\nexport type Point2 = [number, number]\n/** `rect.x` / `rect.z` is the minimum corner; `w` runs along x and `d` along z. */\nexport type Region = { polygon: Point2[] } | { rect: { x: number; z: number; w: number; d: number } }\n\nexport interface ScatterRule {\n /** species id, a list (uniform pick) or weighted ids */\n species: string | string[] | { id: string; weight: number }[]\n /** plants per square meter */\n density: number\n /** minimum distance between plants of this rule, meters */\n minDistance: number\n /** areas where this rule must not place anything (paths, house footprint, ...) */\n exclude?: Region[]\n /** `edge` hugs the boundary (hedges, flowerbeds against walls), `center` avoids it */\n prefer?: 'edge' | 'center' | 'any'\n /** how fast the edge preference falls off with distance from the boundary (meters, default max(0.4, 0.8 * minDistance)) */\n edgeWidth?: number\n /** random scale range (default [1, 1]) */\n scale?: [number, number]\n /** random rotation about y: true = full circle (default), false = none, or [min, max] radians */\n rotate?: boolean | [number, number]\n /** cap on the number of placements of this rule */\n maxCount?: number\n}\n\nexport interface ScatterOptions {\n seed: number | string\n /** exclusions applied to every rule */\n exclude?: Region[]\n}\n\nexport function regionPolygon(r: Region): Point2[] {\n if ('polygon' in r) return r.polygon\n const { x, z, w, d } = r.rect\n return [[x, z], [x + w, z], [x + w, z + d], [x, z + d]]\n}\n\nexport function pointInPolygon(x: number, z: number, poly: Point2[]): boolean {\n let inside = false\n for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {\n const [xi, zi] = poly[i]\n const [xj, zj] = poly[j]\n if (zi > z !== zj > z && x < ((xj - xi) * (z - zi)) / (zj - zi) + xi) inside = !inside\n }\n return inside\n}\n\nexport function polygonArea(poly: Point2[]): number {\n let a = 0\n for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) a += (poly[j][0] + poly[i][0]) * (poly[j][1] - poly[i][1])\n return Math.abs(a) / 2\n}\n\n/** Distance from a point to the boundary of a polygon. */\nexport function distanceToBoundary(x: number, z: number, poly: Point2[]): number {\n let best = Infinity\n for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {\n const [ax, az] = poly[j]\n const [bx, bz] = poly[i]\n const dx = bx - ax\n const dz = bz - az\n const l2 = dx * dx + dz * dz\n const t = l2 === 0 ? 0 : clamp(((x - ax) * dx + (z - az) * dz) / l2, 0, 1)\n const d = Math.hypot(x - (ax + dx * t), z - (az + dz * t))\n if (d < best) best = d\n }\n return best\n}\n\nfunction pickSpecies(rule: ScatterRule, rng: Rng): string {\n const s = rule.species\n if (typeof s === 'string') return s\n if (s.length === 0) throw new Error('game-vegetation: scatter rule has no species')\n if (typeof s[0] === 'string') return rng.pick(s as string[])\n const w = s as { id: string; weight: number }[]\n const total = w.reduce((a, b) => a + b.weight, 0)\n let r = rng.next() * total\n for (const it of w) {\n r -= it.weight\n if (r <= 0) return it.id\n }\n return w[w.length - 1].id\n}\n\n/**\n * Poisson-disc style placement (dart throwing with a spatial hash) inside a polygon or rectangle.\n * Deterministic for a given seed. Rules are processed in order, so earlier rules keep their spots.\n */\nexport function scatter(area: Region, rules: ScatterRule[], opts: ScatterOptions): Placement[] {\n const poly = regionPolygon(area)\n const seed = toSeed(opts.seed)\n const area2 = polygonArea(poly)\n let minX = Infinity\n let minZ = Infinity\n let maxX = -Infinity\n let maxZ = -Infinity\n for (const [x, z] of poly) {\n minX = Math.min(minX, x)\n maxX = Math.max(maxX, x)\n minZ = Math.min(minZ, z)\n maxZ = Math.max(maxZ, z)\n }\n const globalEx = (opts.exclude ?? []).map(regionPolygon)\n const cell = Math.max(0.05, ...rules.map((r) => r.minDistance))\n const grid = new Map<string, { x: number; z: number; md: number }[]>()\n const key = (cx: number, cz: number): string => cx + ',' + cz\n const out: Placement[] = []\n const inradius = Math.max(0.5, Math.sqrt(area2) * 0.5)\n rules.forEach((rule, ri) => {\n const rng = new Rng(hashMix(seed, ri + 1))\n const ex = [...globalEx, ...(rule.exclude ?? []).map(regionPolygon)]\n let target = Math.round(area2 * rule.density)\n if (rule.maxCount !== undefined) target = Math.min(target, rule.maxCount)\n const prefer = rule.prefer ?? 'any'\n const edgeW = rule.edgeWidth ?? Math.max(0.4, rule.minDistance * 0.8)\n const sc = rule.scale ?? [1, 1]\n let placed = 0\n const attempts = target * 60 + 300\n for (let a = 0; a < attempts && placed < target; a++) {\n const x = rng.range(minX, maxX)\n const z = rng.range(minZ, maxZ)\n const accept = rng.next()\n const spec = pickSpecies(rule, rng)\n const sd = rng.seed()\n const ry = rule.rotate === false ? 0 : Array.isArray(rule.rotate) ? rng.range(rule.rotate[0], rule.rotate[1]) : rng.range(0, TAU)\n const scale = rng.range(sc[0], sc[1])\n if (!pointInPolygon(x, z, poly)) continue\n let blocked = false\n for (const e of ex) {\n if (pointInPolygon(x, z, e)) {\n blocked = true\n break\n }\n }\n if (blocked) continue\n if (prefer !== 'any') {\n const d = distanceToBoundary(x, z, poly)\n const p = prefer === 'edge' ? Math.max(0.02, Math.exp(-d / edgeW)) : Math.max(0.05, clamp(d / inradius, 0, 1))\n if (accept > p) continue\n }\n const cx = Math.floor(x / cell)\n const cz = Math.floor(z / cell)\n let ok = true\n for (let ix = cx - 2; ix <= cx + 2 && ok; ix++) {\n for (let iz = cz - 2; iz <= cz + 2 && ok; iz++) {\n const items = grid.get(key(ix, iz))\n if (!items) continue\n for (const it of items) {\n const need = (it.md + rule.minDistance) / 2\n if ((it.x - x) ** 2 + (it.z - z) ** 2 < need * need) {\n ok = false\n break\n }\n }\n }\n }\n if (!ok) continue\n const k = key(cx, cz)\n const list = grid.get(k)\n if (list) list.push({ x, z, md: rule.minDistance })\n else grid.set(k, [{ x, z, md: rule.minDistance }])\n out.push({ species: spec, x, z, ry, scale, seed: sd })\n placed++\n }\n })\n return out\n}\n","import { GENERATORS } from './generate'\n\nconst ENUMS: Record<string, readonly string[]> = {\n crownShape: ['round', 'spreading', 'columnar', 'weeping'],\n leafShape: ['clump', 'sparse'],\n crownStyle: ['dome', 'lumpy', 'cloud', 'sphere', 'umbrella', 'willow', 'sparse_high'],\n variant: ['coconut', 'royal', 'fan', 'areca', 'date'],\n shape: ['cone', 'candelabra', 'round', 'hedge', 'loose', 'terracotta', 'cylinder', 'square', 'cachepot'],\n flowerType: ['daisy', 'rose', 'tulip', 'sunflower', 'hibiscus', 'cluster', 'lily', 'bird_of_paradise', 'pompom', 'hydrangea'],\n form: ['agave', 'sword', 'aloe', 'echeveria'],\n armStyle: ['candelabra', 'saguaro', 'sprawl'],\n style: ['dots', 'clusters', 'hibiscus', 'bell', 'bract', 'passion'],\n}\nconst POSITIVE = [\n 'height', 'trunkRadius', 'crownRadius', 'radius', 'length', 'width', 'frondLength', 'padSize', 'leafSize', 'flowerSize', 'size', 'tiers', 'ribs', 'branchLevels',\n 'clumpSize', 'frondCount', 'leafCount', 'stemCount', 'stems', 'generations', 'count',\n]\nconst SEASONS = ['spring', 'summer', 'autumn', 'winter']\n\nfunction isColor(v: unknown): boolean {\n return typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 0xffffff\n}\n\n/**\n * Validate a plant spec. Returns a list of problems (empty when valid). It checks the archetype, numeric ranges, enum values,\n * color integers (0xRRGGBB) and nested specs (potted).\n */\nexport function validateSpec(spec: unknown, path = 'spec'): string[] {\n const errors: string[] = []\n if (typeof spec !== 'object' || spec === null || Array.isArray(spec)) return [`${path}: must be an object`]\n const obj = spec as Record<string, unknown>\n if (typeof obj.archetype !== 'string' || !(obj.archetype in GENERATORS)) {\n errors.push(`${path}.archetype: unknown archetype \"${String(obj.archetype)}\"`)\n return errors\n }\n const walk = (o: Record<string, unknown>, p: string): void => {\n for (const [k, v] of Object.entries(o)) {\n const here = `${p}.${k}`\n if (k === 'plant') {\n errors.push(...validateSpec(v, here))\n continue\n }\n if (v === null || v === undefined) continue\n if (/colou?rs?$/i.test(k) && k !== 'colors' && !Array.isArray(v) && typeof v !== 'object') {\n if (!isColor(v)) errors.push(`${here}: must be an integer color 0..0xffffff`)\n } else if (k === 'colors' || k === 'leafColor' || k === 'petalColors') {\n if (Array.isArray(v)) {\n if (v.length === 0) errors.push(`${here}: must not be empty`)\n v.forEach((c, i) => {\n if (!isColor(c)) errors.push(`${here}[${i}]: must be an integer color 0..0xffffff`)\n })\n } else if (k !== 'colors' && !isColor(v)) errors.push(`${here}: must be a color or an array of colors`)\n } else if (k === 'seasons') {\n if (!Array.isArray(v) || v.some((s) => !SEASONS.includes(s as string))) errors.push(`${here}: must be a list of seasons`)\n } else if (k === 'arms') {\n if (!(typeof v === 'number' || (Array.isArray(v) && v.length === 2 && v.every((n) => typeof n === 'number')))) errors.push(`${here}: must be a number or [min, max]`)\n } else if (k === 'host') {\n const h = v as Record<string, unknown>\n if (!('path' in h) && !('wall' in h)) errors.push(`${here}: needs path or wall`)\n } else if (k in ENUMS) {\n if (typeof v === 'string' && !ENUMS[k].includes(v)) errors.push(`${here}: \"${v}\" is not one of ${ENUMS[k].join(', ')}`)\n } else if (POSITIVE.includes(k)) {\n if (typeof v !== 'number' || !Number.isFinite(v) || v <= 0) errors.push(`${here}: must be a positive number`)\n }\n if (typeof v === 'object' && !Array.isArray(v) && k !== 'host') walk(v as Record<string, unknown>, here)\n }\n }\n walk(obj, path)\n return errors\n}\n","import type * as ThreeTypes from 'three'\nimport type { MaterialIds } from '../destruction'\n\n/** The THREE namespace is passed in by the host at runtime (r160). This package only imports its types. */\nexport type ThreeNS = typeof ThreeTypes\nexport type Material = ThreeTypes.Material\n\nexport const MAX_ACTORS = 4\n\nexport interface WindSettings {\n /** world-space direction on the xz plane (normalized internally) */\n direction: [number, number]\n /** 0..1 */\n strength: number\n /** 0..1 slowly varying extra push */\n gust: number\n}\nexport interface ActorInput {\n x: number\n y: number\n z: number\n radius: number\n}\nexport interface MaterialOptions {\n /** override of the destruction SDK material ids written to `userData.destructionMaterial` (see DEFAULT_MATERIAL_IDS) */\n materialIds?: Partial<MaterialIds>\n /** flat shaded foliage (default true) */\n flatShading?: boolean\n roughness?: number\n /** override the alpha cut etc. in the future; currently unused */\n [key: string]: unknown\n}\nexport interface VegetationMaterials {\n /** resolved destruction material ids used by createPlantObject / createLotObject unless they get their own `materialIds` */\n materialIds?: MaterialIds\n wood: ThreeTypes.MeshStandardMaterial\n foliage: ThreeTypes.MeshStandardMaterial\n flowers: ThreeTypes.MeshStandardMaterial\n fruit: ThreeTypes.MeshStandardMaterial\n spines: ThreeTypes.MeshStandardMaterial\n /** advance the wind clock (seconds). Does not allocate. */\n update(timeSeconds: number): void\n setWind(wind: Partial<WindSettings>): void\n /** up to MAX_ACTORS actors bend the vegetation away; extra entries are ignored. Does not allocate. */\n setActors(actors: readonly ActorInput[]): void\n dispose(): void\n}\n","import type { MaterialOptions, ThreeNS, VegetationMaterials, WindSettings, ActorInput } from './types'\nimport { MAX_ACTORS } from './types'\nimport { resolveMaterialIds } from '../destruction'\n\nconst COMMON = /* glsl */ `\n#include <common>\nattribute float sway;\nuniform float uVegTime;\nuniform vec2 uWindDir;\nuniform float uWindStrength;\nuniform float uWindGust;\nuniform vec4 uActors[${MAX_ACTORS}];\nvec3 vegDisplace( vec3 wp, vec3 origin, float s ) {\n float ph = dot( origin.xz, vec2( 1.7, 1.3 ) ) + dot( wp.xz, vec2( 0.35, 0.25 ) );\n float t = uVegTime;\n float w = sin( t * 1.6 + ph ) * 0.6 + sin( t * 3.3 + ph * 1.9 + 1.3 ) * 0.4;\n float g = 0.5 + 0.5 * sin( t * 0.45 + ph * 0.3 );\n float m = s * ( uWindStrength * ( 0.5 + 0.5 * w ) * 0.14 + uWindGust * g * 0.22 );\n float flutter = s * s * uWindStrength * sin( t * 7.0 + ph * 3.1 ) * 0.025;\n wp.xz += uWindDir * ( m + flutter );\n wp.y -= abs( m ) * 0.25;\n for ( int i = 0; i < ${MAX_ACTORS}; i ++ ) {\n vec4 a = uActors[ i ];\n if ( a.w > 0.0 ) {\n vec2 dv = wp.xz - a.xz;\n float d = length( dv );\n float f = ( 1.0 - smoothstep( 0.0, a.w, d ) ) * ( 1.0 - smoothstep( 1.6, 2.4, abs( wp.y - a.y ) ) );\n vec2 away = d > 0.0001 ? dv / d : vec2( 1.0, 0.0 );\n wp.xz += away * f * s * a.w * 0.6;\n wp.y -= f * s * 0.18;\n }\n }\n return wp;\n}\n`\n\nconst PROJECT = /* glsl */ `\nvec4 vegLocal = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n vegLocal = instanceMatrix * vegLocal;\n vec3 vegOrigin = ( modelMatrix * vec4( instanceMatrix[ 3 ].xyz, 1.0 ) ).xyz;\n#else\n vec3 vegOrigin = modelMatrix[ 3 ].xyz;\n#endif\nvec4 vegWorld = modelMatrix * vegLocal;\nvegWorld.xyz = vegDisplace( vegWorld.xyz, vegOrigin, sway );\nvec4 mvPosition = viewMatrix * vegWorld;\ngl_Position = projectionMatrix * mvPosition;\n`\n\n/**\n * Vertex-colored standard materials patched with wind sway (by the `sway` attribute) and actor bend, driven only by\n * shared uniforms: time, wind (direction / strength / gust) and up to 4 actors (vec4 x, y, z, radius).\n */\nexport function createVegetationMaterials(THREE: ThreeNS, opts: MaterialOptions = {}): VegetationMaterials {\n const uniforms = {\n uVegTime: { value: 0 },\n uWindDir: { value: new THREE.Vector2(1, 0.3).normalize() },\n uWindStrength: { value: 0.35 },\n uWindGust: { value: 0.15 },\n uActors: { value: Array.from({ length: MAX_ACTORS }, () => new THREE.Vector4(0, 0, 0, 0)) },\n }\n const patch = (m: InstanceType<ThreeNS['MeshStandardMaterial']>): void => {\n m.onBeforeCompile = (shader) => {\n Object.assign(shader.uniforms, uniforms)\n shader.vertexShader = shader.vertexShader.replace('#include <common>', COMMON).replace('#include <project_vertex>', PROJECT)\n }\n m.customProgramCacheKey = () => 'vegetation-sway-v1'\n }\n const flat = opts.flatShading !== false\n const rough = typeof opts.roughness === 'number' ? opts.roughness : 0.85\n const make = (flatShading: boolean, double: boolean, roughness: number) => {\n const m = new THREE.MeshStandardMaterial({\n vertexColors: true,\n flatShading,\n roughness,\n metalness: 0,\n side: double ? THREE.DoubleSide : THREE.FrontSide,\n })\n patch(m)\n return m\n }\n const wood = make(false, false, 0.95)\n const foliage = make(flat, true, rough)\n const flowers = make(flat, true, 0.7)\n const fruit = make(flat, false, 0.55)\n const spines = make(true, true, 0.8)\n const dir = uniforms.uWindDir.value\n return {\n materialIds: resolveMaterialIds(opts.materialIds),\n wood,\n foliage,\n flowers,\n fruit,\n spines,\n update(t: number) {\n uniforms.uVegTime.value = t\n },\n setWind(w: Partial<WindSettings>) {\n if (w.direction) {\n const l = Math.hypot(w.direction[0], w.direction[1]) || 1\n dir.set(w.direction[0] / l, w.direction[1] / l)\n }\n if (w.strength !== undefined) uniforms.uWindStrength.value = w.strength\n if (w.gust !== undefined) uniforms.uWindGust.value = w.gust\n },\n setActors(actors: readonly ActorInput[]) {\n const arr = uniforms.uActors.value\n for (let i = 0; i < MAX_ACTORS; i++) {\n const a = actors[i]\n if (a) arr[i].set(a.x, a.y, a.z, a.radius)\n else arr[i].set(0, 0, 0, 0)\n }\n },\n dispose() {\n wood.dispose()\n foliage.dispose()\n flowers.dispose()\n fruit.dispose()\n spines.dispose()\n },\n }\n}\n","import type { MeshData, PartKind, Vec3, Placement, PlantMesh, PlantSpec, GenerateOptions } from '../types'\nimport type { Lot } from '../lot'\nimport { extractPlant, hideLotPlant } from '../lot'\nimport { generate } from '../generate'\nimport type { ThreeNS, VegetationMaterials } from './types'\nimport { createVegetationMaterials } from './materials'\nimport { materialKeyForPart, resolveMaterialIds, type MaterialIds } from '../destruction'\nimport type { Condition } from '../types'\n\nimport type { BufferGeometry as Geo } from 'three'\ntype Obj = InstanceType<ThreeNS['Object3D']>\n\nconst PART_ORDER: PartKind[] = ['wood', 'foliage', 'flowers', 'fruit', 'spines']\n\n/** MeshData -> BufferGeometry with attributes position, normal, color, sway. */\nexport function toBufferGeometry(THREE: ThreeNS, mesh: MeshData): Geo {\n const g = new THREE.BufferGeometry()\n g.setAttribute('position', new THREE.BufferAttribute(mesh.positions, 3))\n g.setAttribute('normal', new THREE.BufferAttribute(mesh.normals, 3))\n g.setAttribute('color', new THREE.BufferAttribute(mesh.colors, 3))\n g.setAttribute('sway', new THREE.BufferAttribute(mesh.sway, 1))\n g.setIndex(new THREE.BufferAttribute(mesh.indices, 1))\n g.computeBoundingSphere()\n g.computeBoundingBox()\n return g\n}\n\nfunction inflate(g: Geo, m: number): void {\n // wind and bend move vertices a little outside the static bounds: keep culling safe\n if (g.boundingSphere) g.boundingSphere.radius += m\n}\n\nexport interface DestructionOptions {\n /** override any destruction material id (merged over the materials' own mapping, then DEFAULT_MATERIAL_IDS) */\n materialIds?: Partial<MaterialIds>\n}\nexport interface PlantObjectOptions extends DestructionOptions {\n /**\n * Build one child Mesh per `plant.pieces` entry instead of one per part. Each child is positioned at the piece pivot (so it can\n * fall / rotate about it), carries `userData.destructionPart = { id, kind, parent, material, materialKey }` (wood pieces add `radius`, `length`, `axis`, `base`) and\n * `userData.destructionMaterial`. Default false.\n */\n separable?: boolean\n}\n\nfunction idsFor(mats: VegetationMaterials, o?: DestructionOptions): MaterialIds {\n return resolveMaterialIds({ ...(mats.materialIds ?? {}), ...(o?.materialIds ?? {}) })\n}\n\nfunction meshFor(THREE: ThreeNS, data: MeshData, material: unknown, ids?: MaterialIds, condition?: Condition): InstanceType<ThreeNS['Mesh']> {\n const geo = toBufferGeometry(THREE, data)\n inflate(geo, 0.4)\n const mesh = new THREE.Mesh(geo, material as InstanceType<ThreeNS['Material']>)\n mesh.name = data.kind\n mesh.userData.damageable = { material: data.material }\n if (ids) mesh.userData.destructionMaterial = ids[materialKeyForPart(data.kind, data.material, condition)]\n return mesh\n}\n\n/** Copy the triangles of one index range into their own compact MeshData, moved by -origin. */\nexport function slicePiece(mesh: MeshData, indexStart: number, indexCount: number, origin: Vec3): MeshData {\n const remap = new Map<number, number>()\n const order: number[] = []\n const indices = new Uint32Array(indexCount)\n for (let i = 0; i < indexCount; i++) {\n const v = mesh.indices[indexStart + i]\n let n = remap.get(v)\n if (n === undefined) {\n n = order.length\n remap.set(v, n)\n order.push(v)\n }\n indices[i] = n\n }\n const positions = new Float32Array(order.length * 3)\n const normals = new Float32Array(order.length * 3)\n const colors = new Float32Array(order.length * 3)\n const sway = new Float32Array(order.length)\n for (let i = 0; i < order.length; i++) {\n const v = order[i]\n positions[i * 3] = mesh.positions[v * 3] - origin[0]\n positions[i * 3 + 1] = mesh.positions[v * 3 + 1] - origin[1]\n positions[i * 3 + 2] = mesh.positions[v * 3 + 2] - origin[2]\n normals.set(mesh.normals.subarray(v * 3, v * 3 + 3), i * 3)\n colors.set(mesh.colors.subarray(v * 3, v * 3 + 3), i * 3)\n sway[i] = mesh.sway[v]\n }\n return { positions, normals, colors, sway, indices, triangleCount: indexCount / 3, kind: mesh.kind, material: mesh.material }\n}\n\n/** One Mesh per part. userData: collider, bendable, thorny, species, bounds. */\nexport function createPlantObject(THREE: ThreeNS, plant: PlantMesh, materials?: VegetationMaterials, options: PlantObjectOptions = {}): InstanceType<ThreeNS['Group']> {\n const mats = materials ?? createVegetationMaterials(THREE)\n const ids = idsFor(mats, options)\n const g = new THREE.Group()\n g.name = plant.species\n if (options.separable) {\n for (const pc of plant.pieces) {\n const src = plant.parts[pc.part]\n if (!src) continue\n const data = slicePiece(src, pc.indexStart, pc.indexCount, pc.pivot)\n const mesh = meshFor(THREE, data, mats[pc.part])\n mesh.name = pc.id\n mesh.position.set(pc.pivot[0], pc.pivot[1], pc.pivot[2])\n const id = ids[pc.material]\n mesh.userData.destructionMaterial = id\n mesh.userData.destructionPart = { id: pc.id, kind: pc.kind, parent: pc.parent, material: id, materialKey: pc.material, ...(pc.radius === undefined ? {} : { radius: pc.radius, length: pc.length, axis: pc.axis, base: pc.base }) }\n g.add(mesh)\n }\n g.userData = { collider: plant.collider, bendable: plant.bendable, thorny: plant.thorny, species: plant.species, bounds: plant.bounds, pieces: plant.pieces, separable: true }\n return g\n }\n for (const kind of PART_ORDER) {\n const data = plant.parts[kind]\n if (!data) continue\n g.add(meshFor(THREE, data, mats[kind], ids, plant.condition))\n }\n g.userData = { collider: plant.collider, bendable: plant.bendable, thorny: plant.thorny, species: plant.species, bounds: plant.bounds, damageable: { material: plant.parts.wood?.material ?? 'foliage' }, destructionMaterial: ids[materialKeyForPart(plant.parts.wood ? 'wood' : 'foliage', plant.parts.wood?.material ?? 'foliage', plant.condition)] }\n return g\n}\n\n/** A merged lot: at most 3 meshes. userData: colliders, triangleCount. */\nexport function createLotObject(THREE: ThreeNS, lot: Lot, materials?: VegetationMaterials, options: DestructionOptions = {}): InstanceType<ThreeNS['Group']> {\n const mats = materials ?? createVegetationMaterials(THREE)\n const ids = idsFor(mats, options)\n const g = new THREE.Group()\n g.name = 'vegetation-lot'\n const { wood, foliage, flowers } = lot.meshes\n if (wood) g.add(meshFor(THREE, wood, mats.wood, ids, lot.condition))\n if (foliage) g.add(meshFor(THREE, foliage, mats.foliage, ids, lot.condition))\n if (flowers) g.add(meshFor(THREE, flowers, mats.flowers, ids, lot.condition))\n g.userData = { colliders: lot.colliders, triangleCount: lot.triangleCount, materialIds: ids }\n return g\n}\n\n/**\n * Swap one merged plant of a lot for its separable version: its triangles are hidden in the lot meshes (`lotObject` is the result\n * of createLotObject for `lot`) and a Group with one child per piece is returned, already placed (position, rotation.y, scale).\n * Add it to the scene yourself.\n */\nexport function separatePlantFromLot(THREE: ThreeNS, lot: Lot, lotObject: Obj, plantIndex: number, materials?: VegetationMaterials, options: DestructionOptions = {}): InstanceType<ThreeNS['Group']> {\n const { plant, placement } = extractPlant(lot, plantIndex)\n hideLotPlant(lot, plantIndex)\n lotObject.traverse((o) => {\n const geo = (o as InstanceType<ThreeNS['Mesh']>).geometry as Geo | undefined\n if (geo?.index) geo.index.needsUpdate = true\n })\n const obj = createPlantObject(THREE, plant, materials, { ...options, separable: true })\n obj.position.set(placement.x, 0, placement.z)\n obj.rotation.y = placement.ry\n obj.scale.setScalar(placement.scale)\n obj.userData.plantIndex = plantIndex\n return obj\n}\n\n/** InstancedMesh per part for many copies of one plant (grass, flowers, hedges). Wind phase varies per instance. */\nexport function createInstancedPlants(THREE: ThreeNS, plant: PlantMesh, placements: readonly Placement[], materials?: VegetationMaterials, options: PlantObjectOptions = {}): InstanceType<ThreeNS['Group']> {\n const mats = materials ?? createVegetationMaterials(THREE)\n const ids = idsFor(mats, options)\n const g = new THREE.Group()\n g.name = plant.species + '-instanced'\n const pos = new THREE.Vector3()\n const quat = new THREE.Quaternion()\n const scl = new THREE.Vector3()\n const up = new THREE.Vector3(0, 1, 0)\n const m4 = new THREE.Matrix4()\n for (const kind of PART_ORDER) {\n const data = plant.parts[kind]\n if (!data) continue\n const geo = toBufferGeometry(THREE, data)\n const im = new THREE.InstancedMesh(geo, mats[kind], Math.max(1, placements.length))\n im.count = placements.length\n for (let i = 0; i < placements.length; i++) {\n const p = placements[i]\n pos.set(p.x, 0, p.z)\n quat.setFromAxisAngle(up, p.ry)\n scl.setScalar(p.scale)\n m4.compose(pos, quat, scl)\n im.setMatrixAt(i, m4)\n }\n im.instanceMatrix.needsUpdate = true\n im.computeBoundingSphere()\n im.frustumCulled = false\n im.name = kind\n im.userData.damageable = { material: data.material }\n im.userData.destructionMaterial = ids[materialKeyForPart(data.kind, data.material, plant.condition)]\n g.add(im)\n }\n g.userData = { collider: plant.collider, bendable: plant.bendable, species: plant.species, count: placements.length }\n return g\n}\n\nexport interface LodObjectOptions extends GenerateOptions {\n /** distances at which lod 0 / 1 / 2 start (default 0, 25, 60) */\n distances?: [number, number, number]\n materials?: VegetationMaterials\n species?: string\n}\n\n/** THREE.LOD with the three LODs of a plant. */\nexport function lodObject(THREE: ThreeNS, spec: PlantSpec, opts: LodObjectOptions = {}): InstanceType<ThreeNS['LOD']> {\n const mats = opts.materials ?? createVegetationMaterials(THREE)\n const d = opts.distances ?? [0, 25, 60]\n const lod = new THREE.LOD()\n for (const l of [0, 1, 2] as const) {\n const plant = generate(spec, { ...opts, lod: l })\n lod.addLevel(createPlantObject(THREE, plant, mats) as Obj, d[l])\n }\n lod.userData = { collider: generate(spec, { ...opts, lod: 2 }).collider }\n return lod\n}\n","[\n {\n \"id\": \"mango_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 8.5,\n \"trunkRadius\": 0.34,\n \"crownRadius\": 4.6,\n \"crownShape\": \"spreading\",\n \"branchLevels\": 3,\n \"leafColor\": [\n \"#1f5a2a\",\n \"#2a6a30\",\n \"#2f7434\"\n ],\n \"barkColor\": \"#5a4030\",\n \"fruit\": {\n \"colors\": [\n \"#e8a02a\",\n \"#d9602d\",\n \"#c8d04a\",\n \"#e8c040\"\n ],\n \"count\": 16,\n \"radius\": 0.17\n },\n \"crownStyle\": \"dome\",\n \"trunkFraction\": 0.34\n },\n \"tags\": [\n \"tree\",\n \"fruit\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"yellow_ipe\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 9.5,\n \"trunkRadius\": 0.26,\n \"crownRadius\": 3.5,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.3,\n \"leafColor\": [\n \"#5aa045\",\n \"#4a9040\",\n \"#68ac4c\"\n ],\n \"barkColor\": \"#7a6a58\",\n \"bloom\": {\n \"colors\": [\n \"#f4c81e\",\n \"#f6d43a\",\n \"#ecb818\"\n ],\n \"seasons\": [\n \"winter\",\n \"spring\"\n ],\n \"replacesLeaves\": true,\n \"density\": 1\n },\n \"crownStyle\": \"dome\",\n \"clumpSize\": 0.95\n },\n \"tags\": [\n \"tree\",\n \"flowering\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"pink_ipe\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 9.5,\n \"trunkRadius\": 0.27,\n \"crownRadius\": 3.5,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.3,\n \"leafColor\": [\n \"#5aa045\",\n \"#4a9040\",\n \"#68ac4c\"\n ],\n \"barkColor\": \"#7d6e5c\",\n \"bloom\": {\n \"colors\": [\n \"#d86aa8\",\n \"#e88ac0\",\n \"#c2549a\"\n ],\n \"seasons\": [\n \"winter\",\n \"spring\"\n ],\n \"replacesLeaves\": true,\n \"density\": 1\n },\n \"crownStyle\": \"dome\",\n \"clumpSize\": 0.95\n },\n \"tags\": [\n \"tree\",\n \"flowering\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"jabuticaba_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 5,\n \"trunkRadius\": 0.2,\n \"crownRadius\": 2.4,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.34,\n \"branchLevels\": 3,\n \"leafColor\": [\n \"#2e6e34\",\n \"#3a7a3a\",\n \"#357a38\"\n ],\n \"barkColor\": \"#b8a68c\",\n \"fruit\": {\n \"colors\": [\n \"#6e2c92\",\n \"#7d3aa4\",\n \"#5e2480\"\n ],\n \"count\": 380,\n \"radius\": 0.085,\n \"onTrunk\": true\n },\n \"crownStyle\": \"cloud\",\n \"clumpSize\": 0.95\n },\n \"tags\": [\n \"tree\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"flamboyant\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 8,\n \"trunkRadius\": 0.3,\n \"crownRadius\": 5.8,\n \"crownShape\": \"spreading\",\n \"trunkFraction\": 0.44,\n \"leafColor\": [\n \"#6aa84a\",\n \"#7ab858\",\n \"#5a9a42\"\n ],\n \"barkColor\": \"#7a6a58\",\n \"bloom\": {\n \"colors\": [\n \"#e0361e\",\n \"#ec5a22\",\n \"#d02a1c\"\n ],\n \"seasons\": [\n \"spring\",\n \"summer\"\n ],\n \"replacesLeaves\": true,\n \"density\": 0.78\n },\n \"crownStyle\": \"umbrella\"\n },\n \"tags\": [\n \"tree\",\n \"flowering\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"guava_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 4.8,\n \"trunkRadius\": 0.15,\n \"crownRadius\": 2.6,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.3,\n \"leafColor\": [\n \"#74ae4c\",\n \"#82ba56\",\n \"#68a248\"\n ],\n \"barkColor\": \"#b28c6c\",\n \"fruit\": {\n \"colors\": [\n \"#d8e070\",\n \"#e8d450\",\n \"#c8dc5a\"\n ],\n \"count\": 10,\n \"radius\": 0.075\n },\n \"crownStyle\": \"cloud\"\n },\n \"tags\": [\n \"tree\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"avocado_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 8.5,\n \"trunkRadius\": 0.26,\n \"crownRadius\": 3.0,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.34,\n \"leafColor\": [\n \"#1c5628\",\n \"#266432\",\n \"#215e2c\"\n ],\n \"barkColor\": \"#6a5444\",\n \"fruit\": {\n \"colors\": [\n \"#1e2e14\",\n \"#2c3c1a\",\n \"#3a4a22\"\n ],\n \"count\": 10,\n \"radius\": 0.1\n },\n \"crownStyle\": \"cloud\"\n },\n \"tags\": [\n \"tree\",\n \"fruit\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"lemon_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 3.6,\n \"trunkRadius\": 0.13,\n \"crownRadius\": 2.1,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.28,\n \"leafColor\": [\n \"#70bc4a\",\n \"#80c856\",\n \"#62ac42\"\n ],\n \"barkColor\": \"#7a6a52\",\n \"fruit\": {\n \"colors\": [\n \"#f6dc2c\",\n \"#f0d020\",\n \"#f8e450\"\n ],\n \"count\": 18,\n \"radius\": 0.075\n },\n \"crownStyle\": \"cloud\"\n },\n \"tags\": [\n \"tree\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"pitanga_bush_tree\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 3.4,\n \"trunkRadius\": 0.1,\n \"crownRadius\": 1.9,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.22,\n \"branchLevels\": 3,\n \"leafColor\": [\n \"#5eaa44\",\n \"#6eb850\",\n \"#80c45c\"\n ],\n \"barkColor\": \"#8a6a50\",\n \"fruit\": {\n \"colors\": [\n \"#d82a1a\",\n \"#e8501e\",\n \"#c01a18\"\n ],\n \"count\": 40,\n \"radius\": 0.04\n },\n \"crownStyle\": \"cloud\"\n },\n \"tags\": [\n \"tree\",\n \"fruit\",\n \"hedge\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"sidewalk_ficus\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 7,\n \"trunkRadius\": 0.22,\n \"crownRadius\": 2.6,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.5,\n \"clipped\": true,\n \"leafColor\": [\n \"#1e6428\",\n \"#256c2e\",\n \"#206028\"\n ],\n \"barkColor\": \"#9a8a78\",\n \"crownStyle\": \"sphere\"\n },\n \"tags\": [\n \"tree\",\n \"street\",\n \"shade\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"oak_like\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 10,\n \"trunkRadius\": 0.45,\n \"crownRadius\": 5,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.3,\n \"deciduous\": true,\n \"leafColor\": [\n \"#4a8a38\",\n \"#5e9c3e\",\n \"#72a032\",\n \"#3a7a34\"\n ],\n \"barkColor\": \"#5a4636\",\n \"crownStyle\": \"lumpy\"\n },\n \"tags\": [\n \"tree\",\n \"shade\"\n ],\n \"climate\": [\n \"temperate\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"weeping_willow\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 11.5,\n \"trunkRadius\": 0.34,\n \"crownRadius\": 4.3,\n \"crownShape\": \"weeping\",\n \"trunkFraction\": 0.28,\n \"deciduous\": true,\n \"leafColor\": [\n \"#8ab040\",\n \"#9ac053\",\n \"#7aa238\"\n ],\n \"barkColor\": \"#4a3c30\",\n \"crownStyle\": \"willow\"\n },\n \"tags\": [\n \"tree\",\n \"shade\"\n ],\n \"climate\": [\n \"temperate\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"araucaria\",\n \"archetype\": \"conifer\",\n \"params\": {\n \"shape\": \"candelabra\",\n \"height\": 16,\n \"radius\": 5,\n \"tiers\": 6,\n \"trunkRadius\": 0.3,\n \"leafColor\": \"#3d6e3a\",\n \"barkColor\": \"#5a4838\"\n },\n \"tags\": [\n \"tree\",\n \"conifer\"\n ],\n \"climate\": [\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"pine\",\n \"archetype\": \"conifer\",\n \"params\": {\n \"shape\": \"cone\",\n \"height\": 12,\n \"radius\": 2.8,\n \"tiers\": 10,\n \"trunkRadius\": 0.26,\n \"leafColor\": \"#37803f\",\n \"barkColor\": \"#6b4b34\"\n },\n \"tags\": [\n \"tree\",\n \"conifer\"\n ],\n \"climate\": [\n \"temperate\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"eucalyptus\",\n \"archetype\": \"broadleaf_tree\",\n \"params\": {\n \"height\": 16,\n \"trunkRadius\": 0.45,\n \"crownRadius\": 4.2,\n \"crownShape\": \"round\",\n \"trunkFraction\": 0.58,\n \"leafColor\": [\n \"#8c9f6a\",\n \"#7d9460\",\n \"#9aab74\"\n ],\n \"barkColor\": \"#a89a82\",\n \"crownStyle\": \"sparse_high\"\n },\n \"tags\": [\n \"tree\",\n \"street\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"dead_tree\",\n \"archetype\": \"dead_tree\",\n \"params\": {\n \"height\": 6,\n \"trunkRadius\": 0.24,\n \"crownRadius\": 2.4\n },\n \"tags\": [\n \"tree\",\n \"dead\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n }\n]\n","[\n {\n \"id\": \"coconut_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"coconut\",\n \"height\": 7.5,\n \"trunkRadius\": 0.2,\n \"frondCount\": 18,\n \"frondLength\": 3.4,\n \"fruit\": {\n \"color\": \"#6f8a2e\",\n \"count\": 9,\n \"radius\": 0.14\n }\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"royal_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"royal\",\n \"height\": 12,\n \"trunkRadius\": 0.28,\n \"frondCount\": 16,\n \"frondLength\": 4.6\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"street\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"fan_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"fan\",\n \"height\": 3.2,\n \"trunkRadius\": 0.2,\n \"frondCount\": 10,\n \"frondLength\": 2.3\n },\n \"tags\": [\n \"tree\",\n \"palm\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"areca_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"areca\",\n \"height\": 2.8,\n \"stems\": 7,\n \"trunkRadius\": 0.03\n },\n \"tags\": [\n \"palm\",\n \"shrub\",\n \"indoor\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"date_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"date\",\n \"height\": 6.5,\n \"trunkRadius\": 0.26,\n \"fruit\": {\n \"color\": \"#e8902a\",\n \"count\": 22,\n \"radius\": 0.03\n }\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"fruit\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"banana_plant\",\n \"archetype\": \"banana\",\n \"params\": {\n \"height\": 3.8,\n \"leafCount\": 8\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"tropical\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"banana_with_bunch\",\n \"archetype\": \"banana\",\n \"params\": {\n \"height\": 3.8,\n \"leafCount\": 8,\n \"bunch\": true,\n \"bud\": true\n },\n \"tags\": [\n \"tree\",\n \"palm\",\n \"fruit\",\n \"tropical\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": true\n }\n]\n","[\n {\n \"id\": \"boxwood_hedge\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"hedge\",\n \"length\": 2.4,\n \"height\": 1.0,\n \"width\": 0.65,\n \"leafColor\": [\n \"#347a3a\"\n ]\n },\n \"tags\": [\n \"shrub\",\n \"hedge\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"ixora_hedge\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"hedge\",\n \"length\": 2.4,\n \"height\": 1.1,\n \"width\": 0.7,\n \"leafColor\": [\n \"#2e6e34\"\n ],\n \"flowers\": {\n \"colors\": [\n \"#d8281e\",\n \"#e04a2a\"\n ],\n \"count\": 20,\n \"style\": \"dots\",\n \"size\": 0.05\n }\n },\n \"tags\": [\n \"shrub\",\n \"hedge\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"hibiscus_shrub\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"round\",\n \"radius\": 0.85,\n \"height\": 1.7,\n \"leafColor\": [\n \"#2f7a35\",\n \"#3a8a3a\"\n ],\n \"flowers\": {\n \"colors\": [\n \"#e0243a\",\n \"#f06a8a\"\n ],\n \"count\": 9,\n \"style\": \"hibiscus\",\n \"size\": 0.07\n }\n },\n \"tags\": [\n \"shrub\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"bougainvillea\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"loose\",\n \"radius\": 1.1,\n \"height\": 1.8,\n \"leafColor\": [\n \"#3f8a3a\",\n \"#4a9a42\"\n ],\n \"flowers\": {\n \"colors\": [\n \"#c8208a\",\n \"#d8409a\",\n \"#e060a8\"\n ],\n \"count\": 70,\n \"style\": \"clusters\",\n \"size\": 0.06\n }\n },\n \"tags\": [\n \"shrub\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"azalea\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"round\",\n \"radius\": 0.6,\n \"height\": 0.8,\n \"leafColor\": [\n \"#356e38\",\n \"#3f7a3e\"\n ],\n \"flowers\": {\n \"colors\": [\n \"#e870a8\",\n \"#f0a0c8\"\n ],\n \"count\": 60,\n \"style\": \"dots\",\n \"size\": 0.05\n }\n },\n \"tags\": [\n \"shrub\",\n \"flowering\"\n ],\n \"climate\": [\n \"temperate\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"croton\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"round\",\n \"radius\": 0.55,\n \"height\": 1.0,\n \"leafColor\": [\n \"#2f7a35\",\n \"#3a8a3a\"\n ],\n \"variegation\": [\n \"#f0c020\",\n \"#d84020\",\n \"#2f7a35\",\n \"#e88a20\"\n ],\n \"leafSize\": 1.2\n },\n \"tags\": [\n \"shrub\",\n \"ornamental\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"lady_palm\",\n \"archetype\": \"palm\",\n \"params\": {\n \"variant\": \"fan\",\n \"stems\": 7,\n \"height\": 2.4,\n \"trunkRadius\": 0.025,\n \"frondLength\": 0.9,\n \"frondCount\": 3,\n \"trunkColor\": \"#6a5a3a\",\n \"lean\": 0.24\n },\n \"tags\": [\n \"palm\",\n \"shrub\",\n \"indoor\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"generic_round_shrub\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"round\",\n \"radius\": 0.7,\n \"height\": 1.0\n },\n \"tags\": [\n \"shrub\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"overgrown_bush\",\n \"archetype\": \"shrub\",\n \"params\": {\n \"shape\": \"loose\",\n \"radius\": 1.0,\n \"height\": 1.5,\n \"density\": 1.3,\n \"leafColor\": [\n \"#3a7a34\",\n \"#2f6a30\",\n \"#4a8a3a\"\n ]\n },\n \"tags\": [\n \"shrub\",\n \"neglected\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"m\",\n \"solid\": false\n }\n]\n","[\n {\n \"id\": \"rose_bush_red\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"rose\",\n \"petalColors\": [\n \"#d0243a\"\n ],\n \"height\": 0.95\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"rose_bush_pink\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"rose\",\n \"petalColors\": [\n \"#f08ab0\"\n ],\n \"height\": 0.95\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"rose_bush_white\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"rose\",\n \"petalColors\": [\n \"#f6f0e6\"\n ],\n \"height\": 0.95\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"sunflower\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"sunflower\"\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"daisy\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"daisy\"\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"tulip\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"tulip\",\n \"petalColors\": [\n \"#e03a52\",\n \"#e8c020\",\n \"#f08ab0\"\n ]\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"lily\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"lily\"\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"marigold\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"pompom\",\n \"petalColors\": [\n \"#f08a1a\",\n \"#f5b020\",\n \"#e8701a\"\n ],\n \"height\": 0.34,\n \"stemCount\": 10\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"periwinkle_pink\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"daisy\",\n \"spreading\": true,\n \"petalColors\": [\n \"#f0a0c8\"\n ],\n \"height\": 0.24,\n \"stemCount\": 11,\n \"flowerSize\": 0.024\n },\n \"tags\": [\n \"flower\",\n \"flowering\",\n \"ground\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"periwinkle_white\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"daisy\",\n \"spreading\": true,\n \"petalColors\": [\n \"#f6f2ea\"\n ],\n \"height\": 0.24,\n \"stemCount\": 11,\n \"flowerSize\": 0.024\n },\n \"tags\": [\n \"flower\",\n \"flowering\",\n \"ground\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"hydrangea\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"hydrangea\",\n \"petalColors\": [\n \"#5a84d8\",\n \"#8aa8e8\",\n \"#9a90e0\"\n ],\n \"height\": 1.2,\n \"stemCount\": 6\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"temperate\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"bird_of_paradise\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"bird_of_paradise\"\n },\n \"tags\": [\n \"flower\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"wild_flowers\",\n \"archetype\": \"flower_plant\",\n \"params\": {\n \"flowerType\": \"daisy\",\n \"petalColors\": [\n \"#f5f0e0\",\n \"#f08ab0\",\n \"#f2c230\",\n \"#a070e0\"\n ],\n \"stemCount\": 12,\n \"height\": 0.45\n },\n \"tags\": [\n \"flower\",\n \"flowering\",\n \"ground\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n }\n]\n","[\n {\n \"id\": \"mandacaru\",\n \"archetype\": \"columnar_cactus\",\n \"params\": {\n \"height\": 4.6,\n \"ribs\": 6,\n \"armStyle\": \"candelabra\",\n \"arms\": [\n 4,\n 6\n ],\n \"color\": \"#5a9a88\",\n \"spineColor\": \"#cdbf94\",\n \"flowers\": {\n \"color\": \"#fdf8f0\",\n \"count\": 1\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"semiarid\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"saguaro\",\n \"archetype\": \"columnar_cactus\",\n \"params\": {\n \"height\": 5.2,\n \"ribs\": 12,\n \"armStyle\": \"saguaro\",\n \"arms\": 2,\n \"color\": \"#5f9a62\"\n },\n \"tags\": [\n \"cactus\",\n \"spiny\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"l\",\n \"solid\": true\n },\n {\n \"id\": \"xique_xique\",\n \"archetype\": \"columnar_cactus\",\n \"params\": {\n \"height\": 1.4,\n \"radius\": 0.07,\n \"ribs\": 6,\n \"armStyle\": \"sprawl\",\n \"arms\": [\n 5,\n 7\n ],\n \"color\": \"#7aa890\"\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"semiarid\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"prickly_pear\",\n \"archetype\": \"paddle_cactus\",\n \"params\": {\n \"fruit\": {\n \"color\": \"#c83a4a\",\n \"count\": 7\n },\n \"flowers\": {\n \"color\": \"#f2c230\",\n \"count\": 3\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"semiarid\",\n \"fruit\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"crown_cactus\",\n \"archetype\": \"globe_cactus\",\n \"params\": {\n \"radius\": 0.22,\n \"height\": 0.5,\n \"ribs\": 12,\n \"cephalium\": {\n \"color\": \"#c8305a\"\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"semiarid\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"barrel_cactus\",\n \"archetype\": \"globe_cactus\",\n \"params\": {\n \"radius\": 0.4,\n \"ribs\": 16,\n \"height\": 0.8,\n \"flowers\": {\n \"color\": \"#f2c230\",\n \"count\": 8\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"m\",\n \"solid\": true\n },\n {\n \"id\": \"small_cactus\",\n \"archetype\": \"globe_cactus\",\n \"params\": {\n \"radius\": 0.09,\n \"height\": 0.14,\n \"ribs\": 10,\n \"flowers\": {\n \"color\": \"#f080b0\",\n \"count\": 5\n }\n },\n \"tags\": [\n \"cactus\",\n \"spiny\",\n \"indoor\"\n ],\n \"climate\": [\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n }\n]\n","[\n {\n \"id\": \"snake_plant\",\n \"archetype\": \"rosette\",\n \"params\": {\n \"form\": \"sword\",\n \"height\": 0.9\n },\n \"tags\": [\n \"succulent\",\n \"indoor\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"agave\",\n \"archetype\": \"rosette\",\n \"params\": {\n \"form\": \"agave\",\n \"height\": 1.0\n },\n \"tags\": [\n \"succulent\",\n \"semiarid\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"aloe_vera\",\n \"archetype\": \"rosette\",\n \"params\": {\n \"form\": \"aloe\",\n \"height\": 0.55,\n \"bloom\": {\n \"color\": \"#e8702a\"\n }\n },\n \"tags\": [\n \"succulent\",\n \"indoor\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"echeveria\",\n \"archetype\": \"rosette\",\n \"params\": {\n \"form\": \"echeveria\",\n \"height\": 0.14\n },\n \"tags\": [\n \"succulent\",\n \"indoor\"\n ],\n \"climate\": [\n \"arid\",\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"s\",\n \"solid\": false\n }\n]\n","[\n {\n \"id\": \"lawn_tuft\",\n \"archetype\": \"grass_tuft\",\n \"params\": {\n \"count\": 46,\n \"height\": 0.3,\n \"color\": \"#6aa646\"\n },\n \"tags\": [\n \"ground\",\n \"grass\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"wild_grass_tall\",\n \"archetype\": \"grass_tuft\",\n \"params\": {\n \"count\": 30,\n \"height\": 0.9,\n \"color\": \"#9ab05a\",\n \"seedHeads\": true\n },\n \"tags\": [\n \"ground\",\n \"grass\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"weeds\",\n \"archetype\": \"grass_tuft\",\n \"params\": {\n \"count\": 30,\n \"height\": 0.5,\n \"color\": \"#7a9a4a\",\n \"radius\": 0.3\n },\n \"tags\": [\n \"ground\",\n \"grass\",\n \"neglected\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"papyrus\",\n \"archetype\": \"grass_tuft\",\n \"params\": {\n \"count\": 30,\n \"height\": 1.8,\n \"color\": \"#5f9a44\",\n \"umbrellaHeads\": true,\n \"radius\": 0.55\n },\n \"tags\": [\n \"ground\",\n \"grass\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"fern\",\n \"archetype\": \"fern\",\n \"params\": {},\n \"tags\": [\n \"ground\",\n \"fern\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": false\n },\n {\n \"id\": \"boston_fern\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"cachepot\",\n \"radius\": 0.22,\n \"height\": 0.3,\n \"color\": \"#d8d0bc\"\n },\n \"plant\": {\n \"archetype\": \"fern\",\n \"frondCount\": 16,\n \"frondLength\": 0.85\n }\n },\n \"tags\": [\n \"ground\",\n \"fern\",\n \"potted\",\n \"indoor\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"s\",\n \"solid\": true\n }\n]\n","[\n {\n \"id\": \"bougainvillea_vine\",\n \"archetype\": \"vine\",\n \"params\": {\n \"host\": {\n \"wall\": {\n \"width\": 2.6,\n \"height\": 2.4\n }\n },\n \"leafColor\": \"#3f8a3a\",\n \"flowers\": {\n \"colors\": [\n \"#c8208a\",\n \"#d8409a\",\n \"#e060a8\"\n ],\n \"style\": \"bract\",\n \"count\": 18\n }\n },\n \"tags\": [\n \"vine\",\n \"flowering\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"ivy\",\n \"archetype\": \"vine\",\n \"params\": {\n \"host\": {\n \"wall\": {\n \"width\": 2.6,\n \"height\": 2.4\n }\n },\n \"leafColor\": \"#2f6e34\",\n \"leafSize\": 0.9,\n \"density\": 1.4\n },\n \"tags\": [\n \"vine\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\"\n ],\n \"size\": \"m\",\n \"solid\": false\n },\n {\n \"id\": \"passion_fruit_vine\",\n \"archetype\": \"vine\",\n \"params\": {\n \"host\": {\n \"wall\": {\n \"width\": 2.6,\n \"height\": 2.4\n }\n },\n \"leafColor\": \"#4a9a40\",\n \"leafSize\": 1.2,\n \"flowers\": {\n \"colors\": [\n \"#f6f0f8\",\n \"#c8b0e0\",\n \"#6a3a9a\"\n ],\n \"style\": \"passion\",\n \"count\": 8\n }\n },\n \"tags\": [\n \"vine\",\n \"flowering\",\n \"fruit\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\"\n ],\n \"size\": \"m\",\n \"solid\": false\n }\n]\n","[\n {\n \"id\": \"potted_fern\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"terracotta\",\n \"radius\": 0.2,\n \"height\": 0.3\n },\n \"plant\": {\n \"archetype\": \"fern\",\n \"frondCount\": 12,\n \"frondLength\": 0.65\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"fern\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_snake_plant\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"cylinder\",\n \"radius\": 0.17,\n \"height\": 0.28,\n \"color\": \"#6a6e72\"\n },\n \"plant\": {\n \"archetype\": \"rosette\",\n \"form\": \"sword\",\n \"height\": 0.8\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"succulent\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_areca\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"cachepot\",\n \"radius\": 0.27,\n \"height\": 0.38\n },\n \"plant\": {\n \"archetype\": \"palm\",\n \"variant\": \"areca\",\n \"height\": 1.6,\n \"stems\": 6,\n \"trunkRadius\": 0.02,\n \"frondLength\": 1.0\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"palm\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_cactus\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"terracotta\",\n \"radius\": 0.12,\n \"height\": 0.16\n },\n \"plant\": {\n \"archetype\": \"globe_cactus\",\n \"radius\": 0.1,\n \"height\": 0.18,\n \"ribs\": 11,\n \"flowers\": {\n \"color\": \"#f080b0\",\n \"count\": 4\n }\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"cactus\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_rose\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"terracotta\",\n \"radius\": 0.22,\n \"height\": 0.32\n },\n \"plant\": {\n \"archetype\": \"flower_plant\",\n \"flowerType\": \"rose\",\n \"petalColors\": [\n \"#e0405a\"\n ],\n \"height\": 0.6,\n \"stemCount\": 5\n }\n },\n \"tags\": [\n \"potted\",\n \"flowering\",\n \"flower\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n },\n {\n \"id\": \"potted_succulents\",\n \"archetype\": \"potted\",\n \"params\": {\n \"pot\": {\n \"shape\": \"cachepot\",\n \"radius\": 0.14,\n \"height\": 0.14,\n \"color\": \"#e8e2d4\"\n },\n \"plant\": {\n \"archetype\": \"rosette\",\n \"form\": \"echeveria\",\n \"height\": 0.12\n }\n },\n \"tags\": [\n \"potted\",\n \"indoor\",\n \"succulent\"\n ],\n \"climate\": [\n \"tropical\",\n \"subtropical\",\n \"temperate\",\n \"arid\"\n ],\n \"size\": \"s\",\n \"solid\": true\n }\n]\n","{\n \"mango_tree\": {\n \"name\": \"Mangueira\",\n \"description\": \"Copa larga e sombreada com mangas penduradas.\"\n },\n \"yellow_ipe\": {\n \"name\": \"Ipê-amarelo\",\n \"description\": \"Verde no verão, copa coberta de flores amarelas na seca.\"\n },\n \"pink_ipe\": {\n \"name\": \"Ipê-roxo\",\n \"description\": \"Verde no verão, copa coberta de flores rosa na seca.\"\n },\n \"jabuticaba_tree\": {\n \"name\": \"Jabuticabeira\",\n \"description\": \"Árvore densa e pequena com frutos escuros brotando direto do tronco.\"\n },\n \"flamboyant\": {\n \"name\": \"Flamboyant\",\n \"description\": \"Copa em guarda-chuva coberta de flores vermelhas.\"\n },\n \"guava_tree\": {\n \"name\": \"Goiabeira\",\n \"description\": \"Árvore pequena e retorcida, casca lisa avermelhada e frutos redondos.\"\n },\n \"avocado_tree\": {\n \"name\": \"Abacateiro\",\n \"description\": \"Árvore alta de folhagem escura com frutos em forma de pera.\"\n },\n \"lemon_tree\": {\n \"name\": \"Limoeiro\",\n \"description\": \"Árvore pequena de quintal com limões amarelos.\"\n },\n \"pitanga_bush_tree\": {\n \"name\": \"Pitangueira\",\n \"description\": \"Árvore baixa e ramificada coberta de frutinhas vermelhas.\"\n },\n \"sidewalk_ficus\": {\n \"name\": \"Ficus de calçada\",\n \"description\": \"Copa redonda e podada, típica de calçadas.\"\n },\n \"oak_like\": {\n \"name\": \"Árvore de folha larga\",\n \"description\": \"Árvore de sombra genérica que muda com as estações.\"\n },\n \"weeping_willow\": {\n \"name\": \"Salgueiro-chorão\",\n \"description\": \"Cortinas caídas de folhas verde-claras.\"\n },\n \"araucaria\": {\n \"name\": \"Araucária\",\n \"description\": \"Tronco alto e limpo com copa em candelabro de ramos erguidos.\"\n },\n \"pine\": {\n \"name\": \"Pinheiro\",\n \"description\": \"Conífera cônica com camadas caídas.\"\n },\n \"eucalyptus\": {\n \"name\": \"Eucalipto\",\n \"description\": \"Árvore muito alta de casca clara e copa rala.\"\n },\n \"dead_tree\": {\n \"name\": \"Árvore morta\",\n \"description\": \"Tronco torcido e sem folhas, com galhos quebrados.\"\n },\n \"coconut_palm\": {\n \"name\": \"Coqueiro\",\n \"description\": \"Tronco curvo e inclinado, copa de frondes longas e cocos.\"\n },\n \"royal_palm\": {\n \"name\": \"Palmeira-imperial\",\n \"description\": \"Tronco reto, liso e cinza, com bainha verde sob a copa.\"\n },\n \"fan_palm\": {\n \"name\": \"Palmeira-leque\",\n \"description\": \"Tronco curto e grosso com frondes redondas em leque.\"\n },\n \"areca_palm\": {\n \"name\": \"Palmeira-areca\",\n \"description\": \"Palmeira em touceira com muitas hastes finas e frondes plumosas.\"\n },\n \"date_palm\": {\n \"name\": \"Tamareira\",\n \"description\": \"Tronco áspero, frondes rígidas e eretas e cachos de tâmaras.\"\n },\n \"banana_plant\": {\n \"name\": \"Bananeira\",\n \"description\": \"Falso tronco com folhas enormes, algumas rasgadas.\"\n },\n \"banana_with_bunch\": {\n \"name\": \"Bananeira com cacho\",\n \"description\": \"Bananeira com um cacho pendente e o coração roxo.\"\n },\n \"boxwood_hedge\": {\n \"name\": \"Cerca-viva de buxinho\",\n \"description\": \"Cerca-viva podada de verde escuro.\"\n },\n \"ixora_hedge\": {\n \"name\": \"Cerca-viva de ixora\",\n \"description\": \"Cerca-viva salpicada de cachos de flores vermelhas.\"\n },\n \"hibiscus_shrub\": {\n \"name\": \"Hibisco\",\n \"description\": \"Arbusto de folhas brilhantes com grandes flores vermelhas e rosa.\"\n },\n \"bougainvillea\": {\n \"name\": \"Primavera\",\n \"description\": \"Arbusto espalhado coberto de brácteas magenta.\"\n },\n \"azalea\": {\n \"name\": \"Azaleia\",\n \"description\": \"Arbusto baixo e redondo cheio de flores rosa.\"\n },\n \"croton\": {\n \"name\": \"Cróton\",\n \"description\": \"Arbusto de folhas multicoloridas em amarelo, vermelho e verde.\"\n },\n \"lady_palm\": {\n \"name\": \"Palmeira-ráfia\",\n \"description\": \"Palmeira-leque anã em touceira, com hastes finas (rhapis).\"\n },\n \"generic_round_shrub\": {\n \"name\": \"Arbusto redondo\",\n \"description\": \"Arbusto verde redondo e simples.\"\n },\n \"overgrown_bush\": {\n \"name\": \"Moita crescida\",\n \"description\": \"Moita desgrenhada e sem poda.\"\n },\n \"rose_bush_red\": {\n \"name\": \"Roseira vermelha\",\n \"description\": \"Hastes espinhosas com rosas vermelhas.\"\n },\n \"rose_bush_pink\": {\n \"name\": \"Roseira rosa\",\n \"description\": \"Hastes espinhosas com rosas cor-de-rosa.\"\n },\n \"rose_bush_white\": {\n \"name\": \"Roseira branca\",\n \"description\": \"Hastes espinhosas com rosas brancas.\"\n },\n \"sunflower\": {\n \"name\": \"Girassol\",\n \"description\": \"Hastes altas com grandes flores douradas.\"\n },\n \"daisy\": {\n \"name\": \"Margarida\",\n \"description\": \"Pétalas brancas em volta de um miolo amarelo.\"\n },\n \"tulip\": {\n \"name\": \"Tulipa\",\n \"description\": \"Flores em forma de taça sobre hastes retas.\"\n },\n \"lily\": {\n \"name\": \"Lírio\",\n \"description\": \"Flores brancas em forma de estrela.\"\n },\n \"marigold\": {\n \"name\": \"Cravo-de-defunto\",\n \"description\": \"Flores laranja redondas em pompom.\"\n },\n \"periwinkle_pink\": {\n \"name\": \"Vinca rosa\",\n \"description\": \"Tapete baixo de florzinhas rosa.\"\n },\n \"periwinkle_white\": {\n \"name\": \"Vinca branca\",\n \"description\": \"Tapete baixo de florzinhas brancas.\"\n },\n \"hydrangea\": {\n \"name\": \"Hortênsia\",\n \"description\": \"Grandes bolas azuis de florzinhas.\"\n },\n \"bird_of_paradise\": {\n \"name\": \"Estrelítzia\",\n \"description\": \"Flores laranja e azuis em forma de ave sobre folhas grandes.\"\n },\n \"wild_flowers\": {\n \"name\": \"Flores do campo\",\n \"description\": \"Mistura de florzinhas de campo.\"\n },\n \"mandacaru\": {\n \"name\": \"Mandacaru\",\n \"description\": \"Cacto alto em candelabro, azul-esverdeado, com grandes flores brancas noturnas.\"\n },\n \"saguaro\": {\n \"name\": \"Saguaro\",\n \"description\": \"Cacto colunar gigante com braços voltados para cima.\"\n },\n \"xique_xique\": {\n \"name\": \"Xique-xique\",\n \"description\": \"Cacto colunar baixo e espalhado do sertão.\"\n },\n \"prickly_pear\": {\n \"name\": \"Palma\",\n \"description\": \"Raquetes achatadas encadeadas, com frutos vermelhos.\"\n },\n \"crown_cactus\": {\n \"name\": \"Coroa-de-frade\",\n \"description\": \"Globo com costelas coroado por uma capa vermelha.\"\n },\n \"barrel_cactus\": {\n \"name\": \"Cacto-barril\",\n \"description\": \"Barril redondo com costelas e espinhos dourados.\"\n },\n \"small_cactus\": {\n \"name\": \"Cactinho\",\n \"description\": \"Cacto pequeno e redondo.\"\n },\n \"snake_plant\": {\n \"name\": \"Espada-de-são-jorge\",\n \"description\": \"Folhas altas e rígidas em forma de espada, com faixas.\"\n },\n \"agave\": {\n \"name\": \"Agave\",\n \"description\": \"Grande roseta azul-esverdeada de folhas grossas e pontudas.\"\n },\n \"aloe_vera\": {\n \"name\": \"Babosa\",\n \"description\": \"Folhas carnudas e serrilhadas com espiga de flores laranja.\"\n },\n \"echeveria\": {\n \"name\": \"Echeveria\",\n \"description\": \"Roseta compacta de folhas com pontas rosadas.\"\n },\n \"lawn_tuft\": {\n \"name\": \"Touceira de grama\",\n \"description\": \"Touceira curta de grama verde.\"\n },\n \"wild_grass_tall\": {\n \"name\": \"Capim alto\",\n \"description\": \"Capim alto com espigas.\"\n },\n \"weeds\": {\n \"name\": \"Mato\",\n \"description\": \"Tufo bagunçado de mato.\"\n },\n \"papyrus\": {\n \"name\": \"Papiro\",\n \"description\": \"Juncos altos coroados por penachos.\"\n },\n \"fern\": {\n \"name\": \"Samambaia\",\n \"description\": \"Frondes arqueadas de folíolos pequenos.\"\n },\n \"boston_fern\": {\n \"name\": \"Samambaia-americana\",\n \"description\": \"Samambaia farta em vaso, com frondes caindo pela borda.\"\n },\n \"bougainvillea_vine\": {\n \"name\": \"Primavera trepadeira\",\n \"description\": \"Trepadeira coberta de brácteas magenta.\"\n },\n \"ivy\": {\n \"name\": \"Hera\",\n \"description\": \"Trepadeira densa e verde escura para muros.\"\n },\n \"passion_fruit_vine\": {\n \"name\": \"Maracujazeiro\",\n \"description\": \"Trepadeira vigorosa com flores roxas e brancas.\"\n },\n \"potted_fern\": {\n \"name\": \"Samambaia de vaso\",\n \"description\": \"Samambaia em vaso de barro.\"\n },\n \"potted_snake_plant\": {\n \"name\": \"Espada-de-são-jorge de vaso\",\n \"description\": \"Espada-de-são-jorge em vaso cinza.\"\n },\n \"potted_areca\": {\n \"name\": \"Areca de vaso\",\n \"description\": \"Palmeira-areca em cachepô.\"\n },\n \"potted_cactus\": {\n \"name\": \"Cacto de vaso\",\n \"description\": \"Cacto redondo pequeno em vaso.\"\n },\n \"potted_rose\": {\n \"name\": \"Rosa de vaso\",\n \"description\": \"Roseira em vaso.\"\n },\n \"potted_succulents\": {\n \"name\": \"Suculenta de vaso\",\n \"description\": \"Echeveria em cachepô pequeno.\"\n }\n}\n","{\n \"mango_tree\": {\n \"name\": \"Mango tree\",\n \"description\": \"Broad umbrella crown with hanging mangoes.\"\n },\n \"yellow_ipe\": {\n \"name\": \"Yellow ipe\",\n \"description\": \"Green in summer, a crown of golden flowers in the dry season.\"\n },\n \"pink_ipe\": {\n \"name\": \"Pink ipe\",\n \"description\": \"Green in summer, a crown of pink flowers in the dry season.\"\n },\n \"jabuticaba_tree\": {\n \"name\": \"Jabuticaba tree\",\n \"description\": \"Dense small tree with dark fruit growing straight on the trunk.\"\n },\n \"flamboyant\": {\n \"name\": \"Flamboyant\",\n \"description\": \"Umbrella crown covered in red blooms.\"\n },\n \"guava_tree\": {\n \"name\": \"Guava tree\",\n \"description\": \"Small crooked tree with smooth reddish bark and round fruit.\"\n },\n \"avocado_tree\": {\n \"name\": \"Avocado tree\",\n \"description\": \"Tall dark-green tree with pear-shaped fruit.\"\n },\n \"lemon_tree\": {\n \"name\": \"Lemon tree\",\n \"description\": \"Small backyard tree with bright yellow lemons.\"\n },\n \"pitanga_bush_tree\": {\n \"name\": \"Pitanga tree\",\n \"description\": \"Bushy small tree covered in tiny red fruit.\"\n },\n \"sidewalk_ficus\": {\n \"name\": \"Street ficus\",\n \"description\": \"Clipped round crown typical of sidewalks.\"\n },\n \"oak_like\": {\n \"name\": \"Broadleaf tree\",\n \"description\": \"Generic broadleaf shade tree that changes with the seasons.\"\n },\n \"weeping_willow\": {\n \"name\": \"Weeping willow\",\n \"description\": \"Drooping curtains of pale green leaves.\"\n },\n \"araucaria\": {\n \"name\": \"Araucaria\",\n \"description\": \"Tall bare trunk with an umbrella of upturned branches.\"\n },\n \"pine\": {\n \"name\": \"Pine\",\n \"description\": \"Conical evergreen with drooping tiers.\"\n },\n \"eucalyptus\": {\n \"name\": \"Eucalyptus\",\n \"description\": \"Very tall tree with pale bark and a sparse crown.\"\n },\n \"dead_tree\": {\n \"name\": \"Dead tree\",\n \"description\": \"Bare twisted trunk with broken limbs.\"\n },\n \"coconut_palm\": {\n \"name\": \"Coconut palm\",\n \"description\": \"Leaning curved trunk with a crown of long fronds and coconuts.\"\n },\n \"royal_palm\": {\n \"name\": \"Royal palm\",\n \"description\": \"Straight smooth grey trunk and a green crownshaft.\"\n },\n \"fan_palm\": {\n \"name\": \"Fan palm\",\n \"description\": \"Short thick trunk with round fan-shaped fronds.\"\n },\n \"areca_palm\": {\n \"name\": \"Areca palm\",\n \"description\": \"Clumping palm with many thin canes and feathery fronds.\"\n },\n \"date_palm\": {\n \"name\": \"Date palm\",\n \"description\": \"Rough trunk with stiff upright fronds and date clusters.\"\n },\n \"banana_plant\": {\n \"name\": \"Banana plant\",\n \"description\": \"Pseudostem with huge torn paddle leaves.\"\n },\n \"banana_with_bunch\": {\n \"name\": \"Banana plant with bunch\",\n \"description\": \"Banana plant with a hanging bunch and a purple flower bud.\"\n },\n \"boxwood_hedge\": {\n \"name\": \"Boxwood hedge\",\n \"description\": \"Clipped dark green hedge.\"\n },\n \"ixora_hedge\": {\n \"name\": \"Ixora hedge\",\n \"description\": \"Hedge dotted with clusters of red flowers.\"\n },\n \"hibiscus_shrub\": {\n \"name\": \"Hibiscus shrub\",\n \"description\": \"Glossy shrub with big red and pink flowers.\"\n },\n \"bougainvillea\": {\n \"name\": \"Bougainvillea\",\n \"description\": \"Sprawling shrub covered in magenta bracts.\"\n },\n \"azalea\": {\n \"name\": \"Azalea\",\n \"description\": \"Low round shrub packed with pink blooms.\"\n },\n \"croton\": {\n \"name\": \"Croton\",\n \"description\": \"Shrub with multicoloured leaves in yellow, red and green.\"\n },\n \"lady_palm\": {\n \"name\": \"Lady palm\",\n \"description\": \"Dwarf clumping fan palm (rhapis) with slender canes.\"\n },\n \"generic_round_shrub\": {\n \"name\": \"Round shrub\",\n \"description\": \"Plain round green shrub.\"\n },\n \"overgrown_bush\": {\n \"name\": \"Overgrown bush\",\n \"description\": \"Shaggy untrimmed bush.\"\n },\n \"rose_bush_red\": {\n \"name\": \"Red rose bush\",\n \"description\": \"Thorny stems with deep red roses.\"\n },\n \"rose_bush_pink\": {\n \"name\": \"Pink rose bush\",\n \"description\": \"Thorny stems with pink roses.\"\n },\n \"rose_bush_white\": {\n \"name\": \"White rose bush\",\n \"description\": \"Thorny stems with white roses.\"\n },\n \"sunflower\": {\n \"name\": \"Sunflower\",\n \"description\": \"Tall stems with big golden heads.\"\n },\n \"daisy\": {\n \"name\": \"Daisy\",\n \"description\": \"White petals around a yellow eye.\"\n },\n \"tulip\": {\n \"name\": \"Tulip\",\n \"description\": \"Cup-shaped flowers on straight stems.\"\n },\n \"lily\": {\n \"name\": \"Lily\",\n \"description\": \"Star-shaped white flowers.\"\n },\n \"marigold\": {\n \"name\": \"Marigold\",\n \"description\": \"Round orange pompon flowers.\"\n },\n \"periwinkle_pink\": {\n \"name\": \"Pink periwinkle\",\n \"description\": \"Low carpet of small pink flowers.\"\n },\n \"periwinkle_white\": {\n \"name\": \"White periwinkle\",\n \"description\": \"Low carpet of small white flowers.\"\n },\n \"hydrangea\": {\n \"name\": \"Hydrangea\",\n \"description\": \"Big blue balls of small flowers.\"\n },\n \"bird_of_paradise\": {\n \"name\": \"Bird of paradise\",\n \"description\": \"Orange and blue crested flowers over big leaves.\"\n },\n \"wild_flowers\": {\n \"name\": \"Wild flowers\",\n \"description\": \"A mix of small meadow flowers.\"\n },\n \"mandacaru\": {\n \"name\": \"Mandacaru\",\n \"description\": \"Tall blue-green candelabra cactus with large white night flowers.\"\n },\n \"saguaro\": {\n \"name\": \"Saguaro\",\n \"description\": \"Giant columnar cactus with upturned arms.\"\n },\n \"xique_xique\": {\n \"name\": \"Xique-xique\",\n \"description\": \"Low sprawling columnar cactus of the dry backlands.\"\n },\n \"prickly_pear\": {\n \"name\": \"Prickly pear\",\n \"description\": \"Chained flat pads with red fruit.\"\n },\n \"crown_cactus\": {\n \"name\": \"Turk's cap cactus\",\n \"description\": \"Ribbed globe topped by a red cap.\"\n },\n \"barrel_cactus\": {\n \"name\": \"Barrel cactus\",\n \"description\": \"Round ribbed barrel with golden spines.\"\n },\n \"small_cactus\": {\n \"name\": \"Small cactus\",\n \"description\": \"Tiny round cactus.\"\n },\n \"snake_plant\": {\n \"name\": \"Snake plant\",\n \"description\": \"Tall stiff sword leaves with banded colour.\"\n },\n \"agave\": {\n \"name\": \"Agave\",\n \"description\": \"Big blue-green rosette of thick pointed leaves.\"\n },\n \"aloe_vera\": {\n \"name\": \"Aloe vera\",\n \"description\": \"Fleshy toothed leaves with an orange flower spike.\"\n },\n \"echeveria\": {\n \"name\": \"Echeveria\",\n \"description\": \"Tight rosette with pink-tipped leaves.\"\n },\n \"lawn_tuft\": {\n \"name\": \"Lawn tuft\",\n \"description\": \"Short green grass tuft.\"\n },\n \"wild_grass_tall\": {\n \"name\": \"Tall wild grass\",\n \"description\": \"Tall wild grass with seed heads.\"\n },\n \"weeds\": {\n \"name\": \"Weeds\",\n \"description\": \"Untidy patch of weeds.\"\n },\n \"papyrus\": {\n \"name\": \"Papyrus\",\n \"description\": \"Tall reeds topped with feathery heads.\"\n },\n \"fern\": {\n \"name\": \"Fern\",\n \"description\": \"Arching fronds of small leaflets.\"\n },\n \"boston_fern\": {\n \"name\": \"Boston fern\",\n \"description\": \"Lush fern in a pot, fronds spilling over the rim.\"\n },\n \"bougainvillea_vine\": {\n \"name\": \"Bougainvillea vine\",\n \"description\": \"Climbing vine covered in magenta bracts.\"\n },\n \"ivy\": {\n \"name\": \"Ivy\",\n \"description\": \"Dense dark green climber for walls.\"\n },\n \"passion_fruit_vine\": {\n \"name\": \"Passion fruit vine\",\n \"description\": \"Vigorous climber with intricate purple and white flowers.\"\n },\n \"potted_fern\": {\n \"name\": \"Potted fern\",\n \"description\": \"Fern in a terracotta pot.\"\n },\n \"potted_snake_plant\": {\n \"name\": \"Potted snake plant\",\n \"description\": \"Snake plant in a grey pot.\"\n },\n \"potted_areca\": {\n \"name\": \"Potted areca palm\",\n \"description\": \"Areca palm in a cachepot.\"\n },\n \"potted_cactus\": {\n \"name\": \"Potted cactus\",\n \"description\": \"Small round cactus in a pot.\"\n },\n \"potted_rose\": {\n \"name\": \"Potted rose\",\n \"description\": \"Rose bush in a pot.\"\n },\n \"potted_succulents\": {\n \"name\": \"Potted succulent\",\n \"description\": \"Echeveria in a small cachepot.\"\n }\n}\n","{\n \"id\": \"br\",\n \"name\": \"Brazil (urban)\",\n \"contexts\": {\n \"front_yard\": [\n {\n \"species\": \"boxwood_hedge\",\n \"weight\": 6\n },\n {\n \"species\": \"hibiscus_shrub\",\n \"weight\": 5\n },\n {\n \"species\": \"ixora_hedge\",\n \"weight\": 4\n },\n {\n \"species\": \"bougainvillea\",\n \"weight\": 4\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"croton\",\n \"weight\": 4\n },\n {\n \"species\": \"rose_bush_red\",\n \"weight\": 3\n },\n {\n \"species\": \"rose_bush_pink\",\n \"weight\": 3\n },\n {\n \"species\": \"rose_bush_white\",\n \"weight\": 2\n },\n {\n \"species\": \"azalea\",\n \"weight\": 3\n },\n {\n \"species\": \"potted_fern\",\n \"weight\": 2\n },\n {\n \"species\": \"lemon_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"bird_of_paradise\",\n \"weight\": 2\n },\n {\n \"species\": \"daisy\",\n \"weight\": 2\n },\n {\n \"species\": \"marigold\",\n \"weight\": 2\n },\n {\n \"species\": \"banana_plant\",\n \"weight\": 1\n },\n {\n \"species\": \"periwinkle_pink\",\n \"weight\": 2\n },\n {\n \"species\": \"periwinkle_white\",\n \"weight\": 2\n },\n {\n \"species\": \"areca_palm\",\n \"weight\": 2\n },\n {\n \"species\": \"bougainvillea_vine\",\n \"weight\": 1\n },\n {\n \"species\": \"sidewalk_ficus\",\n \"weight\": 1\n }\n ],\n \"backyard\": [\n {\n \"species\": \"mango_tree\",\n \"weight\": 4\n },\n {\n \"species\": \"banana_plant\",\n \"weight\": 5\n },\n {\n \"species\": \"banana_with_bunch\",\n \"weight\": 3\n },\n {\n \"species\": \"guava_tree\",\n \"weight\": 3\n },\n {\n \"species\": \"lemon_tree\",\n \"weight\": 3\n },\n {\n \"species\": \"pitanga_bush_tree\",\n \"weight\": 3\n },\n {\n \"species\": \"avocado_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"jabuticaba_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"coconut_palm\",\n \"weight\": 1\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 6\n },\n {\n \"species\": \"weeds\",\n \"weight\": 4\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 2\n },\n {\n \"species\": \"fern\",\n \"weight\": 2\n },\n {\n \"species\": \"aloe_vera\",\n \"weight\": 2\n },\n {\n \"species\": \"snake_plant\",\n \"weight\": 1\n },\n {\n \"species\": \"passion_fruit_vine\",\n \"weight\": 2\n },\n {\n \"species\": \"papyrus\",\n \"weight\": 1\n },\n {\n \"species\": \"hibiscus_shrub\",\n \"weight\": 1\n }\n ],\n \"sidewalk_tree\": [\n {\n \"species\": \"sidewalk_ficus\",\n \"weight\": 8\n },\n {\n \"species\": \"yellow_ipe\",\n \"weight\": 3\n },\n {\n \"species\": \"pink_ipe\",\n \"weight\": 3\n },\n {\n \"species\": \"royal_palm\",\n \"weight\": 2\n },\n {\n \"species\": \"eucalyptus\",\n \"weight\": 2\n },\n {\n \"species\": \"mango_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"flamboyant\",\n \"weight\": 2\n },\n {\n \"species\": \"oak_like\",\n \"weight\": 1\n },\n {\n \"species\": \"coconut_palm\",\n \"weight\": 1\n }\n ],\n \"square\": [\n {\n \"species\": \"royal_palm\",\n \"weight\": 4\n },\n {\n \"species\": \"flamboyant\",\n \"weight\": 3\n },\n {\n \"species\": \"yellow_ipe\",\n \"weight\": 3\n },\n {\n \"species\": \"pink_ipe\",\n \"weight\": 3\n },\n {\n \"species\": \"mango_tree\",\n \"weight\": 3\n },\n {\n \"species\": \"sidewalk_ficus\",\n \"weight\": 3\n },\n {\n \"species\": \"araucaria\",\n \"weight\": 2\n },\n {\n \"species\": \"fan_palm\",\n \"weight\": 2\n },\n {\n \"species\": \"boxwood_hedge\",\n \"weight\": 4\n },\n {\n \"species\": \"azalea\",\n \"weight\": 3\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"rose_bush_red\",\n \"weight\": 2\n },\n {\n \"species\": \"hibiscus_shrub\",\n \"weight\": 2\n },\n {\n \"species\": \"weeping_willow\",\n \"weight\": 1\n },\n {\n \"species\": \"coconut_palm\",\n \"weight\": 1\n }\n ],\n \"vacant_lot\": [\n {\n \"species\": \"weeds\",\n \"weight\": 8\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 7\n },\n {\n \"species\": \"overgrown_bush\",\n \"weight\": 4\n },\n {\n \"species\": \"dead_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"guava_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"eucalyptus\",\n \"weight\": 1\n },\n {\n \"species\": \"wild_flowers\",\n \"weight\": 2\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 3\n },\n {\n \"species\": \"mango_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"banana_plant\",\n \"weight\": 1\n },\n {\n \"species\": \"prickly_pear\",\n \"weight\": 1\n }\n ],\n \"indoor\": [\n {\n \"species\": \"potted_fern\",\n \"weight\": 4\n },\n {\n \"species\": \"potted_snake_plant\",\n \"weight\": 4\n },\n {\n \"species\": \"potted_areca\",\n \"weight\": 3\n },\n {\n \"species\": \"potted_cactus\",\n \"weight\": 2\n },\n {\n \"species\": \"potted_rose\",\n \"weight\": 1\n },\n {\n \"species\": \"potted_succulents\",\n \"weight\": 3\n },\n {\n \"species\": \"boston_fern\",\n \"weight\": 2\n }\n ],\n \"semiarid\": [\n {\n \"species\": \"mandacaru\",\n \"weight\": 5\n },\n {\n \"species\": \"xique_xique\",\n \"weight\": 5\n },\n {\n \"species\": \"prickly_pear\",\n \"weight\": 4\n },\n {\n \"species\": \"crown_cactus\",\n \"weight\": 2\n },\n {\n \"species\": \"barrel_cactus\",\n \"weight\": 1\n },\n {\n \"species\": \"agave\",\n \"weight\": 2\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 3\n },\n {\n \"species\": \"weeds\",\n \"weight\": 3\n },\n {\n \"species\": \"dead_tree\",\n \"weight\": 2\n },\n {\n \"species\": \"aloe_vera\",\n \"weight\": 1\n }\n ]\n }\n}\n","{\n \"id\": \"default\",\n \"name\": \"Temperate (generic)\",\n \"contexts\": {\n \"front_yard\": [\n {\n \"species\": \"boxwood_hedge\",\n \"weight\": 5\n },\n {\n \"species\": \"azalea\",\n \"weight\": 4\n },\n {\n \"species\": \"rose_bush_red\",\n \"weight\": 3\n },\n {\n \"species\": \"rose_bush_pink\",\n \"weight\": 2\n },\n {\n \"species\": \"tulip\",\n \"weight\": 3\n },\n {\n \"species\": \"daisy\",\n \"weight\": 3\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"generic_round_shrub\",\n \"weight\": 4\n },\n {\n \"species\": \"hydrangea\",\n \"weight\": 3\n },\n {\n \"species\": \"lily\",\n \"weight\": 2\n },\n {\n \"species\": \"potted_fern\",\n \"weight\": 1\n }\n ],\n \"backyard\": [\n {\n \"species\": \"oak_like\",\n \"weight\": 3\n },\n {\n \"species\": \"lemon_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"weeds\",\n \"weight\": 3\n },\n {\n \"species\": \"wild_flowers\",\n \"weight\": 2\n },\n {\n \"species\": \"fern\",\n \"weight\": 2\n },\n {\n \"species\": \"generic_round_shrub\",\n \"weight\": 3\n },\n {\n \"species\": \"sunflower\",\n \"weight\": 2\n },\n {\n \"species\": \"ivy\",\n \"weight\": 1\n }\n ],\n \"sidewalk_tree\": [\n {\n \"species\": \"oak_like\",\n \"weight\": 6\n },\n {\n \"species\": \"sidewalk_ficus\",\n \"weight\": 2\n },\n {\n \"species\": \"pine\",\n \"weight\": 2\n },\n {\n \"species\": \"weeping_willow\",\n \"weight\": 1\n }\n ],\n \"square\": [\n {\n \"species\": \"oak_like\",\n \"weight\": 5\n },\n {\n \"species\": \"pine\",\n \"weight\": 3\n },\n {\n \"species\": \"weeping_willow\",\n \"weight\": 2\n },\n {\n \"species\": \"boxwood_hedge\",\n \"weight\": 4\n },\n {\n \"species\": \"lawn_tuft\",\n \"weight\": 8\n },\n {\n \"species\": \"rose_bush_red\",\n \"weight\": 2\n },\n {\n \"species\": \"tulip\",\n \"weight\": 2\n },\n {\n \"species\": \"daisy\",\n \"weight\": 2\n }\n ],\n \"vacant_lot\": [\n {\n \"species\": \"weeds\",\n \"weight\": 8\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 7\n },\n {\n \"species\": \"overgrown_bush\",\n \"weight\": 3\n },\n {\n \"species\": \"dead_tree\",\n \"weight\": 1\n },\n {\n \"species\": \"wild_flowers\",\n \"weight\": 2\n },\n {\n \"species\": \"pine\",\n \"weight\": 1\n }\n ],\n \"indoor\": [\n {\n \"species\": \"potted_fern\",\n \"weight\": 4\n },\n {\n \"species\": \"potted_snake_plant\",\n \"weight\": 3\n },\n {\n \"species\": \"potted_succulents\",\n \"weight\": 2\n },\n {\n \"species\": \"potted_cactus\",\n \"weight\": 1\n },\n {\n \"species\": \"boston_fern\",\n \"weight\": 2\n }\n ],\n \"semiarid\": [\n {\n \"species\": \"agave\",\n \"weight\": 3\n },\n {\n \"species\": \"prickly_pear\",\n \"weight\": 3\n },\n {\n \"species\": \"barrel_cactus\",\n \"weight\": 2\n },\n {\n \"species\": \"wild_grass_tall\",\n \"weight\": 4\n },\n {\n \"species\": \"weeds\",\n \"weight\": 3\n },\n {\n \"species\": \"dead_tree\",\n \"weight\": 1\n }\n ]\n }\n}\n","import type { ScatterRule } from '@adatechnology/game-vegetation'\nimport { getSpecies, pickForContext } from './index'\nimport type { Region, Species } from './types'\n\n/** The four groups the picked species are split into, each planted by its own scatter rule. */\nexport type PlantGroup = 'trees' | 'hedges' | 'mid' | 'ground'\n\nexport interface ScatterRulesOptions {\n /** How many different species to pick for the context (default 12). */\n n?: number\n /** How many draws of the regional table to try to find `n` usable species (default 60). */\n draws?: number\n /** Archetypes left out of the picks (default `['vine']`: a vine needs a support to climb). */\n skipArchetypes?: readonly string[]\n /** Leave out the big trees (size `l`, or a tree that is not of size `s`): the front yard and the narrow strips beside the house. */\n noLarge?: boolean\n /** Cap on the plants of each group (the page's `trees`, `hedges`, `mid`, `ground`); no cap when absent. */\n maxCount?: Partial<Record<PlantGroup, number>>\n /** Trees per square metre (default 0.03). */\n treeDensity?: number\n /** Replaces or extends the rule of a group (the defaults are the Viveiro's numbers). */\n groupRules?: Partial<Record<PlantGroup, Partial<Omit<ScatterRule, 'species'>>>>\n /** Which species form each group. Defaults: trees are tagged `tree` and not size `s`; hedges are shrubs tagged `hedge`; ground is grass tufts and ferns; mid is the rest. */\n classify?: (species: Species) => PlantGroup\n}\n\nexport interface ScatterRulesResult {\n /** One rule for each group that has species, in the order trees, hedges, mid, ground. */\n rules: ScatterRule[]\n /** The distinct species picked, in the order they were drawn. */\n picks: Species[]\n}\n\nconst isTree = (s: Species): boolean => s.tags.includes('tree') && s.size !== 's'\n\n/** The Viveiro's split: trees, then hedges, then ground cover (grass and ferns), then the rest. */\nexport const defaultClassify = (s: Species): PlantGroup => (isTree(s) ? 'trees' : s.archetype === 'shrub' && s.tags.includes('hedge') ? 'hedges' : s.archetype === 'grass_tuft' || s.archetype === 'fern' ? 'ground' : 'mid')\n\nconst DEFAULT_RULES: Record<PlantGroup, Omit<ScatterRule, 'species' | 'maxCount'>> = {\n trees: { density: 0.03, minDistance: 4.2, scale: [0.85, 1.05], prefer: 'any' },\n hedges: { density: 0.5, minDistance: 1.1, prefer: 'edge', edgeWidth: 0.6, scale: [0.9, 1.1] },\n mid: { density: 0.45, minDistance: 0.9, scale: [0.85, 1.15] },\n ground: { density: 1.2, minDistance: 0.5, scale: [0.8, 1.2] },\n}\n\nconst ORDER: PlantGroup[] = ['trees', 'hedges', 'mid', 'ground']\n\n/**\n * Turns the regional planting table of a context into scatter rules for `scatter` of `@adatechnology/game-vegetation`: draws species from the table (the same seed draws the same),\n * leaves out what cannot be planted alone (vines) and, when asked, the big trees, and splits the picks into trees, hedges, the middle layer and the ground cover, each with its own\n * density, spacing and scale. Port of the Viveiro's `rulesFor` (vegetacao__viveiro.js 77943-77963); every number of it is an option.\n */\nexport function scatterRulesFor(region: Region, context: string, seed: number | string, options: ScatterRulesOptions = {}): ScatterRulesResult {\n const n = options.n ?? 12\n const draws = options.draws ?? 60\n const skip = new Set(options.skipArchetypes ?? ['vine'])\n const classify = options.classify ?? defaultClassify\n const seen = new Set<string>()\n const picks: Species[] = []\n for (let i = 0; i < draws && picks.length < n; i++) {\n const id = pickForContext(region, context, `${seed}:${context}:${i}`)\n const species = getSpecies(id)\n if (!species || seen.has(id) || skip.has(species.archetype)) continue\n if (options.noLarge && (species.size === 'l' || isTree(species))) continue\n seen.add(id)\n picks.push(species)\n }\n const groups: Record<PlantGroup, string[]> = { trees: [], hedges: [], mid: [], ground: [] }\n for (const species of picks) groups[classify(species)].push(species.id)\n const rules: ScatterRule[] = []\n for (const group of ORDER) {\n const ids = groups[group]\n if (ids.length === 0) continue\n const base = { ...DEFAULT_RULES[group], ...(group === 'trees' && options.treeDensity !== undefined ? { density: options.treeDensity } : {}), ...options.groupRules?.[group] }\n const maxCount = options.maxCount?.[group]\n rules.push({ species: ids, ...base, ...(maxCount === undefined ? {} : { maxCount }) })\n }\n return { rules, picks }\n}\n","import type { PlantSpec } from '@adatechnology/game-vegetation'\nimport trees from '../data/species/trees.json'\nimport palms from '../data/species/palms.json'\nimport shrubs from '../data/species/shrubs.json'\nimport flowers from '../data/species/flowers.json'\nimport cacti from '../data/species/cacti.json'\nimport succulents from '../data/species/succulents.json'\nimport grasses from '../data/species/grasses.json'\nimport vines from '../data/species/vines.json'\nimport potted from '../data/species/potted.json'\nimport ptBR from '../data/locales/pt-BR.json'\nimport en from '../data/locales/en.json'\nimport br from '../data/regions/br.json'\nimport defaultRegion from '../data/regions/default.json'\nimport type { Locale, LocaleTable, Region, Species } from './types'\n\nexport * from './types'\n\n/** Every species of the pack. */\nexport const species: Species[] = [\n ...trees,\n ...palms,\n ...shrubs,\n ...flowers,\n ...cacti,\n ...succulents,\n ...grasses,\n ...vines,\n ...potted,\n] as Species[]\n\nconst byId = new Map<string, Species>(species.map((s) => [s.id, s]))\n\nexport function getSpecies(id: string): Species | undefined {\n return byId.get(id)\n}\n\nexport function listIds(): string[] {\n return species.map((s) => s.id)\n}\n\nexport function byTag(tag: string): Species[] {\n return species.filter((s) => s.tags.includes(tag))\n}\n\nconst HEX = /^#[0-9a-fA-F]{6}$/\n\n/** Replace `#rrggbb` strings by 0xRRGGBB integers, recursively. */\nfunction resolveColors(v: unknown): unknown {\n if (typeof v === 'string' && HEX.test(v)) return parseInt(v.slice(1), 16)\n if (Array.isArray(v)) return v.map(resolveColors)\n if (v && typeof v === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, x] of Object.entries(v)) out[k] = resolveColors(x)\n return out\n }\n return v\n}\n\n/** Convert a species (or its id) into a spec for `generate()`, with hex colors turned into integers. */\nexport function toSpec(s: Species | string): PlantSpec {\n const sp = typeof s === 'string' ? getSpecies(s) : s\n if (!sp) throw new Error(`game-vegetation-species: unknown species \"${String(s)}\"`)\n return { archetype: sp.archetype, ...(resolveColors(sp.params) as Record<string, unknown>) } as PlantSpec\n}\n\nconst locales: Record<Locale, LocaleTable> = { 'pt-BR': ptBR as LocaleTable, en: en as LocaleTable }\n\n/** Display texts for a locale (unknown locales fall back to `en`). */\nexport function loadLocale(locale: Locale | string = 'en'): LocaleTable {\n return (locales as Record<string, LocaleTable>)[locale] ?? locales.en\n}\n\nexport function name(id: string, locale: Locale | string = 'en'): string {\n return loadLocale(locale)[id]?.name ?? locales.en[id]?.name ?? id\n}\n\nexport function description(id: string, locale: Locale | string = 'en'): string {\n return loadLocale(locale)[id]?.description ?? locales.en[id]?.description ?? ''\n}\n\nexport const regions = { br: br as Region, default: defaultRegion as Region }\n\n/** Anything that yields numbers in [0, 1): a function, an object with `next()`, or a seed. */\nexport type RngLike = (() => number) | { next(): number } | number | string\n\nfunction toNext(rng: RngLike): () => number {\n if (typeof rng === 'function') return rng\n if (typeof rng === 'object') return () => rng.next()\n // mulberry32 seeded from a number or string\n let s = typeof rng === 'number' ? rng >>> 0 : 0x811c9dc5\n if (typeof rng === 'string') {\n for (let i = 0; i < rng.length; i++) {\n s ^= rng.charCodeAt(i)\n s = Math.imul(s, 0x01000193)\n }\n s >>>= 0\n }\n return () => {\n s = (s + 0x6d2b79f5) >>> 0\n let t = s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** Weighted pick of a species id for a context ('front_yard', 'sidewalk_tree', ...) of a region. */\nexport function pickForContext(region: Region, context: string, rng: RngLike): string {\n const list = region.contexts[context]\n if (!list || list.length === 0) throw new Error(`game-vegetation-species: region \"${region.id}\" has no context \"${context}\"`)\n const next = toNext(rng)\n const total = list.reduce((a, b) => a + b.weight, 0)\n let r = next() * total\n for (const it of list) {\n r -= it.weight\n if (r <= 0) return it.species\n }\n return list[list.length - 1].species\n}\n\nexport { scatterRulesFor, defaultClassify } from './rules'\nexport type { PlantGroup, ScatterRulesOptions, ScatterRulesResult } from './rules'\n","import type { Condition, Lod, Placement, Season } from '@adatechnology/game-vegetation'\nimport type { ScatterRulesOptions } from '@adatechnology/game-vegetation-species'\nimport { shapeGeometries } from '@adatechnology/game-shapes-three'\n\nimport type { MaterialsLike, SpeciesSdk, VegetationSdk } from './types'\n\ntype Three = any\n\n/** The plot of the Viveiro's lot demo, in metres: the corner at (0, 0), the street on the negative z side. */\nexport const LOT = { W: 12, D: 20 } as const\nexport const HOUSE = { x0: 2.5, x1: 9.5, z0: 6.5, z1: 13 } as const\n/** The walker's route (x, z). */\nexport const WAY: readonly (readonly [number, number])[] = [[6, 1.2], [6, 5.4], [10.8, 5.4], [10.8, 14.2], [8, 18.6], [3, 18.6], [1.2, 14.2], [1.2, 5.4], [4, 3.2], [8, 3.2]]\n\ntype Rect = { rect: { x: number; z: number; w: number; d: number } }\nexport const EX_HOUSE: Rect = { rect: { x: HOUSE.x0 - 0.7, z: HOUSE.z0 - 0.7, w: HOUSE.x1 - HOUSE.x0 + 1.4, d: HOUSE.z1 - HOUSE.z0 + 1.4 } }\nexport const EX_PATH: Rect = { rect: { x: 5.1, z: 0, w: 1.8, d: HOUSE.z0 } }\n/** Where each kind of planting goes. */\nexport const AREAS: Readonly<Record<'front_yard' | 'backyard' | 'sides' | 'sidewalk_tree', Rect[]>> = {\n front_yard: [{ rect: { x: 0.5, z: 0.5, w: 11, d: 5.6 } }],\n backyard: [{ rect: { x: 0.5, z: 13.7, w: 11, d: 5.8 } }],\n sides: [{ rect: { x: 0.5, z: 6.2, w: 1.3, d: 7.4 } }, { rect: { x: 10.2, z: 6.2, w: 1.3, d: 7.4 } }],\n sidewalk_tree: [{ rect: { x: 0.8, z: -1.9, w: 10.4, d: 1.2 } }],\n}\n\n/** The four plantings of the lot: the context of the regional table, where, how many of each group, and the tag of the scatter seed. */\nexport type Planting = { context: string; areas: Rect[]; options: ScatterRulesOptions & { n: number }; tag: string }\nexport const PLANTINGS: readonly Planting[] = [\n { context: 'front_yard', areas: AREAS.front_yard, options: { n: 12, noLarge: true, maxCount: { trees: 1, hedges: 10, mid: 14, ground: 40 } }, tag: 'f' },\n { context: 'backyard', areas: AREAS.backyard, options: { n: 14, maxCount: { trees: 3, hedges: 4, mid: 12, ground: 50 } }, tag: 'b' },\n { context: 'front_yard', areas: AREAS.sides, options: { n: 8, noLarge: true, maxCount: { trees: 0, hedges: 4, mid: 6, ground: 14 } }, tag: 's' },\n { context: 'sidewalk_tree', areas: AREAS.sidewalk_tree, options: { n: 4, treeDensity: 0.3, maxCount: { trees: 2, hedges: 0, mid: 0, ground: 0 } }, tag: 'c' },\n]\n\nexport type NurserySettings = { seed: number; quality: 'high' | 'game'; lod: Lod; condition: Condition; season: Season }\n\nexport type LotStats = { triangles: number; plants: number; colliders: number; meshes: number; lod: [number, number, number]; buildMs: number; species: number }\n\n/**\n * The scatter of the lot: the same picks, rules and placements as the Viveiro's `buildLotVeg`. Every planting draws its species from the regional table of its context, splits\n * them into trees, hedges, middle layer and ground cover, and scatters each group over the areas of the plot without touching the house or the path.\n */\nexport function scatterLot(sdk: VegetationSdk, species: SpeciesSdk, seedNumber: number, plantings: readonly Planting[] = PLANTINGS): { placements: Placement[]; used: Set<string> } {\n const seed = `quintal-${seedNumber}`\n const placements: Placement[] = []\n const used = new Set<string>()\n for (const planting of plantings) {\n const { rules, picks } = species.scatterRulesFor(species.regions.br, planting.context, seed, planting.options)\n for (const p of picks) used.add(p.id)\n planting.areas.forEach((area, i) => {\n const exclude = [EX_HOUSE, EX_PATH]\n const perArea = rules.map((rule) => ({ ...rule, maxCount: Math.max(1, Math.ceil((rule.maxCount as number) / planting.areas.length)) }))\n placements.push(...sdk.scatter(area as never, perArea, { seed: `${seed}:${planting.tag}:${i}`, exclude: exclude as never }))\n })\n }\n return { placements, used }\n}\n\n/** The static scenery of the plot: ground, street, sidewalk, path, house and walls. Simple boxes; the room's own floor is under it. */\nfunction buildScenery(THREE: Three): any {\n const g = new THREE.Group()\n g.name = 'nursery-scenery'\n const material = (color: number, roughness = 0.9): any => new THREE.MeshStandardMaterial({ color, roughness, metalness: 0 })\n const mats = { ground: material(0x5f7d45), asphalt: material(0x3a3d42), concrete: material(0xb7b3a8), house: material(0xe3d6bd), roof: material(0x9a4d38), door: material(0x6b4a2f), glass: material(0x9fc7dd, 0.2), wall: material(0xc9c2b2) }\n const box = (w: number, h: number, d: number, m: any, x: number, y: number, z: number): any => {\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), m)\n mesh.position.set(x, y, z)\n mesh.castShadow = mesh.receiveShadow = true\n g.add(mesh)\n return mesh\n }\n const yard = new THREE.Mesh(new THREE.PlaneGeometry(LOT.W, LOT.D), mats.ground)\n yard.rotation.x = -Math.PI / 2\n yard.position.set(6, 0.01, 10)\n yard.receiveShadow = true\n g.add(yard)\n box(30, 0.04, 4.6, mats.asphalt, 6, 0.0, -4.6) // street\n box(30, 0.1, 2.2, mats.concrete, 6, 0.04, -1.1) // sidewalk\n box(1.6, 0.03, 6.6, mats.concrete, 6, 0.02, 3.2) // path to the door\n const hw = HOUSE.x1 - HOUSE.x0\n const hd = HOUSE.z1 - HOUSE.z0\n const hcx = (HOUSE.x0 + HOUSE.x1) / 2\n const hcz = (HOUSE.z0 + HOUSE.z1) / 2\n box(hw, 2.8, hd, mats.house, hcx, 1.4, hcz)\n const roof = new THREE.Mesh(new THREE.ConeGeometry(1, 1.5, 4), mats.roof)\n roof.rotation.y = Math.PI / 4\n roof.scale.set((hw + 1.2) / Math.SQRT2, 1, (hd + 1.2) / Math.SQRT2)\n roof.position.set(hcx, 2.8 + 0.75, hcz)\n roof.castShadow = roof.receiveShadow = true\n g.add(roof)\n box(1.1, 2.1, 0.08, mats.door, 6, 1.05, HOUSE.z0 - 0.04)\n box(1.6, 1.1, 0.08, mats.glass, 3.8, 1.5, HOUSE.z0 - 0.04)\n box(1.6, 1.1, 0.08, mats.glass, 8.2, 1.5, HOUSE.z0 - 0.04)\n // walls\n box(5, 1.4, 0.2, mats.wall, 2.5, 0.7, 0)\n box(5, 1.4, 0.2, mats.wall, 9.5, 0.7, 0)\n box(0.2, 1.8, LOT.D, mats.wall, 0, 0.9, 10)\n box(0.2, 1.8, LOT.D, mats.wall, LOT.W, 0.9, 10)\n box(LOT.W, 1.8, 0.2, mats.wall, 6, 0.9, LOT.D)\n return g\n}\n\n/**\n * The nursery: the 12 x 20 m plot of the Viveiro's lot demo (house, walls, street, path) planted by `scatterRulesFor` + `scatter` + `buildLot`, and the walker that crosses it and bends\n * the plants (the wind shader's actors). The module owns it; `plant` builds it, `clear` takes it away.\n */\nexport function createNursery(sdk: VegetationSdk, species: SpeciesSdk, THREE: Three, materials: MaterialsLike, parent: any, origin: readonly [number, number]) {\n // three with its primitive geometries made by game-shapes (bit-identical, cached by parameters)\n const T = shapeGeometries(THREE) as Three\n const group = new THREE.Group()\n group.name = 'nursery'\n group.position.set(origin[0], 0, origin[1])\n const dynamic = new THREE.Group()\n const colliders = new THREE.Group()\n colliders.visible = false\n let scenery: any = null\n let lotObject: any = null\n let data: ReturnType<VegetationSdk['buildLot']> | null = null\n let stats: LotStats | null = null\n let actor: any = null\n const walker = { x: WAY[0]![0], z: WAY[0]![1], waypoint: 0, on: false }\n const actors = [{ x: 0, y: 0.8, z: 0, radius: 1.5 }]\n let attached = false\n\n const disposeObject = (object: any): void => {\n object.traverse((child: any) => {\n child.geometry?.dispose?.()\n })\n }\n const clearGroup = (g: any): void => {\n for (const child of [...g.children]) {\n g.remove(child)\n disposeObject(child)\n child.material?.dispose?.()\n }\n }\n const ensure = (): void => {\n if (attached) return\n attached = true\n scenery = buildScenery(T)\n // a capsule where this three.js has one (r139+), else a cylinder of the same size\n const body = T.CapsuleGeometry ? new T.CapsuleGeometry(0.28, 1.0, 4, 10) : new T.CylinderGeometry(0.28, 0.28, 1.56, 10)\n actor = new THREE.Mesh(body, new THREE.MeshStandardMaterial({ color: 0xd9822b, roughness: 0.7 }))\n actor.castShadow = true\n actor.position.set(walker.x, 0.78, walker.z)\n actor.visible = false\n group.add(scenery, dynamic, colliders, actor)\n parent.add(group)\n }\n\n const blocked = (x: number, z: number): boolean => {\n if (x < 0.55 || x > LOT.W - 0.55 || z < 0.55 || z > LOT.D - 0.55) return true\n if (x > HOUSE.x0 - 0.4 && x < HOUSE.x1 + 0.4 && z > HOUSE.z0 - 0.4 && z < HOUSE.z1 + 0.4) return true\n if (data) {\n for (const c of data.colliders) {\n const dx = x - c.x\n const dz = z - c.z\n const r = c.r + 0.3\n if (dx * dx + dz * dz < r * r) return true\n }\n }\n return false\n }\n\n return {\n group,\n get stats(): LotStats | null {\n return stats\n },\n get planted(): boolean {\n return lotObject !== null\n },\n get walking(): boolean {\n return walker.on\n },\n get position(): { x: number; z: number } {\n return { x: walker.x, z: walker.z }\n },\n /** Plants the lot with the settings (replaces the one standing). */\n plant(settings: NurserySettings): LotStats {\n ensure()\n if (lotObject) {\n dynamic.remove(lotObject)\n disposeObject(lotObject)\n lotObject = null\n }\n clearGroup(colliders)\n const { placements, used } = scatterLot(sdk, species, settings.seed)\n const t0 = Date.now()\n data = sdk.buildLot(placements, (id) => species.toSpec(id), { seed: `quintal-${settings.seed}`, quality: settings.quality, lod: settings.lod, condition: settings.condition, season: settings.season })\n const buildMs = Date.now() - t0\n lotObject = sdk.createLotObject(THREE, data, materials as never)\n lotObject.traverse((c: any) => {\n if (c.isMesh) {\n c.castShadow = true\n c.receiveShadow = true\n }\n })\n dynamic.add(lotObject)\n for (const c of data.colliders) {\n const m = new THREE.Mesh(new T.CylinderGeometry(c.r, c.r, c.h, 14, 1, true), new THREE.MeshBasicMaterial({ color: c.damage ? 0xff7a1a : 0xe5251d, wireframe: true }))\n m.position.set(c.x, c.h / 2, c.z)\n colliders.add(m)\n }\n stats = { triangles: data.triangleCount, plants: data.plantCount, colliders: data.colliders.length, meshes: Object.keys(data.meshes).length, lod: data.lodCounts, buildMs, species: used.size }\n return stats\n },\n /** The colliders of the lot as wire cylinders. */\n showColliders(on: boolean): void {\n colliders.visible = on\n },\n /** Starts or stops the walker that crosses the lot along `WAY`, bending the plants. */\n setWalker(on: boolean): void {\n ensure()\n walker.on = on\n actor.visible = on\n if (!on) {\n actors[0]!.radius = 0\n materials.setActors(actors)\n } else actors[0]!.radius = 1.5\n },\n step(dt: number): void {\n if (!attached || !walker.on) return\n const target = WAY[walker.waypoint]!\n const ddx = target[0] - walker.x\n const ddz = target[1] - walker.z\n const d = Math.hypot(ddx, ddz)\n let dx = 0\n let dz = 0\n if (d < 0.25) walker.waypoint = (walker.waypoint + 1) % WAY.length\n else {\n dx = ddx / d\n dz = ddz / d\n }\n if (dx || dz) {\n const sp = 2.0 * dt\n const nx = walker.x + dx * sp\n const nz = walker.z + dz * sp\n if (!blocked(nx, walker.z)) walker.x = nx\n if (!blocked(walker.x, nz)) walker.z = nz\n if (blocked(nx, nz)) walker.waypoint = (walker.waypoint + 1) % WAY.length\n actor.rotation.y = Math.atan2(dx, dz)\n }\n actor.position.set(walker.x, 0.78, walker.z)\n const a = actors[0]!\n a.x = origin[0] + walker.x\n a.z = origin[1] + walker.z\n a.y = 0.8\n materials.setActors(actors)\n },\n /** Takes the lot, the walker and the scenery away. */\n clear(): void {\n if (walker.on) this.setWalker(false)\n if (lotObject) {\n dynamic.remove(lotObject)\n disposeObject(lotObject)\n lotObject = null\n }\n clearGroup(colliders)\n if (attached) {\n parent.remove(group)\n clearGroup(group)\n attached = false\n scenery = null\n actor = null\n }\n data = null\n stats = null\n walker.x = WAY[0]![0]\n walker.z = WAY[0]![1]\n walker.waypoint = 0\n },\n }\n}\n\nexport type Nursery = ReturnType<typeof createNursery>\n","import type { Vec3 } from './destruction'\n\n/**\n * The numbers of the shove a blast gives to a body that moves (a loose item, a piece of furniture, a person): all of them a game value, with a default that reads well in a room,\n * not a physical table. A host reads them once and lends them to the modules that move their own bodies (`ModuleHost.blastShove`).\n */\nexport interface BlastShoveOptions {\n /**\n * The share of the blast energy that reaches a body as motion: the speed at the centre is `sqrt(2 * energy * coupling / mass)`, before the falloff (default 0.02).\n */\n readonly coupling?: number\n /** Fastest a body is thrown, in m/s, at the centre of the blast (default 20). */\n readonly maxSpeed?: number\n /** How much of the push goes up: the direction is `(away, lift)` normalised from the horizontal outward direction (default 0.3). */\n readonly lift?: number\n /** Below this speed (m/s) nothing moves: a heavy thing far from a small blast stays where it is (default 0.3). */\n readonly minSpeed?: number\n /** Exponent of the falloff `(1 - distance / radius) ^ power`, the same as the damage of the destruction world (default 2). */\n readonly falloffPower?: number\n}\n\n/** The defaults of `BlastShoveOptions`. */\nexport const DEFAULT_BLAST_SHOVE: Readonly<Required<BlastShoveOptions>> = { coupling: 0.02, maxSpeed: 20, lift: 0.3, minSpeed: 0.3, falloffPower: 2 }\n\n/** A blast as the shove reads it: where, how much energy (J) and how far it reaches (m). `reach` (0..1) is the share that got through what stood in the way. */\nexport interface BlastSource {\n readonly point: Vec3\n readonly energy: number\n readonly radius: number\n readonly reach?: number\n}\n\n/** What a blast does to one body: how fast it leaves (m/s), the unit direction it leaves in, and how far from the centre it was. */\nexport interface BlastShove {\n readonly speed: number\n readonly direction: Vec3\n readonly distance: number\n /** The falloff applied, 0..1. */\n readonly falloff: number\n}\n\n/**\n * The shove a blast gives to a body of `mass` kg whose centre is at `position`: away from the centre, lifted a little, with the speed\n * `min(maxSpeed, sqrt(2 * energy * reach * coupling / mass)) * (1 - distance / radius) ^ 2`. Undefined when the body is outside the radius or the speed is under `minSpeed`.\n * The same rule moves the loose items and furniture of the test room and the people of the characters module, so a game that tunes the options tunes all of them.\n */\nexport function blastShove(blast: BlastSource, target: { readonly position: Vec3; readonly mass: number }, options: BlastShoveOptions = {}): BlastShove | undefined {\n const o = { ...DEFAULT_BLAST_SHOVE, ...options }\n const dx = target.position[0] - blast.point[0]\n const dy = target.position[1] - blast.point[1]\n const dz = target.position[2] - blast.point[2]\n const distance = Math.hypot(dx, dy, dz)\n if (!(blast.radius > 0) || distance > blast.radius) return undefined\n const falloff = (1 - distance / blast.radius) ** o.falloffPower\n const mass = Math.max(target.mass, 0.05)\n const speed = Math.min(o.maxSpeed, Math.sqrt((2 * blast.energy * (blast.reach ?? 1) * o.coupling) / mass)) * falloff\n if (!(speed >= o.minSpeed)) return undefined\n // straight above or below the centre there is no \"away\": the push goes up\n const direction: Vec3 = distance > 1e-4 ? [dx / distance, dy / distance + o.lift, dz / distance] : [0, 1, 0]\n const length = Math.hypot(direction[0], direction[1], direction[2])\n return { speed, direction: [direction[0] / length, direction[1] / length, direction[2] / length], distance, falloff }\n}\n","import type { DamageType, DestructibleSpec, DestructionEvent, Hit, JointSpec, ObjectState, ToolKind, Vec3 } from './destruction'\n\n/**\n * What a game module implements for an object whose behaviour it owns (a vehicle with its own panel deformation, a creature, a machine). The\n * world (`DestructionWorld.register`) hosts it next to its own objects: raycast, shoot, explode, hit, disassemble, extinguish, update, state,\n * reset and `on` all route to it.\n *\n * Space: the impl receives hits in WORLD space and returns events in WORLD space (it owns its transform; the transform given to `register` or\n * `setTransform` is only used by the world for raycasts and blast range). Every event must carry `object === id` and name parts listed by\n * `describe()`.\n */\nexport interface DestructibleImpl {\n readonly id: string\n readonly name?: string\n /** Parts, joints and structure in the impl's local space, for raycast, inspector and log. Called often: keep it cheap. */\n describe(): DestructibleSpec\n /** Apply one hit (see `IMPACT_CONTRACT` for the fields per type) and return the events it caused. */\n hit(hit: Hit): DestructionEvent[]\n /** Advance fire, melting, collapse and other timed behaviour. */\n update?(dt: number): DestructionEvent[]\n state(): ObjectState\n reset?(): void\n /** Same contract as `DestructionWorld.disassemble`: progress 0..1, or -1 when the tool cannot undo the joint. */\n disassemble?(jointId: string, tool: ToolKind, dt: number): number\n extinguish?(partId?: string): void\n /** Optional: an animation moved a part; `position` / `rotation` (Euler XYZ, radians) are object-local. Keep raycast and hit shapes in sync. */\n setPartPose?(partId: string, position: Vec3, rotation?: Vec3): void\n /** Plain JSON of the impl's own state, stored in `DestructionSnapshot.impls`. */\n serialize?(): unknown\n load?(data: unknown): void\n}\n\n/** The fields a weapon or hazard must put in a `Hit`, per damage type. THE impact contract. */\nexport interface ImpactContract {\n required: string[]\n optional: string[]\n note: string\n}\n\nexport const IMPACT_CONTRACT: Record<DamageType, ImpactContract> = {\n ballistic: { required: ['type', 'point', 'direction', 'energy', 'caliber'], optional: ['space', 'source'], note: 'bullets and pellets: joules and diameter in millimetres' },\n blunt: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'contact radius in metres (default 3 cm)' },\n slash: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'axes, knives, machetes' },\n explosive: { required: ['type', 'point', 'energy', 'radius'], optional: ['lethalRadius', 'space', 'source'], note: 'point is the centre of the blast, radius the range in metres' },\n fire: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'flame temperature in °C; duration in seconds (call every frame with `dt`)' },\n heat: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'heat without flame (cutting torch, hot plate)' },\n}\n\n/** Problems with a hit according to the impact contract (empty when it is valid). */\nexport const checkHit = (hit: Hit): string[] => {\n const c = IMPACT_CONTRACT[hit.type]\n if (!c) return [`unknown damage type \"${String(hit.type)}\"`]\n const out: string[] = []\n for (const f of c.required) {\n const v = (hit as unknown as Record<string, unknown>)[f]\n if (v === undefined || (Array.isArray(v) ? v.some((n) => !Number.isFinite(n)) : typeof v === 'number' && !Number.isFinite(v))) out.push(`${hit.type} hit needs \"${f}\"`)\n }\n return out\n}\n\nexport interface CheckOptions {\n /**\n * Ids of every material the impl may use (the contracts package does not know the materials of your world: pass the ids of\n * `world.materials`, or the built-in plus your own). When omitted, the material check is skipped.\n */\n materials?: Iterable<string>\n}\n\nconst finiteJson = (v: unknown, path: string, out: string[]) => {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) out.push(`${path} is not a finite number`)\n } else if (Array.isArray(v)) v.forEach((x, i) => finiteJson(x, `${path}[${i}]`, out))\n else if (v && typeof v === 'object') for (const [k, x] of Object.entries(v)) finiteJson(x, `${path}.${k}`, out)\n else if (typeof v === 'function' || typeof v === 'symbol' || typeof v === 'bigint') out.push(`${path} is not JSON`)\n}\n\n/**\n * Contract checker for the test room (it needs no world): `describe()` is valid, a 500 J ballistic hit at a part centre returns well-formed events of this impl, `state()`\n * matches `describe()`, hit points never go negative, `update(0.016)` returns an array and every event is JSON-serializable. It hits the impl\n * (and calls `reset()` afterwards when there is one).\n */\nexport const checkDestructible = (impl: DestructibleImpl, options: CheckOptions = {}): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const known = options.materials ? new Set(options.materials) : null\n let spec: DestructibleSpec | undefined\n try {\n spec = impl.describe()\n } catch (e) {\n return { ok: false, problems: [`describe() threw: ${String(e)}`] }\n }\n if (!spec || !Array.isArray(spec.parts) || spec.parts.length === 0) return { ok: false, problems: ['describe() must return at least one part'] }\n const ids = new Set<string>()\n for (const p of spec.parts) {\n if (ids.has(p.id)) problems.push(`duplicate part id \"${p.id}\"`)\n ids.add(p.id)\n if (known && !known.has(p.material)) problems.push(`part \"${p.id}\" has unknown material \"${p.material}\"`)\n if (!p.shape || !['box', 'cylinder', 'sphere'].includes(p.shape.kind)) problems.push(`part \"${p.id}\" has no valid shape`)\n if (!Array.isArray(p.position) || p.position.length !== 3) problems.push(`part \"${p.id}\" has no position`)\n }\n const jointIds = new Set<string>()\n for (const j of (spec.joints ?? []) as JointSpec[]) {\n if (!ids.has(j.a) || !ids.has(j.b)) problems.push(`joint \"${j.id ?? `${j.a}~${j.b}`}\" references an unknown part`)\n const jid = j.id ?? `${j.a}~${j.b}`\n if (jointIds.has(jid)) problems.push(`duplicate joint id \"${jid}\"`)\n jointIds.add(jid)\n }\n const checkState = (label: string) => {\n let st: ObjectState\n try {\n st = impl.state()\n } catch (e) {\n problems.push(`state() threw ${label}: ${String(e)}`)\n return\n }\n const sids = st.parts.map((p) => p.id).sort().join(',')\n if (sids !== [...ids].sort().join(',')) problems.push(`state() part ids do not match describe() ${label}`)\n for (const p of st.parts) if (!(p.hp >= 0)) problems.push(`part \"${p.id}\" has negative or invalid hp ${label}`)\n }\n const checkEvents = (events: unknown, label: string) => {\n if (!Array.isArray(events)) {\n problems.push(`${label} must return an array`)\n return\n }\n const evs = events as DestructionEvent[]\n evs.forEach((e, i) => {\n if (e.object !== impl.id) problems.push(`${label} event ${i} (${e.type}) has object \"${String(e.object)}\", expected \"${impl.id}\"`)\n const part = (e as { part?: string }).part\n if (part !== undefined && !ids.has(part)) problems.push(`${label} event ${i} (${e.type}) names unknown part \"${part}\"`)\n })\n const bad: string[] = []\n finiteJson(evs, 'events', bad)\n problems.push(...bad.map((b) => `${label}: ${b}`))\n try {\n const s = JSON.stringify(evs)\n if (JSON.stringify(JSON.parse(s)) !== s) problems.push(`${label} events do not survive a JSON round trip`)\n } catch (e) {\n problems.push(`${label} events are not JSON-serializable: ${String(e)}`)\n }\n }\n checkState('before the hit')\n const target = spec.parts[0]\n try {\n const hit: Hit = { type: 'ballistic', point: [target.position[0], target.position[1], target.position[2]], direction: [0, 0, -1], energy: 500, caliber: 9 }\n checkEvents(impl.hit(hit), 'hit()')\n } catch (e) {\n problems.push(`hit() threw: ${String(e)}`)\n }\n checkState('after the hit')\n if (impl.update) {\n try {\n checkEvents(impl.update(0.016), 'update()')\n } catch (e) {\n problems.push(`update() threw: ${String(e)}`)\n }\n checkState('after update')\n }\n try {\n impl.reset?.()\n } catch (e) {\n problems.push(`reset() threw: ${String(e)}`)\n }\n return { ok: problems.length === 0, problems }\n}\n","/** The slots of a body an item can cover (the item slot vocabulary: game-items imports it from here). */\nexport type BodySlot = 'head' | 'eyes' | 'torso' | 'arms' | 'hands' | 'legs' | 'feet' | 'over'\n\n/** The 11 segments of the detailed body model (the Arsenal ids). */\nexport type SegmentKind = 'head' | 'jaw' | 'neck' | 'torso' | 'pelvis' | 'upperArm' | 'forearm' | 'hand' | 'thigh' | 'shin' | 'foot'\n\n/** The 6 regions of the crowd model (the game regions 0..5). */\nexport type BodyRegion = 'head' | 'torso' | 'armL' | 'armR' | 'legL' | 'legR'\n\n/** Bits of the `missing` mask of a body. The instanced body shader reads them, so the values are part of the contract. */\nexport const MISSING_BITS = {\n head: 1,\n armL: 2,\n armR: 4,\n legL: 8,\n legR: 16,\n armLBroken: 32,\n armRBroken: 64,\n legLBroken: 128,\n legRBroken: 256,\n jaw: 512,\n} as const\n","import type { DestructibleSpec, PartSpec } from './destruction'\n\nexport interface CheckSpecOptions {\n /** Known material ids. When given, every part's material must be one of them. */\n materials?: Iterable<string>\n}\n\nexport interface SpecReport {\n /** False when there is at least one problem (warnings do not count). */\n ok: boolean\n problems: string[]\n /** Things that are legal but probably wrong, e.g. structural parts that cannot reach an anchored part. */\n warnings: string[]\n}\n\nconst STRUCTURE_ROLES = ['foundation', 'column', 'beam', 'slab', 'wall', 'partition', 'roof', 'stair', 'none']\nconst BEARS = [true, false, 'a_on_b', 'b_on_a']\n\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\nconst positive = (n: unknown): boolean => finite(n) && n > 0\nconst vec3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every(finite)\nconst nonNegative = (n: unknown): boolean => n === undefined || (finite(n) && n >= 0)\n\nconst FACES = ['both', '+', '-']\nconst BONDS = ['running', 'stack']\n\n/** Layers, reinforcement, units and breach: known materials, finite positive sizes. */\nconst checkStagedFields = (p: PartSpec | undefined, label: string, materials: Set<string> | null, problems: string[]): void => {\n const known = (m: unknown, what: string): void => {\n if (materials && !materials.has(m as string)) problems.push(`${label} ${what} has unknown material \"${String(m)}\"`)\n }\n ;(p?.layers ?? []).forEach((l, i) => {\n known(l?.material, `layer ${i}`)\n if (!positive(l?.thickness)) problems.push(`${label} layer ${i} thickness must be finite and positive`)\n if (!FACES.includes(l?.faces)) problems.push(`${label} layer ${i} has an invalid faces \"${String(l?.faces)}\"`)\n })\n const r = p?.reinforcement\n if (r) {\n known(r.material, 'reinforcement')\n if (!positive(r.spacing) || !positive(r.diameter)) problems.push(`${label} reinforcement spacing and diameter must be finite and positive`)\n if (r.residualCapacity !== undefined && !(finite(r.residualCapacity) && r.residualCapacity >= 0 && r.residualCapacity <= 1)) problems.push(`${label} reinforcement residualCapacity must be between 0 and 1`)\n }\n const u = p?.units\n if (u) {\n known(u.mortar, 'units mortar')\n if (!vec3(u.size) || !u.size.every(positive)) problems.push(`${label} units size must be three finite positive numbers`)\n if (!BONDS.includes(u.bond)) problems.push(`${label} units has an invalid bond \"${String(u.bond)}\"`)\n }\n if (p?.breach && p.breach.area !== undefined && !positive(p.breach.area)) problems.push(`${label} breach area must be finite and positive`)\n}\n\n/**\n * Static checks on a `DestructibleSpec` (no world needed), for items that give a `spec` instead of an `impl`: unique part ids, known materials\n * (when `options.materials` is given), joints that reference existing, different parts, finite positive sizes, non-negative mass / hp / capacity,\n * valid structure roles and `bears` directions. A structural part with no path of joints to an anchored part is a warning, not a problem: it\n * is allowed, it just falls.\n */\nexport const checkSpec = (spec: DestructibleSpec, options: CheckSpecOptions = {}): SpecReport => {\n const problems: string[] = []\n const warnings: string[] = []\n const materials = options.materials ? new Set(options.materials) : null\n const parts = Array.isArray(spec?.parts) ? spec.parts : []\n if (!Array.isArray(spec?.parts) || parts.length === 0) problems.push('the spec needs at least one part')\n const ids = new Set<string>()\n for (const p of parts) {\n const id = String(p?.id ?? '')\n const label = `part \"${id}\"`\n if (id === '') problems.push('a part has no id')\n else if (ids.has(id)) problems.push(`duplicate part id \"${id}\"`)\n ids.add(id)\n if (materials && !materials.has(p?.material)) problems.push(`${label} has unknown material \"${String(p?.material)}\"`)\n else if (typeof p?.material !== 'string' || p.material === '') problems.push(`${label} needs a material`)\n const s = p?.shape\n if (s?.kind === 'box') {\n if (!Array.isArray(s.size) || s.size.length !== 3 || !s.size.every(positive)) problems.push(`${label} box size must be three finite positive numbers`)\n } else if (s?.kind === 'cylinder') {\n if (!positive(s.radius) || !positive(s.height)) problems.push(`${label} cylinder radius and height must be finite and positive`)\n } else if (s?.kind === 'sphere') {\n if (!positive(s.radius)) problems.push(`${label} sphere radius must be finite and positive`)\n } else problems.push(`${label} has an unknown shape`)\n if (!vec3(p?.position)) problems.push(`${label} needs a finite position [x, y, z]`)\n if (p?.rotation !== undefined && !vec3(p.rotation)) problems.push(`${label} has an invalid rotation`)\n for (const f of ['mass', 'hp', 'thickness'] as const) if (!nonNegative(p?.[f])) problems.push(`${label} ${f} must be a finite number >= 0`)\n if (p?.fill !== undefined && !(finite(p.fill) && p.fill >= 0 && p.fill <= 1)) problems.push(`${label} fill must be between 0 and 1`)\n if (p?.structure) {\n if (!STRUCTURE_ROLES.includes(p.structure.role)) problems.push(`${label} has an invalid structure role \"${String(p.structure.role)}\"`)\n if (!nonNegative(p.structure.capacity)) problems.push(`${label} structure capacity must be a finite number >= 0`)\n }\n if (p?.contains && !nonNegative(p.contains.liters)) problems.push(`${label} contains.liters must be a finite number >= 0`)\n checkStagedFields(p, label, materials, problems)\n }\n\n const jointIds = new Set<string>()\n const edges: Array<[string, string]> = []\n for (const j of spec?.joints ?? []) {\n const id = j.id ?? `${j.a}~${j.b}`\n const label = `joint \"${id}\"`\n if (jointIds.has(id)) problems.push(`duplicate joint id \"${id}\"`)\n jointIds.add(id)\n if (!ids.has(j.a)) problems.push(`${label} references unknown part \"${String(j.a)}\"`)\n if (!ids.has(j.b)) problems.push(`${label} references unknown part \"${String(j.b)}\"`)\n if (j.a === j.b) problems.push(`${label} joins part \"${String(j.a)}\" to itself`)\n if (j.bears !== undefined && !BEARS.includes(j.bears)) problems.push(`${label} has an invalid bears \"${String(j.bears)}\"`)\n if (!nonNegative(j.strength)) problems.push(`${label} strength must be a finite number >= 0`)\n if (!nonNegative(j.seconds)) problems.push(`${label} seconds must be a finite number >= 0`)\n if (j.bears !== false && ids.has(j.a) && ids.has(j.b) && j.a !== j.b) edges.push([j.a, j.b])\n }\n\n // structural parts must reach an anchored part over the joints (only when the spec lists its joints: otherwise they are inferred later)\n const structural = parts.filter((p) => p?.structure && p.structure.role !== 'none')\n if (structural.length && spec.joints) {\n const anchored = parts.filter((p) => p.anchored || p.structure?.role === 'foundation').map((p) => p.id)\n const adj = new Map<string, string[]>()\n for (const [a, b] of edges) {\n adj.set(a, [...(adj.get(a) ?? []), b])\n adj.set(b, [...(adj.get(b) ?? []), a])\n }\n const seen = new Set(anchored)\n const queue = [...anchored]\n while (queue.length) {\n for (const n of adj.get(queue.pop()!) ?? []) {\n if (seen.has(n)) continue\n seen.add(n)\n queue.push(n)\n }\n }\n const lost = structural.filter((p) => !seen.has(p.id)).map((p) => p.id)\n if (lost.length) warnings.push(`structural part(s) ${lost.map((i) => `\"${i}\"`).join(', ')} cannot reach an anchored part, so they will fall`)\n }\n return { ok: problems.length === 0, problems, warnings }\n}\n","import type { BallisticExtras, Hit, HitIgnition, Vec3 } from './destruction'\n\n/**\n * A ballistic shot (one per pellet) as a weapon module produces it. Plain data: any damage model can consume it (`shotToHit` makes the `Hit`).\n */\nexport interface Shot {\n origin: Vec3\n /** Unit vector. */\n direction: Vec3\n /** Muzzle energy in joules. */\n energy: number\n /** Bullet diameter in millimetres. */\n caliber: number\n /** snake_case calibre id, e.g. `9x19`. */\n caliberId: string\n /** Muzzle speed in m/s. */\n speed: number\n /** Projectile mass in grams (one pellet for a shotgun load). */\n mass?: number\n /** Energy at a distance in metres, with the calibre's drag. */\n energyAt(distance: number): number\n pellet: number\n /** snake_case weapon id. */\n weapon: string\n source?: string\n /** Kind of the round that was loaded (`fmj`, `hp`, `ap`, `buck`, `slug`, `incendiary`, `tracer`...). */\n ammo?: string\n /** Millimetres of steel, concrete, brick and wood the round goes through at the muzzle (the ammo table of the weapons module). `shotToHit` scales it by the energy left. */\n penetration?: Readonly<Record<string, number>>\n incendiary?: boolean\n tracer?: boolean\n /** Chances that the round lights flammable vapour or fuel. */\n ignition?: HitIgnition\n}\n\n/**\n * The fields of the round that a damage model takes besides the geometry: the penetration by material scaled by the energy that is left at `distance`\n * (linear in the energy: half the energy goes through half as much), the incendiary and tracer flags and the ignition chances. Pass it as the sixth\n * argument of `DestructionWorld.shoot` or spread it in a `Hit`.\n */\nexport const shotExtras = (shot: Shot, distance = 0): BallisticExtras => {\n const out: { -readonly [K in keyof BallisticExtras]: BallisticExtras[K] } = {}\n if (shot.penetration) {\n const k = shot.energy > 0 ? Math.min(1, Math.max(0, shot.energyAt(distance) / shot.energy)) : 1\n const scaled: Record<string, number> = {}\n for (const key of Object.keys(shot.penetration)) scaled[key] = shot.penetration[key]! * k\n out.penetration = scaled\n }\n if (shot.incendiary) out.incendiary = true\n if (shot.tracer) out.tracer = true\n if (shot.ignition) out.ignition = { spark: shot.ignition.spark, flame: shot.ignition.flame }\n return out\n}\n\n/** One use of a non-firearm (melee swing, flame tick, heat tick, throw, tool tick, extinguisher tick). */\nexport type Use =\n | { kind: 'melee'; damage: 'blunt' | 'slash'; energy: number; radius: number; reach: number; origin: Vec3; direction: Vec3 }\n | { kind: 'flame'; temperature: number; radius: number; range: number; cone: boolean; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'heat'; temperature: number; radius: number; range: number; duration: number; origin: Vec3; direction: Vec3 }\n | {\n kind: 'throw'\n energy: number\n radius: number\n fuse: number\n velocity: Vec3\n origin: Vec3\n fire?: { temperature: number; radius: number; seconds: number }\n /** Explosive id (`m67`, `molotov`, `pg7v`...): the host looks the numbers up in the arsenal. Absent on a plain thrown object. */\n explosive?: string\n /** What sets it off: `timer` after `fuse` seconds, `impact` on the first hit once armed. */\n trigger?: 'timer' | 'impact'\n /** Metres the projectile must fly before an impact sets it off; closer, it hits without exploding (rocket launchers). */\n armDistance?: number\n /** Radius in metres of the wounding area (`radius` is the lethal one). */\n injuryRadius?: number\n /** Seconds the blast stuns whoever is inside the injury radius (flashbang). */\n stunSeconds?: number\n /** Seconds the thrower held it after pulling the pin: `fuse` is what was left of the full fuse when it left the hand. */\n cooked?: number\n /** Went off in the thrower's hand (held past the fuse): no velocity, `fuse` is 0 and the blast is at `origin`. */\n inHand?: boolean\n }\n /** An explosive set down where the trigger is pulled (mine, C4, charge): it waits for its trigger instead of flying. */\n | {\n kind: 'place'\n explosive: string\n /** `wire`: something trips it; `remote`: the player fires it; `timer`: after `fuse` seconds. */\n triggers: readonly ('timer' | 'wire' | 'remote')[]\n energy: number\n /** Lethal radius in metres. */\n radius: number\n injuryRadius: number\n /** Cone the blast goes through, in front of `direction` (mine); absent for a blast in every direction. */\n cone?: { halfAngleDeg: number; length: number }\n /** The wire a `wire` charge stretches from where it is set down: metres out, degrees from its facing (counter-clockwise from above) and metres above it. */\n tripwire?: { length: number; angleDeg: number; height: number }\n fuse?: number\n origin: Vec3\n direction: Vec3\n }\n /** The blast behind a rocket launcher: dangerous inside `radius` metres, in the cone around `direction` (pointing away from the target). */\n | { kind: 'backblast'; radius: number; halfAngleDeg: number; origin: Vec3; direction: Vec3 }\n | { kind: 'tool'; tool: string; reach: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'extinguish'; range: number; coolC: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'hand'; reach: number; origin: Vec3; direction: Vec3 }\n\n/**\n * The `Hit` a ballistic shot makes at `point` (world space): the energy is what is left of the shot at that distance from its origin\n * (`shot.energyAt`), the direction and calibre come from the shot. `normal` (the surface normal at the point, when the caller knows it) does not\n * change the hit; it is accepted so that callers can pass what their raycast returned and so that a stricter implementation could use it.\n */\nexport const shotToHit = (shot: Shot, point: Vec3, normal?: Vec3): Hit => {\n void normal\n const dx = point[0] - shot.origin[0]\n const dy = point[1] - shot.origin[1]\n const dz = point[2] - shot.origin[2]\n const distance = Math.hypot(dx, dy, dz)\n return {\n type: 'ballistic',\n point: [point[0], point[1], point[2]],\n direction: [shot.direction[0], shot.direction[1], shot.direction[2]],\n energy: shot.energyAt(distance),\n caliber: shot.caliber,\n ...(shot.mass === undefined ? {} : { mass: shot.mass }),\n ...shotExtras(shot, distance),\n source: shot.source ?? shot.weapon,\n }\n}\n\n/**\n * The `Hit` a non-firearm `Use` makes at `point` (world space), or `null` for uses that do not damage by themselves.\n *\n * - `melee` -> `blunt` / `slash` with the swing's `energy`, contact `radius` and `direction`;\n * - `flame` -> `fire` and `heat` -> `heat`, with `temperature`, `duration` and a contact radius of at most 0.3 m (one ray of the cone);\n * - `throw` -> the blast (`explosive`, `energy`, `radius`, centred on `point`, the place it detonates). A thrown item with no blast energy but\n * a `fire` patch (a molotov) gives that patch as a `fire` hit (`temperature`, `radius`, `seconds` as `duration`). No energy and no fire -> `null`;\n * - `tool`, `extinguish` and `hand` -> `null` (tools work on joints, the extinguisher cools, the hand only grabs).\n *\n * `normal` does not change the hit (same as `shotToHit`).\n */\nexport const useToHit = (use: Use, point: Vec3, normal?: Vec3): Hit | null => {\n void normal\n const p: Vec3 = [point[0], point[1], point[2]]\n switch (use.kind) {\n case 'melee':\n return { type: use.damage, point: p, direction: [use.direction[0], use.direction[1], use.direction[2]], energy: use.energy, radius: use.radius }\n case 'flame':\n case 'heat':\n return {\n type: use.kind === 'flame' ? 'fire' : 'heat',\n point: p,\n direction: [use.direction[0], use.direction[1], use.direction[2]],\n temperature: use.temperature,\n radius: Math.min(use.radius, 0.3),\n duration: use.duration,\n }\n case 'throw':\n if (use.energy > 0) return { type: 'explosive', point: p, energy: use.energy, radius: use.radius }\n if (use.fire) return { type: 'fire', point: p, temperature: use.fire.temperature, radius: use.fire.radius, duration: use.fire.seconds }\n return null\n default:\n return null\n }\n}\n","import type { Hit } from './destruction'\n\n/**\n * How a container of flammable fluid (a fuel tank, a jerrycan, a gas bottle) is set alight by what hits it. A normal bullet that goes through only\n * makes a leak; the leak lights when something supplies a flame: a spark of a hard round on metal, an incendiary or tracer round, a fire nearby\n * or a blast. These are the numbers of the target side; the numbers of the round (core, jacket, incendiary, tracer) are in the weapons module\n * (`rules.ignition` of `@adatechnology/game-weapons`) and reach the target in `Hit.ignition`. Every number is a default to be changed per game.\n */\nexport interface IgnitionRules {\n /**\n * How much of the spark and of the flame of a round reaches the vapour, by how full the container is: points `[filled, factor]`, `filled` 0..1\n * (litres over capacity), `factor` 0..1, linear between points. A full container holds a mixture too rich to burn (the vapour has no air) and\n * mostly leaks; a nearly empty one holds the vapour/air mixture of a flammable range and lights the easiest; a dry one has little vapour left.\n * Default: 0.6 empty, 1 at 10 percent, 0.6 at 35, 0.3 at 65, 0.15 at 90 and 0.12 full.\n */\n fillCurve: ReadonlyArray<readonly [number, number]>\n /** 0..1: how much of the fill factor also weighs on the flame of an incendiary or tracer (1: as much as on a spark; 0: not at all). Default 0.5. */\n flameFillInfluence: number\n /** Chance of the flame of a round that is flagged `incendiary` or `tracer` but carries no `ignition` numbers (a host that passes only the flags). */\n flameDefaults: { incendiary: number; tracer: number }\n /**\n * What a spark needs to strike: a factor 0..1 by material id of the struck part. A material that is not listed but is metal takes\n * `sparkMetalDefault`; a part that is not metal never sparks. Default: steel and iron 1, aluminium 0.25.\n */\n sparkTarget: Readonly<Record<string, number>>\n sparkMetalDefault: number\n /**\n * Factor 0..1 on the spark by fluid (default 1): diesel has a flash point of 52 degrees C and more, so a spark that lights petrol vapour does\n * not light it (a flame does). Default: diesel 0.15.\n */\n sparkFluid: Readonly<Record<string, number>>\n /** A leaking container of flammable fluid within `radius` metres of a burning part or a burning fuel stain lights at `chancePerSecond`. */\n fireNear: { radius: number; chancePerSecond: number }\n}\n\n/** Defaults of `IgnitionRules`. */\nexport const DEFAULT_IGNITION_RULES: IgnitionRules = {\n fillCurve: [\n [0, 0.6],\n [0.1, 1],\n [0.35, 0.6],\n [0.65, 0.3],\n [0.9, 0.15],\n [1, 0.12],\n ],\n flameFillInfluence: 0.5,\n flameDefaults: { incendiary: 0.7, tracer: 0.2 },\n sparkTarget: { steel: 1, iron: 1, aluminium: 0.25 },\n sparkMetalDefault: 0.5,\n sparkFluid: { diesel: 0.15 },\n fireNear: { radius: 1.5, chancePerSecond: 0.5 },\n}\n\n/** Merges a partial `IgnitionRules` over the defaults (an object is merged one level deep). */\nexport const resolveIgnitionRules = (rules?: Partial<IgnitionRules>): IgnitionRules => ({\n ...DEFAULT_IGNITION_RULES,\n ...rules,\n flameDefaults: { ...DEFAULT_IGNITION_RULES.flameDefaults, ...rules?.flameDefaults },\n sparkTarget: { ...DEFAULT_IGNITION_RULES.sparkTarget, ...rules?.sparkTarget },\n sparkFluid: { ...DEFAULT_IGNITION_RULES.sparkFluid, ...rules?.sparkFluid },\n fireNear: { ...DEFAULT_IGNITION_RULES.fireNear, ...rules?.fireNear },\n})\n\n/** Linear interpolation of the fill curve at `fill` (0..1); outside the points it keeps the first or the last. */\nexport const fillFactor = (fill: number, curve: IgnitionRules['fillCurve'] = DEFAULT_IGNITION_RULES.fillCurve): number => {\n if (curve.length === 0) return 1\n const f = Math.min(1, Math.max(0, fill))\n if (f <= curve[0]![0]) return curve[0]![1]\n for (let i = 1; i < curve.length; i++) {\n const [x1, y1] = curve[i]!\n const [x0, y0] = curve[i - 1]!\n if (f <= x1) return x1 === x0 ? y1 : y0 + ((y1 - y0) * (f - x0)) / (x1 - x0)\n }\n return curve[curve.length - 1]![1]\n}\n\n/** The factor of what a spark strikes: 0 when the struck part is not metal. */\nexport const sparkTargetFactor = (materialId: string, metal: boolean, rules: IgnitionRules = DEFAULT_IGNITION_RULES): number =>\n !metal ? 0 : rules.sparkTarget[materialId] ?? rules.sparkMetalDefault\n\n/**\n * Chance that one round that went through the wall of a container lights the fluid that leaks: the spark (only on metal) and the flame (any\n * wall), each weighed by the fill of the container; the two are independent. 0 when the round carries nothing (`Hit.ignition` absent and not\n * flagged `incendiary` or `tracer`): a plain bullet on a plain wall only leaks.\n */\nexport const ignitionChance = (hit: Pick<Hit, 'incendiary' | 'tracer' | 'ignition'>, target: { sparkTarget: number; fill: number; fluid?: string }, rules: IgnitionRules = DEFAULT_IGNITION_RULES): number => {\n const k = fillFactor(target.fill, rules.fillCurve)\n const spark = (hit.ignition?.spark ?? 0) * target.sparkTarget * (target.fluid === undefined ? 1 : rules.sparkFluid[target.fluid] ?? 1) * k\n const flameBase = hit.ignition?.flame ?? Math.max(hit.incendiary ? rules.flameDefaults.incendiary : 0, hit.tracer ? rules.flameDefaults.tracer : 0)\n const flame = flameBase * (1 - rules.flameFillInfluence * (1 - k))\n return 1 - (1 - Math.min(1, Math.max(0, spark))) * (1 - Math.min(1, Math.max(0, flame)))\n}\n","import type { Vec3 } from './destruction'\n\n/** Pose of one part (or of the whole item) at a key: position offset in metres and Euler XYZ rotation in radians, both relative to the rest pose. */\nexport interface AnimationPose {\n position?: Vec3\n rotation?: Vec3\n}\n\nexport interface AnimationKey {\n /** Seconds from the start of the clip. */\n t: number\n /** Pose of the item's root. */\n position?: Vec3\n rotation?: Vec3\n /** Poses of named parts: the key is a destruction part id (a pistol `reload` moves `mag`; a car door `open` rotates `door_l`). */\n parts?: Record<string, AnimationPose>\n}\n\nexport interface AnimationEventSpec {\n /** Seconds from the start of the clip. */\n t: number\n /** snake_case type the host maps (`sound`, `eject_casing`, `door_latch`...). */\n type: string\n data?: Record<string, unknown>\n}\n\n/** A use animation a module brings with its item. Poses between keys are interpolated by the player (the test room does it linearly). */\nexport interface AnimationClipSpec {\n /** snake_case: `reload`, `open`, `drink`... Unique within the item. */\n id: string\n /** Seconds. */\n duration: number\n keys: AnimationKey[]\n events?: AnimationEventSpec[]\n}\n\n/** What an item exposes when it brings its own animations. */\nexport interface ItemAnimationContract {\n animations: AnimationClipSpec[]\n}\n\nconst finite3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every((n) => typeof n === 'number' && Number.isFinite(n))\n\n/**\n * Problems with a clip (empty when it is valid): a snake_case id, a positive finite duration, at least one key, key and event times inside\n * `[0, duration]` and not going backwards, finite vectors, every named part one of `partIds`, event types that are non-empty strings and\n * JSON-serializable event data.\n */\nexport const checkAnimation = (clip: AnimationClipSpec, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const parts = new Set(partIds)\n const id = String(clip?.id ?? '')\n if (!/^[a-z][a-z0-9_]*$/.test(id)) problems.push(`clip id \"${id}\" must be snake_case`)\n const label = `clip \"${id}\"`\n if (!(typeof clip?.duration === 'number' && Number.isFinite(clip.duration) && clip.duration > 0)) problems.push(`${label} needs a positive finite duration`)\n const dur = typeof clip?.duration === 'number' && clip.duration > 0 ? clip.duration : Infinity\n if (!Array.isArray(clip?.keys) || clip.keys.length === 0) {\n problems.push(`${label} needs at least one key`)\n return { ok: false, problems }\n }\n let prev = -Infinity\n clip.keys.forEach((k, i) => {\n if (!(typeof k.t === 'number' && Number.isFinite(k.t)) || k.t < 0 || k.t > dur + 1e-9) problems.push(`${label} key ${i} has t=${String(k.t)} outside 0..${dur}`)\n else if (k.t < prev) problems.push(`${label} key ${i} goes back in time (${k.t} < ${prev})`)\n else prev = k.t\n for (const f of ['position', 'rotation'] as const) if (k[f] !== undefined && !finite3(k[f])) problems.push(`${label} key ${i} has an invalid ${f}`)\n for (const [pid, pose] of Object.entries(k.parts ?? {})) {\n if (!parts.has(pid)) problems.push(`${label} key ${i} moves unknown part \"${pid}\"`)\n for (const f of ['position', 'rotation'] as const) if (pose?.[f] !== undefined && !finite3(pose[f])) problems.push(`${label} key ${i} part \"${pid}\" has an invalid ${f}`)\n }\n })\n let prevEv = -Infinity\n ;(clip.events ?? []).forEach((e, i) => {\n if (!(typeof e.t === 'number' && Number.isFinite(e.t)) || e.t < 0 || e.t > dur + 1e-9) problems.push(`${label} event ${i} has t=${String(e.t)} outside 0..${dur}`)\n else if (e.t < prevEv) problems.push(`${label} event ${i} goes back in time`)\n else prevEv = e.t\n if (typeof e.type !== 'string' || e.type === '') problems.push(`${label} event ${i} needs a type`)\n try {\n JSON.stringify(e.data ?? {})\n } catch {\n problems.push(`${label} event ${i} data is not JSON`)\n }\n })\n return { ok: problems.length === 0, problems }\n}\n","import type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from './animation'\nimport { checkAnimation } from './animation'\nimport type { HostEvent } from './module'\n\n/** Clips a tool can bring, one per move of its cycle. A tool brings the ones it has; a missing clip is simply not played. */\nexport const TOOL_CLIP = {\n DRAW: 'draw',\n SHOT: 'shot',\n MISFIRE: 'misfire',\n EMPTY: 'empty',\n CYCLE: 'cycle',\n RELOAD: 'reload',\n FEED: 'feed',\n FAULT: 'fault',\n CLEAR: 'clear',\n SAFETY_ON: 'safety_on',\n SAFETY_OFF: 'safety_off',\n MODE: 'mode',\n /** A throwable with the pin out, held until it is thrown. */\n COOK: 'cook',\n /** The stock folds, unfolds, slides in or out (variants `fold`, `unfold`, `collapse`, `extend`). */\n STOCK: 'stock',\n /** A light or a laser is switched (variants `on`, `off`). */\n TOGGLE: 'toggle',\n} as const\nexport type ToolClipId = (typeof TOOL_CLIP)[keyof typeof TOOL_CLIP]\n\n/** What a renderer does when a rule event arrives. `variant` picks `<clip>_<variant>` when the tool has it, else `<clip>`. */\nexport type ToolAnimationStep =\n | { readonly type: 'play'; readonly clip: ToolClipId; readonly variant?: string; readonly duration?: number; readonly repeat?: number }\n /** Move the clip that is playing to the marker (a clip event `stage` with `data.stage`) the rule just reached. */\n | { readonly type: 'sync'; readonly stage: string }\n /** The rule says the phase is over: the clip jumps to its end if it is still running. */\n | { readonly type: 'finish'; readonly clip: ToolClipId }\n\nconst stockVariant = (event: Extract<HostEvent, { type: 'stock' }>): string => {\n const isFolding = event.kind === undefined ? false : event.kind.includes('fold')\n if (event.state === 'collapsed') return isFolding ? 'fold' : 'collapse'\n return isFolding ? 'unfold' : 'extend'\n}\n\n/** The move a host event asks of the tool in hand, or null when it has no motion. */\nexport const toolAnimationStep = (event: HostEvent): ToolAnimationStep | null => {\n switch (event.type) {\n case 'tool':\n return { type: 'play', clip: TOOL_CLIP.DRAW, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'shot':\n return { type: 'play', clip: TOOL_CLIP.SHOT, repeat: Math.max(1, event.rounds ?? 1) }\n case 'misfire':\n return { type: 'play', clip: TOOL_CLIP.MISFIRE }\n case 'empty':\n return { type: 'play', clip: TOOL_CLIP.EMPTY }\n case 'mode':\n return { type: 'play', clip: TOOL_CLIP.MODE, variant: event.mode }\n case 'fault':\n return { type: 'play', clip: TOOL_CLIP.FAULT, variant: event.fault }\n case 'clear':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CLEAR }\n return { type: 'play', clip: TOOL_CLIP.CLEAR, variant: event.fault, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'safety':\n return { type: 'play', clip: event.on ? TOOL_CLIP.SAFETY_ON : TOOL_CLIP.SAFETY_OFF }\n case 'cycle':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CYCLE }\n return { type: 'play', clip: TOOL_CLIP.CYCLE, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'reload':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.RELOAD }\n return { type: 'play', clip: TOOL_CLIP.RELOAD, ...(event.kind === undefined ? {} : { variant: event.kind }), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'stage':\n return { type: 'sync', stage: event.stage }\n case 'feed':\n return { type: 'play', clip: TOOL_CLIP.FEED }\n case 'cook':\n if (event.phase === 'start') return { type: 'play', clip: TOOL_CLIP.COOK, duration: event.fuse }\n return { type: 'finish', clip: TOOL_CLIP.COOK }\n case 'stock':\n return { type: 'play', clip: TOOL_CLIP.STOCK, variant: stockVariant(event), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'toggle':\n return { type: 'play', clip: TOOL_CLIP.TOGGLE, variant: event.on ? 'on' : 'off' }\n default:\n return null\n }\n}\n\n/** Where a renderer puts the poses: every part of the tool by id (the ids the clips move), and the whole tool. Poses are offsets from rest. */\nexport interface ToolRig {\n setPartPose(partId: string, pose: AnimationPose): void\n setRootPose?(pose: AnimationPose): void\n}\n\n/** Clips by id, with the variants as `<clip>_<variant>`. */\nexport type ToolClipSet = Readonly<Record<string, AnimationClipSpec>>\n\n/** A renderer's tool animator: feed it the host events and the frame time. */\nexport interface ToolAnimator {\n handle(event: HostEvent): void\n update(dt: number): void\n /** Ids of the clips playing now. */\n readonly playing: readonly string[]\n dispose(): void\n}\n\nexport const STAGE_EVENT = 'stage'\n\n/** The clip with its times (keys and events) scaled so that it lasts `duration` seconds. */\nexport const scaleClip = (clip: AnimationClipSpec, duration: number): AnimationClipSpec => {\n const factor = clip.duration > 0 ? duration / clip.duration : 1\n return {\n ...clip,\n duration,\n keys: clip.keys.map((key) => ({ ...key, t: key.t * factor })),\n ...(clip.events ? { events: clip.events.map((event) => ({ ...event, t: event.t * factor })) } : {}),\n }\n}\n\nconst ZERO: [number, number, number] = [0, 0, 0]\nconst mix = (from: readonly number[], to: readonly number[], fraction: number): [number, number, number] => [\n (from[0] ?? 0) + ((to[0] ?? 0) - (from[0] ?? 0)) * fraction,\n (from[1] ?? 0) + ((to[1] ?? 0) - (from[1] ?? 0)) * fraction,\n (from[2] ?? 0) + ((to[2] ?? 0) - (from[2] ?? 0)) * fraction,\n]\n\n/** Pose of the whole tool (`partId` undefined) or of one part at `time`, linear between keys; a key that does not name it means rest. */\nexport const sampleClip = (clip: AnimationClipSpec, partId: string | undefined, time: number): { position: [number, number, number]; rotation: [number, number, number] } => {\n const points = clip.keys.map((key) => {\n const pose = partId === undefined ? key : key.parts?.[partId]\n return { t: key.t, position: pose?.position ?? ZERO, rotation: pose?.rotation ?? ZERO }\n })\n const first = points[0]\n if (!first || first.t > 0) points.unshift({ t: 0, position: ZERO, rotation: ZERO })\n const last = points[points.length - 1]\n if (!last) return { position: ZERO, rotation: ZERO }\n if (time >= last.t) return { position: mix(last.position, last.position, 0), rotation: mix(last.rotation, last.rotation, 0) }\n const index = Math.max(0, points.findIndex((point, i) => time >= point.t && time < (points[i + 1]?.t ?? Infinity)))\n const from = points[index]\n const to = points[index + 1]\n if (!from || !to) return { position: ZERO, rotation: ZERO }\n const fraction = to.t > from.t ? (time - from.t) / (to.t - from.t) : 0\n return { position: mix(from.position, to.position, fraction), rotation: mix(from.rotation, to.rotation, fraction) }\n}\n\n/** Problems with a clip set (empty when valid): each key is the clip id (or `<clip>_<variant>`), every clip passes `checkAnimation`, and a `stage` event names its stage. */\nexport const checkToolClips = (clips: ToolClipSet, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const parts = [...partIds]\n const problems: string[] = []\n for (const [key, clip] of Object.entries(clips)) {\n if (clip.id !== key) problems.push(`clip \"${key}\" has the id \"${clip.id}\"`)\n if (!(clip.duration > 0)) problems.push(`clip \"${key}\" has no duration`)\n problems.push(...checkAnimation(clip, parts).problems)\n for (const event of clip.events ?? []) if (event.type === STAGE_EVENT && typeof event.data?.stage !== 'string') problems.push(`clip \"${key}\" has a stage event without data.stage`)\n }\n return { ok: problems.length === 0, problems }\n}\n\ninterface Instance {\n readonly name: string\n readonly clip: AnimationClipSpec\n time: number\n delay: number\n fired: number\n}\n\nexport interface ToolClipPlayerOptions {\n clips: ToolClipSet\n rig: ToolRig\n /** Called for each clip event as its time passes (`eject_casing`, `drop_magazine`, `stage`...). */\n onEvent?(event: AnimationEventSpec, clip: string): void\n /** Seconds between the rounds of a `repeat` (a burst): default 0.1. */\n repeatInterval?(): number\n}\n\n/** The default player of a tool's clips: runs the steps of `toolAnimationStep` against a rig, scaled to the duration the rule gives. */\nexport interface ToolClipPlayer {\n apply(step: ToolAnimationStep): void\n update(dt: number): void\n readonly playing: readonly string[]\n /** The clips being played with the time each has reached and the clip itself (scaled to the duration the rule gave), for a renderer that has to follow what the clip does now (the hands working a part). */\n readonly running: ReadonlyArray<{ readonly name: string; readonly time: number; readonly clip: AnimationClipSpec }>\n}\n\nexport const createToolClipPlayer = (options: ToolClipPlayerOptions): ToolClipPlayer => {\n const { clips, rig, onEvent } = options\n let instances: Instance[] = []\n\n const find = (clip: string, variant?: string): { name: string; clip: AnimationClipSpec } | undefined => {\n const name = variant !== undefined && clips[`${clip}_${variant}`] ? `${clip}_${variant}` : clip\n const found = clips[name]\n return found ? { name, clip: found } : undefined\n }\n\n const render = (instance: Instance): void => {\n const time = Math.min(instance.time, instance.clip.duration)\n const root = sampleClip(instance.clip, undefined, time)\n if (instance.clip.keys.some((key) => key.position || key.rotation)) rig.setRootPose?.(root)\n const touched = new Set(instance.clip.keys.flatMap((key) => Object.keys(key.parts ?? {})))\n for (const id of touched) rig.setPartPose(id, sampleClip(instance.clip, id, time))\n }\n\n const fireEvents = (instance: Instance, upTo: number): void => {\n const events = instance.clip.events ?? []\n while (instance.fired < events.length && (events[instance.fired]?.t ?? Infinity) <= upTo + 1e-9) {\n const event = events[instance.fired]\n instance.fired += 1\n if (event) onEvent?.(event, instance.name)\n }\n }\n\n return {\n apply(step) {\n if (step.type === 'sync') {\n for (const instance of instances) {\n const marker = (instance.clip.events ?? []).find((event) => event.type === STAGE_EVENT && event.data?.stage === step.stage)\n if (marker && instance.time < marker.t) instance.time = marker.t\n }\n return\n }\n if (step.type === 'finish') {\n for (const instance of instances) {\n if (instance.name !== step.clip && !instance.name.startsWith(`${step.clip}_`)) continue\n fireEvents(instance, instance.clip.duration)\n instance.time = instance.clip.duration\n }\n return\n }\n const found = find(step.clip, step.variant)\n if (!found) return\n const clip = step.duration && step.duration > 0 ? scaleClip(found.clip, step.duration) : found.clip\n const interval = options.repeatInterval?.() ?? 0.1\n instances = instances.filter((existing) => existing.name !== found.name || existing.delay > 0)\n for (let round = 0; round < (step.repeat ?? 1); round++) {\n instances.push({ name: found.name, clip, time: 0, delay: round * interval, fired: 0 })\n }\n },\n update(dt) {\n for (const instance of instances) {\n const carried = instance.delay > 0 ? dt - instance.delay : dt\n if (instance.delay > 0) {\n instance.delay = Math.max(0, instance.delay - dt)\n if (instance.delay > 0) continue\n }\n instance.time += carried\n fireEvents(instance, instance.time)\n render(instance)\n }\n instances = instances.filter((instance) => instance.delay > 0 || instance.time < instance.clip.duration)\n },\n get playing() {\n return instances.map((instance) => instance.name)\n },\n get running() {\n return instances.filter((instance) => instance.delay <= 0).map((instance) => ({ name: instance.name, time: instance.time, clip: instance.clip }))\n },\n }\n}\n","type PlainObject = Record<string, unknown>\ntype Entry = { readonly id: string }\n\n/** Keys that would reach the prototype of the result when a patch comes from parsed JSON. */\nconst UNSAFE_KEYS: ReadonlySet<string> = new Set(['__proto__', 'constructor', 'prototype'])\n\nconst isPlainObject = (value: unknown): value is PlainObject =>\n typeof value === 'object' && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype\n\n/** Recursively optional; arrays and functions are replaced as a whole, objects are merged. */\nexport type DeepPartial<TValue> = TValue extends (...args: never[]) => unknown\n ? TValue\n : TValue extends readonly unknown[]\n ? TValue\n : TValue extends object\n ? { [TKey in keyof TValue]?: DeepPartial<TValue[TKey]> }\n : TValue\n\n/** Merges `patch` over `base`: plain objects merge field by field, arrays, functions and primitives replace. `undefined` in the patch is ignored. */\nexport const deepMerge = <TBase extends object>(base: TBase, patch: object | undefined): TBase => {\n if (!patch) return base\n const result: PlainObject = { ...(base as PlainObject) }\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined || UNSAFE_KEYS.has(key)) continue\n const current = result[key]\n result[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value\n }\n return result as TBase\n}\n\n/** The shipped entries with the ones from `extra` added or, when the id exists, replaced. */\nexport const mergeById = <TEntry extends Entry>(shipped: readonly TEntry[], extra: readonly TEntry[] | undefined): Map<string, TEntry> => {\n const entries = new Map<string, TEntry>()\n for (const entry of [...shipped, ...(extra ?? [])]) entries.set(entry.id, entry)\n return entries\n}\n\n/** Applies `patch` by id; a patch for an id that does not exist is ignored. */\nexport const applyPatches = <TEntry extends Entry>(entries: Map<string, TEntry>, patches: Readonly<Record<string, DeepPartial<TEntry> | Partial<TEntry>>> | undefined): void => {\n for (const [id, patch] of Object.entries(patches ?? {})) {\n const entry = entries.get(id)\n if (entry) entries.set(id, deepMerge(entry, patch))\n }\n}\n\nexport const removeIds = (entries: Map<string, unknown>, ids: readonly string[] | undefined): void => {\n for (const id of ids ?? []) entries.delete(id)\n}\n","import type { Vec3 } from './destruction'\n\n/**\n * The bench of a module: controls, layers and counters it declares as data. The host keeps the values, draws them in a generic way and hands\n * every change back through `ModuleHost.bench`. Nothing here is specific to a kind of module.\n */\nexport type ControlValue = number | boolean | string\n\nexport interface ChoiceOption {\n readonly id: string\n readonly name: string\n /** Heading the host lists the option under (`optgroup`, a grouped row of buttons). Options of a group must sit next to each other. */\n readonly group?: string\n}\n\ninterface ControlBase {\n /** snake_case, unique across the module's controls, layers and metrics. */\n readonly id: string\n /** Display name, already translated for the locale the host asked for. */\n readonly name: string\n readonly hint?: string\n readonly hidden?: boolean\n /**\n * The change (or the press, for an action) takes a noticeable time, a third of a second or more: the host shows its loading indicator while it works, with this text, or the control's name for `true`.\n * Only the host's own controls panel does it; a change made through `TestRoom.bench().set / act` runs at once.\n */\n readonly slow?: boolean | string\n}\n\nexport interface NumberControl extends ControlBase {\n readonly kind: 'number'\n readonly min: number\n readonly max: number\n readonly step?: number\n readonly unit?: string\n readonly default: number\n}\n\nexport interface BooleanControl extends ControlBase {\n readonly kind: 'boolean'\n readonly default: boolean\n}\n\nexport interface ChoiceControl extends ControlBase {\n readonly kind: 'choice'\n readonly options: readonly ChoiceOption[]\n readonly default: string\n}\n\n/** A button: no value, only the press. */\nexport interface ActionControl extends ControlBase {\n readonly kind: 'action'\n}\n\nexport type ModuleControl = NumberControl | BooleanControl | ChoiceControl | ActionControl\n\n/** Something of the module the viewer turns on or off (smoke, flash, casings). */\nexport interface ModuleLayer {\n readonly id: string\n readonly name: string\n /** On unless `false`. */\n readonly default?: boolean\n}\n\n/** Pulled: the room calls read only when it samples (~4 Hz, or on TestRoom.metrics()). */\nexport interface ModuleMetric {\n readonly id: string\n readonly name: string\n readonly unit?: string\n /** Budget: the host shows a bar and warns past it. */\n readonly max?: number\n readonly digits?: number\n read(): number | string\n}\n\nexport type BenchChange =\n | { readonly kind: 'control'; readonly id: string; readonly value: ControlValue }\n | { readonly kind: 'layer'; readonly id: string; readonly on: boolean }\n | { readonly kind: 'action'; readonly id: string }\n\nexport interface ControlPatch {\n readonly hidden?: boolean\n readonly disabled?: boolean\n readonly options?: readonly ChoiceOption[]\n readonly value?: ControlValue\n}\n\n/** What the host lends a module that declares a bench: the current values and the changes. */\nexport interface ModuleBench {\n value(id: string): ControlValue | undefined\n layer(id: string): boolean\n /** Right after attach returns, the host sends one change per control (not actions) and per layer, in declaration order. */\n onChange(listener: (change: BenchChange) => void): () => void\n /** `value` sets without emitting (no echo loops); `options` falls back to the first option if the value is no longer offered. */\n patch(id: string, patch: ControlPatch): void\n /** Move the host camera (a near / middle / far choice). */\n look(eye: Vec3, target: Vec3): void\n /** Shows a sheet on the host's panel, or takes it down with `null`. A host without a sheet area ignores it. */\n sheet?(sheet: BenchSheet | null): void\n}\n\n/**\n * A card of text the module puts on the host's panel (the sheet of an effect, of a weapon): what it is, its numbers, its steps, its colours and,\n * optionally, a strip of segments over time. Names and texts are already translated for the host's locale.\n */\nexport interface BenchSheet {\n readonly kicker?: string\n readonly title: string\n readonly body?: string\n readonly facts?: readonly { readonly label: string; readonly value: string }[]\n readonly steps?: readonly { readonly at: string; readonly text: string }[]\n readonly swatches?: readonly { readonly color: string; readonly name: string }[]\n readonly note?: string\n /** A strip of named segments (seconds), with tick marks and a playhead that follows the module metric `metric`. */\n readonly timeline?: {\n readonly segments: readonly { readonly name: string; readonly start: number; readonly end: number; readonly color: string }[]\n readonly ticks: readonly number[]\n readonly metric: string\n }\n}\n\nexport interface BenchReport {\n readonly ok: boolean\n readonly problems: readonly string[]\n}\n\nexport interface BenchDeclaration {\n readonly controls?: readonly ModuleControl[]\n readonly layers?: readonly ModuleLayer[]\n readonly metrics?: readonly ModuleMetric[]\n}\n\nconst SNAKE_CASE = /^[a-z][a-z0-9_]*$/\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\n\nfunction checkControl(control: ModuleControl, problems: string[]): void {\n const label = `control \"${control.id}\"`\n if (control.kind === 'number') {\n if (!finite(control.min) || !finite(control.max) || control.min >= control.max) problems.push(`${label} needs min < max`)\n if (control.step !== undefined && !(finite(control.step) && control.step > 0)) problems.push(`${label} needs a step > 0`)\n if (!finite(control.default) || control.default < control.min || control.default > control.max) problems.push(`${label} default ${String(control.default)} is outside ${control.min}..${control.max}`)\n return\n }\n if (control.kind !== 'choice') return\n if (control.options.length === 0) {\n problems.push(`${label} needs at least one option`)\n return\n }\n const seen = new Set<string>()\n const groups = new Set<string>()\n let previousGroup: string | undefined\n for (const option of control.options) {\n if (seen.has(option.id)) problems.push(`${label} repeats option \"${option.id}\"`)\n seen.add(option.id)\n if (option.group !== undefined && (typeof option.group !== 'string' || option.group === '')) problems.push(`${label} option \"${option.id}\" has an empty group`)\n else if (option.group !== undefined && option.group !== previousGroup && groups.has(option.group)) problems.push(`${label} group \"${option.group}\" is split: its options must be next to each other`)\n if (typeof option.group === 'string' && option.group !== '') groups.add(option.group)\n previousGroup = option.group\n }\n if (!seen.has(control.default)) problems.push(`${label} default \"${control.default}\" is not among its options`)\n}\n\n/** snake_case ids unique across controls, layers and metrics; min < max; step > 0; default in range; options non-empty, unique, default among them, each group in one run; metric max > 0. */\nexport function checkBench(declared: BenchDeclaration): BenchReport {\n const problems: string[] = []\n const ids = new Set<string>()\n const claim = (kind: string, id: string): void => {\n if (!SNAKE_CASE.test(id)) problems.push(`${kind} id \"${id}\" must be snake_case`)\n if (ids.has(id)) problems.push(`duplicate id \"${id}\" across controls, layers and metrics`)\n ids.add(id)\n }\n for (const control of declared.controls ?? []) {\n claim('control', control.id)\n checkControl(control, problems)\n }\n for (const layer of declared.layers ?? []) claim('layer', layer.id)\n for (const metric of declared.metrics ?? []) {\n claim('metric', metric.id)\n if (metric.max !== undefined && !(finite(metric.max) && metric.max > 0)) problems.push(`metric \"${metric.id}\" needs a max > 0`)\n }\n return { ok: problems.length === 0, problems }\n}\n","/** The weather, light and ground as the world is right now. Written by whoever drives the weather, read by whoever reacts to it. */\nexport interface EnvironmentState {\n /** Rain in mm/h; 0 is dry. */\n readonly rain: number\n /** Wind in m/s along x and z, and its strength (the length of that vector). */\n readonly windX: number\n readonly windZ: number\n readonly windSpeed: number\n /** Strongest gust in m/s. */\n readonly gust: number\n /** Render fog far distance in metres. */\n readonly fogFar: number\n /** How far one can see for gameplay, in metres (not the render fog). */\n readonly visibility: number\n /** 0 is full daylight, 1 is the darkest night. */\n readonly nightFactor: number\n readonly temperatureC: number\n /** Wet ground, 0..1: rises with rain and dries after it stops. */\n readonly wetness: number\n}\n\nexport type EnvironmentKey = keyof EnvironmentState\n\n/** A calm dry day (the normal world, before anything went wrong). */\nexport const DEFAULT_ENVIRONMENT: EnvironmentState = {\n rain: 0,\n windX: 0,\n windZ: 0,\n windSpeed: 0,\n gust: 0,\n fogFar: 220,\n visibility: 220,\n nightFactor: 0,\n temperatureC: 20,\n wetness: 0,\n}\n\n/** The host's environment (`ModuleHost.environment`): a store the weather module writes to and the others read. */\nexport interface EnvironmentBus {\n get(): EnvironmentState\n /** Merges `patch` into the state; listeners hear it only when a value really changed. */\n set(patch: Partial<EnvironmentState>): void\n /** Hears every change with the keys that changed. Returns the unsubscribe function. */\n on(listener: (state: EnvironmentState, changed: readonly EnvironmentKey[]) => void): () => void\n}\n\n/** A plain store that implements the bus; the test room and tests use it, a game may bring its own. */\nexport function createEnvironmentBus(initial: Partial<EnvironmentState> = {}): EnvironmentBus {\n let state: EnvironmentState = { ...DEFAULT_ENVIRONMENT, ...initial }\n const listeners = new Set<(state: EnvironmentState, changed: readonly EnvironmentKey[]) => void>()\n return {\n get: () => state,\n set(patch) {\n const changed = (Object.keys(patch) as EnvironmentKey[]).filter((key) => patch[key] !== undefined && patch[key] !== state[key])\n if (changed.length === 0) return\n const next = { ...state } as { -readonly [Key in EnvironmentKey]: number }\n for (const key of changed) next[key] = patch[key] as number\n state = next\n for (const listener of [...listeners]) listener(state, changed)\n },\n on(listener) {\n listeners.add(listener)\n return () => void listeners.delete(listener)\n },\n }\n}\n","import { applyPatches, deepMerge, mergeById, removeIds } from './registry'\nimport type { DeepPartial } from './registry'\n\n/** One category (kind) of items. Defaults and required contracts are inherited from the `extends` chain. */\nexport interface CategoryDef<TDefaults extends object = Record<string, unknown>> {\n readonly id: string\n /** Parent category id; the child inherits its defaults and its required contracts. */\n readonly extends?: string\n /** Field values every entry of this kind starts with; objects merge down the chain, arrays replace. */\n readonly defaults?: DeepPartial<TDefaults>\n /** Contract ids (`ContractChecker.id`) every entry of this kind, or of a descendant, must satisfy. */\n readonly requires?: readonly string[]\n /** An abstract category only groups: entries cannot declare it directly, only its descendants. */\n readonly abstract?: boolean\n}\n\n/** Where a checker is being run: the entry's kind and the chain of categories root first. */\nexport interface ContractContext {\n readonly kind: string\n readonly chain: readonly string[]\n}\n\n/** A named contract: returns the problems of an entry, each a short phrase like `missing leftover.despawnSeconds`. Empty means it holds. */\nexport interface ContractChecker<TEntry> {\n readonly id: string\n check(entry: TEntry, ctx: ContractContext): string[]\n}\n\nexport interface CategoryOptions {\n /** Categories added to the shipped ones; the same id replaces. */\n readonly extra?: readonly CategoryDef[]\n /** Partial changes by id, applied after `extra`. */\n readonly patches?: Readonly<Record<string, DeepPartial<CategoryDef> | Partial<CategoryDef>>>\n /** Ids taken out of the tree (their children are then reported by `check()`). */\n readonly remove?: readonly string[]\n}\n\nexport interface CategoryRegistry {\n get(id: string): CategoryDef | undefined\n has(id: string): boolean\n ids(): string[]\n /** Root first, ending at `id`. Throws on an unknown id, an unknown parent or a cycle. */\n chain(id: string): string[]\n /** `defaults` merged along the chain, root first, so the closest category wins. */\n defaults(id: string): Record<string, unknown>\n /** Union of `requires` along the chain, order kept, without duplicates. */\n requires(id: string): string[]\n /** True when `id` is `ancestorId` or descends from it. */\n isA(id: string, ancestorId: string): boolean\n /** Problems in the tree itself: duplicate ids, unknown `extends`, cycles. */\n check(): string[]\n}\n\nexport interface CategorizedOptions {\n /** Field of the entry that names its category. Default `kind`. */\n readonly kindField?: string\n /** Known gaps by entry id: problems starting with one of these texts go to `allowed`, so the list can shrink over time. */\n readonly allow?: Readonly<Record<string, readonly string[]>>\n}\n\nexport interface CategorizedReport {\n readonly ok: boolean\n readonly problems: string[]\n readonly allowed: string[]\n}\n\nexport const defineCategories = (defs: readonly CategoryDef[], options: CategoryOptions = {}): CategoryRegistry => {\n const problems: string[] = []\n const duplicates = (list: readonly CategoryDef[]): void => {\n const ids = new Set<string>()\n for (const def of list) {\n if (ids.has(def.id)) problems.push(`duplicate category \"${def.id}\"`)\n ids.add(def.id)\n }\n }\n duplicates(defs)\n duplicates(options.extra ?? [])\n\n const entries = mergeById(defs, options.extra)\n applyPatches(entries, options.patches)\n removeIds(entries, options.remove)\n\n const chain = (id: string): string[] => {\n const path: string[] = []\n let current: string | undefined = id\n while (current !== undefined) {\n const def = entries.get(current)\n if (!def) throw new Error(path.length === 0 ? `unknown category \"${current}\"` : `category \"${path[0]}\" has unknown parent \"${current}\"`)\n if (path.includes(current)) throw new Error(`category cycle: ${[...path, current].reverse().join(' -> ')}`)\n path.push(current)\n current = def.extends\n }\n return path.reverse()\n }\n\n const registry: CategoryRegistry = {\n get: (id) => entries.get(id),\n has: (id) => entries.has(id),\n ids: () => [...entries.keys()],\n chain,\n defaults: (id) => chain(id).reduce<Record<string, unknown>>((acc, ancestor) => deepMerge(acc, entries.get(ancestor)?.defaults), {}),\n requires: (id) => {\n const out: string[] = []\n for (const ancestor of chain(id)) for (const contract of entries.get(ancestor)?.requires ?? []) if (!out.includes(contract)) out.push(contract)\n return out\n },\n isA: (id, ancestorId) => {\n try {\n return chain(id).includes(ancestorId)\n } catch {\n return false\n }\n },\n check: () => {\n const found = [...problems]\n for (const [id, def] of entries) {\n if (def.extends !== undefined && !entries.has(def.extends)) found.push(`category \"${id}\" extends unknown \"${def.extends}\"`)\n else {\n try {\n chain(id)\n } catch (error) {\n const message = (error as Error).message\n // The same cycle is found from each of its members; the dedupe keeps one line per distinct message.\n if (message.startsWith('category cycle') && !found.includes(message)) found.push(message)\n }\n }\n }\n return found\n },\n }\n return registry\n}\n\n/** The entry with the defaults of its category underneath: the entry wins, objects merge, arrays replace. */\nexport const resolveEntry = <TEntry extends object>(registry: CategoryRegistry, entry: TEntry, kindField = 'kind'): TEntry =>\n deepMerge(registry.defaults(String((entry as Record<string, unknown>)[kindField])) as TEntry, entry)\n\n/** Checks that each entry has a known, concrete kind and satisfies every contract its chain requires. */\nexport const checkCategorized = <TEntry extends { readonly id: string }>(\n entries: readonly TEntry[],\n registry: CategoryRegistry,\n checkers: readonly ContractChecker<TEntry>[],\n options: CategorizedOptions = {},\n): CategorizedReport => {\n const kindField = options.kindField ?? 'kind'\n const byId = new Map(checkers.map((checker) => [checker.id, checker]))\n const problems: string[] = [...registry.check()]\n const allowed: string[] = []\n\n for (const entry of entries) {\n const kind = String((entry as Record<string, unknown>)[kindField])\n if (!registry.has(kind)) {\n problems.push(`\"${entry.id}\" has unknown kind \"${kind}\"`)\n continue\n }\n if (registry.get(kind)?.abstract) {\n problems.push(`\"${entry.id}\" has abstract kind \"${kind}\"`)\n continue\n }\n let path: string[]\n try {\n path = registry.chain(kind)\n } catch (error) {\n problems.push(`\"${entry.id}\" (${kind}): ${(error as Error).message}`)\n continue\n }\n const resolved = resolveEntry(registry, entry, kindField)\n for (const contract of registry.requires(kind)) {\n const owner = path.find((ancestor) => registry.get(ancestor)?.requires?.includes(contract)) ?? kind\n const checker = byId.get(contract)\n if (!checker) {\n problems.push(`kind \"${kind}\" requires contract \"${contract}\" but no checker is registered`)\n continue\n }\n const prefix = `\"${entry.id}\" (${kind}): `\n for (const problem of checker.check(resolved, { kind, chain: path })) {\n const text = `${prefix}${problem}, required by ${owner}`\n if ((options.allow?.[entry.id] ?? []).some((start) => problem.startsWith(start))) allowed.push(text)\n else problems.push(text)\n }\n }\n }\n return { ok: problems.length === 0, problems: [...new Set(problems)], allowed }\n}\n","/**\n * Where a drawn object comes from. Every builder of the kit that draws a piece (a car of the fleet, a house or a wall, a piece of furniture, a person, an\n * animal, a plant, an item, a weapon) marks the root it returns, and every renderer that draws for the room (effects, debris, liquids, the room itself)\n * marks its own roots, so a host can tell a piece of the kit from something drawn on the spot. Duck-typed on three.js objects (`userData`, `parent`,\n * `children`), so the contracts stay free of three.js.\n */\nexport const KIT_ORIGIN_KEY = 'kitOrigin'\n\n/** What drew an object: the package and the kind of piece (`vehicle`, `structure`, `furniture`, `person`... or `effect`, `room` for what is not a piece). */\nexport interface KitOrigin {\n readonly owner: string\n readonly kind: string\n /** The catalogue id of the piece, when it has one. */\n readonly id?: string\n /** Drawn as a simple stand-in shape because the kit has no model of the piece yet (an item with no team model): a model still to make. */\n readonly standIn?: boolean\n}\n\ninterface Node {\n userData?: Record<string, unknown>\n parent?: Node | null\n children?: readonly Node[]\n name?: string\n visible?: boolean\n isMesh?: boolean\n isPoints?: boolean\n isLine?: boolean\n isSprite?: boolean\n}\n\n/** Marks `object` as drawn by `origin.owner` and returns it. */\nexport function markKitOrigin<T>(object: T, origin: KitOrigin): T {\n const node = object as unknown as Node\n node.userData = node.userData ?? {}\n node.userData[KIT_ORIGIN_KEY] = { ...origin }\n return object\n}\n\n/** The origin of the object or of its nearest marked ancestor; null when nothing up the tree is marked. */\nexport function kitOriginOf(object: unknown): KitOrigin | null {\n for (let node = object as Node | null | undefined; node; node = node.parent) {\n const origin = node.userData?.[KIT_ORIGIN_KEY] as KitOrigin | undefined\n if (origin && typeof origin.owner === 'string') return origin\n }\n return null\n}\n\n/** A drawn thing that no builder of the kit marked: what was drawn on the spot. */\nexport interface UnmarkedDrawing {\n /** The names of the object and its named ancestors, outermost first. */\n readonly path: string\n readonly object: unknown\n}\n\n/** Every visible mesh, line, point cloud or sprite under `root` with no marked ancestor (`root` itself not counted as one). */\nexport function unmarkedDrawings(root: unknown): UnmarkedDrawing[] {\n const out: UnmarkedDrawing[] = []\n const pathOf = (node: Node): string => {\n const names: string[] = []\n for (let n: Node | null | undefined = node; n && n !== root; n = n.parent) if (n.name) names.push(n.name)\n return names.reverse().join(' > ') || '(no name)'\n }\n const walk = (node: Node, marked: boolean): void => {\n if (node.visible === false) return\n const here = marked || (node !== root && Boolean((node.userData?.[KIT_ORIGIN_KEY] as KitOrigin | undefined)?.owner))\n if (!here && (node.isMesh || node.isPoints || node.isLine || node.isSprite)) out.push({ path: pathOf(node), object: node })\n for (const child of node.children ?? []) walk(child, here)\n }\n walk(root as Node, false)\n return out\n}\n","import { markKitOrigin } from '@adatechnology/game-contracts'\nimport type { AnimationClipSpec, DestructibleSpec, JointSpec, PartSpec, TestableItem } from '@adatechnology/game-contracts'\nimport type { Condition, PlantMesh, PlantSpec } from '@adatechnology/game-vegetation'\n\nimport type { MaterialsLike, SpeciesSdk, VegetationSdk } from './types'\n\n/** The seed of every plant of the area (the Viveiro's module fixes it, so the plants are the same in every run). */\nexport const PLANT_SEED = 3\n\nexport type PlantDefKind = 'tree' | 'shrub' | 'hedge' | 'flower' | 'cactus' | 'pot' | 'tuft'\n\n/** One item of the area: a species of the pack (or a variant of it) and how it is built. */\nexport type PlantDef = {\n readonly id: string\n /** The species the plant is generated from (default: `id`). */\n readonly base?: string\n readonly kind: PlantDefKind\n readonly sway: boolean\n /** Fields of the species spec replaced for this item. */\n readonly over?: Readonly<Record<string, number>>\n /** The name, `[pt-BR, en]`, when the species name does not fit the variant. */\n readonly name?: readonly [string, string]\n readonly condition?: Condition\n /** Plants side by side (a hedge is 4 sections joined by their stems). */\n readonly segments?: number\n readonly movable?: boolean\n}\n\n/** The 18 items of the Viveiro's module, in its order. */\nexport const PLANT_DEFS: readonly PlantDef[] = [\n { id: 'mango_tree', kind: 'tree', sway: true },\n // young mango trees (same species, thin trunk): the 15 and 30 cm trunks on which the SDK documents the number of axe swings\n { id: 'mango_young_15', base: 'mango_tree', kind: 'tree', sway: true, over: { height: 1.7, trunkRadius: 0.1, crownRadius: 1.0 }, name: ['Mangueira jovem (tronco de 15 cm)', 'Young mango tree (15 cm trunk)'] },\n { id: 'mango_young_30', base: 'mango_tree', kind: 'tree', sway: true, over: { height: 1.7, trunkRadius: 0.17, crownRadius: 1.2 }, name: ['Mangueira jovem (tronco de 30 cm)', 'Young mango tree (30 cm trunk)'] },\n { id: 'yellow_ipe', kind: 'tree', sway: true },\n { id: 'coconut_palm', kind: 'tree', sway: true },\n { id: 'banana_with_bunch', kind: 'tree', sway: true },\n { id: 'araucaria', kind: 'tree', sway: true },\n { id: 'dead_tree', kind: 'tree', sway: true, condition: 'dead' },\n { id: 'hibiscus_shrub', kind: 'shrub', sway: true },\n { id: 'boxwood_hedge', kind: 'hedge', sway: true, segments: 4 },\n { id: 'rose_bush_red', kind: 'shrub', sway: true },\n { id: 'sunflower', kind: 'flower', sway: true },\n { id: 'mandacaru', kind: 'cactus', sway: false },\n { id: 'prickly_pear', kind: 'cactus', sway: false },\n { id: 'crown_cactus', kind: 'cactus', sway: false },\n { id: 'potted_fern', kind: 'pot', sway: true, movable: true },\n { id: 'potted_cactus', kind: 'pot', sway: false, movable: true },\n { id: 'lawn_tuft', kind: 'tuft', sway: true },\n]\n\n/** The id of a mesh or a joint: lower case, runs of other characters turned into one `_` (`crown:flowers` becomes `crown_flowers`). */\nexport const sanitize = (s: string): string => String(s).toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '')\n\n/** What `buildObject` records in `userData.veg` of each piece mesh. */\nexport type PieceMeta = {\n id: string\n piece: string\n kind: string\n sub: string | null\n base: string\n parent: string | null\n seg: number\n materialKey: string\n radius?: number\n length?: number\n axis?: [number, number, number]\n /** Where the plant of this section stands along x in the object (sections of a hedge are side by side). */\n dx: number\n}\n\ntype Three = any\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] }\n\n/** Fraction of the volume of the shape that is solid, by destruction material (what the spec reports as `fill`). */\nconst FILL: Record<string, number> = { green_wood: 0.5, wood_soft: 0.5, foliage: 0.035, flowers: 0.03, flesh_fruit: 0.8, ceramic: 0.2, soil: 0.7, cactus: 0.5 }\n/** Radians of sway, by kind of piece. */\nconst SWAY_AMPLITUDE: Record<string, number> = { trunk: 0.004, branch: 0.012, crown: 0.03, fruit: 0.04, stem: 0.025, arm: 0, pad: 0, pot: 0, soil: 0 }\n\nexport function createPlants(sdk: VegetationSdk, species: SpeciesSdk, materials: (THREE: Three) => MaterialsLike, seed = PLANT_SEED) {\n const defs = new Map(PLANT_DEFS.map((def) => [def.id, def]))\n const specFor = (def: PlantDef): PlantSpec => {\n const spec = species.toSpec(def.base ?? def.id)\n return def.over ? ({ ...spec, ...def.over } as PlantSpec) : spec\n }\n const cache = new Map<string, PlantMesh>()\n const plantFor = (def: PlantDef, segment: number): PlantMesh => {\n const key = `${def.id}:${segment}`\n let plant = cache.get(key)\n if (!plant) {\n plant = sdk.generate(specFor(def), { seed: seed + segment * 7, ...(def.condition ? { condition: def.condition } : {}) })\n cache.set(key, plant)\n }\n return plant\n }\n\n // ---- the 3D object ----------------------------------------------------------------------------------------------------------------------\n function buildObject(THREE: Three, def: PlantDef): any {\n const root = markKitOrigin(new THREE.Group(), { owner: 'game-vegetation-three', kind: 'plant', id: def.base ?? def.id })\n root.name = def.id\n const segments = def.segments ?? 1\n let spacing = 0\n for (let s = 0; s < segments; s++) {\n const plant = plantFor(def, s)\n const object: any = sdk.createPlantObject(THREE, plant, materials(THREE), { separable: true })\n const prefix = segments > 1 ? `s${s}_` : ''\n const children = object.children.slice()\n if (s === 0 && segments > 1) {\n const g0 = children[0].geometry\n g0.computeBoundingBox()\n spacing = (g0.boundingBox.max.x - g0.boundingBox.min.x) * 0.9\n }\n for (const mesh of children) {\n const piece = mesh.userData.destructionPart\n const bits = String(piece.id).split(':')\n const id = prefix + sanitize(piece.id)\n mesh.name = id\n const dx = (s - (segments - 1) / 2) * spacing\n const meta: PieceMeta = {\n id,\n piece: piece.id,\n kind: piece.kind,\n sub: bits[1] ?? null,\n base: prefix + sanitize(bits[0] as string),\n parent: piece.parent ? prefix + sanitize(piece.parent) : null,\n seg: s,\n materialKey: piece.materialKey,\n radius: piece.radius,\n length: piece.length,\n axis: piece.axis,\n dx,\n }\n mesh.userData.veg = meta\n mesh.position.x += dx\n mesh.castShadow = true\n root.add(mesh)\n }\n if (s === 0) {\n root.userData.collider = plant.collider || null\n root.userData.thorny = !!plant.thorny\n }\n }\n root.userData.speciesId = def.id\n root.userData.separable = true\n root.userData.segments = segments\n return root\n }\n\n // ---- the destruction spec -----------------------------------------------------------------------------------------------------------------\n function buildSpec(root: any, def: PlantDef): DestructibleSpec {\n const meshes: any[] = root.children.filter((c: any) => c.isMesh && c.userData.veg)\n const byId: Record<string, any> = {}\n for (const m of meshes) byId[(m.userData.veg as PieceMeta).id] = m\n const parts: Mutable<PartSpec>[] = []\n for (const m of meshes) {\n const v = m.userData.veg as PieceMeta\n const g = m.geometry\n if (!g.boundingBox) g.computeBoundingBox()\n const b = g.boundingBox\n const mn = [b.min.x + m.position.x, b.min.y + m.position.y, b.min.z + m.position.z]\n const mx = [b.max.x + m.position.x, b.max.y + m.position.y, b.max.z + m.position.z]\n const size: [number, number, number] = [Math.max(mx[0]! - mn[0]!, 0.02), Math.max(mx[1]! - mn[1]!, 0.02), Math.max(mx[2]! - mn[2]!, 0.02)]\n const c: [number, number, number] = [(mn[0]! + mx[0]!) / 2, (mn[1]! + mx[1]!) / 2, (mn[2]! + mx[2]!) / 2]\n const material = m.userData.destructionMaterial as string\n const round = v.kind === 'trunk' || v.kind === 'pot'\n let shape: PartSpec['shape'] = round ? { kind: 'cylinder', radius: Math.max(size[0], size[2]) / 2, height: size[1] } : { kind: 'box', size }\n // wood pieces: the real thickness of the SDK (2 x radius by the length along the axis) instead of the bounding box, which overstates leaning trunks, flared bases and curved pieces\n let rotation: [number, number, number] | null = null\n if (!v.sub && (v.radius ?? 0) > 0 && (v.length ?? 0) > 0 && (v.kind === 'trunk' || v.kind === 'branch' || v.kind === 'arm' || v.kind === 'stem')) {\n const rr = Math.max(v.radius as number, 0.01)\n const ll = Math.max(v.length as number, 0.02)\n shape = v.kind === 'trunk' ? { kind: 'cylinder', radius: rr, height: ll } : { kind: 'box', size: [rr * 2, ll, rr * 2] }\n if (v.axis) {\n // the y axis of the shape along the axis of the piece (Euler XYZ: x = atan2(az, ay), z = -asin(ax))\n const ax = v.axis\n const tilt = Math.hypot(ax[0], ax[2])\n if (tilt > 0.02 && ax[1] > -0.99) rotation = [Math.atan2(ax[2], ax[1]), 0, -Math.asin(Math.max(-1, Math.min(1, ax[0])))]\n }\n }\n const tags: string[] = []\n const p: Mutable<PartSpec> = { id: v.id, material, shape, position: c, tags }\n if (rotation) p.rotation = rotation\n p.fill = v.sub === 'spines' ? 0.02 : v.sub === 'flowers' ? 0.01 : v.kind === 'trunk' ? 0.8 : v.kind === 'branch' ? 0.1 : v.kind === 'arm' ? 0.12 : v.kind === 'pad' ? 0.3 : (FILL[material] ?? 0.5)\n if (v.kind === 'fruit' || v.sub === 'wood') p.mass = 15\n if (v.kind === 'trunk') {\n p.grain = 'y'\n tags.push('trunk')\n }\n if (v.kind === 'branch') tags.push('branch')\n if (material === 'foliage' || v.sub === 'foliage') tags.push('leaf')\n if (v.sub === 'flowers') tags.push('flower')\n if (v.sub === 'spines') tags.push('thorns')\n if (v.kind === 'fruit') tags.push('fruit')\n if (v.kind === 'arm') tags.push('arm')\n if (v.kind === 'pad') tags.push('pad')\n if (v.kind === 'pot') {\n // explicit hp: a terracotta pot breaks in 1 to 3 shots of 9 mm\n p.mass = 2.4\n p.hp = 25\n tags.push('pot')\n }\n if (v.kind === 'soil') {\n p.mass = 3.2\n tags.push('soil')\n }\n if (def.kind === 'pot' && v.kind === 'stem' && !v.sub) p.mass = 0.4\n if (def.kind === 'pot' && v.sub) p.mass = 0.05\n // the root piece is fixed to the ground (a loose pot anchors nothing)\n const isRoot = !v.parent && !v.sub && (v.kind === 'trunk' || v.kind === 'pad' || (v.kind === 'stem' && def.kind !== 'pot'))\n if (isRoot && !def.movable) p.anchored = true\n parts.push(p)\n }\n\n const joints: JointSpec[] = []\n const seen = new Set<string>()\n const add = (a: string | null, b: string, kind: JointSpec['kind'], extra?: Partial<JointSpec>): void => {\n if (!a || !b || a === b || !byId[a] || !byId[b]) return\n const id = `${a}~${b}`\n if (seen.has(id)) return\n seen.add(id)\n joints.push({ id, a, b, kind, ...extra })\n }\n const firstOf = (seg: number, kind: string): string | null => {\n for (const m of meshes) {\n const v = m.userData.veg as PieceMeta\n if (v.seg === seg && v.kind === kind && !v.sub) return v.id\n }\n return null\n }\n for (const m of meshes) {\n const v = m.userData.veg as PieceMeta\n if (v.sub) {\n add(v.base, v.id, 'tie')\n continue\n }\n if (v.kind === 'soil') {\n add(v.parent, v.id, 'resting')\n continue\n }\n if (v.parent) {\n add(v.parent, v.id, 'stem', v.kind === 'arm' ? { strength: 60 } : undefined)\n continue\n }\n if (v.kind === 'fruit') {\n add(firstOf(v.seg, 'crown') || firstOf(v.seg, 'pad') || firstOf(v.seg, 'stem') || firstOf(v.seg, 'trunk'), v.id, 'stem')\n continue\n }\n if (def.kind === 'pot' && v.kind === 'stem') add(firstOf(v.seg, 'soil'), v.id, 'tie')\n }\n // hedge: neighbouring sections held by their stems\n const segments = def.segments ?? 1\n if (segments > 1) for (let s = 0; s + 1 < segments; s++) add(`s${s}_stem`, `s${s + 1}_stem`, 'stem')\n return { name: def.id, parts, joints, tags: ['plant'] }\n }\n\n // ---- the wind -----------------------------------------------------------------------------------------------------------------------------\n function swayClip(def: PlantDef): AnimationClipSpec {\n const plant = plantFor(def, 0)\n const segments = def.segments ?? 1\n const keys: { t: number; parts: Record<string, { rotation: [number, number, number] }> }[] = []\n const N = 8\n const D = 4\n for (let k = 0; k <= N; k++) {\n const ph = (k / N) * Math.PI * 2\n const parts: Record<string, { rotation: [number, number, number] }> = {}\n for (let s = 0; s < segments; s++) {\n const prefix = segments > 1 ? `s${s}_` : ''\n for (const pc of plant.pieces) {\n const a = SWAY_AMPLITUDE[pc.kind] || 0\n if (!a) continue\n if (pc.kind === 'stem' && /(^|:)wood$/.test(pc.id)) continue\n if (def.kind === 'pot' && pc.kind === 'stem' && pc.id.indexOf(':') < 0 && def.id === 'potted_cactus') continue\n const f = pc.id.indexOf(':flowers') > 0 ? 1.6 : 1\n parts[prefix + sanitize(pc.id)] = { rotation: [Math.sin(ph + s) * a * f * 0.6, 0, Math.sin(ph * 1 + 0.7 + s) * a * f] }\n }\n }\n keys.push({ t: (k / N) * D, parts: k === 0 || k === N ? {} : parts })\n }\n return { id: 'sway', duration: D, keys, events: [{ t: 0.2, type: 'sound', data: { key: 'leaves_rustle' } }] } as AnimationClipSpec\n }\n\n // ---- the items ----------------------------------------------------------------------------------------------------------------------------\n function items(locale: string, defsToUse: readonly PlantDef[] = PLANT_DEFS): TestableItem[] {\n const loc = String(locale || 'pt-BR').toLowerCase().indexOf('en') === 0 ? 'en' : 'pt-BR'\n return defsToUse.map((def) => {\n const item: Mutable<TestableItem> = {\n id: def.id,\n name: def.name ? (def.name[loc === 'en' ? 1 : 0] as string) : species.name(def.base ?? def.id, loc),\n build: (THREE: unknown) => buildObject(THREE, def),\n spec: (root: unknown) => {\n const spec = buildSpec(root, def)\n ;(root as { userData: Record<string, unknown> }).userData.vegSpec = spec\n return spec\n },\n movable: !!def.movable,\n }\n if (def.sway) item.animations = [swayClip(def)]\n return item\n })\n }\n\n return { defs, specFor, plantFor, buildObject, buildSpec, swayClip, items }\n}\n\nexport type Plants = ReturnType<typeof createPlants>\n","import type { ModuleScenario } from '@adatechnology/game-contracts'\n\nimport type { VegetationContext, VegetationRoom } from './types'\n\ntype A = any\ntype V3 = [number, number, number]\ntype Spawned = { objectId: string; root: { userData: Record<string, any> } }\n\n/**\n * The 13 scenarios of the Viveiro's vegetation module, literal (same objects, same tools, same sentences, in both languages). `veg_*` are the ids of the page.\n * A tool is taken with `setTool`; the room gives every tool its draw time, so each one waits for it (`room.waitUntilReady`) where the page's room used it at once.\n */\nexport function createScenarios(locale: string): ModuleScenario<VegetationContext>[] {\n const en = String(locale || 'pt-BR').toLowerCase().indexOf('en') === 0\n const L = (pt: string, e: string): string => (en ? e : pt)\n const yn = (b: unknown): string => (b ? L('sim', 'yes') : L('não', 'no'))\n\n const specOf = (so: Spawned): A => so.root.userData.vegSpec\n const partSpec = (so: Spawned, pid: string): A => specOf(so).parts.filter((p: A) => p.id === pid)[0]\n const world = (so: Spawned, local: V3): V3 => {\n const r = so.root as A\n return [r.position.x + local[0], r.position.y + local[1], r.position.z + local[2]]\n }\n const norm = (v: V3): V3 => {\n const l = Math.hypot(v[0], v[1], v[2]) || 1\n return [v[0] / l, v[1] / l, v[2] / l]\n }\n const dist = (a: V3, b: V3): number => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2])\n const DIRS: V3[] = [[0, 0, -1], [1, 0, 0], [-1, 0, 0], [0, 0, 1], [0.7, 0, -0.7], [-0.7, 0, -0.7], [0.7, 0, 0.7], [-0.7, 0, 0.7], [0, -1, 0]]\n\n const center = (so: Spawned, pid: string): V3 => world(so, partSpec(so, pid).position)\n\n // Joint tools (saw, knife): the camera position from which the ray hits something within 0.45 m of the joint asked for. Aims the camera.\n const aim = (room: VegetationRoom, so: Spawned, target: V3, standoff: number, opt: { beyond?: number; joint?: string; jointRange?: number } = {}): A => {\n let best: A = null\n for (const dir of DIRS) {\n const d = norm(dir)\n const origin: V3 = [target[0] - d[0] * standoff, target[1] - d[1] * standoff, target[2] - d[2] * standoff]\n if (origin[1] < 0.25) continue\n const hit = room.world.raycast(origin, d, standoff + (opt.beyond == null ? 0.6 : opt.beyond))\n if (!hit || hit.object !== so.objectId) continue\n let score = dist(hit.point, target)\n if (opt.joint) {\n const nj = room.world.nearestJoint(so.objectId, hit.point, opt.jointRange || 0.45)\n if (!nj || nj.id !== opt.joint) score += 20\n }\n if (!best || score < best.score) best = { score, origin, target, hit }\n }\n if (!best) best = { score: 99, origin: [target[0], target[1], target[2] + standoff], target, hit: null }\n room.look(best.origin, best.target)\n return best\n }\n // Weapons and fire: finds a horizontal (or from above) direction from which the first hit of the ray is the piece `pid`, and puts the camera `gap` metres from the surface\n // (blade stroke: 0.5; lighter: 0.08; shot: 2.5). `at` changes the aimed point (object local).\n const AIMDIRS: V3[] = [[0, 0, -1], [0.7, 0, -0.7], [-0.7, 0, -0.7], [1, 0, 0], [-1, 0, 0], [0, -1, 0], [0.7, 0, 0.7], [-0.7, 0, 0.7], [0, 0, 1]]\n const aimPart = (room: VegetationRoom, so: Spawned, pidsIn: string | string[], gap: number, at?: V3): { origin: V3; point: V3; found: boolean; pid: string } => {\n const pids = typeof pidsIn === 'string' ? [pidsIn] : pidsIn\n let best: A = null\n for (const pid of pids) {\n const c = at ? world(so, at) : center(so, pid)\n for (const dir of AIMDIRS) {\n const d = norm(dir)\n const far = 8\n const origin: V3 = [c[0] - d[0] * far, c[1] - d[1] * far, c[2] - d[2] * far]\n if (origin[1] < 0.3) continue\n const hit = room.world.raycast(origin, d, far + 3)\n if (!hit || hit.object !== so.objectId || hit.part !== pid) continue\n const score = dist(hit.point, c)\n if (!best || score < best.score) best = { score, d, hit, pid }\n }\n }\n if (!best) best = { score: 99, d: [0, 0, -1], hit: { point: center(so, pids[0] as string) }, pid: pids[0] }\n const H = best.hit.point as V3\n const from: V3 = [H[0] - best.d[0] * gap, H[1] - best.d[1] * gap, H[2] - best.d[2] * gap]\n if (from[1] < 0.3) from[1] = 0.3\n room.look(from, [H[0] + best.d[0] * 0.3, H[1] + best.d[1] * 0.3, H[2] + best.d[2] * 0.3])\n return { origin: from, point: H, found: best.score < 99, pid: best.pid }\n }\n const crownsOf = (so: Spawned): string[] => specOf(so).parts.filter((p: A) => /^(s\\d+_)?crown\\d*$/.test(p.id)).map((p: A) => p.id)\n const jointPos = (so: Spawned, jid: string): V3 => {\n const j = specOf(so).joints.filter((x: A) => x.id === jid)[0]\n const a = partSpec(so, j.a)\n const b = partSpec(so, j.b)\n const box = (p: A): { min: V3; max: V3 } => {\n const h: V3 = p.shape.kind === 'box' ? p.shape.size.map((s: number) => s / 2) : [p.shape.radius, p.shape.height / 2, p.shape.radius]\n const r = p.rotation || [0, 0, 0] // only x and z (see buildSpec): Euler XYZ = Rx * Rz\n const cx = Math.cos(r[0]), sx = Math.sin(r[0]), cz = Math.cos(r[2]), sz = Math.sin(r[2])\n const mn: V3 = [Infinity, Infinity, Infinity]\n const mx: V3 = [-Infinity, -Infinity, -Infinity]\n for (let i = 0; i < 8; i++) {\n const x = (i & 1 ? 1 : -1) * h[0], y = (i & 2 ? 1 : -1) * h[1], z = (i & 4 ? 1 : -1) * h[2]\n const x1 = x * cz - y * sz, y1 = x * sz + y * cz\n const w = [x1, y1 * cx - z * sx, y1 * sx + z * cx]\n for (let k = 0; k < 3; k++) {\n mn[k] = Math.min(mn[k] as number, p.position[k] + (w[k] as number))\n mx[k] = Math.max(mx[k] as number, p.position[k] + (w[k] as number))\n }\n }\n return { min: mn, max: mx }\n }\n const A_ = box(a)\n const B_ = box(b)\n return world(so, [0, 1, 2].map((k) => (Math.max(A_.min[k] as number, B_.min[k] as number) + Math.min(A_.max[k] as number, B_.max[k] as number)) / 2) as V3)\n }\n const lost = (p: A): boolean => !p || p.status === 'broken' || p.status === 'ashes' || p.status === 'melted'\n // The state of a piece at an instant: world.snapshot(id) gives a copy (state() / part() are live views).\n const snap = (room: VegetationRoom, so: Spawned, pid: string): A => {\n const st = room.world.snapshot(so.objectId)\n const p = st && st.parts.filter((x: A) => x.id === pid)[0]\n if (!p) return null\n return { status: p.status, hp: p.hp, maxHp: p.maxHp, temperature: p.temperature, burning: p.burning, char: p.char || 0, fuel: p.fuel, holes: (p.holes || []).length, material: p.material }\n }\n const logCount = (room: VegetationRoom, so: Spawned, type: string): number => room.log.entries({ type, objectId: so.objectId }).length\n // Joints opened in the log: 'detach' lines (one per joint, or several in one) plus those the 'fracture' event sums up in jointsOpened.\n const jointsOpened = (room: VegetationRoom, so: Spawned): number => {\n let n = 0\n for (const e of room.log.entries({ type: 'detach', objectId: so.objectId })) n += e.data && e.data.joints ? e.data.joints.length : 1\n for (const e of room.log.entries({ type: 'fracture', objectId: so.objectId })) n += (e.data && e.data.jointsOpened) || 0\n return n\n }\n const detachedJoint = (room: VegetationRoom, so: Spawned, jid: string): boolean =>\n room.log.entries({ type: 'detach', objectId: so.objectId }).some((e: A) => e.data && (e.data.joint === jid || (e.data.joints || []).indexOf(jid) >= 0))\n const spawn = (room: VegetationRoom, id: string, x: number, z: number): Spawned => room.spawn(id, [x, 0, z], 0)\n // When a group comes loose, the world moves it to a new object (`obj_N`). `home` is the original object, `loose` the ones that came off.\n const split = (room: VegetationRoom, so: Spawned): A => {\n const home = room.world.snapshot(so.objectId)\n const loose = room.world.ids().filter((i) => /^obj_/.test(i)).map((i) => ({ id: i, st: room.world.snapshot(i) }))\n const anchored: Record<string, boolean> = {}\n for (const p of specOf(so).parts) if (p.anchored) anchored[p.id] = true\n const rooted: string[] = []\n for (const g of home.groups as string[][]) if (g.some((pid) => anchored[pid])) for (const pid of g) rooted.push(pid)\n const inLoose = (pid: string): boolean => loose.some((o) => o.st.parts.some((p: A) => p.id === pid && !lost(p)))\n const inHome = (pid: string): boolean => home.parts.some((p: A) => p.id === pid && !lost(p))\n return { home, loose, rooted, inLoose, inHome, sections: home.groups.length + loose.length }\n }\n\n // Axe on the trunk until it breaks (at most `max` swings); gives the count and the state of the trunk.\n const fell = (room: VegetationRoom, ctx: VegetationContext, so: Spawned, max: number): { swings: number; trunk: A } => {\n take(room, 'axe')\n let swings = 0\n const h = partSpec(so, 'trunk').shape.height\n for (let i = 0; i < max; i++) {\n aimPart(room, so, 'trunk', 0.5, [0, Math.min(0.9, h / 3), 0])\n room.use()\n ctx.step(1.5)\n swings++\n if (lost(room.world.part(so.objectId, 'trunk'))) break\n }\n ctx.step(5)\n return { swings, trunk: snap(room, so, 'trunk') }\n }\n\n const sc = (id: string, ptName: string, enName: string, run: (ctx: VegetationContext) => void): ModuleScenario<VegetationContext> => ({ id: `veg_${id}`, name: L(ptName, enName), run })\n const pct = (x: number): string => `${Math.round((x || 0) * 100)}%`\n // the room gives every tool its draw time; the page's room used the tool the moment it was taken\n const take = (room: VegetationRoom, id: string): void => {\n room.setTool(id)\n room.waitUntilReady()\n }\n\n return [\n // 1 ---------------------------------------------------------------------------------------------------------------\n sc('axe_fells_crown', 'Machado no tronco de 15 cm derruba a copa (8 a 15 golpes)', 'Axe on a 15 cm trunk fells the crown (8 to 15 swings)', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_young_15', 0, -6)\n const r = fell(room, ctx, so, 60)\n const sp = split(room, so)\n const crownGone = lost(room.world.part(so.objectId, 'crown')) || !sp.inHome('crown') || sp.rooted.indexOf('crown') < 0\n const branches: string[] = specOf(so).parts.filter((p: A) => p.tags.indexOf('branch') >= 0).map((p: A) => p.id)\n const branchesFree = branches.every((b) => sp.rooted.indexOf(b) < 0)\n const detach = jointsOpened(room, so)\n ctx.expect(r.trunk.status === 'broken' && r.swings >= 8 && r.swings <= 15, L(`Machado no tronco de 15 cm (hp ${Math.round(r.trunk.maxHp)}): tronco ${r.trunk.status} depois de ${r.swings} golpes (esperado: broken em 8 a 15 golpes)`, `Axe on a 15 cm trunk (hp ${Math.round(r.trunk.maxHp)}): trunk ${r.trunk.status} after ${r.swings} swings (expected: broken in 8 to 15 swings)`), { swings: r.swings, status: r.trunk.status, maxHp: r.trunk.maxHp })\n ctx.expect(sp.rooted.length === 0 && crownGone && branchesFree, L(`Nada da copa continua preso ao chão: peças ainda enraizadas ${sp.rooted.length}, copa solta ${yn(crownGone)}, ${branches.length} galhos soltos ${yn(branchesFree)} (esperado: 0, sim, sim)`, `Nothing of the crown stays rooted: rooted pieces ${sp.rooted.length}, crown free ${yn(crownGone)}, ${branches.length} branches free ${yn(branchesFree)} (expected: 0, yes, yes)`), { rooted: sp.rooted.length })\n ctx.expect(detach > 0 && sp.loose.length > 0, L(`Registro: ${detach} soltura(s) de junta (as juntas se abrem quando o tronco se perde) e ${sp.loose.length} pedaço(s) caindo como objeto próprio (esperado: 1 ou mais de cada)`, `Log: ${detach} joint detach(es) (joints open when the trunk is lost) and ${sp.loose.length} piece(s) falling as their own object (expected: 1+ each)`), { detach, loose: sp.loose.length })\n }),\n sc('axe_fells_30cm', 'Machado no tronco de 30 cm (25 a 40 golpes)', 'Axe on a 30 cm trunk (25 to 40 swings)', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_young_30', 0, -6)\n const r = fell(room, ctx, so, 90)\n const sp = split(room, so)\n ctx.expect(r.trunk.status === 'broken' && r.swings >= 25 && r.swings <= 40, L(`Machado no tronco de 30 cm (hp ${Math.round(r.trunk.maxHp)}): tronco ${r.trunk.status} depois de ${r.swings} golpes (esperado: broken em 25 a 40 golpes)`, `Axe on a 30 cm trunk (hp ${Math.round(r.trunk.maxHp)}): trunk ${r.trunk.status} after ${r.swings} swings (expected: broken in 25 to 40 swings)`), { swings: r.swings, status: r.trunk.status, maxHp: r.trunk.maxHp })\n ctx.expect(sp.rooted.length === 0, L(`Árvore caída: peças ainda presas ao chão ${sp.rooted.length} (esperado: 0)`, `Fallen tree: pieces still rooted ${sp.rooted.length} (expected: 0)`), { rooted: sp.rooted.length })\n }),\n sc('axe_cuts_branch_joint', 'Machado passa pela junta tronco-galho', 'Axe works through the trunk-branch joint', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_tree', 0, -6)\n const jid = 'trunk~branch1'\n take(room, 'axe')\n let swings = 0\n let detached = false\n for (let i = 0; i < 60 && !detached; i++) {\n aim(room, so, jointPos(so, jid), 0.5, { joint: jid, beyond: 0.3 })\n room.use()\n ctx.step(1.5)\n swings++\n detached = detachedJoint(room, so, jid)\n }\n ctx.step(3)\n const trunk = snap(room, so, 'trunk')\n const sp = split(room, so)\n const branchOff = sp.inLoose('branch1') && !sp.inHome('branch1')\n const restStays = sp.inHome('trunk') && sp.rooted.indexOf('trunk') >= 0\n ctx.expect(detached && branchOff, L(`Machado na junta ${jid}: galho solto ${yn(branchOff)} depois de ${swings} golpe(s), com o tronco ${trunk.status} (esperado: sim)`, `Axe on joint ${jid}: branch detached ${yn(branchOff)} after ${swings} swing(s), trunk ${trunk.status} (expected: yes)`), { swings })\n ctx.expect(trunk.status !== 'broken' && restStays, L(`A junta cedeu antes do tronco: tronco ${trunk.status}, tronco de pé e preso ao chão ${yn(restStays)} (esperado: não quebrado, sim)`, `The joint gave way before the trunk: trunk ${trunk.status}, trunk standing and rooted ${yn(restStays)} (expected: not broken, yes)`), {})\n }),\n sc('shot_cannot_fell', 'Tiro de 9 mm não derruba a árvore', 'A 9 mm shot never fells a tree', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_young_15', 0, -6)\n take(room, 'pistol_9mm')\n let shots = 0\n for (let i = 0; i < 30; i++) {\n aimPart(room, so, 'trunk', 2.5, [0, 0.5, 0])\n room.use()\n ctx.step(0.4)\n shots++\n }\n const trunk = snap(room, so, 'trunk')\n const sp = split(room, so)\n ctx.expect(trunk.status !== 'broken' && trunk.hp > 0, L(`${shots} tiros de 9 mm no tronco de 15 cm: tronco ${trunk.status}, hp ${Math.round(trunk.hp)}/${Math.round(trunk.maxHp)} (esperado: não quebrado)`, `${shots} 9 mm shots on the 15 cm trunk: trunk ${trunk.status}, hp ${Math.round(trunk.hp)}/${Math.round(trunk.maxHp)} (expected: not broken)`), { shots, hp: trunk.hp })\n ctx.expect(sp.loose.length === 0 && sp.inHome('trunk') && sp.rooted.indexOf('crown') >= 0, L(`A árvore continua de pé: pedaços soltos ${sp.loose.length}, copa presa ao chão ${yn(sp.rooted.indexOf('crown') >= 0)} (esperado: 0, sim)`, `The tree still stands: loose pieces ${sp.loose.length}, crown rooted ${yn(sp.rooted.indexOf('crown') >= 0)} (expected: 0, yes)`), {})\n }),\n // 2 ---------------------------------------------------------------------------------------------------------------\n sc('saw_cuts_branch', 'Serra no galho', 'Saw on a branch', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'yellow_ipe', 0, -6)\n const jid = 'trunk~branch1'\n take(room, 'hacksaw')\n aim(room, so, jointPos(so, jid), 0.45, { joint: jid })\n room.use(4)\n ctx.step(1)\n const sp = split(room, so)\n const movedBranch = sp.inLoose('branch1') && !sp.inHome('branch1')\n const movedCrown = sp.inLoose('crown1')\n const restStays = ['trunk', 'branch0', 'branch2', 'branch3', 'crown'].every((pid) => sp.inHome(pid) && sp.rooted.indexOf(pid) >= 0)\n const detach = logCount(room, so, 'detach')\n ctx.expect(movedBranch && detach > 0, L(`Serra na junta tronco-galho 1: galho solto do tronco ${yn(movedBranch)}, ${detach} linha(s) de soltura no log (esperado: sim, 1)`, `Saw on the trunk-branch 1 joint: branch detached ${yn(movedBranch)}, ${detach} detach line(s) in the log (expected: yes, 1)`), { detach })\n ctx.expect(movedCrown, L(`A folhagem do galho cortado foi junto: ${yn(movedCrown)} (esperado: sim)`, `The foliage of the cut branch went with it: ${yn(movedCrown)} (expected: yes)`), {})\n ctx.expect(restStays, L(`O resto da árvore (tronco, outros galhos e copa) continua inteiro e preso ao chão: ${yn(restStays)} (esperado: sim)`, `The rest of the tree (trunk, other branches, crown) stays whole and rooted: ${yn(restStays)} (expected: yes)`), {})\n }),\n // 3 ---------------------------------------------------------------------------------------------------------------\n sc('lighter_ignites_foliage', 'Isqueiro na folhagem pega fogo', 'Lighter on the foliage catches fire', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_tree', 0, -6)\n take(room, 'lighter')\n const a = aimPart(room, so, crownsOf(so), 0.08)\n room.use(6)\n const crown = snap(room, so, a.pid)\n const lit = crown.burning || crown.temperature > 300\n let peak = 0\n let charMax = 0\n for (let t = 0; t < 18; t++) {\n ctx.step(5)\n for (const p of room.world.state(so.objectId).parts) {\n if (p.material === 'green_wood') {\n peak = Math.max(peak, p.temperature)\n charMax = Math.max(charMax, p.char || 0)\n }\n }\n }\n const st = room.world.state(so.objectId)\n const burnt = st.parts.filter((p: A) => p.material === 'foliage' && (p.burning || p.char > 0 || p.status === 'ashes')).length\n ctx.expect(lit, L(`Isqueiro na copa: folhagem acesa ou acima de 300 °C = ${yn(lit)} (${Math.round(crown.temperature)} °C; esperado: sim)`, `Lighter on the crown: foliage lit or above 300 C = ${yn(lit)} (${Math.round(crown.temperature)} C; expected: yes)`), { temperature: crown.temperature })\n ctx.expect(burnt > 0, L(`Depois de 90 s: ${burnt} peça(s) de folhagem queimando, carbonizada(s) ou em cinza (esperado: 1 ou mais)`, `After 90 s: ${burnt} foliage piece(s) burning, charred or ash (expected: 1+)`), { burnt })\n ctx.expect(peak > 150 || charMax > 0, L(`O fogo da folhagem passa para a madeira verde (tronco e galhos): pico de ${Math.round(peak)} °C, carbonização máxima ${pct(charMax)} (esperado: pico acima de 150 °C ou carbonização acima de 0; a madeira verde só pega fogo acima de 400 °C)`, `Foliage fire reaches the green wood (trunk and branches): peak ${Math.round(peak)} C, max char ${pct(charMax)} (expected: peak above 150 C or char above 0; green wood only ignites above 400 C)`), { peak, charMax })\n }),\n // 4 ---------------------------------------------------------------------------------------------------------------\n sc('shot_strips_leaves', 'Tiro na copa arranca folhas', 'A shot into the crown strips leaves', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mango_tree', 0, -6)\n take(room, 'pistol_9mm')\n const tgt = aimPart(room, so, crownsOf(so), 2.5).pid\n const before = snap(room, so, tgt)\n for (let i = 0; i < 3; i++) {\n aimPart(room, so, tgt, 2.5)\n room.use()\n ctx.step(0.6)\n }\n const crown = snap(room, so, tgt)\n const leaves = room.log.entries({ type: 'debris', objectId: so.objectId }).filter((e: A) => e.data && e.data.kind === 'leaves').length\n const hurt = crown.hp < before.hp || crown.status === 'broken'\n ctx.expect(hurt && crown.status !== 'intact', L(`Três tiros na copa: hp ${Math.round(before.hp)} para ${Math.round(crown.hp)}, estado ${crown.status} (esperado: hp menor, não intacta)`, `Three shots into the crown: hp ${Math.round(before.hp)} to ${Math.round(crown.hp)}, status ${crown.status} (expected: lower hp, not intact)`), { hp: crown.hp })\n ctx.expect(leaves > 0 || crown.holes > 0, L(`Folhas arrancadas: ${leaves} linha(s) de folhas voando, ${crown.holes} furo(s) na copa (esperado: 1 ou mais)`, `Leaves torn off: ${leaves} flying-leaf line(s), ${crown.holes} hole(s) in the crown (expected: 1+)`), { leaves, holes: crown.holes })\n }),\n // 5 ---------------------------------------------------------------------------------------------------------------\n sc('shot_breaks_pot', 'Tiros quebram o vaso e a terra se espalha', 'Shots break the pot and the soil spills', (ctx) => {\n const room = ctx.room\n const so = room.spawn('potted_fern', [0, 0, -4], 0)\n take(room, 'pistol_9mm')\n // terracotta pot with an explicit hp of 25: it breaks in 1 to 3 shots of 9 mm; the pot-soil joint bursts and the soil comes loose\n let shots = 0\n for (let i = 0; i < 12; i++) {\n const cur = snap(room, so, 'pot')\n if (!cur) break // the pot already left the original object\n aimPart(room, so, 'pot', 1.5)\n room.use()\n ctx.step(0.5)\n shots++\n const after = snap(room, so, 'pot')\n if (after && (after.status === 'broken' || after.hp <= 0)) break // broke\n }\n ctx.step(3)\n const sp = split(room, so)\n let potNow = snap(room, so, 'pot')\n for (const o of sp.loose) {\n const q = o.st.parts.filter((x: A) => x.id === 'pot')[0]\n if (q) potNow = q\n }\n const soilOut = sp.inLoose('soil') || !sp.inHome('soil')\n const soilApart = !sp.home.groups.some((g: string[]) => g.indexOf('soil') >= 0 && g.indexOf('pot') >= 0)\n const cracks = room.log.entries({ type: 'crack', objectId: so.objectId }).length\n const dt = jointsOpened(room, so)\n ctx.expect(!!potNow && (potNow.status === 'broken' || potNow.hp <= 0) && shots >= 1 && shots <= 4, L(`Tiros no vaso: o vaso quebra: cerâmica ${potNow && potNow.status} com hp ${potNow ? `${Math.round(potNow.hp)}/${Math.round(potNow.maxHp)}` : '?'} e ${cracks} trinca(s) depois de ${shots} tiro(s) de 9 mm (esperado: vaso quebrado em 1 a 4 tiros)`, `Shots into the pot: the pot breaks: ceramic ${potNow && potNow.status} with hp ${potNow ? `${Math.round(potNow.hp)}/${Math.round(potNow.maxHp)}` : '?'} and ${cracks} crack(s) after ${shots} 9 mm shot(s) (expected: pot broken in 1 to 4 shots)`), { status: potNow && potNow.status, shots, cracks })\n ctx.expect(soilApart || soilOut, L(`A terra saiu do vaso e caiu junto com a planta: ${yn(soilApart || soilOut)} (esperado: sim)`, `The soil left the pot and fell with the plant: ${yn(soilApart || soilOut)} (expected: yes)`), {})\n ctx.expect(dt > 0, L(`Registro: ${dt} soltura(s) de junta (esperado: 1 ou mais)`, `Log: ${dt} joint detach(es) (expected: 1+)`), { detach: dt })\n }),\n // 6 ---------------------------------------------------------------------------------------------------------------\n sc('machete_arm', 'Machete na junta do braço do mandacaru', 'Machete on the mandacaru arm joint', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'mandacaru', 0, -5)\n take(room, 'machete')\n const arm = 'arm0'\n const jid = `stem~${arm}`\n let swings = 0\n let detached = false\n for (let i = 0; i < 40 && !detached; i++) {\n aim(room, so, jointPos(so, jid), 0.55, { joint: jid, beyond: 0.3 })\n room.use()\n ctx.step(1.2)\n swings++\n detached = detachedJoint(room, so, jid) || lost(room.world.part(so.objectId, arm))\n }\n ctx.step(3)\n const a = snap(room, so, arm)\n const sp = split(room, so)\n const armOff = !a || a.status === 'broken' || (sp.inLoose(arm) && !sp.inHome(arm))\n const stemOk = sp.inHome('stem') && sp.rooted.indexOf('stem') >= 0 && room.world.part(so.objectId, 'stem').status !== 'broken'\n const spines = specOf(so).parts.filter((p: A) => p.tags.indexOf('thorns') >= 0)\n const thorny = so.root.userData.thorny === true && spines.length > 0\n const spinesOff = !sp.rooted.some((pid: string) => pid.indexOf(`${arm}_spines`) === 0)\n ctx.expect(armOff, L(`Machete na junta ${jid}: braço ${a ? a.status : 'solto como objeto próprio'} depois de ${swings} golpe(s) (esperado: solto do caule pela junta)`, `Machete on joint ${jid}: arm ${a ? a.status : 'loose as its own object'} after ${swings} swing(s) (expected: off the stem through the joint)`), { swings })\n ctx.expect(stemOk, L(`O caule principal continua de pé e preso ao chão: ${yn(stemOk)} (esperado: sim)`, `The main stem stays standing and rooted: ${yn(stemOk)} (expected: yes)`), {})\n ctx.expect(thorny && spinesOff, L(`Espinhos: cacto marcado como espinhoso (userData.thorny, ${spines.length} peças de espinho) ${yn(thorny)}, espinhos do braço saíram junto ${yn(spinesOff)} (esperado: sim, sim)`, `Thorns: cactus flagged thorny (userData.thorny, ${spines.length} spine pieces) ${yn(thorny)}, the arm spines went with it ${yn(spinesOff)} (expected: yes, yes)`), { spines: spines.length })\n }),\n // 7 ---------------------------------------------------------------------------------------------------------------\n sc('pad_pulled', 'Palma arrancada', 'Prickly pear pad pulled off', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'prickly_pear', 0, -4)\n const jid = 'pad0~pad1'\n take(room, 'utility_knife')\n aim(room, so, jointPos(so, jid), 0.25, { joint: jid, beyond: 0.3 })\n room.use(1.7)\n ctx.step(1)\n const sp = split(room, so)\n const padOff = sp.inLoose('pad1') && !sp.inHome('pad1')\n const childWith = sp.inLoose('pad3')\n const spinesWith = sp.inLoose('pad1_spines')\n const motherOk = sp.inHome('pad0') && sp.rooted.indexOf('pad0') >= 0 && sp.inHome('pad2')\n ctx.expect(padOff, L(`Raquete 1 cortada da planta-mãe na junta ${jid}: ${yn(padOff)} (esperado: sim)`, `Pad 1 cut off the mother plant at joint ${jid}: ${yn(padOff)} (expected: yes)`), {})\n ctx.expect(childWith && spinesWith, L(`A raquete filha (3) e os espinhos da raquete 1 vão junto: ${yn(childWith && spinesWith)} (esperado: sim)`, `The child pad (3) and the spines of pad 1 go with it: ${yn(childWith && spinesWith)} (expected: yes)`), {})\n ctx.expect(motherOk, L(`A planta-mãe (raquetes 0 e 2) fica presa ao chão: ${yn(motherOk)} (esperado: sim)`, `The mother plant (pads 0 and 2) stays rooted: ${yn(motherOk)} (expected: yes)`), {})\n }),\n // 8 ---------------------------------------------------------------------------------------------------------------\n sc('dead_burns_faster', 'Árvore morta queima mais rápido que viva', 'A dead tree burns faster than a living one', (ctx) => {\n const room = ctx.room\n const dead = spawn(room, 'dead_tree', -4, -6)\n const live = spawn(room, 'mango_tree', 4, -6)\n take(room, 'lighter')\n for (const so of [dead, live]) {\n aimPart(room, so, 'trunk', 0.08, [0, 0.8, 0])\n room.use(8)\n }\n const d0 = snap(room, dead, 'trunk')\n const l0 = snap(room, live, 'trunk')\n ctx.step(120)\n const d = snap(room, dead, 'trunk')\n const l = snap(room, live, 'trunk')\n const score = (p: A): number => (p ? Math.max(p.char, p.burning ? 0.01 : 0, (p.temperature - 20) / 2000) : 0)\n ctx.expect(d0.material === 'wood_soft' && l0.material === 'green_wood', L(`Materiais do tronco: árvore morta ${d0.material}, viva ${l0.material} (esperado: wood_soft, green_wood)`, `Trunk materials: dead tree ${d0.material}, living ${l0.material} (expected: wood_soft, green_wood)`), { dead: d0.material, live: l0.material })\n ctx.expect(score(d) > score(l), L(`Depois de 8 s de isqueiro e 120 s de espera: morta queimando ${yn(d.burning)}, ${Math.round(d.temperature)} °C, carbonização ${pct(d.char)}; viva queimando ${yn(l.burning)}, ${Math.round(l.temperature)} °C, carbonização ${pct(l.char)} (esperado: a morta mais queimada)`, `After 8 s of lighter and 120 s of waiting: dead burning ${yn(d.burning)}, ${Math.round(d.temperature)} C, char ${pct(d.char)}; living burning ${yn(l.burning)}, ${Math.round(l.temperature)} C, char ${pct(l.char)} (expected: dead burns more)`), { dead: score(d), live: score(l) })\n }),\n // 9 ---------------------------------------------------------------------------------------------------------------\n sc('hedge_cut_pieces', 'Cerca viva cortada em partes', 'Hedge cut into sections', (ctx) => {\n const room = ctx.room\n const so = spawn(room, 'boxwood_hedge', 0, -5)\n take(room, 'hacksaw')\n for (const jid of ['s0_stem~s1_stem', 's2_stem~s3_stem']) {\n aim(room, so, jointPos(so, jid), 0.45, { joint: jid })\n room.use(1.7)\n ctx.step(0.3)\n }\n ctx.step(1)\n const sp = split(room, so)\n const all: A[] = [...sp.home.parts]\n for (const o of sp.loose) all.push(...o.st.parts)\n const alive = all.filter((p) => !lost(p)).length\n const total = specOf(so).parts.length\n ctx.expect(sp.sections === 3, L(`Duas serradas na cerca viva: ${sp.sections} parte(s) separada(s) (esperado: 3)`, `Two saw cuts in the hedge: ${sp.sections} separate section(s) (expected: 3)`), { sections: sp.sections })\n ctx.expect(alive === total, L(`Nenhuma seção foi destruída, só separada: ${alive} de ${total} peças inteiras (esperado: todas)`, `No section was destroyed, only separated: ${alive} of ${total} pieces intact (expected: all)`), { alive, total })\n }),\n // 10 --------------------------------------------------------------------------------------------------------------\n sc('walk_on_grass', 'Pisar na grama não colide', 'Walking on grass does not collide', (ctx) => {\n const room = ctx.room\n const tuft = spawn(room, 'lawn_tuft', 0, -3)\n const tree = spawn(room, 'mango_tree', 4, -3)\n const noBlock = !tuft.root.userData.collider\n const treeBlock = !!(tree.root.userData.collider && tree.root.userData.collider.kind)\n ctx.expect(noBlock && treeBlock, L(`Colisor do SDK: touceira ${noBlock ? 'nenhum' : 'tem'}, tronco da mangueira ${treeBlock ? 'tem' : 'nenhum'} (esperado: nenhum, tem)`, `SDK collider: tuft ${noBlock ? 'none' : 'has one'}, mango trunk ${treeBlock ? 'has one' : 'none'} (expected: none, has one)`), {})\n // really walks: room.walk(to, seconds) moves the player through the room's own loop (ctx.step advances the simulation, with no host loop)\n room.look([0, 1.7, -0.5], [0, 1.7, -6])\n const before = room.camera.position.z\n room.walk([0, 1.7, -6], 3)\n ctx.step(3.2)\n const after = room.camera.position.z\n const tp = snap(room, tuft, 'stem')\n ctx.expect(after < -3.3 && !!tp && tp.status === 'intact', L(`Andando para a frente (room.walk): z foi de ${before.toFixed(1)} a ${after.toFixed(1)}, atravessou a touceira ${yn(after < -3.3)}, touceira ${tp && tp.status} (esperado: atravessou, intacta)`, `Walking forward (room.walk): z went from ${before.toFixed(1)} to ${after.toFixed(1)}, crossed the tuft ${yn(after < -3.3)}, tuft ${tp && tp.status} (expected: crossed, intact)`), { before, after })\n }),\n ]\n}\n","/** Words of the vegetation area's bench. */\nexport type VegetationText = {\n group: string\n name: string\n controls: Record<'seed' | 'quality' | 'lod' | 'condition' | 'season' | 'wind' | 'gust', string>\n hints: Record<'seed' | 'quality' | 'lod' | 'condition' | 'season' | 'wind' | 'gust', string>\n options: { quality: Record<string, string>; lod: Record<string, string>; condition: Record<string, string>; season: Record<string, string> }\n actions: Record<'plant_lot' | 'clear_lot' | 'toggle_walker', string>\n layers: Record<'colliders' | 'piece_boxes' | 'wood_axes', string>\n metrics: Record<'plants' | 'pieces' | 'triangles' | 'draw_calls' | 'lot_triangles' | 'lot_plants' | 'lot_colliders' | 'lot_lod0' | 'lot_lod1' | 'lot_lod2' | 'lot_ms', string>\n lot: Record<'planted' | 'cleared' | 'walker_on' | 'walker_off', string>\n}\n\nexport const TEXT: Record<string, VegetationText> = {\n en: {\n group: 'Trees, plants and flowers',\n name: 'Vegetation',\n controls: { seed: 'Lot seed', quality: 'Lot quality', lod: 'Lot detail (LOD)', condition: 'Condition', season: 'Season', wind: 'Wind', gust: 'Gusts' },\n hints: {\n seed: 'The seed of the nursery lot: the same seed plants the same yard',\n quality: 'High: every plant at the detail below. Game: one level for all plants and small ones cheaper, with a triangle budget',\n lod: 'Level of detail of the plants of the lot (0 the most detailed)',\n condition: 'How the lot plants look: healthy, dry, dead or overgrown (decides green or dry wood for the destruction)',\n season: 'Season of the lot (flowers and leaf colours)',\n wind: 'Strength of the wind that sways the leaves, flowers and grass',\n gust: 'Slowly varying extra push on top of the wind',\n },\n options: {\n quality: { high: 'High', game: 'Game' },\n lod: { '0': 'LOD 0', '1': 'LOD 1', '2': 'LOD 2' },\n condition: { healthy: 'Healthy', dry: 'Dry', dead: 'Dead', overgrown: 'Overgrown' },\n season: { spring: 'Spring', summer: 'Summer', autumn: 'Autumn', winter: 'Winter' },\n },\n actions: { plant_lot: 'Plant the nursery lot', clear_lot: 'Remove the nursery lot', toggle_walker: 'Start or stop the walker' },\n layers: { colliders: 'Colliders (trunks and cactus bodies)', piece_boxes: 'Boxes of the pieces', wood_axes: 'Wood axes (radius, length, axis)' },\n metrics: { plants: 'Plants placed', pieces: 'Pieces', triangles: 'Triangles', draw_calls: 'Draw calls', lot_triangles: 'Lot triangles', lot_plants: 'Lot plants', lot_colliders: 'Lot colliders', lot_lod0: 'Lot plants at LOD 0', lot_lod1: 'Lot plants at LOD 1', lot_lod2: 'Lot plants at LOD 2', lot_ms: 'Lot build time' },\n lot: { planted: 'Nursery lot planted: {0} plants, {1} triangles, {2} colliders', cleared: 'Nursery lot removed', walker_on: 'The walker crosses the lot and bends the plants', walker_off: 'The walker stopped' },\n },\n 'pt-BR': {\n group: 'Árvores, plantas e flores',\n name: 'Vegetação',\n controls: { seed: 'Semente do canteiro', quality: 'Qualidade do canteiro', lod: 'Detalhe do canteiro (LOD)', condition: 'Condição', season: 'Estação', wind: 'Vento', gust: 'Rajadas' },\n hints: {\n seed: 'A semente do canteiro: a mesma semente planta o mesmo quintal',\n quality: 'Alta: todas as plantas no detalhe abaixo. Jogo: um nível para todas e as pequenas mais baratas, com orçamento de triângulos',\n lod: 'Nível de detalhe das plantas do canteiro (0 o mais detalhado)',\n condition: 'Como ficam as plantas do canteiro: saudável, seca, morta ou malcuidada (decide madeira verde ou seca na destruição)',\n season: 'Estação do canteiro (flores e cor das folhas)',\n wind: 'Força do vento que balança folhas, flores e grama',\n gust: 'Empurrão extra que varia devagar, somado ao vento',\n },\n options: {\n quality: { high: 'Alta', game: 'Jogo' },\n lod: { '0': 'LOD 0', '1': 'LOD 1', '2': 'LOD 2' },\n condition: { healthy: 'Saudável', dry: 'Seca', dead: 'Morta', overgrown: 'Malcuidada' },\n season: { spring: 'Primavera', summer: 'Verão', autumn: 'Outono', winter: 'Inverno' },\n },\n actions: { plant_lot: 'Plantar o canteiro', clear_lot: 'Tirar o canteiro', toggle_walker: 'Ligar ou desligar o caminhante' },\n layers: { colliders: 'Colisores (troncos e corpos de cacto)', piece_boxes: 'Caixas das peças', wood_axes: 'Eixos da madeira (raio, comprimento, eixo)' },\n metrics: { plants: 'Plantas postas', pieces: 'Peças', triangles: 'Triângulos', draw_calls: 'Chamadas de desenho', lot_triangles: 'Triângulos do canteiro', lot_plants: 'Plantas do canteiro', lot_colliders: 'Colisores do canteiro', lot_lod0: 'Plantas do canteiro em LOD 0', lot_lod1: 'Plantas do canteiro em LOD 1', lot_lod2: 'Plantas do canteiro em LOD 2', lot_ms: 'Tempo de montagem do canteiro' },\n lot: { planted: 'Canteiro plantado: {0} plantas, {1} triângulos, {2} colisores', cleared: 'Canteiro retirado', walker_on: 'O caminhante cruza o canteiro e dobra as plantas', walker_off: 'O caminhante parou' },\n },\n}\n\nexport const fill = (template: string, ...values: readonly unknown[]): string => template.replace(/\\{(\\d+)\\}/g, (_m, i: string) => String(values[Number(i)]))\n","import type { BenchChange, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ModuleScenario, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { shapeGeometries } from '@adatechnology/game-shapes-three'\nimport * as GameVegetationMain from '@adatechnology/game-vegetation'\nimport * as GameVegetationAdapter from '@adatechnology/game-vegetation/three'\nimport * as GameVegetationSpeciesMain from '@adatechnology/game-vegetation-species'\nimport type { Condition, Lod, Season } from '@adatechnology/game-vegetation'\n\nimport { createNursery } from './nursery'\nimport type { Nursery } from './nursery'\nimport { createPlants, PLANT_DEFS, PLANT_SEED } from './plants'\nimport type { PieceMeta } from './plants'\nimport { createScenarios } from './scenarios'\nimport { fill, TEXT } from './text'\nimport type { MaterialsLike, SpeciesSdk, VegetationContext, VegetationSdk, VegetationTestOptions } from './types'\n\nexport const VEGETATION_AREA_ID = 'vegetation'\n\n/** The 18 item ids of the Viveiro's module, in its order. */\nexport const VEGETATION_ITEM_IDS: readonly string[] = PLANT_DEFS.map((def) => def.id)\n\n/** The ids of the 13 scenarios (the ids of the Viveiro's page, `veg_*`). */\nexport const VEGETATION_SCENARIO_IDS: readonly string[] = [\n 'veg_axe_fells_crown',\n 'veg_axe_fells_30cm',\n 'veg_axe_cuts_branch_joint',\n 'veg_shot_cannot_fell',\n 'veg_saw_cuts_branch',\n 'veg_lighter_ignites_foliage',\n 'veg_shot_strips_leaves',\n 'veg_shot_breaks_pot',\n 'veg_machete_arm',\n 'veg_pad_pulled',\n 'veg_dead_burns_faster',\n 'veg_hedge_cut_pieces',\n 'veg_walk_on_grass',\n]\n\ntype Three = any\ntype Placed = { readonly root: any; helpers: any[] }\n\nconst defaultSdk = (): VegetationSdk => ({ ...GameVegetationMain, ...GameVegetationAdapter }) as VegetationSdk\nconst AXIS_COLOURS: Record<string, number> = { trunk: 0xd9822b, branch: 0xe5c07b, arm: 0x6fcf6f, stem: 0x6fcf97, pad: 0x6fb7cf }\n\n/**\n * The vegetation test area as a `TestableModule`: the 18 plants of the Viveiro (mango trees of three sizes, ipe, palm, banana, araucaria, dead tree, hibiscus, hedge, rose, sunflower, three\n * cacti, two pots, a lawn tuft) as items of the default destruction world, each piece a mesh with its spec (shape from the real wood thickness, joints, anchors, tags, sway clip), and the 13\n * scenarios of that page (literal). The bench plants the nursery lot (12 x 20 m, with house, walls and path, by `scatterRulesFor`) with its seed, quality, detail, condition and season, sets\n * the wind and starts the walker that bends the plants; its layers show the colliders, the boxes of the pieces and the axes of the wood; its metrics read triangles, pieces and draw calls.\n */\nexport function createVegetationTestModule(options: VegetationTestOptions = {}): TestableModule<VegetationContext> & { readonly placed: ReadonlyMap<string, unknown>; materials(THREE?: unknown): MaterialsLike; tick(t: number): void; readonly itemIds: readonly string[] } {\n const locale = options.locale ?? 'pt-BR'\n const text = TEXT[locale.toLowerCase().startsWith('en') ? 'en' : 'pt-BR'] as (typeof TEXT)[string]\n const sdk: VegetationSdk = options.GameVegetation ?? defaultSdk()\n const species: SpeciesSdk = options.GameVegetationSpecies ?? (GameVegetationSpeciesMain as SpeciesSdk)\n let mats: MaterialsLike | null = options.materials ?? null\n let three: Three = null\n let host: ModuleHost | null = null\n const materials = (THREE?: unknown): MaterialsLike => {\n if (!mats) mats = sdk.createVegetationMaterials((THREE ?? three) as never) as unknown as MaterialsLike\n return mats\n }\n const plants = createPlants(sdk, species, (THREE) => materials(THREE), options.seed ?? PLANT_SEED)\n const placed = new Map<string, Placed>()\n const settings = { seed: 1, quality: 'high' as 'high' | 'game', lod: 0 as Lod, condition: 'healthy' as Condition, season: 'spring' as Season, wind: 0.35, gust: 0.15 }\n let nursery: Nursery | null = null\n let clock = 0\n let helpersShown = ''\n\n const item = (base: TestableItem): TestableItem => ({\n ...base,\n build: (THREE: unknown) => {\n three = THREE\n const root = base.build(THREE) as any\n placed.set(root.uuid, { root, helpers: [] })\n return root\n },\n })\n\n // ---- the layers ---------------------------------------------------------------------------------------------------------------------------\n const clearHelpers = (): void => {\n for (const entry of placed.values()) {\n for (const helper of entry.helpers) helper.parent?.remove(helper)\n entry.helpers = []\n }\n helpersShown = ''\n }\n const boxKey = (): string => `${host?.bench?.layer('colliders')}|${host?.bench?.layer('piece_boxes')}|${host?.bench?.layer('wood_axes')}|${placed.size}`\n const refreshLayers = (): void => {\n if (!host?.bench || !three) return\n clearHelpers()\n nursery?.showColliders(host.bench.layer('colliders'))\n for (const entry of placed.values()) {\n const root = entry.root\n if (!root.parent) continue\n const mark = (helper: any): void => {\n helper.userData.helper = true\n root.add(helper)\n entry.helpers.push(helper)\n }\n if (host.bench.layer('colliders') && root.userData.collider && root.userData.collider.kind) {\n const c = root.userData.collider\n const wire = new three.Mesh(new (shapeGeometries(three) as any).CylinderGeometry(c.radius, c.radius, c.height, 14, 1, true), new three.MeshBasicMaterial({ color: root.userData.thorny ? 0xff7a1a : 0xe5251d, wireframe: true }))\n wire.position.set(0, c.height / 2, 0)\n mark(wire)\n }\n for (const mesh of root.children) {\n const v = mesh.userData?.veg as PieceMeta | undefined\n if (!v || !mesh.geometry) continue\n if (host.bench.layer('piece_boxes')) {\n mesh.geometry.computeBoundingBox()\n const box = mesh.geometry.boundingBox.clone().translate(mesh.position)\n mark(new three.Box3Helper(box, 0x66ccff))\n }\n if (host.bench.layer('wood_axes') && v.radius !== undefined && v.length !== undefined && v.axis && !v.sub) {\n // the base of the piece is in plant space; the section of a hedge stands `dx` to the side\n const base = pieceBase(root, v)\n if (base) {\n const from = new three.Vector3(base[0] + v.dx, base[1], base[2])\n const to = from.clone().add(new three.Vector3(v.axis[0], v.axis[1], v.axis[2]).multiplyScalar(v.length))\n const line = new three.Line(new three.BufferGeometry().setFromPoints([from, to]), new three.LineBasicMaterial({ color: AXIS_COLOURS[v.kind] ?? 0xffffff }))\n mark(line)\n }\n }\n }\n }\n helpersShown = boxKey()\n }\n // the `base` of a wood piece is recorded on the destruction part of its mesh by the SDK; the module keeps it in `userData.destructionPart` of the mesh\n const pieceBase = (root: any, v: PieceMeta): Vec3 | null => {\n const mesh = root.children.find((c: any) => c.userData?.veg?.id === v.id)\n const base = mesh?.userData?.destructionPart?.base\n return Array.isArray(base) ? (base as Vec3) : null\n }\n\n // ---- the nursery ----------------------------------------------------------------------------------------------------------------------------\n const nurseryOf = (): Nursery | null => {\n if (!host || !three) return null\n if (!nursery) nursery = createNursery(sdk, species, three, materials(three), host.scene, options.nurseryOrigin ?? [-6, 14])\n return nursery\n }\n const plantLot = (): void => {\n const n = nurseryOf()\n if (!n || !host) return\n const stats = n.plant(settings)\n n.showColliders(Boolean(host.bench?.layer('colliders')))\n host.log(fill(text.lot.planted, stats.plants, stats.triangles, stats.colliders), { plants: stats.plants, triangles: stats.triangles })\n }\n const replant = (): void => {\n if (nursery?.planted) plantLot()\n }\n\n // ---- the bench ---------------------------------------------------------------------------------------------------------------------------------\n const applyWind = (): void => {\n if (mats) mats.setWind({ strength: settings.wind, gust: settings.gust })\n }\n const onChange = (change: BenchChange): void => {\n if (change.kind === 'layer') return refreshLayers()\n if (change.kind === 'action') {\n if (change.id === 'plant_lot') plantLot()\n else if (change.id === 'clear_lot') {\n nursery?.clear()\n host?.log(text.lot.cleared)\n } else if (change.id === 'toggle_walker') {\n const n = nurseryOf()\n if (!n) return\n if (!n.planted) plantLot()\n n.setWalker(!n.walking)\n host?.log(n.walking ? text.lot.walker_on : text.lot.walker_off)\n }\n return\n }\n switch (change.id) {\n case 'seed': settings.seed = Number(change.value); replant(); break\n case 'quality': settings.quality = String(change.value) as 'high' | 'game'; replant(); break\n case 'lod': settings.lod = Number(change.value) as Lod; replant(); break\n case 'condition': settings.condition = String(change.value) as Condition; replant(); break\n case 'season': settings.season = String(change.value) as Season; replant(); break\n case 'wind': settings.wind = Number(change.value); applyWind(); break\n case 'gust': settings.gust = Number(change.value); applyWind(); break\n default: break\n }\n }\n\n const frame = (dt: number): void => {\n clock += dt\n if (mats) mats.update(clock)\n for (const [id, entry] of placed) if (!entry.root.parent) placed.delete(id)\n if (host?.bench && boxKey() !== helpersShown && (host.bench.layer('colliders') || host.bench.layer('piece_boxes') || host.bench.layer('wood_axes') || helpersShown !== '')) refreshLayers()\n nursery?.step(dt)\n }\n\n const count = (): { drawCalls: number; triangles: number; pieces: number } => {\n let drawCalls = 0\n let triangles = 0\n let pieces = 0\n for (const entry of placed.values()) {\n entry.root.traverse((mesh: any) => {\n if (!mesh.isMesh || mesh.userData.helper) return\n for (let p = mesh; p; p = p.parent) if (p.visible === false) return\n drawCalls += 1\n if (mesh.userData.veg) pieces += 1\n const g = mesh.geometry\n triangles += (g.index ? g.index.count : g.attributes.position.count) / 3\n })\n }\n return { drawCalls, triangles: Math.round(triangles), pieces }\n }\n const lotCalls = (): number => {\n let calls = 0\n nursery?.group.traverse((o: any) => {\n if (o.isMesh && o.visible) calls += 1\n })\n return calls\n }\n\n return {\n id: VEGETATION_AREA_ID,\n name: text.name,\n group: text.group,\n get placed() {\n return placed\n },\n itemIds: VEGETATION_ITEM_IDS,\n materials,\n tick: (t: number) => {\n if (mats) mats.update(t)\n },\n items: (loc: string) => plants.items(loc || locale).map(item),\n scenarios: (loc: string): ModuleScenario<VegetationContext>[] => createScenarios(loc || locale),\n area: (): ModuleArea => {\n // three rows by size, each plant given room by its width: the small ones in front, the middle ones behind them, the trees at the back\n const rows: { z: number; ids: readonly string[] }[] = [\n { z: -4, ids: ['hibiscus_shrub', 'rose_bush_red', 'sunflower', 'mandacaru', 'prickly_pear', 'crown_cactus'] },\n { z: -9, ids: ['banana_with_bunch', 'dead_tree', 'boxwood_hedge', 'potted_fern', 'potted_cactus', 'lawn_tuft'] },\n { z: -16, ids: ['mango_tree', 'yellow_ipe', 'coconut_palm', 'araucaria', 'mango_young_30', 'mango_young_15'] },\n ]\n const widths: Record<string, number> = { mango_tree: 5, yellow_ipe: 5, coconut_palm: 4.5, araucaria: 4, mango_young_30: 3, mango_young_15: 2.6, banana_with_bunch: 3.5, dead_tree: 3.5, boxwood_hedge: 5.5, hibiscus_shrub: 2, rose_bush_red: 1.6, sunflower: 1.4, mandacaru: 2.2, prickly_pear: 2, crown_cactus: 1.8, potted_fern: 1.4, potted_cactus: 1.2, lawn_tuft: 1.2 }\n const gap = 1.2\n const placements = rows.flatMap((row) => {\n const total = row.ids.reduce((sum, id) => sum + (widths[id] ?? 2) + gap, -gap)\n let cursor = -total / 2\n return row.ids.map((id) => {\n const width = widths[id] ?? 2\n const x = cursor + width / 2\n cursor += width + gap\n return { item: id, position: [x, 0, row.z] as Vec3, rotationY: 0 }\n })\n })\n return { placements, view: { eye: [0, 6, 8], target: [0, 1.8, -10] } }\n },\n controls: (): ModuleControl[] => [\n { kind: 'number', id: 'seed', name: text.controls.seed, hint: text.hints.seed, min: 0, max: 99999, step: 1, default: 1 },\n { kind: 'choice', id: 'quality', name: text.controls.quality, hint: text.hints.quality, options: (['high', 'game'] as const).map((id) => ({ id, name: text.options.quality[id] as string })), default: 'high' },\n { kind: 'choice', id: 'lod', name: text.controls.lod, hint: text.hints.lod, options: (['0', '1', '2'] as const).map((id) => ({ id, name: text.options.lod[id] as string })), default: '0' },\n { kind: 'choice', id: 'condition', name: text.controls.condition, hint: text.hints.condition, options: (['healthy', 'dry', 'dead', 'overgrown'] as const).map((id) => ({ id, name: text.options.condition[id] as string })), default: 'healthy' },\n { kind: 'choice', id: 'season', name: text.controls.season, hint: text.hints.season, options: (['spring', 'summer', 'autumn', 'winter'] as const).map((id) => ({ id, name: text.options.season[id] as string })), default: 'spring' },\n { kind: 'number', id: 'wind', name: text.controls.wind, hint: text.hints.wind, min: 0, max: 1, step: 0.05, default: 0.35 },\n { kind: 'number', id: 'gust', name: text.controls.gust, hint: text.hints.gust, min: 0, max: 1, step: 0.05, default: 0.15 },\n { kind: 'action', id: 'plant_lot', name: text.actions.plant_lot, slow: true },\n { kind: 'action', id: 'clear_lot', name: text.actions.clear_lot },\n { kind: 'action', id: 'toggle_walker', name: text.actions.toggle_walker, slow: true },\n ],\n layers: (): ModuleLayer[] => (['colliders', 'piece_boxes', 'wood_axes'] as const).map((id) => ({ id, name: text.layers[id], default: false })),\n metrics: (): ModuleMetric[] => [\n { id: 'plants', name: text.metrics.plants, read: () => placed.size },\n { id: 'pieces', name: text.metrics.pieces, read: () => count().pieces },\n { id: 'triangles', name: text.metrics.triangles, read: () => count().triangles },\n { id: 'draw_calls', name: text.metrics.draw_calls, read: () => count().drawCalls + lotCalls() },\n { id: 'lot_triangles', name: text.metrics.lot_triangles, read: () => nursery?.stats?.triangles ?? 0 },\n { id: 'lot_plants', name: text.metrics.lot_plants, read: () => nursery?.stats?.plants ?? 0 },\n { id: 'lot_colliders', name: text.metrics.lot_colliders, read: () => nursery?.stats?.colliders ?? 0 },\n { id: 'lot_lod0', name: text.metrics.lot_lod0, read: () => nursery?.stats?.lod[0] ?? 0 },\n { id: 'lot_lod1', name: text.metrics.lot_lod1, read: () => nursery?.stats?.lod[1] ?? 0 },\n { id: 'lot_lod2', name: text.metrics.lot_lod2, read: () => nursery?.stats?.lod[2] ?? 0 },\n { id: 'lot_ms', name: text.metrics.lot_ms, unit: 'ms', read: () => nursery?.stats?.buildMs ?? 0 },\n ],\n attach(lent) {\n host = lent\n three = lent.THREE\n const stopChange = lent.bench?.onChange(onChange)\n const stopFrame = lent.onFrame(frame)\n applyWind()\n return () => {\n stopChange?.()\n stopFrame()\n clearHelpers()\n nursery?.clear()\n nursery = null\n host = null\n }\n },\n }\n}\n\n/** What `loadVegetationTestModule` needs of a room: `TestRoom.loadModule` has it. */\nexport type ModuleRoomLike = { loadModule(module: never): unknown }\n\n/** Loads the vegetation module into a room. */\nexport function loadVegetationTestModule<Room extends ModuleRoomLike>(room: Room, options: VegetationTestOptions = {}): ReturnType<Room['loadModule']> {\n return room.loadModule(createVegetationTestModule(options) as never) as ReturnType<Room['loadModule']>\n}\n"],"mappings":"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,KAAK,EAAE,CAAC,EAAE,SAAS;AACxE,WAAO;EACT;;;;;;;;;;;;;;;;;;AClNA,MAAA,gBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,cAAgB;QAChB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;QACd,eAAiB;MAClB;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,SAAW;YACV;YACA;UACD;UACA,gBAAkB;UAClB,SAAW;QACZ;QACA,YAAc;QACd,WAAa;MACd;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,SAAW;YACV;YACA;UACD;UACA,gBAAkB;UAClB,SAAW;QACZ;QACA,YAAc;QACd,WAAa;MACd;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,cAAgB;QAChB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;UACV,SAAW;QACZ;QACA,YAAc;QACd,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,SAAW;YACV;YACA;UACD;UACA,gBAAkB;UAClB,SAAW;QACZ;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,cAAgB;QAChB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,OAAS;UACR,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,QAAU;QACX;QACA,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,SAAW;QACX,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;QACb,WAAa;UACZ;UACA;UACA;UACA;QACD;QACA,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;QACb,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,OAAS;QACT,aAAe;QACf,WAAa;QACb,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,OAAS;QACT,aAAe;QACf,WAAa;QACb,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,eAAiB;QACjB,WAAa;UACZ;UACA;UACA;QACD;QACA,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,aAAe;QACf,aAAe;MAChB;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AC7hBA,MAAA,gBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,aAAe;QACf,YAAc;QACd,aAAe;QACf,OAAS;UACR,OAAS;UACT,OAAS;UACT,QAAU;QACX;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,aAAe;QACf,YAAc;QACd,aAAe;MAChB;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,aAAe;QACf,YAAc;QACd,aAAe;MAChB;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,OAAS;QACT,aAAe;MAChB;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,QAAU;QACV,aAAe;QACf,OAAS;UACR,OAAS;UACT,OAAS;UACT,QAAU;QACX;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,WAAa;MACd;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,WAAa;QACb,OAAS;QACT,KAAO;MACR;MACA,MAAQ;QACP;QACA;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AChKA,MAAA,iBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,OAAS;QACT,WAAa;UACZ;QACD;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,OAAS;QACT,WAAa;UACZ;QACD;QACA,SAAW;UACV,QAAU;YACT;YACA;UACD;UACA,OAAS;UACT,OAAS;UACT,MAAQ;QACT;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,WAAa;UACZ;UACA;QACD;QACA,SAAW;UACV,QAAU;YACT;YACA;UACD;UACA,OAAS;UACT,OAAS;UACT,MAAQ;QACT;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,WAAa;UACZ;UACA;QACD;QACA,SAAW;UACV,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,OAAS;UACT,MAAQ;QACT;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,WAAa;UACZ;UACA;QACD;QACA,SAAW;UACV,QAAU;YACT;YACA;UACD;UACA,OAAS;UACT,OAAS;UACT,MAAQ;QACT;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,WAAa;UACZ;UACA;QACD;QACA,aAAe;UACd;UACA;UACA;UACA;QACD;QACA,UAAY;MACb;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,SAAW;QACX,OAAS;QACT,QAAU;QACV,aAAe;QACf,aAAe;QACf,YAAc;QACd,YAAc;QACd,MAAQ;MACT;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;MACX;MACA,MAAQ;QACP;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,QAAU;QACV,SAAW;QACX,WAAa;UACZ;UACA;UACA;QACD;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AChQA,MAAA,kBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;QACD;QACA,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;QACD;QACA,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;QACD;QACA,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;UACA;UACA;QACD;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;UACA;UACA;QACD;QACA,QAAU;QACV,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,WAAa;QACb,aAAe;UACd;QACD;QACA,QAAU;QACV,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,WAAa;QACb,aAAe;UACd;QACD;QACA,QAAU;QACV,WAAa;QACb,YAAc;MACf;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;UACA;UACA;QACD;QACA,QAAU;QACV,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;MACf;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,YAAc;QACd,aAAe;UACd;UACA;UACA;UACA;QACD;QACA,WAAa;QACb,QAAU;MACX;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AC/RA,MAAA,gBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,MAAQ;QACR,UAAY;QACZ,MAAQ;UACP;UACA;QACD;QACA,OAAS;QACT,YAAc;QACd,SAAW;UACV,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,MAAQ;QACR,UAAY;QACZ,MAAQ;QACR,OAAS;MACV;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,QAAU;QACV,MAAQ;QACR,UAAY;QACZ,MAAQ;UACP;UACA;QACD;QACA,OAAS;MACV;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;UACR,OAAS;UACT,OAAS;QACV;QACA,SAAW;UACV,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,QAAU;QACV,MAAQ;QACR,WAAa;UACZ,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,MAAQ;QACR,QAAU;QACV,SAAW;UACV,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,QAAU;QACV,QAAU;QACV,MAAQ;QACR,SAAW;UACV,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;ACvKA,MAAA,qBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;QACR,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;QACR,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;QACR,QAAU;QACV,OAAS;UACR,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;QACR,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AChFA,MAAA,kBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,OAAS;MACV;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,OAAS;QACT,WAAa;MACd;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,OAAS;QACT,QAAU;MACX;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,OAAS;QACT,QAAU;QACV,OAAS;QACT,eAAiB;QACjB,QAAU;MACX;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU,CAAC;MACX,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;UACV,OAAS;QACV;QACA,OAAS;UACR,WAAa;UACb,YAAc;UACd,aAAe;QAChB;MACD;MACA,MAAQ;QACP;QACA;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;ACpIA,MAAA,gBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;UACP,MAAQ;YACP,OAAS;YACT,QAAU;UACX;QACD;QACA,WAAa;QACb,SAAW;UACV,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;UACP,MAAQ;YACP,OAAS;YACT,QAAU;UACX;QACD;QACA,WAAa;QACb,UAAY;QACZ,SAAW;MACZ;MACA,MAAQ;QACP;MACD;MACA,SAAW;QACV;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,MAAQ;UACP,MAAQ;YACP,OAAS;YACT,QAAU;UACX;QACD;QACA,WAAa;QACb,UAAY;QACZ,SAAW;UACV,QAAU;YACT;YACA;YACA;UACD;UACA,OAAS;UACT,OAAS;QACV;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AC5FA,MAAA,iBAAA;IACC;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;QACX;QACA,OAAS;UACR,WAAa;UACb,YAAc;UACd,aAAe;QAChB;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;UACV,OAAS;QACV;QACA,OAAS;UACR,WAAa;UACb,MAAQ;UACR,QAAU;QACX;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;QACX;QACA,OAAS;UACR,WAAa;UACb,SAAW;UACX,QAAU;UACV,OAAS;UACT,aAAe;UACf,aAAe;QAChB;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;QACX;QACA,OAAS;UACR,WAAa;UACb,QAAU;UACV,QAAU;UACV,MAAQ;UACR,SAAW;YACV,OAAS;YACT,OAAS;UACV;QACD;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;QACX;QACA,OAAS;UACR,WAAa;UACb,YAAc;UACd,aAAe;YACd;UACD;UACA,QAAU;UACV,WAAa;QACd;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;IACA;MACC,IAAM;MACN,WAAa;MACb,QAAU;QACT,KAAO;UACN,OAAS;UACT,QAAU;UACV,QAAU;UACV,OAAS;QACV;QACA,OAAS;UACR,WAAa;UACb,MAAQ;UACR,QAAU;QACX;MACD;MACA,MAAQ;QACP;QACA;QACA;MACD;MACA,SAAW;QACV;QACA;QACA;QACA;MACD;MACA,MAAQ;MACR,OAAS;IACV;EACD;AC7LA,MAAA,gBAAA;IACC,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,QAAU;MACT,MAAQ;MACR,aAAe;IAChB;IACA,QAAU;MACT,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,qBAAuB;MACtB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,kBAAoB;MACnB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,kBAAoB;MACnB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,SAAW;MACV,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,SAAW;MACV,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,KAAO;MACN,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;EACD;AC7RA,MAAA,aAAA;IACC,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,YAAc;MACb,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,QAAU;MACT,MAAQ;MACR,aAAe;IAChB;IACA,QAAU;MACT,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,qBAAuB;MACtB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,gBAAkB;MACjB,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,UAAY;MACX,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,kBAAoB;MACnB,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,kBAAoB;MACnB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,SAAW;MACV,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,WAAa;MACZ,MAAQ;MACR,aAAe;IAChB;IACA,iBAAmB;MAClB,MAAQ;MACR,aAAe;IAChB;IACA,OAAS;MACR,MAAQ;MACR,aAAe;IAChB;IACA,SAAW;MACV,MAAQ;MACR,aAAe;IAChB;IACA,MAAQ;MACP,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,KAAO;MACN,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,oBAAsB;MACrB,MAAQ;MACR,aAAe;IAChB;IACA,cAAgB;MACf,MAAQ;MACR,aAAe;IAChB;IACA,eAAiB;MAChB,MAAQ;MACR,aAAe;IAChB;IACA,aAAe;MACd,MAAQ;MACR,aAAe;IAChB;IACA,mBAAqB;MACpB,MAAQ;MACR,aAAe;IAChB;EACD;AC7RA,MAAA,aAAA;IACC,IAAM;IACN,MAAQ;IACR,UAAY;MACX,YAAc;QACb;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,UAAY;QACX;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,eAAiB;QAChB;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,QAAU;QACT;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,YAAc;QACb;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,QAAU;QACT;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,UAAY;QACX;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;IACD;EACD;AC/XA,MAAA,kBAAA;IACC,IAAM;IACN,MAAQ;IACR,UAAY;MACX,YAAc;QACb;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,UAAY;QACX;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,eAAiB;QAChB;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,QAAU;QACT;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;MACD;MACA,YAAc;QACb;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;UACC,SAAW;UACX,QAAU;QACX;QACA;U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","names":["width","height","depth","indexArray","sign","tube","len","list","num","equals","area","ring","bs","layeroffset","cache","tube","make","srgbToLinear","n","a","b","c","acc","smooth","ring","len","color","sub","anchors","clump","cache","sphere","DEFAULT_LEAF","clamp","generate","mesh","tube","box","area","area2","list","COMMON","make","PART_ORDER","mesh","generate","species","list","species","area","color","box","mesh","stats","object","object","species","cache","object","mesh","byId","add","norm","dist","box","species","dist_exports","mesh","box","stats"]}