for(_='](~c[c.`;`_"_fc~^Math.ZZcos(Y()XfillXWZsin(VVf/U]=TT"#R0,Q,Q7Pba~O;t(NforL.b,KQ2J.aH16G,bB);AA`l~@8B-4@a5,276@=-h*l+Ac.scale(*aX*d-db7aa45"&&(=d+1A0>255, GB+4+e@aaBm(,e,d,g)=32+32*eX,_ta~var 20_Oarc(,Q300)_bC~	10D)*aH*(1+h)k[a]strokeXfunction_fyRW_OA`m~L(v in c)c[v[0]+[v[6]]Tv;f=Qk=[]; {b=b+2;e=e+1/2;d=d+*aX-8;0>b-dbe-de=d||(0>g?g=0:0<gg=,`fyT"rgba(0.5)",`O),cHrc(b,e,dP),c.W,)} n(a){if(a){b=aKe=X{b=(8*b+9)%7;return b/6},dgl=g-d,h=aH/400*8,CQl15QD=7*aKr=Y;a=VC+r,l+ah,hAm(e,QQg,d1/h,1/h)-C-r,-l-a)}} t(){`sSR_ldT3GPA`m~+G@+0}setInterval(X{f++;L(a=8;a--;)||(={b:ZrandomX,a:9}),H+=.3*K0<H=aabbFF^QQ406D8448"5	GJ,GQ3,087a45a"	QQQ	30J9J5Q400N19QN15J3N23J4;k.LEach(nAa=0+0*Yf/5B=150+*U,e=0<U4)?-9:0@a---8B@a+++8Bdbcb53"4P;a=*U5a,7c652e^198,24Q4,6_sSRffe0bd"_ldT7195@18199,2642,305@211,252-a,},17A';G=/[^ -?C-FIMS[\]a-}]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
          // a = Canvas Element
  // c = 2d Context
  const canvasWidth = 400;
  const canvasHeight = 300;
  let time = 0;
  const skyColor = '#aabbFF';
  const skinColor = '#ffe0bd';
  const broomColor = '#7c652e';
  const snitchColor = '#dbcb53';
  const snitchWingColor = '#b7aa45';
  const cloudColor = 'rgba(255, 255, 255, 0.5)';
  const broomWidth = 4;
  const broomDepth = 60;
  const broomLeft = canvasWidth / 2 - broomWidth / 2;
  const broomTop = canvasHeight - broomDepth;
  const armDistanceFromBroom = 8;
  const maxClouds = 8;
  const maxCloudDistance = canvasWidth;
  const minCloudRadius = 32;
  const maxCloudSpeed = .3;
  const wingWidth = 16;
  const wingHeight = 8;
  const MathPI2 = 7;
  const clouds = [];
  function renderSkyBackground() {
    c.fillStyle = skyColor;
    c.fillRect(0, 0, canvasWidth, canvasHeight);
  }
  function renderArmsAndBroomstick() {
    const armsMovement = Math.sin(time / 50) * 20;
    c.translate(armsMovement, 0);
    // Render broom
    c.fillStyle = broomColor;
    c.fillRect(
      broomLeft,
      broomTop,
      broomWidth,
      broomDepth
    );
    // Render arms
    c.strokeStyle = skinColor;
    c.lineWidth = 7;
    c.beginPath();
    c.moveTo(broomLeft - armDistanceFromBroom, canvasHeight + 5); // add a bit to make offscreen
    c.lineTo(broomLeft - armDistanceFromBroom - 5, canvasHeight - broomDepth * .4);
    c.lineTo(broomLeft + 1, canvasHeight - broomDepth * .6);
    c.stroke();
    c.beginPath();
    c.moveTo(broomLeft + broomWidth + armDistanceFromBroom, canvasHeight + 5); // add a bit to make offscreen
    c.lineTo(broomLeft + broomWidth + armDistanceFromBroom + 5, canvasHeight - broomDepth * .4);
    c.lineTo(broomLeft + 3, canvasHeight - broomDepth * .8);
    c.stroke();
    c.translate(-armsMovement, 0);
  }
  function renderPartialCloud(nextFloat, xLast, yLast, rLast, lLast) {
    let x = xLast + nextFloat() * (2 * rLast) - rLast,
        y = yLast + nextFloat() * (1 * rLast) - rLast / 2,
        r = rLast + nextFloat() * 10 - 8,
        l = lLast;
    if (x - r < 0) x = r + 1;
    if (y - r < 0) y = r + 1;
    if (r <= 0) return;
    // TODO: Might be able to do this with some math clamp
    if (l < 0) l = 0;
    else if (l > 100) l = 100;
    // This is the short version of adding transparency
    c.fillStyle = cloudColor;
    c.beginPath();
    c.arc(
      x,
      y,
      r,
      0,
      MathPI2
    );
    c.fill();
    renderPartialCloud(nextFloat, x, y, r, l);
  }
  function renderCloud(cloud) {
    // If cloud has not been re-generated, skip
    if (!cloud) {
      return;
    }
    // Creating a random number generator here, using a seed
    // LCG using GCC's constants ~ Or crappy ones...
    const rngM = 7;
    const rngA = 8;
    const rngC = 9;
    let rngState = cloud.seed;
    const nextFloat = () => {
      rngState = (rngA * rngState + rngC) % rngM;
      return rngState / (rngM - 1)
    };
    // End of RNG
    const left = minCloudRadius + nextFloat() * minCloudRadius;
    const right = minCloudRadius + nextFloat() * minCloudRadius;
    const width = right - left;
    const scaleAmount = cloud.distance / maxCloudDistance * 8;
    const centerScaleX = (-scaleAmount * width) + canvasWidth / 2;
    const centerScaleY = (-scaleAmount * width) + canvasHeight / 2;
    const direction = cloud.seed * MathPI2;
    const dx = Math.cos(direction) * cloud.distance * (1 + scaleAmount);
    const dy = Math.sin(direction) * cloud.distance * (1 + scaleAmount);
    // Translate and Scale must be done in this order...
    c.translate(
      centerScaleX + dx,
      centerScaleY + dy
    );
    c.scale(scaleAmount, scaleAmount);
    renderPartialCloud(
      nextFloat,
      0,
      0,
      // This makes the clouds differ in size
      right,
      left
    );
    c.scale(1 / scaleAmount, 1 / scaleAmount);
    c.translate(
      -centerScaleX - dx,
      -centerScaleY - dy
    );
  }
  function renderHoop(x, y) {
    c.strokeStyle = snitchWingColor;
    c.lineWidth = 3;
    c.beginPath();
    c.arc(
      x,
      y,
      16,
      0,
      MathPI2
    );
    c.moveTo(x, y + 16);
    c.lineTo(x, y + 100);
    c.stroke();
  }
  function renderSnitch() {
    // Move snitch in a believable flying motion
    const cx = canvasWidth / 2 + Math.cos(time / 50) * 100;
    const cy = canvasHeight / 2 + Math.sin(time / 100) * 20;
    // Using SIN movement as my toggle
    const movementAmount = Math.sin(time / 4) > 0 ? -9 : 0;
    // Left wing
    c.fillStyle = snitchWingColor;
    c.beginPath();
    c.moveTo(cx, cy);
    // top/middle of wing
    c.lineTo(cx - wingWidth / 2, cy - wingHeight / 2);
    // far left tip
    c.lineTo(cx - wingWidth, cy + wingHeight / 2 + movementAmount);
    // bottom/middle
    c.lineTo(cx - wingWidth / 2, cy);
    c.fill();
    // Right wing
    c.beginPath();
    c.moveTo(cx, cy);
    // top/middle of wing
    c.lineTo(cx + wingWidth / 2, cy - wingHeight / 2);
    // far left tip
    c.lineTo(cx + wingWidth, cy + wingHeight / 2 + movementAmount);
    // bottom/middle
    c.lineTo(cx + wingWidth / 2, cy);
    c.fill();
    // Body
    c.fillStyle = snitchColor;
    c.beginPath();
    c.arc(
      cx,
      cy,
      4,
      0,
      MathPI2
    );
    c.fill();
  }
  function renderMountains() {
    // Background
    c.fillStyle = '#6D8448';
    c.beginPath();
    c.moveTo(50, canvasHeight);
    c.bezierCurveTo(
      110 + 50, canvasHeight - 100 + 10,
      110 + 50, canvasHeight + 10,
      150 + 50, canvasHeight
    );
    c.fill();
    // Foreground
    c.fillStyle = '#87a45a';
    c.beginPath();
    c.moveTo(0, canvasHeight);
    c.bezierCurveTo(
      100, canvasHeight - 100,
      100, canvasHeight,
      200, canvasHeight
    );
    c.bezierCurveTo(
      300, canvasHeight - 10,
      300, canvasHeight - 50,
      canvasWidth, canvasHeight
    );
    c.fill();
  }
  function gameLoop() {
    // Update time
    time++;
    // Update clouds
    let i = maxClouds;
    while (i--) {
      // Generate if needed
      if (!clouds[i]) {
        clouds[i] = {
          seed: Math.random(),
          // Starting distance
          distance: 9
        };
      }
      // Move cloud closer
      const speed = clouds[i].seed * maxCloudSpeed;
      clouds[i].distance += speed;
      // Replace if offsceen
      if (clouds[i].distance > maxCloudDistance / 2) {
        clouds[i] = 0;
      }
    }
    // Draw all the things
    renderSkyBackground();
    renderMountains();
    renderHoop(canvasWidth / 2 - 10, canvasHeight - 100);
    renderHoop(canvasWidth / 2 - 10 - 40, canvasHeight - 70);
    renderHoop(canvasWidth / 2 - 10 + 40, canvasHeight - 60);
    clouds.forEach(renderCloud);
    renderSnitch();
    renderArmsAndBroomstick();
  }
  // 17 ~ 1000/60 ~ 60 frames per second
  setInterval(gameLoop, 17);