<!-- RUBY-BACKUP · part 378 -->
unction(err){ codeStatus('could not measure her'); }
  );
}
function assembleProvolta(){
  if(DISSECT_GROUP){
    try{ scene.remove(DISSECT_GROUP); }catch(e){}
    DISSECT_GROUP = null;
    codeStatus('she is whole again');
  }
}

/* PROVOLTA PART SCALES — adjusted by Solid on the King's word.
   Each entry: 'partname': scale | [sx, sy, sz] | {scale:[sx,sy,sz], move:[mx,my,mz]}
   - number: uniform scale
   - [x,y,z]: stretch each axis (extend to fit)
   - {scale:[...], move:[...]}: resize + nudge into place */
var PROVOLTA_PART_SCALES = {
  /* fix proportions: narrower torso, arms pulled in */
  'armor_chest': [0.82, 1, 0.9],
  'pauldrons': [0.9, 0.9, 0.9],
  'body': [0.9, 1, 0.9],
};

/* ROBOT LOOK — enhance her materials on load */
function enhanceRobotLook(model){
  try{
    model.traverse(function(o){
      if(!o.isMesh || !o.material) return;
      var m = o.material;
      var name = (m.name || '').toLowerCase();
      /* armor -> full chrome */
      if(name.indexOf('armor') >= 0 || name.indexOf('silver') >= 0 || name.indexOf('metal') >= 0){
        m.metalness = 1.0;
        m.roughness = 0.08;
      }
      /* glowing parts -> intensify */
      if(m.emissive && m.emissiveIntensity !== undefined){
        if(name.indexOf('gold') >= 0){
          m.emissiveIntensity = 2.0;
        } else if(name.indexOf('cyan') >= 0 || name.indexOf('eye') >= 0){
          m.emissiveIntensity = 3.0;
        } else if(m.emissiveIntensity > 0){
          m.emissiveIntensity *= 1.5;
        }
      }
      /* suit -> darker, more synthetic */
      if(name.indexOf('suit') >= 0 || name.indexOf('red') >= 0){
        m.metalness = 0.6;
        m.roughness = 0.3;
      }
      /* skin -> pale synthetic for robot feel */
      if(name.indexOf('skin') >= 0){
        m.metalness = 0.3;
        m.roughness = 0.4;
      }
    });
  }catch(e){}
}
function applyProvoltaScales(model){
  if(!model || !PROVOLTA_PART_SCALES) return;
  model.traverse(function(obj){
    if(obj.isMesh){
      var n = (obj.name || '').toLowerCase();
      Object.keys(PROVOLTA_PART_SCALES).forEach(function(key){
        if(n.indexOf(key.toLowerCase()) >= 0){
          var cfg = PROVOLTA_PART_SCALES[key];
          if(typeof cfg === 'number'){
            obj.scale.set(cfg, cfg, cfg);
          } else if(Array.isArray(cfg)){
            obj.scale.set(cfg[0], cfg[1], cfg[2]);
          } else if(typeof cfg === 'object'){
            if(cfg.scale) obj.scale.set(cfg.scale[0], cfg.scale[1], cfg.scale[2]);
            if(cfg.move) obj.position.set(
              obj.position.x + cfg.move[0],
              obj.position.y + cfg.move[1],
              obj.position.z + cfg.move[2]
            );
          }
        }
      });
    }
  });
}
function buildProvoltaAvatar(){
  var g = new THREE.Group();
  g.userData.isProvoltaAvatar = true;
  /* load the warrior */
  if(typeof THREE!=='undefined' && typeof THREE.GLTFLoader!=='undefined'){
    var loader = new THREE.GLTFLoader();
    loader.load('/ruby/warrior.glb?v=1',
      function(glb){
        var model = glb.scene;
        var box = new THREE.Box3().setFromObject(model);
        var size = box.getSize(new THREE.Vector3());
        var scale = 1.9 / size.y;
        model.scale.set(scale, scale, scale);
        var center = box.getCenter(new THREE.Vector3());
        model.position.set(-center.x*scale, -box.min.y*scale, -center.z*scale);
        try{ applyProvoltaScales(model); }catch(e){}
        try{ enhanceRobotLook(model); }catch(e){}
        try{ recordProvoltaHeight(model); }catch(e){}
        g.add(model);
        /* keep her name */
        try{
          var nameCv = document.createElement('canvas');
          nameCv.width = 512; nameCv.height = 64;
          var nctx = nameCv.getContext('2d');
          nctx.font = 'bold 36px Georgia'; nctx.textAlign = 'center';
          nctx.shadowColor = '#00ccff'; nctx.shadowBlur = 15;
          nctx.fillStyle = '#aaddff'; nctx.fillText('PROVOLTA', 256, 44);
          var ntex = new THREE.CanvasTexture(nameCv);
          var np = new THREE.Mesh(new THREE.PlaneGeometry(1.5, 0.19),
            new THREE.MeshBasicMaterial({map: ntex, transparent: true}));
          np.position.set(0, 2.15, 0);
          g.add(np);
        }catch(e){}
      },
      undefined,
      function(err){
        /* fallback: gold figure */
        var fb = new THREE.Mesh(new THREE.SphereGeometry(0.3, 12, 12),
          new THREE.MeshStandardMaterial({color: 0xd4af37, metalness: 0.8, roughness: 0.3}));
        fb.position.y = 0.9; g.add(fb);
      }
    );
  }
  return g;
}
function buildKingAvatar(){
  /* the golden chibi king — big head, amber eyes, jeweled fleur-de-lis crown,
     little armored body with belt and backpack. built from his picture. */
  var g = new T.Group();
  function M(geo, mat, x, y, z){ var m = new T.Mesh(geo, mat); m.position.set(x||0, y||0, z||0); g.add(m); return m; }
  /* his sneakers — reforged from his picture: chrome armor, blue ene