for(_='b].zesww[d%zqMath.!],$,e("@,8@?")$[kk8?jjGR`);_}_^+=se(ac.fillRect(a..lengtha0,,SEU6TC!random()0*var b=32*++Style="#.push({a:if(){return b}	=0;=a[,1j6SEY3C,6OONPCjfor(a,b)^function.forEach( e"";split(",")a=parInt,36).toString(2_32>;)a="0"+a;ba^	f=[[8?462DC6`BJ18,3ZTX4WV4M88M,GPG4CG`AY3G,DFGH6O`BIPQ,WUNOXS7TKL18k7?FNQYGBEUTR0Gk9?7S8B2FIW320OYHWYKGk9,9@5018XX8M0HUA1L0QOk144@22XG1U,ULF8GXT97JZYR4FZXV4BVD3F34NQ2,0")]$A=l m(a=f[n$b=[$d0$a2$g=y=xg<;g1=y*d+x])h=y;h<(y+1_h4)x2=x;x2<(x+1_x24)b192,b:108,c:x2+45f:h+200^x;x==d&&(x=y)}	nw=m(_wtTimeout((A=1},3E3_tInterval((333";0920080_fff";lwAc-a,d=f-b;ab/25;bd/25;1>b&&1>d&&l}l==w)n,n==f)wc=192;f=108;l=0^el{a=m(_p_w;<=b)w=;el dd<-b;d)wqa,b:qb,c:f:0^bb<w;b)w[zczc,w[zfzf;l=0}}6_ p-1;0<b;b--d=!floor(*(b+1)),gb];a[b]d];a[d]=g}};';G=/[-^-`jk?@$!qwz]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
          /*
 * Cosmos...  by Jason "--jp" Plackey
 * jp [at] chicagowebexperts [dot] com
 *
 * For JS1k 2016 - Let's get eleMental!
 * Final packed entry size is 1023b.
 * 
 */
var
    cvs = document.getElementById("cvs"),       // shimmed
    c = cvs.getContext("2d");                   // shimmed
function R() { return Math.random(); }
// Creates a new pixel object, which has a current point and a
// destination point.
function newEl(x, y, tx, ty) {
    return { curX: x, curY: y, targetX: tx, targetY: ty };
}
function drawEl(o) {
    c.fillRect(o.curX, o.curY, 1, 1);
}
function pad(s) {
    while (s.length < 32) {
        s = "0" + s;
    }
    return s;
}
// Functions `u` and `pad` form the sprite unpacker.
function u(s) {
    var U = s.split(',');
    var r = "";
    U.forEach(function (e) {
        r += pad(parseInt(e, 36).toString(2));
    });
    return r;
}
var
    /*
     * Sprites are 1-bit bitmaps that have been base-36 encoded.  Prior to the base-2 => base-36
     * conversion, the binary strings were chunked into 32 "byte" (bit) sections, to avoid overflowing
     * javascript's int, which would have resulted in the base-36 to base-2 conversion failing to
     * produce the correct result.
     *
     *     ....####       00001111
     *     .....##.       00000110
     *     .....##.       00000110
     *     .....##.  ==>  00000110  ==> 0000111100000110000001100000011001100110011001100011110000000000
     *     .##..##.       01100110    V   
     *     .##..##.       01100110    > 00001111000001100000011000000110,01100110011001100011110000000000    
     *     ..####..       00111100    V 
     *     ........       00000000    > 462DC6,SEU6TC
     *
    */
    sprites = [
    [8, 8, u('462DC6,SEU6TC')],
    [8, 8, u('GRBJ18,3ZTX4W')],     // <==
    [8, 8, u('6SEY3C,6OONPC')],
    [8, 8, u('V4M88M,GPG4CG')],
    [8, 8, u('GRAY3G,DFGH6O')],
    [8, 8, u('GRBIPQ,WUNOXS')],     // <==  better compression was achieved repeating sprites vs. maintaining
    [8, 8, u('6SEY3C,6OONPC')],     //      a distinct map with associate lookup code.
    [8, 8, u('7TKL18,SEU6TC')],
    [7, 8, u('FNQYGB,1EUTR0G')],
    [9, 8, u('7S8B2F,1IW320O,1YHWYKG')],
    [9, 9, u('5018XX,18M0HU0,A1L0QO')],
    [14, 14, u('22XG1U,ULF8G,1XT97JZ,1YR4FZX,1V4BVD3,1F34NQ2,0')]
    ],
    go = 0,                 // keeps the starfield stationary for the first few seconds of the demo
    atHomeCount = 0;        // tracks the number of pixels which have reached their destination
/*
 * getSprite takes an input sprite and scales it by a given factor, but instead of simply fillRect'ing
 * by the scale factor, a secondary scale factor (step) is used to create pixel elements within that
 * rectangle at the specified interval.  For example, getSprite(s, 32, 4) would scale `s` by 32 times,
 * but would only fill in every 4th pixel of each 32-pixel scale block.
 *
 * The resulting pixels are converted into 2-coordinate objects: an (x,y) of the target position of the
 * pixel and an initially random (x,y) of the current position of the pixel.
 */
function getSprite(e, scale, step) {
    var ret = [],
        w = e[0],
        h = e[1],
        s = e[2];
    x = 0,
    y = 0;
    for (var i = 0; i < s.length; i++) {
        if (s[y * w + x] == 1) {
            for (var y2 = y * scale; y2 < (y + 1) * scale; y2 += step) {
                for (x2 = x * scale; x2 < (x + 1) * scale; x2 += step) {
                    ret.push(
                        newEl(
                        R() * 1920,
                        R() * 1080,
                        x2 + 450,
                        y2 + 200)
                    );
                }
            }
        }
        x++;
        if (x == w) {
            x = 0;
            y++;
        }
    }
    return ret;
}
// Get the first sprite and render it in its "exploded" starfield state.
var idx = 0;
es = getSprite(sprites[idx], 32, 4);
es.forEach(function (e) {
    drawEl(e);
});
setTimeout(function () { go = 1; }, 3000);      // keep the starfield static for a few seconds...
setInterval(function () {
    c.fillStyle = '#333';
    c.fillRect(0, 0, 1920, 1080);
    c.fillStyle = "#fff";
    atHomeCount = 0;                            // assume none of the pixels are at their target coordinate
    es.forEach(function (e) {                   
        if (go) bringElHome(e);                 // move each pixel closer to its destination
        drawEl(e);                              // then draw it
    });
    if (atHomeCount == es.length) {             // if every pixel of the sprite has reached its destination,
        idx++;                                  // move on to the next sprite in the sequence.
        if (idx == sprites.length) {            // if we're past the last sprite,
            es.forEach(function (e) {
                e.targetX = R() * 1920;         // randomize each pixel position, and explode back out to the
                e.targetY = R() * 1080;         // starfield.
                atHomeCount = 0;
            });
        }
        else {
            var next_es = getSprite(sprites[idx], 32, 4);       // get the next sprite in sequence
            shuffle(next_es);                                   // it's imperative that we shuffle the order of
                                                                // subsequent sprite arrays, or the movement effect
                                                                // is poor, because the top left pixel of the first
                                                                // sprite is generally close to where the top left
                                                                // pixel of the second sprite is, etc.
            /*
             * Here's our "morphing" code.  The concept is pretty simple...
             * Once a sprite has been fully rendered (meaning that all of its
             * pixels are at their target location, the next sprite in sequence
             * is generated and compared to the previous sprite, leaving us in
             * one of two possible situations: either (a) the new sprite contains
             * more pixels than the prior, or (b) the new sprite contains fewer 
             * pixels than the prior.
             *
             * In the case of (b), we simply need to drop the extra pixels from
             * our first sprite.  In the case of (a), things are a bit more
             * complicated because our new sprite needs more pixels than we currently
             * have on screen.  In this case, we add extra pixels into the mix,
             * grabbing some of the existing sprite's pixels' coordinates as a starting
             * point for a seamless transition.
             *
             * Once we have our pixel array sized properly and its pixels' starting 
             * coodinates set, we set each pixel's target coordinate to the target
             * coordinate of our new sprite, and start our travel again.
             */
            var esl = es.length;
            if (next_es.length <= esl) {
                es.length = next_es.length;
            } else {
                for (var i = 0; i < next_es.length - esl; i++) {
                    es.push(newEl(es[i % esl].curX, es[i % esl].curY, 0, 0));
                }
            }
            for (var z = 0; z < es.length; z++) {
                es[z].targetX = next_es[z].targetX;
                es[z].targetY = next_es[z].targetY;
            }
            atHomeCount = 0;
        }
    }
}, 16); // 1000/60 FPS = ~16ms.
// Shuffles an array; see above for usage.
function shuffle(a) {
    for (var i = a.length - 1; i > 0; i--) {
        var j = Math.floor(R() * (i + 1));
        var t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    return a;
}
// Takes a 2-coordinate pixel object and moves it one step closer
// to its destination.  Once the pixel has reached its destination,
// the "at home" counter is increased; this is used to determine
// when to move to the next sprite.
function bringElHome(o) {
    var dx = o.targetX - o.curX;
    var dy = o.targetY - o.curY;
    o.curX += dx / 25;
    o.curY += dy / 25;
    if (dx < 1 && dy < 1) {
        atHomeCount++;
    }
}