for(_='O<$]:$#4*I"=B(!*ow;s.20h.set(.fill(v,O==(50/5-e/8)(j)*v/2]+&&=P.data,(x]*=f,for(--;)),x=xy=	ImageData(=>{~~((O,oI,y)]*,l[i,y/2s=Math,t=random,B=sin,d=cos,DOP=c.createw=510,v=w/2l=Array(w*w)e=0hx=y=v;Ou=x-j=y-u*u+j*j>v*v*.9(j=t()*PI,x=v+dy=v+B)l[I+=g(y+=g())+;;Oi=w*w-i-- >)]-1+1-w+w])/5;A=v/l.reduce()=>max))}I)=>O+o*wg>3*t())-1rahv	0;y<y++){=A,f=.7+(-w-1]*A-O)/30,o!(y+x*y)*x*ym=$?[99+O1+5+O,235-O#60?m=[180#1O>90o>.5?(O+=[76+23135+2952+13]):$1?[129+3226+990+3#2?[0+92+50+9]:[v],m[0m[1m[2y-O*O/1e3);do{O>=0m,",O/2)))}while(y>O++)}}D(1e6r(C,y)n=3;nh[")+n=y}Np=l,M=A,D(1e5setInterval(oe--,N,0	yp[M,i="-2)$30(h[i+1!y+d(+y)q!y/9-e/4$53+qO>=30+qC-2O-25l[M,C-e-O/3C+99-e)-,O);c.putP,0,0)},40);';G=/[^ &-~]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
          // Constants.
s = Math;
t = s.random;
U = s.sin;
L = s.cos;
//c = a.getContext("2d");	// Handled by JS1K shim
//
D = _ => {
	//J = c.createImageData(a.width=w=510, a.height=v=w/2) // Handled by JS1K shim
	J = c.createImageData(w=510, v=w/2)
	l = Array(w*w).fill(Q=0)
	h = J.data;
	// Generate map.
	x=y=v;
	while(_--){
		u=x-v;
		j=y-v;
		// Check distance.
		if(u*u+j*j>v*v*.9){
			j=t()*s.PI;
			x=v+~~(L(j)*v/2)
			y=v+~~(U(j)*v/2)
		}
		// Increament point.
		l[I(x+=g(),y+=g())]++
	}
	// Simple blur function.
	// Not accurate, in the sense that there's no horizontal bounds checking.
	// It just doesn't cause any problems in this use case.
	for(_=50;_--;){
		i=w*w-w;
		while(i-->w){
			l[i]=(l[i]+l[i-1]+l[i+1]+l[i-w]+l[i+w])/5
		}
	}
	// Max height of map.
	H = v / l.reduce((a, _) => s.max(a, _))
};
// Convert coords to I.
I=(x,y)=>x+y*w;
// Get a random offset (-1, 0, 1).
g=_=>~~(t()*3)-1;
// Render function.
r=_=>{
	h.fill(v)
	for(x=w;x--;){
		for(y=0;y<w;y++){
			z=l[i=I(x,y)]*H;
			// Shadows.
			S=.7+(l[i-w-1]*H-z)/30;
			// Noise
			o = U((y+x*y)*x*y)
			// Water.
			m = z<50
				?[99+z*o,150+o*5+z,235-z]
			// Beach.
			:z<60
				?m = [v, v, 180]
			// Trees.
			:z<150&&z>90&&o>.5
				?(z+=20*o,[76+o*23, 135+o*29, 52+o*13])
			// Grass.
			:z<150
				?[129+o*3, 226+o*9, 90+o*3]
			// Mountain-side.
			:z<220
				?[200+o*9, 220+o*5, 200+o*9]
			// Mountain-top.
			:[v,v,v];
			m[0]*=S;
			m[1]*=S;
			m[2]*=S;
			//
			z = ~~(y - z*z/1e3)
			do {
				if(z>=0)
					h.set(m,I(x,~~(z/2))*4)
			} while (y>z++)
		}
	}
}
D(1e6)
r()
// Modify the color of a pixel at "X"/"Y" by "_"
Y=(X,Y,_)=>{
	for(n=3;n--;)
		h[I(X,Y)*4+n]+=_
};
// Clouds.
k=J.data;
p=l;
M = H;
D(1e5)
setInterval(_=>{
	Q--;
	h.set(k,0)
	for(x=w;x--;){
		for(y=w;y--;){
			// Water animation
			z=p[I(x,y)]*M;
			i=I(x,~~(y/2-2))*4;
			if (z < 30) {
				h[i+1]+=U(y/5-Q/8)+L((x+y)/5-Q/8)
			}
			// Shore wave animation
			q=U(y/9-Q/4)
			if (z<53+q && z>=30+q) {
				Y(x,~~(y/2-2),z-25)
			}
			// Cloud.
			z=l[I(x,y)]*M;
			Y(x-Q,~~(y/2),-z/3)
			Y(x+99-Q,~~(y/2)-50,z)
		}
	}
	c.putImageData(J,0,0)
},40)