<!-- RUBY-BACKUP · part 544 -->
icNodes = [];
  }catch(e){}
}
/* SONG UPLOAD — 2 songs, back-to-back */
var _songs = [], _songIdx = 0, _audioEl = null;
function initSongDB(){
  return new Promise(function(resolve, reject){
    var req = indexedDB.open('ruby-songs', 1);
    req.onupgradeneeded = function(e){ e.target.result.createObjectStore('songs'); };
    req.onsuccess = function(e){ resolve(e.target.result); };
    req.onerror = reject;
  });
}
function saveSong(idx, blob){
  initSongDB().then(function(db){
    var tx = db.transaction('songs', 'readwrite');
    tx.objectStore('songs').put(blob, 'song'+idx);
  });
}
function loadSongs(){
  initSongDB().then(function(db){
    var tx = db.transaction('songs', 'readonly');
    var store = tx.objectStore('songs');
    _songs = [];
    [0,1].forEach(function(i){
      var req = store.get('song'+i);
      req.onsuccess = function(){
        if(req.result){
          _songs[i] = URL.createObjectURL(req.result);
          updateSongBtn();
        }
      };
    });
  });
}
function updateSongBtn(){
  var btn = document.getElementById('songbtn');
  if(btn){
    var n = _songs.filter(Boolean).length;
    btn.innerHTML = n>0 ? '🎶'+n : '🎶';
    btn.title = n>0 ? n+' song'+(n>1?'s':'')+' loaded — tap to play' : 'Upload 2 songs';
  }
}
function playSongs(){
  if(_songs.filter(Boolean).length===0){
    // no songs — open file picker
    document.getElementById('songfile').click();
    return;
  }
  if(!_audioEl){
    _audioEl = new Audio();
    _audioEl.addEventListener('ended', function(){
      _songIdx = (_songIdx + 1) % _songs.filter(Boolean).length;
      playCurrentSong();
    });
  }
  if(_audioEl.paused){
    // stop ambient if playing
    if(typeof _musicOn!=='undefined' && _musicOn && typeof toggleMusic==='function') toggleMusic();
    playCurrentSong();
    if(typeof codeStatus==='function') codeStatus('songs playing');
  }else{
    _audioEl.pause();
    if(typeof codeStatus==='function') codeStatus('songs paused');
  }
}
function playCurrentSong(){
  var list = _songs.filter(Boolean);
  if(list.length===0 || !_audioEl) return;
  _audioEl.src = list[_songIdx % list.length];
  _audioEl.play().catch(function(){});
}
(function(){
  // hidden file input
  var fi = document.createElement('input');
  fi.type = 'file';
  fi.id = 'songfile';
  fi.accept = 'audio/*';
  fi.multiple = true;
  fi.style.display = 'none';
  fi.addEventListener('change', function(){
    var files = Array.prototype.slice.call(fi.files).slice(0, 2);
    files.forEach(function(f, i){
      saveSong(i, f);
      _songs[i] = URL.createObjectURL(f);
    });
    _songIdx = 0;
    updateSongBtn();
    if(typeof codeStatus==='function') codeStatus(files.length+' song'+(files.length>1?'s':'')+' loaded');
  });
  document.body.appendChild(fi);
  // song button
  var btn = document.createElement('div');
  btn.id = 'songbtn';
  btn.innerHTML = '🎶';
  btn.style.cssText = 'position:fixed;left:18px;bottom:335px;z-index:10000;width:44px;height:44px;background:rgba(20,10,0,0.85);border:2px solid #d8a920;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px;cursor:pointer;';
  btn.title = 'Upload 2 songs';
  btn.addEventListener('click', playSongs);
  document.body.appendChild(btn);
  // load saved songs on start
  setTimeout(loadSongs, 2000);
})();
// music button — permanent, by the other buttons
(function(){
  var btn = document.createElement('div');
  btn.id = 'musicbtn';
  btn.innerHTML = '🎵';
  btn.style.cssText = 'position:fixed;left:18px;bottom:280px;z-index:10000;width:44px;height:44px;background:rgba(20,10,0,0.85);border:2px solid #d8a920;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px;opacity:0.4;cursor:pointer;';
  btn.title = 'Music';
  btn.addEventListener('click', toggleMusic);
  document.body.appendChild(btn);
})();
/* TAP THE PLAYA 2.0 BOX → ENGAGE BLOCK BUILDING */
(function(){
  var raycaster = null, mouseVec = null;
  function onTap(e){
    try{
      if(!window._creatorBlock || typeof scene==='undefined') return;
      // only when not in grab mode (grab picks it up, tap opens Creator)
      if(typeof GRAB!=='undefined' && GRAB) return;
      raycaster = raycaster || new THREE.Raycaster();
      mouseVec = mouseVec || new THREE.Vector2();
      var cx = (e.clientX !== undefined) ? e.clientX : (e.touches && e.touches[0] ? e.touches[0].clientX : 0);
      var cy = (e.clientY !== undefined) ? e.clientY : (e.touches && e.touches[0] ? e.touches[0].clientY : 0);
      mouseVec.x = (cx / window.innerWidth) * 2 - 1;
      mouseVec.y = -(cy / window.innerHeight) * 2 + 1;
      raycaster.setFromCamera(mouseVec, camera);
      var hits = raycaster.intersectObject(window._creatorBlock, true);
      if(hits.length > 0){
        // ENGAGE — open the Creator (block building)
        var btn = document.getElementById('creatorblockbtn');
        if(btn){ btn.click(); }
        else if(typeof toggleCreator==='function'){ toggle