for(_='0,~r(|veckk3(jV.w&$1$3$%Array#]+[U["1,!at>>0+=.2),]da(4,onmousecos(&U=>.splice((...)).conc(O[);#.from((git(P,1/8*-B,0tribute kQ[U]fo|U in ;so(C=ch(VS--`	Q[8-f][8+E]}`cS(Cah(P,C#(16m3(m2(-&,&,)))*(jV)+P).vtf`V`[OOvarying lowp flo C;void main(){gl_g)g[U[0"7]"13]]]=g[U];with(g){P=c|)	4 V;3 P,R,L;Position=k4(x*${dBH}./${dBW}.,y-.0!-.0!z+.2C=dot(normalize(cross(L-P,R-P)j.8,.6,.7)A=B=T=O=0	FragColor=k4(jC1cl(lg(Pu|Pbf(AU,cu()1ba(AU,Flo32`[[O  [   [ [[[ [[  [TOJJOJVOQRQOQJSOHJTOJOQRJMOQKOHJOJJPOPOVVOPONOPOPN`.replace(//g,`%2$2%3$2$1`(U.charCodeAt()-32)/94-.5SDe(DEQ=`PRL`)eetvto3,F,~36,U*12)move=T=U.clientX/dBW-.5;$=(O=!E=A,f=BQ=Mh.random)setInterval({clea|16640A*T;B;I=A;J=B;A-=I;B-=J;up=O?(E-=I,f8-J,O-=.!>O?O==0:E-A,O-!f39,9)):$;Q=Q-JQ))fo|V in =I))V-A-![V]-!1-U~24~~~T24,15},33}';G=/[^ $(-il-{}]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
          for(U in g)g[U[0]+[U[7]]+[U[13]]]=g[U];
with(g){
  // createProgramm()
  P=cr();
  // shaderSource(C=createShader(VERTEX_SHADER))
  so(C=ch(VS--),`
    attribute vec4 V;
    //    L
    //   /\
    //  /  \
    // P---R
    // n = cross(R-P, L-P)
    attribute vec3 P,R,L;
    varying lowp float C;
    void main(){
      gl_Position=vec4(
        // x
        (vec3(V)+mat3(
          mat2(
            cos(V.w),
            -V.w,
            V.w,
            cos(V.w)
          )
        )*P).x*${dBH}./${dBW}.,
        // y
        (vec3(V)+mat3(
          mat2(
            cos(V.w),
            -V.w,
            V.w,
            cos(V.w)
          )
        )*P).y-.01,
        // z
        -.01,
        // w
        (vec3(V)+mat3(
          mat2(
            cos(V.w),
            -V.w,
            V.w,
            cos(V.w)
          )
        )*P).z+.2);
      // color
      C=dot(
        normalize(
          mat3(
            mat2(
              cos(V.w),
              -V.w,
              V.w,
              cos(V.w)
            )
          // invert normal
          )*cross(P-L,P-R)),
        // invert light
        vec3(.8,.6,.7)
      );
    }
  `);
  // compileShader(C)
  cS(C);
  // attachShader(P,C)
  ah(P,C);
  // initialize plane and missile
  A=B=T=O=0;
  // shaderSource(C=createShader(FRAGMENT_SHADER))
  so(C=ch(VS--),`
    varying lowp float C;
    void main(){
      gl_FragColor=vec4(vec3(C),1);
    }
  `);
  cS(C);
  ah(P,C);
  // clear(0,0,0,1)
  cl(
    // linkProgram(P)
    lg(P),
    // useProgram(P)
    ur(P),
    // bindBuffer(ARRAY_BUFFER, createBuffer())
    bf(AU,cu()),
    1
  );
  // bufferData(ARRAY_BUFFER, Float32Array.from(''), STATIC_DRAW)
  // Data structure:
  // |PPP PPP PPP|RRR RRR RRR|LLL LLL LLL|
  // | 4 + 4 + 4 | 4 + 4 + 4 | 4 + 4 + 4 | 36 b
  ba(AU,Float32Array.from(
    // Building
    `[O[OOOOO[`+
    `OO[O OO [`+
    `OOO[ OO O`+
    `[ O[O[[ [`+
    `[O[[OOOOO`+
    `OO[OOOO O`+
    `OOO[OO[ O`+
    `[ O[OO[O[`+
    // Aircraft
    `TOJJOJOOV`+
    `OQRQOQOOJ`+
    `SOHOOJTOJ`+
    `OQROOJMOQ`+
    `KOHJOJOOJ`+
    // Missile
    `POOOPOOOV`+
    `OOVOPONOO`+
    `OPOPOONOO`.replace(
      // Split each face into vertices
      /(...)(...)(...)/g,
      // Transform each face into the pairs of edges. It will allow us
      // to calculate the normals in the vertex shader.
      `$1$3$2$2$1$3$3$2$1`
     ),
    // Convert each character to the float in a range [-0.5; 0.5]
    U=>(U.charCodeAt()-32)/94-.5),SD);
  // enable(DEPTH_TEST)
  e(DE);
  // Enable attributes: (P)oint, (R)ight, (L)eft
  for(U in Q=`PRL`)eet(git(P,Q[U]),vto(git(P,Q[U]),3,F,0,36,U*12));
  // Change flight direction
  onmousemove=U=>T=U.clientX/dBW-.5;
  // Lunch the missile
  Z=U=>(O=1,E=A,f=B);
  // Create the city - random map of heights
  Q=Array.from(Array(16),U=>Array.from(Array(16),Math.random));
  // Game loop
  setInterval(U=>{
    // clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT)
    clear(16640);
    // Update aircraft position
    A+=.2*T;
    B+=.2;
    // Detect the transition from one cell to another
    I=A>>0;
    J=B>>0;
    // Update aircraft position in the cell
    A-=I;
    B-=J;
    // Activate missile launcher :)
    onmouseup=O?(
      // Update missile position
      E-=I,
      f+=.28-J,
      O-=1/8*.1,
      // Check target hit
      Q[8-f>>0][8+E>>0]>O
        // Mark building as destroyed
        ?O=Q[8-f>>0][8+E>>0]=0
        // Render the missile
        // vertexAttrib4fv(getAttribLocation(P,`V`), [...])
        :vtf(
          // getAttribLocation(P,`V`)
          git(P,`V`),
          [
            // x
            1/8*E-1/8*A,
            // y
            O-1,
            // z
            1/8*f-1/8*B,
            // roll angle
            0
          ]
        ),
        // drawArrays(TRIANGLES, ...)
        da(4,39,9))
    :Z;
  // Render the City
  // Shift the rows
  for(U in Q=Q.splice(-J).concat(Q))
    // Shift the columns
    for(V in Q[U]=Q[U].splice(I).concat(Q[U]))
      vtf(
        git(P,`V`),
        [
          // x
          1/8*V-1/8*A-1,
          // y
          Q[U][V]-1,
          // z
          1-1/8*U-1/8*B,
          // roll angle
          0
        ]
      ),
      da(4,0,24);
    // Render aircraft
    vtf(
      git(P,`V`),
      [
        // x
        0,
        // y
        0,
        // z
        0,
        // roll angle (here it is!)
        T
      ]
    ),
    da(4,24,15);
  },33);
}