<!-- SOLID CITY · part 3663 -->
signer delivered their standing surfaces as raw triangle
 * geometry — "VISUAL GEOMETRY ONLY until stand/collision registry
 * integrated" — so this placer performs the integration he specified:
 * the exact triangles of each connector answer standY by barycentric
 * height, the same mathematics his measureConnector proves them by. */
function triHeight(tris, x, z) {
  // each tri: [ax, ay, az, bx, by, bz, cx, cy, cz] in world coordinates
  for (var i = 0; i < tris.length; i++) {
    var t = tris[i];
    var den = (t[5] - t[8]) * (t[0] - t[6]) + (t[6] - t[3]) * (t[2] - t[8]);
    if (Math.abs(den) < 1e-10) continue;
    var u = ((t[5] - t[8]) * (x - t[6]) + (t[6] - t[3]) * (z - t[8])) / den;
    var v = ((t[8] - t[2]) * (x - t[6]) + (t[0] - t[6]) * (z - t[8])) / den;
    var w = 1 - u - v;
    if (Math.min(u, v, w) < -1e-7) continue;
    return u * t[1] + v * t[4] + w * t[7];
  }
  return null;
}
/* THE SPATIAL INDEX (ladder stage 3, 2026-10-13): triHeight's full scan
 * answered every standing query by walking every triangle of every
 * join. The index buckets each join's triangles by their bounding boxes
 * on a 16 m grid; a query visits only its own cell's candidates, in
 * original registration order — the first containing triangle it finds
 * is the very one the full scan would return. Same barycentric rule,
 * same selection, same answers; the scan is now proportional to the
 * neighbourhood, not the nation. */
function indexTris(tris) {
  var cells = {};
  for (var i = 0; i < tris.length; i++) {
    var t = tris[i];
    var x0 = Math.floor(Math.min(t[0], t[3], t[6]) / 16), x1 = Math.floor(Math.max(t[0], t[3], t[6]) / 16);
    var z0 = Math.floor(Math.min(t[2], t[5], t[8]) / 16), z1 = Math.floor(Math.max(t[2], t[5], t[8]) / 16);
    for (var cx = x0; cx <= x1; cx++) for (var cz = z0; cz <= z1; cz++) {
      var k = cx + ',' + cz;
      (cells[k] = cells[k] || []).push(i);
    }
  }
  return { tris: tris, cells: cells };
}
function triHeightIx(ix, x, z) {
  if (!ix) return null;
  var cand = ix.cells[Math.floor(x / 16) + ',' + Math.floor(z / 16)];
  if (!cand) return null;
  var tris = ix.tris;
  for (var n = 0; n < cand.length; n++) {
    var t = tris[cand[n]];
    var den = (t[5] - t[8]) * (t[0] - t[6]) + (t[6] - t[3]) * (t[2] - t[8]);
    if (Math.abs(den) < 1e-10) continue;
    var u = ((t[5] - t[8]) * (x - t[6]) + (t[6] - t[3]) * (z - t[8])) / den;
    var v = ((t[8] - t[2]) * (x - t[6]) + (t[0] - t[6]) * (z - t[8])) / den;
    var w = 1 - u - v;
    if (Math.min(u, v, w) < -1e-7) continue;
    return u * t[1] + v * t[4] + w * t[7];
  }
  return null;
}
function extractTris(geo) {
  var pos = geo.getAttribute('position'), idx = geo.getIndex(), tris = [];
  var n = idx ? idx.count : pos.count;
  for (var i = 0; i + 2 < n; i += 3) {
    var tri = [];
    for (var k = 0; k < 3; k++) {
      var vi = idx ? idx.getX(i + k) : i + k;
      tri.push(pos.getX(vi), pos.getY(vi), pos.getZ(vi));
    }
    tris.push(tri);
  }
  return tris;
}
function standY(x, z, py) {
  var best = -1000;
  for (var h = 0; h < H.houses.length; h++) {
    var hs = H.houses[h], st = hs.stand, uv = localUV(st, x, z), floor = st.center[1];
    var cand = [];
    if (Math.abs(uv[0]) <= 4 && Math.abs(uv[1]) <= 5) cand.push(floor);
    if (hs.roofTop && Math.abs(uv[0]) <= 4.35 && Math.abs(uv[1]) <= 5.35) cand.push(hs.roofTop);
    for (var i = 0; i < cand.length; i++) if ((py == null || cand[i] <= py + 1.6) && cand[i] > best) best = cand[i];
  }
  for (var j = 0; j < H.joins.length; j++) {
    var y = triHeightIx(H.joinIx[j], x, z);
    if (y != null && (py == null || y <= py + 1.6) && y > best) best = y;
  }
  return best;
}
function radar(rg, blip, flying) {
  if (!H.houses.length) return;
  blip(H.housePos.x, H.housePos.z, '#ffd27a', flying ? 3 : 6, flying ? '' : 'PILOT HOUSE');
  for (var h = 1; h < H.houses.length; h++) blip(H.houses[h].cx, H.houses[h].cz, '#ffd27a', 3, '');
  for (var k in LINK_MID) blip(LINK_MID[k].x, LINK_MID[k].z, '#ffd27a', 3, '');
  blip(-1127, -524, '#ffd27a', 3, '');
  blip(-912, -768, '#ffd27a', 3, '');
}
function update(dt) {
  if (!H.houses.length) return;
  var dx = S.p.x - H.housePos.x, dz = S.p.z - H.housePos.z;
  if (!H.saidHouse && dx * dx + dz * dz < 150 * 150) {
    H.saidHouse = true;
    A.help('🏠 THE PILOT HOUSE — the nation\'s first dwelling, in Ward 2. Its door is glass; walk in, stand on its floor, examine its foundations. Nine more lawful houses now stand beside it.', 8);
  }
  for (var w in STREET) {
    if (H.saidStreet[w]) continue;
    var st = STREET[w], sx = S.p.x - st.x, sz = S.p.z - st.z;
    if (sx * sx + sz * sz < 130 * 130) { H.saidStreet[w] = true; A.help(st.line || ('🏘 ' + st.name + ' STREET — dwellings of the nation stand along this path, each founded on sampled ground, each floor under standing law.'), 7); }
  }
  var clx = S.p.x + 912, clz = S.p.z + 768;
  if (!H.saidClimb && clx * clx + clz * clz < 90 * 90) { H.saidClimb = true; A.help