{
  "streamed": true,
  "usage": {
    "prompt_tokens": 160,
    "completion_tokens": 19479,
    "total_tokens": 19639,
    "cost": 0.97555,
    "is_byok": false,
    "prompt_tokens_details": {
      "cached_tokens": 0,
      "cache_write_tokens": 0,
      "audio_tokens": 0,
      "video_tokens": 0
    },
    "cost_details": {
      "upstream_inference_cost": 0.97555,
      "upstream_inference_prompt_cost": 0.0016,
      "upstream_inference_completions_cost": 0.97395
    },
    "completion_tokens_details": {
      "reasoning_tokens": 2791,
      "image_tokens": 0,
      "audio_tokens": 0
    }
  },
  "finishReason": "stop",
  "content": "```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Big Mac — three.js</title>\n<style>\n  html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #0e0e10; }\n  canvas { display: block; }\n</style>\n<script type=\"importmap\">\n{\n  \"imports\": {\n    \"three\": \"https://unpkg.com/three@0.160.0/build/three.module.js\",\n    \"three/addons/\": \"https://unpkg.com/three@0.160.0/examples/jsm/\"\n  }\n}\n</script>\n</head>\n<body>\n<script type=\"module\">\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\nimport { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';\n\n/* ---------------- Renderer / Scene / Camera ---------------- */\nconst renderer = new THREE.WebGLRenderer({ antialias: true });\nrenderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\nrenderer.setSize(window.innerWidth, window.innerHeight);\nrenderer.shadowMap.enabled = true;\nrenderer.shadowMap.type = THREE.PCFSoftShadowMap;\nrenderer.toneMapping = THREE.ACESFilmicToneMapping;\nrenderer.toneMappingExposure = 1.15;\ndocument.body.appendChild(renderer.domElement);\n\nconst scene = new THREE.Scene();\nscene.background = new THREE.Color(0x0e0e10);\nscene.fog = new THREE.Fog(0x0e0e10, 14, 32);\n\nconst camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 100);\ncamera.position.set(4.6, 3.4, 5.6);\n\nconst controls = new OrbitControls(camera, renderer.domElement);\ncontrols.target.set(0, 1.5, 0);\ncontrols.enableDamping = true;\ncontrols.dampingFactor = 0.06;\ncontrols.minDistance = 3.2;\ncontrols.maxDistance = 15;\ncontrols.maxPolarAngle = Math.PI * 0.52;\n\n/* ---------------- Environment (IBL) ---------------- */\nconst pmrem = new THREE.PMREMGenerator(renderer);\nscene.environment = pmrem.fromScene(new RoomEnvironment(), 0.04).texture;\n\n/* ---------------- Lights ---------------- */\nconst key = new THREE.DirectionalLight(0xfff1de, 3.0);\nkey.position.set(5, 8, 4);\nkey.castShadow = true;\nkey.shadow.mapSize.set(2048, 2048);\nkey.shadow.camera.left = -5; key.shadow.camera.right = 5;\nkey.shadow.camera.top = 5; key.shadow.camera.bottom = -5;\nkey.shadow.camera.near = 1; key.shadow.camera.far = 25;\nkey.shadow.bias = -0.0002;\nkey.shadow.normalBias = 0.02;\nscene.add(key);\n\nconst fill = new THREE.DirectionalLight(0xbfd4ff, 0.55);\nfill.position.set(-6, 3, -2);\nscene.add(fill);\n\nconst rim = new THREE.DirectionalLight(0xffffff, 1.1);\nrim.position.set(-2, 5, -7);\nscene.add(rim);\n\nscene.add(new THREE.AmbientLight(0x404048, 0.4));\n\n/* ---------------- Floor ---------------- */\nconst floor = new THREE.Mesh(\n  new THREE.CircleGeometry(30, 64),\n  new THREE.MeshStandardMaterial({ color: 0x17171a, roughness: 0.95, metalness: 0, envMapIntensity: 0.25 })\n);\nfloor.rotation.x = -Math.PI / 2;\nfloor.receiveShadow = true;\nscene.add(floor);\n\n/* ---------------- Procedural canvas textures ---------------- */\nfunction canvasTex(draw, size = 512, srgb = true) {\n  const c = document.createElement('canvas');\n  c.width = c.height = size;\n  draw(c.getContext('2d'), size);\n  const t = new THREE.CanvasTexture(c);\n  if (srgb) t.colorSpace = THREE.SRGBColorSpace;\n  t.wrapS = t.wrapT = THREE.RepeatWrapping;\n  t.anisotropy = 8;\n  return t;\n}\nconst R = Math.random;\nfunction speck(ctx, s, n, colFn, rMin, rMax) {\n  for (let i = 0; i < n; i++) {\n    ctx.fillStyle = colFn();\n    ctx.beginPath();\n    ctx.arc(R() * s, R() * s, rMin + R() * (rMax - rMin), 0, 7);\n    ctx.fill();\n  }\n}\n\nconst bunTex = canvasTex((ctx, s) => {\n  const g = ctx.createLinearGradient(0, 0, 0, s);\n  g.addColorStop(0.00, '#c97a2e');\n  g.addColorStop(0.45, '#d18a3d');\n  g.addColorStop(0.80, '#e8b46e');\n  g.addColorStop(1.00, '#f0cd96');\n  ctx.fillStyle = g; ctx.fillRect(0, 0, s, s);\n  speck(ctx, s, 2600, () => `rgba(100,50,12,${0.03 + R() * 0.05})`, 1, 3);\n  speck(ctx, s, 2200, () => `rgba(255,235,190,${0.03 + R() * 0.05})`, 1, 3);\n  speck(ctx, s, 90, () => `rgba(160,90,30,${0.03 + R() * 0.04})`, 8, 28);\n});\n\nconst noiseBump = canvasTex((ctx, s) => {\n  ctx.fillStyle = '#808080'; ctx.fillRect(0, 0, s, s);\n  speck(ctx, s, 3500, () => { const v = 60 + (R() * 140) | 0; return `rgba(${v},${v},${v},0.16)`; }, 1, 4);\n  speck(ctx, s, 260, () => { const v = 60 + (R() * 140) | 0; return `rgba(${v},${v},${v},0.09)`; }, 5, 16);\n}, 512, false);\n\nconst pattyTex = canvasTex((ctx, s) => {\n  ctx.fillStyle = '#452a19'; ctx.fillRect(0, 0, s, s);\n  const cols = ['#2b1a10', '#5c3a22', '#6e4a2c', '#38220f', '#503018'];\n  speck(ctx, s, 1600, () => { ctx.globalAlpha = 1; return cols[(R() * cols.length) | 0] + ''; }, 2, 7);\n  ctx.globalAlpha = 1;\n  speck(ctx, s, 340, () => `rgba(18,10,6,${0.25 + R() * 0.25})`, 1, 6);\n  speck(ctx, s, 220, () => `rgba(150,100,58,${0.1 + R() * 0.15})`, 1, 4);\n});\n\nconst pattyBump = canvasTex((ctx, s) => {\n  ctx.fillStyle = '#707070'; ctx.fillRect(0, 0, s, s);\n  speck(ctx, s, 1400, () => { const v = 20 + (R() * 220) | 0; return `rgba(${v},${v},${v},0.35)`; }, 2, 8);\n}, 512, false);\n\nconst lettuceTex = canvasTex((ctx, s) => {\n  const g = ctx.createRadialGradient(s / 2, s / 2, 10, s / 2, s / 2, s / 2);\n  g.addColorStop(0, '#cfe382');\n  g.addColorStop(0.6, '#93c04a');\n  g.addColorStop(1, '#69a02e');\n  ctx.fillStyle = g; ctx.fillRect(0, 0, s, s);\n  ctx.strokeStyle = 'rgba(230,245,175,0.3)';\n  for (let i = 0; i < 60; i++) {\n    const a = R() * Math.PI * 2, len = s * (0.2 + R() * 0.3);\n    ctx.lineWidth = 1 + R() * 3;\n    ctx.beginPath();\n    ctx.moveTo(s / 2, s / 2);\n    ctx.quadraticCurveTo(\n      s / 2 + Math.cos(a + 0.3) * len * 0.5, s / 2 + Math.sin(a + 0.3) * len * 0.5,\n      s / 2 + Math.cos(a) * len, s / 2 + Math.sin(a) * len);\n    ctx.stroke();\n  }\n  speck(ctx, s, 900, () => `rgba(40,90,20,${0.05 + R() * 0.08})`, 1, 3);\n});\n\nconst cheeseTex = canvasTex((ctx, s) => {\n  ctx.fillStyle = '#f2a33a'; ctx.fillRect(0, 0, s, s);\n  speck(ctx, s, 700, () => `rgba(255,200,120,${0.05 + R() * 0.07})`, 2, 6);\n  speck(ctx, s, 500, () => `rgba(200,120,30,${0.04 + R() * 0.06})`, 2, 5);\n});\n\nconst pickleTex = canvasTex((ctx, s) => {\n  const g = ctx.createRadialGradient(s / 2, s / 2, 5, s / 2, s / 2, s / 2);\n  g.addColorStop(0, '#aab861');\n  g.addColorStop(0.75, '#7d8f3f');\n  g.addColorStop(1, '#5c6e2a');\n  ctx.fillStyle = g; ctx.fillRect(0, 0, s, s);\n  for (let i = 0; i < 30; i++) { // seeds\n    ctx.fillStyle = `rgba(225,232,170,${0.4 + R() * 0.3})`;\n    ctx.save();\n    ctx.translate(s / 2 + (R() - 0.5) * s * 0.55, s / 2 + (R() - 0.5) * s * 0.55);\n    ctx.rotate(R() * 7);\n    ctx.beginPath(); ctx.ellipse(0, 0, 5 + R() * 6, 3 + R() * 3, 0, 0, 7); ctx.fill();\n    ctx.restore();\n  }\n  speck(ctx, s, 600, () => `rgba(50,70,20,${0.05 + R() * 0.08})`, 1, 3);\n});\n\n/* ---------------- Materials ---------------- */\nfunction mat(p) {\n  return new THREE.MeshPhysicalMaterial(Object.assign({ envMapIntensity: 0.7, metalness: 0 }, p));\n}\nconst bunMat = mat({ map: bunTex, bumpMap: noiseBump, bumpScale: 0.9, roughness: 0.52, sheen: 0.3, sheenColor: 0xffe0b0 });\nconst pattyMat = mat({ map: pattyTex, bumpMap: pattyBump, bumpScale: 1.6, roughness: 0.72 });\nconst cheeseMat = mat({ map: cheeseTex, roughness: 0.32, clearcoat: 0.35, clearcoatRoughness: 0.4, side: THREE.DoubleSide });\nconst lettuceMat = mat({ map: lettuceTex, roughness: 0.42, sheen: 0.5, sheenColor: 0xd6ff9a, side: THREE.DoubleSide });\nconst sauceMat = mat({ color: 0xf0bf72, roughness: 0.28, clearcoat: 0.6, clearcoatRoughness: 0.3, side: THREE.DoubleSide });\nconst pickleMat = mat({ map: pickleTex, roughness: 0.22, clearcoat: 0.8, clearcoatRoughness: 0.2 });\nconst onionMat = mat({ color: 0xfdf6e0, roughness: 0.3, transparent: true, opacity: 0.85, clearcoat: 0.5 });\nconst seedMat = mat({ color: 0xf7ecd2, roughness: 0.55, bumpMap: noiseBump, bumpScale: 0.3 });\n\n/* ---------------- Geometry helpers ---------------- */\nfunction lathe(pts, mat_) {\n  const g = new THREE.LatheGeometry(pts.map(p => new THREE.Vector2(p[0], p[1])), 128);\n  const m = new THREE.Mesh(g, mat_);\n  return m;\n}\n\nfunction ruffledDisc(radius, opts) {\n  const o = Object.assign({ rings: 22, segs: 160, freq: 12, amp: 0.1, jitter: 0.05, droop: 0, dome: 0 }, opts);\n  const pos = [], uv = [], idx = [];\n  for (let i = 0; i <= o.rings; i++) {\n    const t = i / o.rings;\n    for (let j = 0; j <= o.segs; j++) {\n      const a = j / o.segs * Math.PI * 2;\n      const rr = t * radius * (1 + o.jitter * Math.sin(a * 3 + 1) + o.jitter * 0.7 * Math.sin(a * 7 + 3));\n      const y = o.amp * Math.sin(a * o.freq + t * 2) * t * t + o.dome * (1 - t * t) - o.droop * t * t * t;\n      pos.push(Math.cos(a) * rr, y, Math.sin(a) * rr);\n      uv.push(0.5 + 0.5 * t * Math.cos(a), 0.5 + 0.5 * t * Math.sin(a));\n    }\n  }\n  for (let i = 0; i < o.rings; i++) for (let j = 0; j < o.segs; j++) {\n    const a = i * (o.segs + 1) + j, b = a + o.segs + 1;\n    idx.push(a, b, a + 1, b, b + 1, a + 1);\n  }\n  const g = new THREE.BufferGeometry();\n  g.setAttribute('position', new THREE.Float32BufferAttribute(pos, 3));\n  g.setAttribute('uv', new THREE.Float32BufferAttribute(uv, 2));\n  g.setIndex(idx);\n  g.computeVertexNormals();\n  return g;\n}\n\nfunction makePatty() {\n  const g = new THREE.CylinderGeometry(1.58, 1.58, 0.32, 128, 8);\n  const p = g.attributes.position;\n  for (let i = 0; i < p.count; i++) {\n    const x = p.getX(i), y = p.getY(i), z = p.getZ(i);\n    const r = Math.hypot(x, z);\n    if (r > 0.2) {\n      const a = Math.atan2(z, x);\n      const nr = 1 + 0.035 * Math.sin(a * 9 + y * 8) + 0.02 * Math.sin(a * 23 + 2) + 0.015 * Math.sin(a * 41);\n      p.setX(i, x * nr); p.setZ(i, z * nr);\n    }\n    p.setY(i, y + 0.022 * Math.sin(x * 14 + 1) * Math.sin(z * 12 + 2) * (Math.abs(y) > 0.1 ? 1 : 0.3));\n  }\n  g.computeVertexNormals();\n  g.translate(0, 0.17, 0);\n  const m = new THREE.Mesh(g, pattyMat);\n  return m;\n}\n\nfunction makeCheese() {\n  const g = new THREE.PlaneGeometry(2.5, 2.5, 32, 32);\n  g.rotateX(-Math.PI / 2);\n  const p = g.attributes.position;\n  for (let i = 0; i < p.count; i++) {\n    const x = p.getX(i), z = p.getZ(i);\n    const d = Math.hypot(x, z);\n    const over = Math.max(0, d - 1.5);\n    p.setY(i, -over * over * 1.7 + 0.02 * Math.sin(x * 8) * Math.sin(z * 8));\n  }\n  g.computeVertexNormals();\n  return new THREE.Mesh(g, cheeseMat);\n}\n\nfunction makePickle() {\n  const g = new THREE.CylinderGeometry(0.44, 0.44, 0.08, 48, 1);\n  const p = g.attributes.position;\n  for (let i = 0; i < p.count; i++) {\n    const x = p.getX(i), z = p.getZ(i);\n    const r = Math.hypot(x, z);\n    if (r > 0.2) {\n      const a = Math.atan2(z, x);\n      const nr = 1 + 0.06 * Math.sin(a * 8 + 1);\n      p.setX(i, x * nr); p.setZ(i, z * nr);\n    }\n  }\n  g.computeVertexNormals();\n  return new THREE.Mesh(g, pickleMat);\n}\n\nfunction lettuceLayer(y, rot, radius) {\n  const m = new THREE.Mesh(ruffledDisc(radius, { freq: 11, amp: 0.14, jitter: 0.09, droop: 0.06 }), lettuceMat);\n  m.position.y = y; m.rotation.y = rot;\n  return m;\n}\n\nfunction sauceLayer(y) {\n  const m = new THREE.Mesh(ruffledDisc(1.62, { freq: 7, amp: 0.03, jitter: 0.13, droop: 0.1, dome: 0.09 }), sauceMat);\n  m.position.y = y;\n  return m;\n}\n\nfunction onionBits(y) {\n  const grp = new THREE.Group();\n  for (let i = 0; i < 7; i++) {\n    const g = new THREE.TorusGeometry(0.28 + R() * 0.12, 0.04, 8, 28, Math.PI * (0.8 + R() * 0.8));\n    g.rotateX(-Math.PI / 2);\n    g.scale(1, 0.55, 1);\n    const m = new THREE.Mesh(g, onionMat);\n    const a = R() * Math.PI * 2, rr = 0.6 + R() * 0.75;\n    m.position.set(Math.cos(a) * rr, y, Math.sin(a) * rr);\n    m.rotation.y = R() * Math.PI * 2;\n    grp.add(m);\n  }\n  return grp;\n}\n\nfunction makeCrownSeeds() {\n  const Rr = 1.64, H = 0.9, yB = 0.12;\n  const geo = new THREE.SphereGeometry(1, 12, 8);\n  geo.scale(0.052, 0.032, 0.088);\n  const inst = new THREE.InstancedMesh(geo, seedMat, 85);\n  const placed = [];\n  const M = new THREE.Matrix4(), P = new THREE.Vector3(), N = new THREE.Vector3();\n  const q1 = new THREE.Quaternion(), q2 = new THREE.Quaternion(), UP = new THREE.Vector3(0, 1, 0);\n  let count = 0, tries = 0;\n  while (count < 85 && tries < 3000) {\n    tries++;\n    const th = 0.18 + Math.acos(1 - R() * (1 - Math.cos(1.15))) ; // biased distribution over cap\n    const t2 = Math.min(th, 1.28);\n    const ph = R() * Math.PI * 2;\n    P.set(Rr * Math.sin(t2) * Math.cos(ph), yB + H * Math.cos(t2), Rr * Math.sin(t2) * Math.sin(ph));\n    let ok = true;\n    for (const q of placed) if (q.distanceTo(P) < 0.17) { ok = false; break; }\n    if (!ok) continue;\n    placed.push(P.clone());\n    N.set(P.x / (Rr * Rr), (P.y - yB) / (H * H), P.z / (Rr * Rr)).normalize();\n    q1.setFromUnitVectors(UP, N);\n    q2.setFromAxisAngle(UP, R() * Math.PI * 2);\n    q1.multiply(q2);\n    M.compose(P.clone().addScaledVector(N, 0.005), q1, new THREE.Vector3(1, 1, 1));\n    inst.setMatrixAt(count, M);\n    count++;\n  }\n  inst.count = count;\n  return inst;\n}\n\n/* ---------------- Assemble the Big Mac ---------------- */\nconst burger = new THREE.Group();\n\n// Heel bun\nburger.add(lathe([[0, 0], [1.45, 0], [1.58, 0.04], [1.62, 0.18], [1.56, 0.34], [1.35, 0.42], [0, 0.42]], bunMat));\n\n// Bottom section: sauce, onions, lettuce, cheese, patty\nburger.add(sauceLayer(0.38));\nburger.add(onionBits(0.47));\nburger.add(lettuceLayer(0.46, 0, 1.86));\nburger.add(lettuceLayer(0.55, 2.1, 1.8));\nconst cheese = makeCheese();\ncheese.position.y = 0.70; cheese.rotation.y = 0.45;\nburger.add(cheese);\nconst patty1 = makePatty();\npatty1.position.y = 0.72;\nburger.add(patty1);\n\n// Club (middle bun)\nconst club = lathe([[0, 0], [1.5, 0], [1.6, 0.06], [1.62, 0.2], [1.58, 0.34], [1.4, 0.4], [0, 0.4]], bunMat);\nclub.position.y = 1.04;\nburger.add(club);\n\n// Top section: sauce, lettuce, pickles, patty\nburger.add(sauceLayer(1.42));\nburger.add(lettuceLayer(1.50, 0.9, 1.86));\nburger.add(lettuceLayer(1.58, 3.6, 1.78));\nconst pk1 = makePickle(); pk1.position.set(0.62, 1.68, 0.35); pk1.rotation.set(0.06, 0.5, -0.04);\nconst pk2 = makePickle(); pk2.position.set(-0.55, 1.68, -0.42); pk2.rotation.set(-0.05, 1.7, 0.06);\nburger.add(pk1, pk2);\nconst patty2 = makePatty();\npatty2.position.y = 1.72; patty2.rotation.y = 1.3;\nburger.add(patty2);\n\n// Crown (top bun) with sesame seeds\nconst crown = new THREE.Group();\nconst crownPts = [[0, 0], [1.52, 0], [1.62, 0.06], [1.64, 0.12]];\nfor (let i = 1; i <= 18; i++) {\n  const t = i / 18 * Math.PI / 2;\n  crownPts.push([1.64 * Math.cos(t), 0.12 + 0.9 * Math.sin(t)]);\n}\ncrown.add(lathe(crownPts, bunMat));\ncrown.add(makeCrownSeeds());\ncrown.position.y = 2.02;\nburger.add(crown);\n\nburger.traverse(o => { if (o.isMesh) { o.castShadow = true; o.receiveShadow = true; } });\nscene.add(burger);\n\n/* ---------------- Resize / Animate ---------------- */\nwindow.addEventListener('resize', () => {\n  camera.aspect = window.innerWidth / window.innerHeight;\n  camera.updateProjectionMatrix();\n  renderer.setSize(window.innerWidth, window.innerHeight);\n});\n\nconst clock = new THREE.Clock();\nfunction animate() {\n  requestAnimationFrame(animate);\n  const dt = clock.getDelta();\n  burger.rotation.y += dt * 0.25;\n  controls.update();\n  renderer.render(scene, camera);\n}\nanimate();\n</script>\n</body>\n</html>\n```"
}