<!-- RUBY-BACKUP · part 57 -->
al.dispose();
                  }catch(e){}
                }, k*100);
              });
            }
            if(link.thread){
              try{
                if(window.scene) window.scene.remove(link.thread);
                link.thread.geometry.dispose(); link.thread.material.dispose();
              }catch(e){}
            }
          }catch(e){}
        })(L);
        var oa = findSeed(L.a), ob = findSeed(L.b);
        var otherA = (L.a === seedId) ? L.b : L.a;
        var otherB = (L.b === seedId) ? L.a : L.b;
        if(oa){ var ix = oa.linked.indexOf(otherA); if(ix>=0) oa.linked.splice(ix,1); }
        if(ob){ var jx = ob.linked.indexOf(otherB); if(jx>=0) ob.linked.splice(jx,1); }
        links.splice(i, 1);
      }
    }
  }

  function unlinkSeed(sd){
    var n0 = links.length;
    severLinksOf(sd.id);
    if(links.length < n0) status('link severed — each seed grows on its own now.');
    else status('that seed holds no links.');
  }

  function listSeeds(){
    if(!seeds.length){ status('no seeds planted'); return; }
    var bits = seeds.map(function(sd){
      return sd.id + (sd.linked.length ? ' ~' + sd.linked.join(',') : '');
    });
    status(seeds.length + ' seeds: ' + bits.join(' | ') + ' — ' + links.length + ' links');
  }

  /* ---------- tap hook ---------- */
  function hookTaps(){
    var tries = 0;
    var iv = setInterval(function(){
      try{
        tries++;
        if(typeof dDown === 'function' && !dDown.__seedWrapped){
          var orig = dDown;
          var mine = function(id, sx, sy){
            try{
              if(window.__installArmed || window.__uninstallArmed)
                return orig.apply(this, arguments);
              if(seedArmed){
                seedArmed = false;
                var obj = pickBlock(sx, sy);
                if(obj){ plantSeed(obj, null); return true; }
                status('tap a block to plant the seed');
                return true;
              }
              if(plantTplArmed){
                var tpl = plantTplArmed; plantTplArmed = null;
                var o2 = pickBlock(sx, sy);
                if(o2){ plantSeed(o2, tpl); return true; }
                status('tap a block to plant the template');
                return true;
              }
              if(linkArmed){
                var o3 = pickBlock(sx, sy);
                var sd3 = o3 ? findSeedByBlock(o3) : null;
                if(!sd3){ status('tap a seed block — that is not one'); return true; }
                if(!linkFirst){ linkFirst = sd3; status('first seed held — tap the second'); return true; }
                if(linkFirst.id === sd3.id){ status('tap a different seed'); return true; }
                linkArmed = false;
                var first = linkFirst; linkFirst = null;
                createLink(first, sd3);
                return true;
              }
              if(unlinkArmed){
                unlinkArmed = false;
                var o4 = pickBlock(sx, sy);
                var sd4 = o4 ? findSeedByBlock(o4) : null;
                if(!sd4){ status('tap a seed block'); return true; }
                unlinkSeed(sd4);
                return true;
              }
            }catch(e){}
            return orig.apply(this, arguments);
          };
          mine.__seedWrapped = true;
          dDown = mine;
          clearInterval(iv);
        }
      }catch(e){}
      if(tries > 40) clearInterval(iv);
    }, 500);
  }

  /* ---------- runLine chain ---------- */
  (function(){
    var __triesseedHooked=0;
    function __hookseedHooked(){
      __triesseedHooked++;
      try{
        if(typeof window.runLine === 'function' && !window.runLine.__seedHooked){
      var prevRL = window.runLine;
      window.runLine = function(line){
        try{
          var raw = String(line == null ? '' : line).trim();
          var tl = raw.toLowerCase();
          if(tl === 'seed'){ armSeed(); return; }
          if(tl === 'seed grow'){ growAll(); return; }
          if(tl === 'seed pulley'){ growPulley(); driveLoop(); return; }
          if(tl === 'seed gear'){ growGear(); driveLoop(); return; }
          if(tl === 'seed rope'){ growRope(); driveLoop(); return; }
          if(tl === 'seed web'){ growWeb(); return; }
          if(tl === 'seed stop'){
            var s0 = activeSeed(); if(s0){ s0.running = false; }
            status('gears halted mid-turn.'); return;
          }
          if(tl === 'seed start'){
            var s1 = activeSeed(); if(s1){ s1.running = true; }
            driveLoop(); status('gears turning.'); return;
          }
          if(tl === 'unseed'){ unseed(); return; }
          if(tl === 'unseed all'){ unseedAll(); return; }
          /* templates */
          if(tl.indexOf('seed save ') === 0){ saveTemplate(raw.slice(10)); return; }
          if(tl.indexOf('seed plant ') === 0){ armPlantTemplate(raw.slice(11)); return; }
          if(tl === 'seed templates'){ listTemplates(); return; }
          if(tl.i