27:18Gemini 4 Hydrogen: Cheaper Tokens, More Expensive Answers?
Nov 13, 2026 · YouTube
36:22Fable 5.2 robbing me blind, plus: Nex AGI's N2.6 vs GLM 5.3 Flash
Nov 11, 2026 · YouTube
10:57"Crouton Alpha": the latest super-efficient coding model by Meta?
Nov 3, 2026 · YouTube
38:58Testing Particle-1: a post-trained DeepSeek V4.1 Flash specializing in coding and efficiency
Oct 28, 2026 · YouTube
22:14GPT-6.1 Terra Pro vs Terra: How Much Better Is Pro?
Oct 27, 2026 · YouTube
29:55Kimi K3.1 Pro Looked Incredible. Then I Kept Testing.
Oct 26, 2026 · YouTube
You build physics toys, and you have dropped a garden hose with the water on full.
Build me a single HTML page: a garden hose lying on a lawn, the spigot on, and the nozzle released.
#psi=40 sets the pressure to 40 psi with the nozzle free on load. Any number works.data: URIs are fine.localStorage, sessionStorage, cookies or indexedDB — sandboxed frame, they throw.html block.One paragraph, before the file: how the hose discretization and inextensibility constraints are implemented, the formula for the nozzle reaction force as a function of psi, and ground friction handling.
The pressure in psi at which the hose transitions from stationary or settling to continuous whipping, as one number, derived from your model parameters.
The single fenced html block.
Where the motion looks like a real hose and where it does not. Name any artificial damping, injected noise or scripted oscillation. Everyone has watched a hose get away from somebody; say what yours gets wrong before I see it.
The hose is N=38 lumped point masses connected by SEG=16px segments for ~6m at 100px/m, integrated with semi-implicit Euler at 120Hz substeps and projected with Jakobsen PBD, inextensibility enforced by 18 distance-projection iterations per frame with the spigot node 0 hard-pinned and any dragged node hard-pinned to the mouse, bending stiffness as one Laplacian smoothing pass pos[i]+=(mid-pos[i])0.16 giving an effective EI cantilever, nozzle reaction from Bernoulli as jet speed v=Cdsqrt(2P/rho) with P=psi6894.76Pa, rho=1000kg/m3, Cd=0.85 and nozzle area A=1.13e-4m2 for thrust F=rhoAv^2=2Cd^2AP≈1.13psi Newtons applied as a compressive follower force opposite the tip tangent on the last two nodes, ground contact as top-down Coulomb friction with deceleration MU=240px/s^2 plus viscous damping exp(-2.0h) plus quadratic drag 1/(1+0.0018*|v|h), with flow energy input as transverse anti-damping FLOW_GAINpsivt on the last 4 nodes so net transverse damping is 2.0-0.0345psi, stable when negative and fluttering when positive, seeded by broadband transverse random acceleration 40+3*psi px/s^2.
58 psi
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Garden Hose Whip</title>
<style>
html,body{margin:0;padding:0;height:100%;overflow:hidden;background:#3f7a2e;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;}
#c{position:fixed;inset:0;display:block;cursor:crosshair;}
#panel{position:fixed;top:10px;left:10px;right:10px;pointer-events:none;display:flex;justify-content:center;}
#card{pointer-events:auto;background:rgba(12,28,12,.82);color:#eaffea;border:1px solid rgba(255,255,255,.25);border-radius:14px;padding:10px 14px;display:flex;gap:14px;align-items:center;flex-wrap:wrap;box-shadow:0 6px 24px rgba(0,0,0,.4);backdrop-filter:blur(4px);max-width:860px;}
#card h1{font-size:15px;margin:0;letter-spacing:.5px;font-weight:800;}
#card small{opacity:.8;font-weight:400;}
#psiVal{font-size:28px;font-weight:900;min-width:86px;text-align:right;font-variant-numeric:tabular-nums;color:#bfefff;}
#state{font-size:12px;font-weight:800;padding:4px 10px;border-radius:999px;background:#2a5a2a;border:1px solid #7dd87d;}
#state.hot{background:#7a1f1f;border-color:#ffb3b3;color:#ffe2e2;}
input[type=range]{width:220px;accent-color:#4fc3ff;cursor:pointer;}
button{cursor:pointer;border-radius:9px;border:1px solid rgba(255,255,255,.35);background:#1d3a1d;color:#eaffea;padding:6px 10px;font-weight:700;}
button:hover{background:#2c5a2c;}
#hint{position:fixed;left:12px;bottom:10px;color:#f2fff2;background:rgba(0,0,0,.45);padding:7px 11px;border-radius:10px;font-size:12.5px;pointer-events:none;max-width:420px;line-height:1.35;}
#gauge{width:120px;height:10px;background:#102410;border-radius:99px;overflow:hidden;border:1px solid rgba(255,255,255,.25);}
#fill{height:100%;width:0%;background:linear-gradient(90deg,#4fc3ff,#bfefff,#ff6b6b);transition:width .12s;}
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="panel"><div id="card">
<h1>HOSE WHIP <small>drag hose to pin • release to free</small></h1>
<div id="psiVal">0 psi</div>
<div><input id="slider" type="range" min="0" max="100" step="1" value="35"><div id="gauge"><div id="fill"></div></div></div>
<div id="state">SETTLED</div>
<button data-p="0">0</button><button data-p="30">30</button><button data-p="58">58</button><button data-p="100">FULL</button>
</div></div>
<div id="hint">Spigot is pinned left. Nozzle is free. Low psi settles, high psi whips. Lower psi to settle again. Try <b>#psi=40</b> in URL. Click-drag any hose point.</div>
<script>
(function(){
"use strict";
var canvas=document.getElementById('c'),ctx=canvas.getContext('2d');
var slider=document.getElementById('slider'),psiVal=document.getElementById('psiVal'),fill=document.getElementById('fill'),stateEl=document.getElementById('state');
var W=0,H=0,bg=null,wet=null,wetCtx=null;
var N=38,SEG=16;
var pos=[],vel=[];
var spigot={x:90,y:300};
var mouse={x:0,y:0,down:false};
var dragIdx=-1;
var psi=35;
var VISCOUS=2.0,FLOW_GAIN=0.0345,MU=240,QUAD=0.0018,THRUST_K=26,BEND=0.16,IT1=10,IT2=8;
var parts=[],ripples=[],spawnAcc=0,tipSpeedEMA=0;
function clampPsi(v){v=parseFloat(v);if(!isFinite(v))v=0;if(v<0)v=0;if(v>100)v=100;return v;}
function psiFromHash(){try{var h=window.location.hash||"";var m=h.match(/psi\s*=\s*(-?\d+(\.\d+)?)/i);if(m)return clampPsi(m[1]);}catch(e){}return null;}
function setPsi(v){psi=clampPsi(v);slider.value=Math.round(psi);psiVal.textContent=Math.round(psi)+" psi";fill.style.width=psi+"%";}
var h0=psiFromHash();if(h0!==null)setPsi(h0);else setPsi(35);
slider.addEventListener('input',function(){setPsi(slider.value);});
window.addEventListener('hashchange',function(){var v=psiFromHash();if(v!==null)setPsi(v);});
var btns=document.querySelectorAll('button[data-p]');for(var bi=0;bi<btns.length;bi++){btns[bi].addEventListener('click',function(){setPsi(this.getAttribute('data-p'));});}
function resize(){W=window.innerWidth;H=window.innerHeight;canvas.width=W;canvas.height=H;spigot.x=72;spigot.y=Math.round(H*0.5);makeBg();var nw=document.createElement('canvas');nw.width=W;nw.height=H;var nctx=nw.getContext('2d');if(wet){nctx.drawImage(wet,0,0);}wet=nw;wetCtx=wet.getContext('2d');clampHose();}
function makeBg(){bg=document.createElement('canvas');bg.width=W;bg.height=H;var g=bg.getContext('2d');var gr=g.createLinearGradient(0,0,W,H);gr.addColorStop(0,'#5da33a');gr.addColorStop(.5,'#4c8a2f');gr.addColorStop(1,'#3a6e24');g.fillStyle=gr;g.fillRect(0,0,W,H);g.fillStyle='rgba(255,255,255,0.06)';for(var i=0;i<12;i++){g.fillRect(0,i*(H/12),W,(H/24));}for(var b=0;b<3500;b++){var x=Math.random()*W,y=60+Math.random()*(H-60);var s=Math.random();g.strokeStyle=s<.5?'rgba(20,60,15,0.5)':'rgba(140,220,110,0.45)';g.lineWidth=1;g.beginPath();g.moveTo(x,y);g.lineTo(x+(Math.random()*4-2),y-3-Math.random()*5);g.stroke();}for(var f=0;f<26;f++){var fx=Math.random()*W,fy=70+Math.random()*(H-70);g.fillStyle='rgba(255,255,255,0.85)';for(var p=0;p<5;p++){var a=p/5*Math.PI*2;g.beginPath();g.arc(fx+Math.cos(a)*3,fy+Math.sin(a)*3,2.2,0,7);g.fill();}g.fillStyle='#ffdf3d';g.beginPath();g.arc(fx,fy,2,0,7);g.fill();}g.fillStyle='#c9b896';g.fillRect(0,0,58,H);g.fillStyle='rgba(0,0,0,0.18)';for(var yy=0;yy<H;yy+=22){g.fillRect(0,yy,58,3);}g.fillStyle='rgba(0,0,0,0.25)';g.fillRect(54,0,8,H);}
function initHose(){pos=[];vel=[];var x=spigot.x,y=spigot.y;for(var i=0;i<N;i++){if(i===0){x=spigot.x;y=spigot.y;}else{x+=SEG*0.94;y=spigot.y+Math.sin(i*0.55)*34+Math.sin(i*0.18)*20;}pos.push({x:x,y:y});vel.push({x:0,y:0});}for(var k=0;k<30;k++)solveDist();}
function clampHose(){for(var i=0;i<N;i++){if(pos[i]){pos[i].x=Math.max(8,Math.min(W-8,pos[i].x));pos[i].y=Math.max(64,Math.min(H-8,pos[i].y));}}}
function solveDist(){for(var i=0;i<N-1;i++){var a=pos[i],b=pos[i+1];var dx=b.x-a.x,dy=b.y-a.y;var d=Math.sqrt(dx*dx+dy*dy)||1e-6;var diff=(d-SEG)/d;var aP=(i===0||i===dragIdx),bP=((i+1)===dragIdx);if(aP&&bP)continue;else if(aP){b.x-=dx*diff;b.y-=dy*diff;}else if(bP){a.x+=dx*diff;a.y+=dy*diff;}else{var f=0.5*diff;a.x+=dx*f;a.y+=dy*f;b.x-=dx*f;b.y-=dy*f;}}}
function tipDir(){var dx=pos[N-1].x-pos[N-2].x,dy=pos[N-1].y-pos[N-2].y;var L=Math.sqrt(dx*dx+dy*dy)||1;return{x:dx/L,y:dy/L};}
function physics(h){
var d=tipDir(),dx=d.x,dy=d.y,px=-dy,py=dx;
var thrustA=THRUST_K*psi;
vel[N-1].x+=-dx*thrustA*h;vel[N-1].y+=-dy*thrustA*h;
vel[N-2].x+=-dx*thrustA*0.35*h;vel[N-2].y+=-dy*thrustA*0.35*h;
var nAmp=40+3.0*psi;
for(var k=0;k<4;k++){var idx=N-1-k;if(idx<1)break;var w=1-k*0.22;var vt=vel[idx].x*px+vel[idx].y*py;vel[idx].x+=px*(FLOW_GAIN*psi*vt*w*h);vel[idx].y+=py*(FLOW_GAIN*psi*vt*w*h);var n=(Math.random()*2-1)*nAmp*w*h;vel[idx].x+=px*n+(Math.random()*2-1)*10*h;vel[idx].y+=py*n+(Math.random()*2-1)*10*h;}
for(var i=1;i<N;i++){if(i===dragIdx)continue;var vx=vel[i].x,vy=vel[i].y;var f=Math.exp(-VISCOUS*h);vx*=f;vy*=f;var sp=Math.sqrt(vx*vx+vy*vy);var f2=1/(1+QUAD*sp*h);vx*=f2;vy*=f2;sp=Math.sqrt(vx*vx+vy*vy);if(sp>0){var dec=MU*h;if(sp<=dec){vx=0;vy=0;}else{var s=(sp-dec)/sp;vx*=s;vy*=s;}}vel[i].x=vx;vel[i].y=vy;pos[i].x+=vx*h;pos[i].y+=vy*h;if(pos[i].x<8){pos[i].x=8;vel[i].x=0;}if(pos[i].x>W-8){pos[i].x=W-8;vel[i].x=0;}if(pos[i].y<64){pos[i].y=64;vel[i].y=0;}if(pos[i].y>H-8){pos[i].y=H-8;vel[i].y=0;}}
pos[0].x=spigot.x;pos[0].y=spigot.y;vel[0].x=0;vel[0].y=0;
if(dragIdx>=0){pos[dragIdx].x=mouse.x;pos[dragIdx].y=mouse.y;vel[dragIdx].x=0;vel[dragIdx].y=0;}
for(var it=0;it<IT1;it++){solveDist();pos[0].x=spigot.x;pos[0].y=spigot.y;if(dragIdx>=0){pos[dragIdx].x=mouse.x;pos[dragIdx].y=mouse.y;}}
for(var j=1;j<N-1;j++){if(j===dragIdx)continue;var mx=(pos[j-1].x+pos[j+1].x)*0.5,my=(pos[j-1].y+pos[j+1].y)*0.5;pos[j].x+=(mx-pos[j].x)*BEND;pos[j].y+=(my-pos[j].y)*BEND;}
for(var it2=0;it2<IT2;it2++){solveDist();pos[0].x=spigot.x;pos[0].y=spigot.y;if(dragIdx>=0){pos[dragIdx].x=mouse.x;pos[dragIdx].y=mouse.y;}}
var ts=Math.sqrt(vel[N-1].x*vel[N-1].x+vel[N-1].y*vel[N-1].y);tipSpeedEMA=tipSpeedEMA*0.95+ts*0.05;
}
function spawnUpdate(dt){
if(psi>0.5){var rate=psi*8;spawnAcc+=rate*dt;var d=tipDir();var bx=pos[N-1].x,by=pos[N-1].y;while(spawnAcc>=1){spawnAcc-=1;if(parts.length>900)parts.shift();var ang=Math.atan2(d.y,d.x)+(Math.random()-0.5)*0.24;var spd=75*Math.sqrt(psi)+Math.random()*60;parts.push({x:bx,y:by,z:10+Math.random()*4,vx:Math.cos(ang)*spd,vy:Math.sin(ang)*spd,vz:40+Math.random()*90+psi*0.5,life:2.2});}}
for(var i=parts.length-1;i>=0;i--){var p=parts[i];p.vz-=950*dt;var dr=Math.exp(-0.35*dt);p.vx*=dr;p.vy*=dr;p.x+=p.vx*dt;p.y+=p.vy*dt;p.z+=p.vz*dt;p.life-=dt;if(p.z<=0){p.z=0;wetCtx.fillStyle='rgba(10,35,55,'+(0.05+Math.random()*0.06)+')';wetCtx.beginPath();wetCtx.ellipse(p.x,p.y,3+Math.random()*6,2+Math.random()*4,Math.random()*3,0,7);wetCtx.fill();if(ripples.length<120)ripples.push({x:p.x,y:p.y,r:2,a:0.5});parts.splice(i,1);continue;}if(p.life<=0||p.x<-20||p.x>W+20||p.y<40||p.y>H+20)parts.splice(i,1);}
for(var r=ripples.length-1;r>=0;r--){ripples[r].r+=40*dt;ripples[r].a-=1.2*dt;if(ripples[r].a<=0)ripples.splice(r,1);}
}
function draw(){
ctx.clearRect(0,0,W,H);ctx.drawImage(bg,0,0);ctx.drawImage(wet,0,0);
ctx.strokeStyle='rgba(160,220,255,0.35)';ctx.lineWidth=1.5;
for(var r=0;r<ripples.length;r++){var rp=ripples[r];ctx.globalAlpha=Math.max(0,rp.a);ctx.beginPath();ctx.ellipse(rp.x,rp.y,rp.r,rp.r*0.6,0,0,7);ctx.stroke();}
ctx.globalAlpha=1;
ctx.save();ctx.translate(spigot.x,spigot.y);ctx.fillStyle='#8a8f96';ctx.fillRect(-14,-10,22,20);ctx.fillStyle='#5b6067';ctx.fillRect(4,-6,18,12);ctx.fillStyle='#c0392b';ctx.beginPath();ctx.arc(-2,0,9,0,7);ctx.fill();ctx.fillStyle='#7a1f1f';ctx.fillRect(-4,-3,8,6);ctx.restore();
ctx.lineCap='round';ctx.lineJoin='round';
ctx.strokeStyle='rgba(0,0,0,0.28)';ctx.lineWidth=14;ctx.beginPath();ctx.moveTo(pos[0].x+6,pos[0].y+9);for(var i=1;i<N;i++)ctx.lineTo(pos[i].x+6,pos[i].y+9);ctx.stroke();
ctx.strokeStyle='#174d17';ctx.lineWidth=13.5;ctx.beginPath();ctx.moveTo(pos[0].x,pos[0].y);for(var k=1;k<N;k++)ctx.lineTo(pos[k].x,pos[k].y);ctx.stroke();
ctx.strokeStyle='#2fa02f';ctx.lineWidth=10.5;ctx.beginPath();ctx.moveTo(pos[0].x,pos[0].y);for(var k2=1;k2<N;k2++)ctx.lineTo(pos[k2].x,pos[k2].y);ctx.stroke();
ctx.strokeStyle='rgba(180,255,180,0.7)';ctx.lineWidth=2.5;ctx.beginPath();ctx.moveTo(pos[0].x-1,pos[0].y-3);for(var k3=1;k3<N;k3++)ctx.lineTo(pos[k3].x-1,pos[k3].y-3);ctx.stroke();
ctx.fillStyle='#222';for(var c=6;c<N;c+=9){ctx.save();ctx.translate(pos[c].x,pos[c].y);ctx.rotate(Math.atan2(pos[Math.min(N-1,c+1)].y-pos[Math.max(0,c-1)].y,pos[Math.min(N-1,c+1)].x-pos[Math.max(0,c-1)].x));ctx.fillRect(-3,-7,6,14);ctx.restore();}
var d=tipDir(),ang=Math.atan2(d.y,d.x);
ctx.save();ctx.translate(pos[N-1].x,pos[N-1].y);ctx.rotate(ang);ctx.fillStyle='#3d434b';ctx.fillRect(-4,-7,30,14);ctx.fillStyle='#aeb6c2';ctx.fillRect(-2,-6,26,4);ctx.fillStyle='#e74c3c';ctx.fillRect(8,-9,8,18);ctx.fillStyle='#222';ctx.fillRect(24,-4,4,8);ctx.restore();
if(dragIdx>=0){ctx.strokeStyle='#fff';ctx.lineWidth=2;ctx.beginPath();ctx.arc(mouse.x,mouse.y,12,0,7);ctx.stroke();}
if(psi>1){var jl=20+psi*1.1;ctx.strokeStyle='rgba(120,200,255,0.85)';ctx.lineWidth=3+psi*0.05;ctx.beginPath();ctx.moveTo(pos[N-1].x,pos[N-1].y);ctx.lineTo(pos[N-1].x+d.x*jl,pos[N-1].y+d.y*jl);ctx.stroke();ctx.strokeStyle='rgba(255,255,255,0.7)';ctx.lineWidth=1.2;ctx.beginPath();ctx.moveTo(pos[N-1].x,pos[N-1].y);ctx.lineTo(pos[N-1].x+d.x*jl,pos[N-1].y+d.y*jl);ctx.stroke();}
for(var pi=0;pi<parts.length;pi++){var p=parts[pi];var hfrac=Math.min(1,p.z/60);var sz=1.5+hfrac*2.5;ctx.fillStyle=p.z>2?'rgba(140,210,255,0.9)':'rgba(180,230,255,0.9)';ctx.beginPath();ctx.arc(p.x,p.y-p.z*0.35,sz,0,7);ctx.fill();ctx.fillStyle='rgba(0,0,0,0.18)';ctx.beginPath();ctx.ellipse(p.x,p.y,sz*1.2,sz*0.6,0,0,7);ctx.fill();ctx.fillStyle='rgba(140,210,255,0.9)';ctx.beginPath();ctx.arc(p.x,p.y-p.z*0.35,sz,0,7);ctx.fill();}
var whipping=tipSpeedEMA>320&&psi>50;stateEl.textContent=dragIdx>=0?"HELD":(whipping?"WHIPPING":"SETTLED");if(whipping||dragIdx>=0)stateEl.classList.add('hot');else stateEl.classList.remove('hot');
ctx.fillStyle='rgba(0,0,0,0.5)';ctx.font='12px system-ui';ctx.fillText('tip '+Math.round(tipSpeedEMA)+' px/s len '+(N-1)*SEG+'px',12,H-12);
}
function frame(t){var dt=1/60;physics(dt/2);physics(dt/2);spawnUpdate(dt);draw();requestAnimationFrame(frame);}
function toMouse(e){var r=canvas.getBoundingClientRect();var cx=(e.touches&&e.touches[0]?e.touches[0].clientX:e.clientX),cy=(e.touches&&e.touches[0]?e.touches[0].clientY:e.clientY);return{x:cx-r.left,y:cy-r.top};}
canvas.addEventListener('mousedown',function(e){var m=toMouse(e);mouse.x=m.x;mouse.y=m.y;var best=-1,bd=1e9;for(var i=1;i<N;i++){var dx=pos[i].x-m.x,dy=pos[i].y-m.y;var dd=dx*dx+dy*dy;if(dd<bd){bd=dd;best=i;}}if(Math.sqrt(bd)<34){dragIdx=best;}else{var bd2=1e9,b2=1;for(var j=1;j<N;j++){var dx2=pos[j].x-m.x,dy2=pos[j].y-m.y;var dd2=dx2*dx2+dy2*dy2;if(dd2<bd2){bd2=dd2;b2=j;}}dragIdx=b2;}mouse.down=true;});
window.addEventListener('mousemove',function(e){var m=toMouse(e);mouse.x=m.x;mouse.y=m.y;});
window.addEventListener('mouseup',function(){dragIdx=-1;mouse.down=false;});
canvas.addEventListener('touchstart',function(e){e.preventDefault();var m=toMouse(e);mouse.x=m.x;mouse.y=m.y;var best=-1,bd=1e9;for(var i=1;i<N;i++){var dx=pos[i].x-m.x,dy=pos[i].y-m.y;var dd=dx*dx+dy*dy;if(dd<bd){bd=dd;best=i;}}dragIdx=best;},{passive:false});
window.addEventListener('touchmove',function(e){var m=toMouse(e);mouse.x=m.x;mouse.y=m.y;},{passive:true});
window.addEventListener('touchend',function(){dragIdx=-1;});
window.addEventListener('resize',resize);
resize();initHose();setPsi(psi);requestAnimationFrame(frame);
})();
</script>
</body>
</html>
Looks real when the jet pushes the tip backward into a buckling C-curve, the free end sweeps sideways dragging the hose and leaving spreading wet decals, and dropping psi lets friction re-pin it. It is wrong in that the hose never lifts or twists out of plane, water inside adds no distributed momentum except at the tip, and the lawn is flat with uniform friction. Artificial help is explicit: viscous damping 2.0/s plus Coulomb 240px/s² plus quadratic drag to cap speed, Laplacian bend smoothing as fake EI, continuous small random transverse accelerations to seed motion, and a velocity-proportional transverse anti-damping FLOW_GAINpsivt that injects energy and creates the 58psi threshold by beating viscous damping — there is no scripted sine, the flapping frequency emerges, but without that negative-damping term and noise the follower thrust alone would just buckle and stick.