<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var assert = require('assert');
var bufrw = require('bufrw');
var http = require('http');
var PassThrough = require('readable-stream').PassThrough;
var extend = require('xtend');
var extendInto = require('xtend/mutable');
var errors = require('../errors.js');

var headerRW = bufrw.Repeat(bufrw.UInt16BE,
    bufrw.Series(bufrw.str2, bufrw.str2));

module.exports = TChannelHTTP;

function HTTPReqArg2(method, url, headerPairs) {
    var self = this;
    self.method = method || '';
    self.url = url || '';
    self.headerPairs = headerPairs || [];
}

HTTPReqArg2.RW = bufrw.Struct(HTTPReqArg2, {
    method: bufrw.str1,   // method~1
    url: bufrw.strn,      // url~N
    headerPairs: headerRW // numHeaders:2 (headerName~2 headerValue~2){numHeaders}
});

function HTTPResArg2(statusCode, message, headerPairs) {
    var self = this;
    self.statusCode = statusCode || 0;
    self.message = message || '';
    self.headerPairs = headerPairs || [];
}

HTTPResArg2.RW = bufrw.Struct(HTTPResArg2, {
    statusCode: bufrw.UInt16BE, // statusCode:2
    message: bufrw.strn,        // message~N
    headerPairs: headerRW       // numHeaders:2 (headerName~2 headerValue~2){numHeaders}
});

function TChannelHTTP(options) {
    if (!(this instanceof TChannelHTTP)) {
        return new TChannelHTTP(options);
    }
}

TChannelHTTP.prototype.sendRequest = function send(treq, hreq, options, callback) {
    assert(treq.streamed, 'as http must have a streamed tchannel request');

    if (typeof options === 'function') {
        callback = options;
        options = null;
    }

    var head = new HTTPReqArg2(hreq.method, hreq.url);
    // TODO: get lower level access to raw request header pairs
    var keys = Object.keys(hreq.headers);
    for (var i = 0; i < keys.length; i++) {
        head.headerPairs.push([keys[i], hreq.headers[keys[i]]]);
    }

    var arg1 = ''; // TODO: left empty for now, could compute circuit names heuristically
    var arg2res = bufrw.toBufferResult(HTTPReqArg2.RW, head);
    if (arg2res.err) {
        callback(arg2res.err, null, null);
        return;
    }
    var arg2 = arg2res.value;

    treq.headers.as = 'http';
    return treq.sendStreams(arg1, arg2, hreq, onResponse);

    function onResponse(err, treq, tres) {
        if (err) {
            callback(err, null, null);
        } else if (tres.streamed) {
            tres.arg2.onValueReady(arg2Ready);
        } else {
            arg2Ready(null, tres.arg2);
        }
        function arg2Ready(err, arg2) {
            if (err) {
                callback(err, null, null);
            } else {
                readArg2(tres, arg2);
            }
        }
    }

    function readArg2(tres, arg2) {
        // TODO: currently does the wrong thing and doesn't implement a
        // multi-map, due to assuming node-like mangling on the other side
        // to ensure singularity
        var arg2res = bufrw.fromBufferResult(HTTPResArg2.RW, arg2);
        if (arg2res.err) {
            callback(arg2res.err, null, null);
        } else if (tres.streamed) {
            callback(null, arg2res.value, tres.arg3);
        } else {
            var body = PassThrough();
            body.end(tres.arg3);
            callback(null, arg2res.value, body);
        }

    }
};

TChannelHTTP.prototype.sendResponse = function send(buildResponse, hres, callback) {
    // TODO: map http response codes onto error frames and application errors

    var head = new HTTPResArg2(hres.statusCode, hres.statusMessage);
    var keys = Object.keys(hres.headers);
    for (var i = 0; i < keys.length; i++) {
        head.headerPairs.push([keys[i], hres.headers[keys[i]]]);
    }

    var arg2res = bufrw.toBufferResult(HTTPResArg2.RW, head);
    if (arg2res.err) {
        // TODO: wrapped error
        callback(arg2res.err, null, null);
        buildResponse().sendError('UnexpectedError',
            'Couldn\'t encode as-http response arg2: ' +
            arg2res.err.message);
        return;
    }
    var arg2 = arg2res.value;

    return buildResponse({
        streamed: true,
        headers: {
            as: 'http'
        }
    }).sendStreams(arg2, hres, callback);
};

TChannelHTTP.prototype.setHandler = function register(tchannel, handler) {
    var self = this;
    tchannel.handler = new AsHTTPHandler(self, tchannel, handler);
    return tchannel.handler;
};

TChannelHTTP.prototype.forwardToTChannel = function forwardToTChannel(tchannel, hreq, hres, tchannelRequestOptions, callback) {
    var self = this;

    // TODO: no retrying due to:
    // - streamed bypasses TChannelRequest
    // - driving peer selection manually therefore
    // TODO: more http state machine integration

    var options = tchannel.requestOptions(extendInto({
        streamed: true,
        hasNoParent: true
    }, tchannelRequestOptions));
    var peer = tchannel.peers.choosePeer(null);
    if (!peer) {
        hres.writeHead(503, 'Service Unavailable: no tchannel peer');
        hres.end(); // TODO: error content
        callback(errors.NoPeerAvailable());
        return null;
    } else {
        // TODO: observable
        peer.waitForIdentified(onIdentified);
        return null;
    }

    function onIdentified(err) {
        if (err) {
            hres.writeHead(500, 'Connection failure');
            hres.end();
            return null;
        }

        options.host = peer.hostPort;
        var treq = tchannel.request(options);
        self.sendRequest(treq, hreq, forwarded);
    }

    function forwarded(err, head, body) {
        if (err) {
            // TODO: better map of error type -> http status code, see
            // tchannel/errors.classify
            // TODO: observable
            hres.writeHead(500, err.type + ' - ' + err.message);
            hres.end(); // TODO: error content
        } else {
            // TODO: observable
            // TODO: better lower level mapping of headerPairs
            var headers = {};
            for (var i = 0; i < head.headerPairs.length; i++) {
                var pair = head.headerPairs[i];
                headers[pair[0]] = pair[1];
            }
            hres.writeHead(head.statusCode, head.message, headers);
            body.pipe(hres);
        }
        callback(err);
    }
};

TChannelHTTP.prototype.forwardToHTTP = function forwardToHTTP(ingressChan, options, inreq, outres) {
    // TODO: should use lb_pool

    options = extend(options, {
        method: inreq.head.method,
        path: inreq.head.url,
        headers: {},
        keepAlive: true
    });
    for (var i = 0; i < inreq.head.headerPairs.length; i++) {
        var pair = inreq.head.headerPairs[i];
        options.headers[pair[0]] = pair[1];
    }

    var sent = false;
    // TODO: observable
    var outreq = http.request(options, onResponse);
    outreq.on('error', onError);
    // TODO: more http state machine integration
    inreq.body.pipe(outreq);

    function onResponse(inres) {
        if (!sent) {
            sent = true;
            // TODO: observable
            outres.sendResponse(inres);
        }
    }

    function onError(err) {
        if (!sent) {
            sent = true;
            // TODO: observable
            outres.sendError(err);
        }
    }
};

function AsHTTPHandler(asHTTP, channel, handler) {
    if (typeof handler === 'function') {
        handler = {handleRequest: handler}; // TODO: explicate type?
    }
    var self = this;
    self.asHTTP = asHTTP;
    self.channel = channel;
    self.handler = handler;
}

AsHTTPHandler.prototype.handleRequest = function handleRequest(req, buildResponse) {
    var self = this;
    var hreq = {};

    // TODO: real soon arg1 won't be streamable / fragmentable
    if (req.streamed) {
        req.arg1.onValueReady(onArg1);
    } else {
        onArg1(null, req.arg1);
    }

    function onArg1(err, arg1) {
        if (err) {
            sendError(err);
        } else {
            hreq.url = arg1;
            req.withArg2(onArg2);
        }
    }

    function onArg2(err, arg2) {
        if (err) {
            sendError(err);
            return;
        }

        var arg2res = bufrw.fromBufferResult(HTTPReqArg2.RW, arg2);
        if (arg2res.err) {
            sendError(arg2res.err);
            return;
        }

        hreq.head = arg2res.value;
        if (req.streamed) {
            hreq.body = req.arg3;
        } else {
            hreq.body = PassThrough();
            hreq.body.end(req.arg3);
        }

        handle();
    }

    function handle() {
        var hres = { // TODO: explicate type
            head: new HTTPResArg2(200, 'Ok'),
            sendError: sendError,
            sendResponse: sendResponse
        };
        // TODO: observable
        self.handler.handleRequest(hreq, hres);
    }

    function sendResponse(hres) {
        self.asHTTP.sendResponse(buildResponse, hres, sendError);
    }

    function sendError(err) {
        if (err) {
            // TODO: map type?
            buildResponse().sendError('UnexpectedError', err.message);
        }
    }
};
<commit_msg>Now all code paths in forwardToTChannel are calling callback function<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var assert = require('assert');
var bufrw = require('bufrw');
var http = require('http');
var PassThrough = require('readable-stream').PassThrough;
var extend = require('xtend');
var extendInto = require('xtend/mutable');
var errors = require('../errors.js');

var headerRW = bufrw.Repeat(bufrw.UInt16BE,
    bufrw.Series(bufrw.str2, bufrw.str2));

module.exports = TChannelHTTP;

function HTTPReqArg2(method, url, headerPairs) {
    var self = this;
    self.method = method || '';
    self.url = url || '';
    self.headerPairs = headerPairs || [];
}

HTTPReqArg2.RW = bufrw.Struct(HTTPReqArg2, {
    method: bufrw.str1,   // method~1
    url: bufrw.strn,      // url~N
    headerPairs: headerRW // numHeaders:2 (headerName~2 headerValue~2){numHeaders}
});

function HTTPResArg2(statusCode, message, headerPairs) {
    var self = this;
    self.statusCode = statusCode || 0;
    self.message = message || '';
    self.headerPairs = headerPairs || [];
}

HTTPResArg2.RW = bufrw.Struct(HTTPResArg2, {
    statusCode: bufrw.UInt16BE, // statusCode:2
    message: bufrw.strn,        // message~N
    headerPairs: headerRW       // numHeaders:2 (headerName~2 headerValue~2){numHeaders}
});

function TChannelHTTP(options) {
    if (!(this instanceof TChannelHTTP)) {
        return new TChannelHTTP(options);
    }
}

TChannelHTTP.prototype.sendRequest = function send(treq, hreq, options, callback) {
    assert(treq.streamed, 'as http must have a streamed tchannel request');

    if (typeof options === 'function') {
        callback = options;
        options = null;
    }

    var head = new HTTPReqArg2(hreq.method, hreq.url);
    // TODO: get lower level access to raw request header pairs
    var keys = Object.keys(hreq.headers);
    for (var i = 0; i < keys.length; i++) {
        head.headerPairs.push([keys[i], hreq.headers[keys[i]]]);
    }

    var arg1 = ''; // TODO: left empty for now, could compute circuit names heuristically
    var arg2res = bufrw.toBufferResult(HTTPReqArg2.RW, head);
    if (arg2res.err) {
        callback(arg2res.err, null, null);
        return;
    }
    var arg2 = arg2res.value;

    treq.headers.as = 'http';
    return treq.sendStreams(arg1, arg2, hreq, onResponse);

    function onResponse(err, treq, tres) {
        if (err) {
            callback(err, null, null);
        } else if (tres.streamed) {
            tres.arg2.onValueReady(arg2Ready);
        } else {
            arg2Ready(null, tres.arg2);
        }
        function arg2Ready(err, arg2) {
            if (err) {
                callback(err, null, null);
            } else {
                readArg2(tres, arg2);
            }
        }
    }

    function readArg2(tres, arg2) {
        // TODO: currently does the wrong thing and doesn't implement a
        // multi-map, due to assuming node-like mangling on the other side
        // to ensure singularity
        var arg2res = bufrw.fromBufferResult(HTTPResArg2.RW, arg2);
        if (arg2res.err) {
            callback(arg2res.err, null, null);
        } else if (tres.streamed) {
            callback(null, arg2res.value, tres.arg3);
        } else {
            var body = PassThrough();
            body.end(tres.arg3);
            callback(null, arg2res.value, body);
        }

    }
};

TChannelHTTP.prototype.sendResponse = function send(buildResponse, hres, callback) {
    // TODO: map http response codes onto error frames and application errors

    var head = new HTTPResArg2(hres.statusCode, hres.statusMessage);
    var keys = Object.keys(hres.headers);
    for (var i = 0; i < keys.length; i++) {
        head.headerPairs.push([keys[i], hres.headers[keys[i]]]);
    }

    var arg2res = bufrw.toBufferResult(HTTPResArg2.RW, head);
    if (arg2res.err) {
        // TODO: wrapped error
        callback(arg2res.err, null, null);
        buildResponse().sendError('UnexpectedError',
            'Couldn\'t encode as-http response arg2: ' +
            arg2res.err.message);
        return;
    }
    var arg2 = arg2res.value;

    return buildResponse({
        streamed: true,
        headers: {
            as: 'http'
        }
    }).sendStreams(arg2, hres, callback);
};

TChannelHTTP.prototype.setHandler = function register(tchannel, handler) {
    var self = this;
    tchannel.handler = new AsHTTPHandler(self, tchannel, handler);
    return tchannel.handler;
};

TChannelHTTP.prototype.forwardToTChannel = function forwardToTChannel(tchannel, hreq, hres, tchannelRequestOptions, callback) {
    var self = this;

    // TODO: no retrying due to:
    // - streamed bypasses TChannelRequest
    // - driving peer selection manually therefore
    // TODO: more http state machine integration

    var options = tchannel.requestOptions(extendInto({
        streamed: true,
        hasNoParent: true
    }, tchannelRequestOptions));
    var peer = tchannel.peers.choosePeer(null);
    if (!peer) {
        hres.writeHead(503, 'Service Unavailable: no tchannel peer');
        hres.end(); // TODO: error content
        callback(errors.NoPeerAvailable());
        return null;
    } else {
        // TODO: observable
        peer.waitForIdentified(onIdentified);
        return null;
    }

    function onIdentified(err) {
        if (err) {
            hres.writeHead(500, 'Connection failure');
            hres.end();
            callback(err);
            return null;
        }

        options.host = peer.hostPort;
        var treq = tchannel.request(options);
        self.sendRequest(treq, hreq, forwarded);
    }

    function forwarded(err, head, body) {
        if (err) {
            // TODO: better map of error type -> http status code, see
            // tchannel/errors.classify
            // TODO: observable
            hres.writeHead(500, err.type + ' - ' + err.message);
            hres.end(); // TODO: error content
        } else {
            // TODO: observable
            // TODO: better lower level mapping of headerPairs
            var headers = {};
            for (var i = 0; i < head.headerPairs.length; i++) {
                var pair = head.headerPairs[i];
                headers[pair[0]] = pair[1];
            }
            hres.writeHead(head.statusCode, head.message, headers);
            body.pipe(hres);
        }
        callback(err);
    }
};

TChannelHTTP.prototype.forwardToHTTP = function forwardToHTTP(ingressChan, options, inreq, outres) {
    // TODO: should use lb_pool

    options = extend(options, {
        method: inreq.head.method,
        path: inreq.head.url,
        headers: {},
        keepAlive: true
    });
    for (var i = 0; i < inreq.head.headerPairs.length; i++) {
        var pair = inreq.head.headerPairs[i];
        options.headers[pair[0]] = pair[1];
    }

    var sent = false;
    // TODO: observable
    var outreq = http.request(options, onResponse);
    outreq.on('error', onError);
    // TODO: more http state machine integration
    inreq.body.pipe(outreq);

    function onResponse(inres) {
        if (!sent) {
            sent = true;
            // TODO: observable
            outres.sendResponse(inres);
        }
    }

    function onError(err) {
        if (!sent) {
            sent = true;
            // TODO: observable
            outres.sendError(err);
        }
    }
};

function AsHTTPHandler(asHTTP, channel, handler) {
    if (typeof handler === 'function') {
        handler = {handleRequest: handler}; // TODO: explicate type?
    }
    var self = this;
    self.asHTTP = asHTTP;
    self.channel = channel;
    self.handler = handler;
}

AsHTTPHandler.prototype.handleRequest = function handleRequest(req, buildResponse) {
    var self = this;
    var hreq = {};

    // TODO: real soon arg1 won't be streamable / fragmentable
    if (req.streamed) {
        req.arg1.onValueReady(onArg1);
    } else {
        onArg1(null, req.arg1);
    }

    function onArg1(err, arg1) {
        if (err) {
            sendError(err);
        } else {
            hreq.url = arg1;
            req.withArg2(onArg2);
        }
    }

    function onArg2(err, arg2) {
        if (err) {
            sendError(err);
            return;
        }

        var arg2res = bufrw.fromBufferResult(HTTPReqArg2.RW, arg2);
        if (arg2res.err) {
            sendError(arg2res.err);
            return;
        }

        hreq.head = arg2res.value;
        if (req.streamed) {
            hreq.body = req.arg3;
        } else {
            hreq.body = PassThrough();
            hreq.body.end(req.arg3);
        }

        handle();
    }

    function handle() {
        var hres = { // TODO: explicate type
            head: new HTTPResArg2(200, 'Ok'),
            sendError: sendError,
            sendResponse: sendResponse
        };
        // TODO: observable
        self.handler.handleRequest(hreq, hres);
    }

    function sendResponse(hres) {
        self.asHTTP.sendResponse(buildResponse, hres, sendError);
    }

    function sendError(err) {
        if (err) {
            // TODO: map type?
            buildResponse().sendError('UnexpectedError', err.message);
        }
    }
};
<|endoftext|>


<commit_before>/**
 * Waypoints v1.0 - Add css classes on given waypoints, for animating via css transitions
 * http://github.com/jurnskie/jquery-waypoints
 */

(function ( $ ) {

    $.fn.is_on_screen = function(){
       var win = $(window);
       var viewport = {
           top : win.scrollTop(),
           left : win.scrollLeft()
       };
       viewport.right = viewport.left + win.width();
       viewport.bottom = viewport.top + win.height();

       var bounds = this.offset();
       bounds.right = bounds.left + this.outerWidth();
       bounds.bottom = bounds.top + this.outerHeight();

       return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
   };

    $.fn.waypoints = function ( options ){

       var elements = $(this),
           win = $(window),
           ww = win.width(),
           settings = $.extend({
                scrollTopOffset         : 25,
                addedClass     : 'animate',
                menuClass      : '.main',
                activeOnWidth  : 700
           }, options),
          scrollTop = win.scrollTop() + $(settings.menuClass).outerHeight() + settings.scrollTopOffset;

       win.scroll(function(e){
         if(ww > settings.activeOnWidth){
            return elements.each(function(){
                 el = $(this);
                 sec = el.attr('data-section');

                 if(el.attr('data-waypoint')){
                  waypoint = el.data('waypoint');
                  elOffsetTop = $('.'+waypoint).offset().top;

                  (elOffsetTop <= scrollTop) ? $(this).addClass(settings.addedClass) : $(this).removeClass(settings.addedClass);

                 }else{

                  ($('.' + sec).is_on_screen() ) ? $(this).addClass(settings.addedClass) : $(this).removeClass(settings.addedClass);

                 }

             });
          }
      });

    };

}( jQuery ));

<commit_msg>updated fixed menu check<commit_after>/**
 * Waypoints v1.0 - Add css classes on given waypoints
 * http://github.com/jurnskie/jquery-waypoints
 */

(function ( $ ) {

    $.fn.is_on_screen = function(){
       var win = $(window);
       var viewport = {
           top : win.scrollTop(),
           left : win.scrollLeft()
       };
       viewport.right = viewport.left + win.width();
       viewport.bottom = viewport.top + win.height();

       var bounds = this.offset();
       bounds.right = bounds.left + this.outerWidth();
       bounds.bottom = bounds.top + this.outerHeight();

       return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
   };

    $.fn.waypoints = function ( options ){

       var elements = $(this),
           win = $(window),
           ww = win.width(),
           settings = $.extend({
                scrollTopOffset         : 25,
                addedClass     : 'animate',
                menuClass      : null,
                activeOnWidth  : 700
           }, options),
          scrollTop = (settings.menuClass === null) ?
                win.scrollTop() + $('.' + settings.menuClass).outerHeight() + settings.scrollTopOffset : win.scrollTop()  + settings.scrollTopOffset;

       win.scroll(function(e){
         if(ww > settings.activeOnWidth){
            return elements.each(function(){
                 el = $(this);
                 sec = el.attr('data-section');

                 if(el.attr('data-waypoint')){
                  waypoint = el.data('waypoint');
                  elOffsetTop = $('.'+waypoint).offset().top;

                  (elOffsetTop <= scrollTop) ? $(this).addClass(settings.addedClass) : $(this).removeClass(settings.addedClass);

                 }else{

                  ($('.' + sec).is_on_screen() ) ? $(this).addClass(settings.addedClass) : $(this).removeClass(settings.addedClass);

                 }

             });
          }
      });

    };

}( jQuery ));

<|endoftext|>


<commit_before>ig.module('game.entities.zombie')
.requires(
  'impact.impact',
  'impact.entity',
  'game.entities.particle-spawner',
  'game.effects.zombie-giblet',
  'game.effects.blood-giblet',
  'game.entities.dead-zombie'
)
.defines(function() {
  EntityZombie = ig.Entity.extend({
    // don't allow the editor to scale our object
    _wmScalable: false,

    // always draw a box around us
    _wmDrawBox: true,
    _wmBoxColor: 'rgba(255, 170, 66, 0.7)',

    pointValue: 100,

    animSheet: new ig.AnimationSheet( 'media/zombie.png', 32, 32 ),
    zIndex: 9,

    // the size of our collider
    size: { x: 8, y: 32 },

    health: 9,
    maxHealth: 9,

    deathEntity: EntityDeadZombie,

    // the offset of collider
    offset: { x: 12, y: 0 },

    // movement variables
    maxVel: { x: 6, y: 100 },
    friction: { x: 2000, y: 2000 },
    accel: { x: 0, y: 0 },
    gravityFactor: 10,

    speed: 2000,

    // collision settings, collide against player
    type: ig.Entity.TYPE.B,
    checkAgainst: ig.Entity.TYPE.A,
    collides: ig.Entity.COLLIDES.PASSIVE,

    init: function( x, y, settings ) {
      this.parent( x, y, settings );

      // setup animations
      // true means do not repeat
      // idle is a system animation, called by default
      this.addAnim( 'idle', 3, [0], true);
      this.addAnim( 'walk', 0.3, [1,2,3,4,5,6,7,8]);

      this.flip = settings.flip || false;
    },

    kill: function() {
      // when the zombie dies, spawn a bunch of "giblets"
      var pos = {
        x: this.pos.x + this.size.x / 2,
        y: this.pos.y + this.size.y / 2
      };
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectZombieGiblet,
        particles: 5
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectBloodGiblet,
        particles: 3
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectZombieGibletSmall,
        particles: 30
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectBloodGibletSmall,
        particles: 10
      });

      ig.game.spawnEntity( this.deathEntity, this.pos.x, this.pos.y, {
        flip: this.flip
      });

      // increase the players score
      if(this.lastDamageAmount < this.maxHealth) {
        // player shot too far away from the zombie
        // so they won't get as many points
        this.pointValue /= 2;
      }
      ig.game.hud.addPoints(this.pointValue);

      this.parent();
    },

    receiveDamage: function(amt, other) {
      this.parent(amt, other);
      this.lastDamageAmount = amt;
    },

    check: function(other) {
      // when a zombie hits the player
      // the player should take damage
      other.receiveDamage(10, this);
    },

    update: function() {
      if ( this.vel.x != 0 ) {
        this.currentAnim = this.anims.walk;
      }

      this.accel.x = this.speed * (this.flip ? -1 : 1);
      this.currentAnim.flip.x = this.flip;

      this.parent();
    },

    handleMovementTrace: function( res ) {
      this.parent(res);

      // check the collision map, see if we're colliding with
      // a collision tile, if so then we need to turn around
      if( res.collision.x ) {
        this.flip = !this.flip;
      }
    }
  });
});
<commit_msg>zombies spawn particles when they are hit<commit_after>ig.module('game.entities.zombie')
.requires(
  'impact.impact',
  'impact.entity',
  'game.entities.particle-spawner',
  'game.effects.zombie-giblet',
  'game.effects.blood-giblet',
  'game.entities.dead-zombie'
)
.defines(function() {
  EntityZombie = ig.Entity.extend({
    // don't allow the editor to scale our object
    _wmScalable: false,

    // always draw a box around us
    _wmDrawBox: true,
    _wmBoxColor: 'rgba(255, 170, 66, 0.7)',

    pointValue: 100,

    animSheet: new ig.AnimationSheet( 'media/zombie.png', 32, 32 ),
    zIndex: 9,

    // the size of our collider
    size: { x: 8, y: 32 },

    health: 9,
    maxHealth: 9,

    deathEntity: EntityDeadZombie,

    // the offset of collider
    offset: { x: 12, y: 0 },

    // movement variables
    maxVel: { x: 6, y: 100 },
    friction: { x: 2000, y: 2000 },
    accel: { x: 0, y: 0 },
    gravityFactor: 10,

    speed: 2000,

    // collision settings, collide against player
    type: ig.Entity.TYPE.B,
    checkAgainst: ig.Entity.TYPE.A,
    collides: ig.Entity.COLLIDES.PASSIVE,

    init: function( x, y, settings ) {
      this.parent( x, y, settings );

      // setup animations
      // true means do not repeat
      // idle is a system animation, called by default
      this.addAnim( 'idle', 3, [0], true);
      this.addAnim( 'walk', 0.3, [1,2,3,4,5,6,7,8]);

      this.flip = settings.flip || false;
    },

    kill: function() {
      // when the zombie dies, spawn a bunch of "giblets"
      var pos = {
        x: this.pos.x + this.size.x / 2,
        y: this.pos.y + this.size.y / 2
      };
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectZombieGiblet,
        particles: 5
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectBloodGiblet,
        particles: 3
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectZombieGibletSmall,
        particles: 30
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectBloodGibletSmall,
        particles: 10
      });

      ig.game.spawnEntity( this.deathEntity, this.pos.x, this.pos.y, {
        flip: this.flip
      });

      // increase the players score
      if(this.lastDamageAmount < this.maxHealth) {
        // player shot too far away from the zombie
        // so they won't get as many points
        this.pointValue /= 2;
      }
      ig.game.hud.addPoints(this.pointValue);

      this.parent();
    },

    receiveDamage: function(amt, other) {
      this.parent(amt, other);
      this.lastDamageAmount = amt;

      ig.game.spawnEntity( EntityParticleSpawner, other.pos.x, other.pos.y, {
        Particle: EffectZombieGibletSmall,
        particles: ig._.rndRange(3, 7)
      });
    },

    check: function(other) {
      // when a zombie hits the player
      // the player should take damage
      other.receiveDamage(10, this);
    },

    update: function() {
      if ( this.vel.x != 0 ) {
        this.currentAnim = this.anims.walk;
      }

      this.accel.x = this.speed * (this.flip ? -1 : 1);
      this.currentAnim.flip.x = this.flip;

      this.parent();
    },

    handleMovementTrace: function( res ) {
      this.parent(res);

      // check the collision map, see if we're colliding with
      // a collision tile, if so then we need to turn around
      if( res.collision.x ) {
        this.flip = !this.flip;
      }
    }
  });
});
<|endoftext|>


<commit_before>$(function() {
	var $globalBar = $( ".global-bar");
  var $smartBar = $(".notification");

	if($globalBar.length > 0) {
	    window.globalBar = $globalBar.clone();
	    $globalBar.remove();
    	newbar();
      $smartBar.addClass('white');
  }

  else if(($smartBar).hasClass('white')) {
      $smartBar.addClass('tan');
    }

  else if(($smartBar).hasClass('tan')) {
      $smartBar.addClass('sky');
    }

  else {
    $('.notification').remove();
    $('body').prepend(window.globalBar);
  }

function newbar() {
    $("body").prepend(
     "
Read the ePaper edition. The complete print edition, in its exact layout. Browse the print edition page by page, including stories and ads.<button class='notification__toggle'><svg class='icon-close'><use xlink:href='#icon-close' /></svg></button>
");
     $("body").append(
     "<svg display='none' xmlns='http://www.w3.org/2000/svg'><defs><symbol id='icon-close' viewBox='0 0 100 100'><path d='M76.83,32.561L59.392,50L76.83,67.439c2.594,2.594,2.594,6.798,0,9.392 c-1.296,1.296-2.995,1.945-4.694,1.945c-1.7,0-3.399-0.648-4.695-1.945L50,59.391l-17.44,17.44 c-1.296,1.296-2.995,1.945-4.695,1.945c-1.699,0-3.397-0.648-4.694-1.945c-2.594-2.593-2.594-6.797,0-9.392L40.608,50L23.17,32.561 c-2.594-2.594-2.594-6.798,0-9.392c2.593-2.592,6.795-2.592,9.389,0L50,40.609l17.44-17.44c2.594-2.592,6.796-2.592,9.389,0C79.424,25.763,79.424,29.967,76.83,32.561z'></path></symbol></defs></svg>")

    $('.notification__toggle').click(function() {

      $('.notification').slideToggle('300');

      return false;

  });
  }

});<commit_msg>testing<commit_after>$(function() {
	var $globalBar = $( ".global-bar");
  var $smartBar = $(".notification");

	if($globalBar.length > 0) {
	    window.globalBar = $globalBar.clone();
	    $globalBar.remove();
    	newbar();
      $smartBar.addClass('.notification-white');
  }

  else if(($smartBar).hasClass('notification-white')) {
      $smartBar.removeClass('notification-tan');
      $smartBar.addClass('notification-tan');
    }

  else if(($smartBar).hasClass('notification-tan')) {
      $smartBar.removeClass('notification-tan');
      $smartBar.addClass('notification-sky');
    }

  else {
    $('.notification').remove();
    $('body').prepend(window.globalBar);
  }

function newbar() {
    $("body").prepend(
     "
Read the ePaper edition. The complete print edition, in its exact layout. Browse the print edition page by page, including stories and ads.<button class='notification__toggle'><svg class='icon-close'><use xlink:href='#icon-close' /></svg></button>
");
     $("body").append(
     "<svg display='none' xmlns='http://www.w3.org/2000/svg'><defs><symbol id='icon-close' viewBox='0 0 100 100'><path d='M76.83,32.561L59.392,50L76.83,67.439c2.594,2.594,2.594,6.798,0,9.392 c-1.296,1.296-2.995,1.945-4.694,1.945c-1.7,0-3.399-0.648-4.695-1.945L50,59.391l-17.44,17.44 c-1.296,1.296-2.995,1.945-4.695,1.945c-1.699,0-3.397-0.648-4.694-1.945c-2.594-2.593-2.594-6.797,0-9.392L40.608,50L23.17,32.561 c-2.594-2.594-2.594-6.798,0-9.392c2.593-2.592,6.795-2.592,9.389,0L50,40.609l17.44-17.44c2.594-2.592,6.796-2.592,9.389,0C79.424,25.763,79.424,29.967,76.83,32.561z'></path></symbol></defs></svg>")

    $('.notification__toggle').click(function() {

      $('.notification').slideToggle('300');

      return false;

  });
  }

});<|endoftext|>


<commit_before>import './main.sass'
import 'babel-core/polyfill'

import React from 'react'
import ReactDOM from 'react-dom'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import createBrowserHistory from 'history/lib/createBrowserHistory'
import { compose, createStore, applyMiddleware } from 'redux'
import { reduxReactRouter, routerStateReducer, ReduxRouter } from 'redux-router'
import { Provider } from 'react-redux'
import * as reducers from './reducers'
import { analytics, uploader, requester } from './middleware'
import App from './containers/App'
import { persistStore, autoRehydrate } from 'redux-persist'

import './vendor/embetter'
import './vendor/time_ago_in_words'

// TODO: move this somewhere else?
window.embetter.activeServices = [
  window.embetter.services.youtube,
  window.embetter.services.vimeo,
  window.embetter.services.soundcloud,
  window.embetter.services.dailymotion,
  window.embetter.services.mixcloud,
  window.embetter.services.codepen,
  window.embetter.services.bandcamp,
  window.embetter.services.ustream,
]
window.embetter.reloadPlayers = (el = document.body) => {
  window.embetter.utils.disposeDetachedPlayers()
  window.embetter.utils.initMediaPlayers(el, window.embetter.activeServices)
}
window.embetter.stopPlayers = (el = document.body) => {
  window.embetter.utils.unembedPlayers(el)
  window.embetter.utils.disposeDetachedPlayers()
}
window.embetter.removePlayers = (el = document.body) => {
  window.embetter.stopPlayers(el)
  for (const ready of el.querySelectorAll('.embetter-ready')) {
    ready.classList.remove('embetter-ready')
  }
  for (const statix of el.querySelectorAll('.embetter-static')) {
    statix.classList.remove('embetter-static')
  }
}
window.embetter.reloadPlayers()

function createRedirect(from, to) {
  return {
    path: from,
    onEnter(nextState, replaceState) {
      replaceState(nextState, to)
    },
  }
}

const routes = [
  createRedirect('/', '/following'),
  {
    path: '/',
    component: App,
    childRoutes: [
      createRedirect('onboarding', '/onboarding/communities'),
      require('./routes/discover'),
      require('./routes/following'),
      require('./routes/onboarding'),
      require('./routes/post_detail'),
      require('./routes/search'),
      require('./routes/starred'),
      require('./routes/user_detail'),
    ],
  },
]

const logger = createLogger({ collapsed: true })
function reducer(state = {}, action) {
  return {
    json: reducers.json(state.json, action, state.router),
    devtools: reducers.devtools(state.devtools, action),
    modals: reducers.modals(state.modals, action),
    profile: reducers.profile(state.profile, action),
    router: routerStateReducer(state.router, action),
    stream: reducers.stream(state.stream, action),
  }
}
const store = compose(
  autoRehydrate(),
  applyMiddleware(thunk, uploader, requester, analytics, logger),
  reduxReactRouter({routes: routes, createHistory: createBrowserHistory})
)(createStore)(reducer)

const element = (
  <Provider store={store}>
    <ReduxRouter />
  </Provider>
)

persistStore(store, { blacklist: ['router'] }, () => {
  ReactDOM.render(element, document.getElementById('root'))
})
<commit_msg>Reorder routes to trigger rebuild.<commit_after>import './main.sass'
import 'babel-core/polyfill'

import React from 'react'
import ReactDOM from 'react-dom'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import createBrowserHistory from 'history/lib/createBrowserHistory'
import { compose, createStore, applyMiddleware } from 'redux'
import { reduxReactRouter, routerStateReducer, ReduxRouter } from 'redux-router'
import { Provider } from 'react-redux'
import * as reducers from './reducers'
import { analytics, uploader, requester } from './middleware'
import App from './containers/App'
import { persistStore, autoRehydrate } from 'redux-persist'

import './vendor/embetter'
import './vendor/time_ago_in_words'

// TODO: move this somewhere else?
window.embetter.activeServices = [
  window.embetter.services.youtube,
  window.embetter.services.vimeo,
  window.embetter.services.soundcloud,
  window.embetter.services.dailymotion,
  window.embetter.services.mixcloud,
  window.embetter.services.codepen,
  window.embetter.services.bandcamp,
  window.embetter.services.ustream,
]
window.embetter.reloadPlayers = (el = document.body) => {
  window.embetter.utils.disposeDetachedPlayers()
  window.embetter.utils.initMediaPlayers(el, window.embetter.activeServices)
}
window.embetter.stopPlayers = (el = document.body) => {
  window.embetter.utils.unembedPlayers(el)
  window.embetter.utils.disposeDetachedPlayers()
}
window.embetter.removePlayers = (el = document.body) => {
  window.embetter.stopPlayers(el)
  for (const ready of el.querySelectorAll('.embetter-ready')) {
    ready.classList.remove('embetter-ready')
  }
  for (const statix of el.querySelectorAll('.embetter-static')) {
    statix.classList.remove('embetter-static')
  }
}
window.embetter.reloadPlayers()

function createRedirect(from, to) {
  return {
    path: from,
    onEnter(nextState, replaceState) {
      replaceState(nextState, to)
    },
  }
}

const routes = [
  createRedirect('/', '/following'),
  {
    path: '/',
    component: App,
    childRoutes: [
      require('./routes/discover'),
      require('./routes/following'),
      createRedirect('onboarding', '/onboarding/communities'),
      require('./routes/onboarding'),
      require('./routes/post_detail'),
      require('./routes/search'),
      require('./routes/starred'),
      require('./routes/user_detail'),
    ],
  },
]

const logger = createLogger({ collapsed: true })
function reducer(state = {}, action) {
  return {
    json: reducers.json(state.json, action, state.router),
    devtools: reducers.devtools(state.devtools, action),
    modals: reducers.modals(state.modals, action),
    profile: reducers.profile(state.profile, action),
    router: routerStateReducer(state.router, action),
    stream: reducers.stream(state.stream, action),
  }
}
const store = compose(
  autoRehydrate(),
  applyMiddleware(thunk, uploader, requester, analytics, logger),
  reduxReactRouter({routes: routes, createHistory: createBrowserHistory})
)(createStore)(reducer)

const element = (
  <Provider store={store}>
    <ReduxRouter />
  </Provider>
)

persistStore(store, { blacklist: ['router'] }, () => {
  ReactDOM.render(element, document.getElementById('root'))
})
<|endoftext|>


<commit_before>/* Copyright 2013 William Summers, Metatribal Research
 * adapted from https://developer.mozilla.org/en-US/docs/JXON
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author William Summers
 *
 */
var xmlToJSON = (function () {

        var options = { // set up the default options
                mergeCDATA: true,	// extract cdata and merge with text
                grokAttr: true,		// convert truthy attributes to boolean, etc
                grokText: true,		// convert truthy text/attr to boolean, etc
                normalize: true,	// collapse multiple spaces to single space
                xmlns: true, 		// include namespaces as attribute in output
                namespaceKey: '_ns', 	// tag name for namespace objects
                textKey: '_text', 	// tag name for text nodes
                valueKey: '_value', 	// tag name for attribute values
                attrKey: '_attr', 	// tag for attr groups
                cdataKey: '_cdata'	// tag for cdata nodes (ignored if mergeCDATA is true)
                attrsAsObject: true, 	// if false, key is used as prefix to name, set prefix to '' to merge children and attrs.
                stripAttrPrefix: true, 	// remove namespace prefixes from attributes
                stripElemPrefix: true, 	// for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
                childrenAsArray: true 	// force children into arrays
        };

        var prefixMatch = new RegExp(/(?!xmlns)^.*:/);
        var trimMatch = new RegExp(/^\s+|\s+$/g);

        var grokType = function (sValue) {
                if (/^\s*$/.test(sValue)) {
                        return null;
                }
                if (/^(?:true|false)$/i.test(sValue)) {
                        return sValue.toLowerCase() === "true";
                }
                if (isFinite(sValue)) {
                        return parseFloat(sValue);
                }
                //if (isFinite(Date.parse(sValue))) {
                //		return new Date(sValue);
                //}
                return sValue;
        };

        var parseString = function (xmlString, opt) {
                return this.parseXML(stringToXML(xmlString), opt);
        }

        var parseXML = function (oXMLParent, opt) {

                // initialize options
                for (key in opt) {
                        options[key] = opt[key];
                }

                var vResult = {}, nLength = 0, sCollectedTxt = "";

                // parse namespace information
                if (options.xmlns && oXMLParent.namespaceURI) {
                        vResult[options.namespaceKey] = oXMLParent.namespaceURI;
                }

                // parse attributes
                // using attributes property instead of hasAttributes method to support older browsers
                if (oXMLParent.attributes && oXMLParent.attributes.length > 0) {
                        var vAttribs = {};

                        for (nLength; nLength < oXMLParent.attributes.length; nLength++) {
                                oAttrib = oXMLParent.attributes.item(nLength);
                                vContent = {};
                                attribName = '';

                                if (options.stripAttrPrefix) {
                                        attribName = oAttrib.name.replace(prefixMatch, '');

                                } else {
                                        attribName = oAttrib.name;
                                }

                                if (options.grokAttr) {
                                        vContent[options.valueKey] = grokType(oAttrib.value.replace(trimMatch, ''));
                                } else {
                                        vContent[options.valueKey] = oAttrib.value.replace(trimMatch, '');
                                }

                                if (options.xmlns && oAttrib.namespaceURI) {
                                        vContent[options.namespaceKey] = oAttrib.namespaceURI;
                                }

                                if (options.attrsAsObject) { // attributes with same local name must enable prefixes
                                        vAttribs[attribName] = vContent;
                                } else {
                                        vResult[options.attrKey + attribName] = vContent;
                                }
                        }

                        if (options.attrsAsObject) {
                                vResult[options.attrKey] = vAttribs;
                        } else {}
                }

                // iterate over the children
                if (oXMLParent.hasChildNodes()) {
                        for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
                                oNode = oXMLParent.childNodes.item(nItem);

                                if (oNode.nodeType === 4) {
									if (options.mergeCDATA) {
                                        sCollectedTxt += oNode.nodeValue;
									} else {
										if (vResult.hasOwnProperty(options.cdataKey)) {
												if (vResult[options.cdataKey].constructor !== Array) {
														vResult[options.cdataKey] = [vResult[options.cdataKey]];
												}
												vResult[options.cdataKey].push(oNode.nodeValue);

										} else {
												if (options.childrenAsArray) {
														vResult[options.cdataKey] = [];
														vResult[options.cdataKey].push(oNode.nodeValue);
												} else {
														vResult[options.cdataKey] = oNode.nodeValue;
												}
                                        }
									}
                                } /* nodeType is "CDATASection" (4) */
                                else if (oNode.nodeType === 3) {
                                        sCollectedTxt += oNode.nodeValue;
                                } /* nodeType is "Text" (3) */
                                else if (oNode.nodeType === 1) { /* nodeType is "Element" (1) */

                                        if (nLength === 0) {
                                                vResult = {};
                                        }

                                        // using nodeName to support browser (IE) implementation with no 'localName' property
                                        if (options.stripElemPrefix) {
                                                sProp = oNode.nodeName.replace(prefixMatch, '');
                                        } else {
                                                sProp = oNode.nodeName;
                                        }

                                        vContent = parseXML(oNode);

                                        if (vResult.hasOwnProperty(sProp)) {
                                                if (vResult[sProp].constructor !== Array) {
                                                        vResult[sProp] = [vResult[sProp]];
                                                }
                                                vResult[sProp].push(vContent);

                                        } else {
                                                if (options.childrenAsArray) {
                                                        vResult[sProp] = [];
                                                        vResult[sProp].push(vContent);
                                                } else {
                                                        vResult[sProp] = vContent;
                                                }
                                                nLength++;
                                        }
                                }
                        }
                } else if (!sCollectedTxt){ // no children and no text, return null
					if (options.childrenAsArray) {
							vResult[options.textKey] = [];
							vResult[options.textKey].push(null);
					} else {
							vResult[options.textKey] = null;
					}
				}

                if (sCollectedTxt) {
                        if (options.grokText) {
                                value = grokType(sCollectedTxt.replace(trimMatch, ''));
                                if (value) {
									vResult[options.textKey] = value;
								}
                        } else if (options.normalize) {
                                vResult[options.textKey] = sCollectedTxt.replace(trimMatch, '').replace(/\s+/g, " ");
                        } else {
                                vResult[options.textKey] = sCollectedTxt.replace(trimMatch, '');
                        }
                }

                return vResult;
        }

        // Convert xmlDocument to a string
        // Returns null on failure
        var xmlToString = function (xmlDoc) {
                try {
                        var xmlString = xmlDoc.xml ? xmlDoc.xml : (new XMLSerializer()).serializeToString(xmlDoc);
                        return xmlString;
                } catch (err) {
                        return null;
                }
        }

        // Convert a string to XML Node Structure
        // Returns null on failure
        var stringToXML = function (xmlString) {
                try {
                        var xmlDoc = null;

                        if (window.DOMParser) {

                                var parser = new DOMParser();
                                xmlDoc = parser.parseFromString(xmlString, "text/xml");

                                return xmlDoc;
                        } else {
                                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                                xmlDoc.async = false;
                                xmlDoc.loadXML(xmlString);

                                return xmlDoc;
                        }
                } catch (e) {
                        return null;
                }
        }

        // this is the "revealed"/public part of the module
        return {
                parseXML: parseXML,
                parseString: parseString,
                xmlToString: xmlToString,
                stringToXML: stringToXML
        };

}());
<commit_msg>removed grokType date as nonstandard<commit_after>/* Copyright 2013 William Summers, Metatribal Research
 * adapted from https://developer.mozilla.org/en-US/docs/JXON
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author William Summers
 *
 */
var xmlToJSON = (function () {

        var options = { // set up the default options
                mergeCDATA: true,	// extract cdata and merge with text
                grokAttr: true,		// convert truthy attributes to boolean, etc
                grokText: true,		// convert truthy text/attr to boolean, etc
                normalize: true,	// collapse multiple spaces to single space
                xmlns: true, 		// include namespaces as attribute in output
                namespaceKey: '_ns', 	// tag name for namespace objects
                textKey: '_text', 	// tag name for text nodes
                valueKey: '_value', 	// tag name for attribute values
                attrKey: '_attr', 	// tag for attr groups
                cdataKey: '_cdata'	// tag for cdata nodes (ignored if mergeCDATA is true)
                attrsAsObject: true, 	// if false, key is used as prefix to name, set prefix to '' to merge children and attrs.
                stripAttrPrefix: true, 	// remove namespace prefixes from attributes
                stripElemPrefix: true, 	// for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
                childrenAsArray: true 	// force children into arrays
        };

        var prefixMatch = new RegExp(/(?!xmlns)^.*:/);
        var trimMatch = new RegExp(/^\s+|\s+$/g);

        var grokType = function (sValue) {
                if (/^\s*$/.test(sValue)) {
                        return null;
                }
                if (/^(?:true|false)$/i.test(sValue)) {
                        return sValue.toLowerCase() === "true";
                }
                if (isFinite(sValue)) {
                        return parseFloat(sValue);
                }
                return sValue;
        };

        var parseString = function (xmlString, opt) {
                return this.parseXML(stringToXML(xmlString), opt);
        }

        var parseXML = function (oXMLParent, opt) {

                // initialize options
                for (key in opt) {
                        options[key] = opt[key];
                }

                var vResult = {}, nLength = 0, sCollectedTxt = "";

                // parse namespace information
                if (options.xmlns && oXMLParent.namespaceURI) {
                        vResult[options.namespaceKey] = oXMLParent.namespaceURI;
                }

                // parse attributes
                // using attributes property instead of hasAttributes method to support older browsers
                if (oXMLParent.attributes && oXMLParent.attributes.length > 0) {
                        var vAttribs = {};

                        for (nLength; nLength < oXMLParent.attributes.length; nLength++) {
                                oAttrib = oXMLParent.attributes.item(nLength);
                                vContent = {};
                                attribName = '';

                                if (options.stripAttrPrefix) {
                                        attribName = oAttrib.name.replace(prefixMatch, '');

                                } else {
                                        attribName = oAttrib.name;
                                }

                                if (options.grokAttr) {
                                        vContent[options.valueKey] = grokType(oAttrib.value.replace(trimMatch, ''));
                                } else {
                                        vContent[options.valueKey] = oAttrib.value.replace(trimMatch, '');
                                }

                                if (options.xmlns && oAttrib.namespaceURI) {
                                        vContent[options.namespaceKey] = oAttrib.namespaceURI;
                                }

                                if (options.attrsAsObject) { // attributes with same local name must enable prefixes
                                        vAttribs[attribName] = vContent;
                                } else {
                                        vResult[options.attrKey + attribName] = vContent;
                                }
                        }

                        if (options.attrsAsObject) {
                                vResult[options.attrKey] = vAttribs;
                        } else {}
                }

                // iterate over the children
                if (oXMLParent.hasChildNodes()) {
                        for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
                                oNode = oXMLParent.childNodes.item(nItem);

                                if (oNode.nodeType === 4) {
									if (options.mergeCDATA) {
                                        sCollectedTxt += oNode.nodeValue;
									} else {
										if (vResult.hasOwnProperty(options.cdataKey)) {
												if (vResult[options.cdataKey].constructor !== Array) {
														vResult[options.cdataKey] = [vResult[options.cdataKey]];
												}
												vResult[options.cdataKey].push(oNode.nodeValue);

										} else {
												if (options.childrenAsArray) {
														vResult[options.cdataKey] = [];
														vResult[options.cdataKey].push(oNode.nodeValue);
												} else {
														vResult[options.cdataKey] = oNode.nodeValue;
												}
                                        }
									}
                                } /* nodeType is "CDATASection" (4) */
                                else if (oNode.nodeType === 3) {
                                        sCollectedTxt += oNode.nodeValue;
                                } /* nodeType is "Text" (3) */
                                else if (oNode.nodeType === 1) { /* nodeType is "Element" (1) */

                                        if (nLength === 0) {
                                                vResult = {};
                                        }

                                        // using nodeName to support browser (IE) implementation with no 'localName' property
                                        if (options.stripElemPrefix) {
                                                sProp = oNode.nodeName.replace(prefixMatch, '');
                                        } else {
                                                sProp = oNode.nodeName;
                                        }

                                        vContent = parseXML(oNode);

                                        if (vResult.hasOwnProperty(sProp)) {
                                                if (vResult[sProp].constructor !== Array) {
                                                        vResult[sProp] = [vResult[sProp]];
                                                }
                                                vResult[sProp].push(vContent);

                                        } else {
                                                if (options.childrenAsArray) {
                                                        vResult[sProp] = [];
                                                        vResult[sProp].push(vContent);
                                                } else {
                                                        vResult[sProp] = vContent;
                                                }
                                                nLength++;
                                        }
                                }
                        }
                } else if (!sCollectedTxt){ // no children and no text, return null
					if (options.childrenAsArray) {
							vResult[options.textKey] = [];
							vResult[options.textKey].push(null);
					} else {
							vResult[options.textKey] = null;
					}
				}

                if (sCollectedTxt) {
                        if (options.grokText) {
                                value = grokType(sCollectedTxt.replace(trimMatch, ''));
                                if (value) {
									vResult[options.textKey] = value;
								}
                        } else if (options.normalize) {
                                vResult[options.textKey] = sCollectedTxt.replace(trimMatch, '').replace(/\s+/g, " ");
                        } else {
                                vResult[options.textKey] = sCollectedTxt.replace(trimMatch, '');
                        }
                }

                return vResult;
        }

        // Convert xmlDocument to a string
        // Returns null on failure
        var xmlToString = function (xmlDoc) {
                try {
                        var xmlString = xmlDoc.xml ? xmlDoc.xml : (new XMLSerializer()).serializeToString(xmlDoc);
                        return xmlString;
                } catch (err) {
                        return null;
                }
        }

        // Convert a string to XML Node Structure
        // Returns null on failure
        var stringToXML = function (xmlString) {
                try {
                        var xmlDoc = null;

                        if (window.DOMParser) {

                                var parser = new DOMParser();
                                xmlDoc = parser.parseFromString(xmlString, "text/xml");

                                return xmlDoc;
                        } else {
                                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                                xmlDoc.async = false;
                                xmlDoc.loadXML(xmlString);

                                return xmlDoc;
                        }
                } catch (e) {
                        return null;
                }
        }

        // this is the "revealed"/public part of the module
        return {
                parseXML: parseXML,
                parseString: parseString,
                xmlToString: xmlToString,
                stringToXML: stringToXML
        };

}());
<|endoftext|>


<commit_before>var util = require("util");
var path = require("path");
var Q = require("q");
var _ = require("lodash");
var exec = require('child_process').exec;

var fs = require("fs");
var parse = require("../../parse");
var BaseGenerator = require("../page");

/*
 *  This generator inherits from the single page generator
 *  and convert the page output to ebook
 */
var Generator = function() {
    BaseGenerator.apply(this, arguments);

    // Options for eBook generation
    this.options = _.defaults(this.options, {
        extension: "epub"
    });
};
util.inherits(Generator, BaseGenerator);

Generator.prototype.finish = function() {
    var that = this;

    return BaseGenerator.prototype.finish.apply(this)
    .then(function() {
        var d = Q.defer();

        if (!that.options.cover && fs.existsSync(path.join(that.options.output, "cover.jpg"))) {
            that.options.cover = path.join(that.options.output, "cover.jpg");
        }

        var _options = {
            "--cover": that.options.cover
        };

        var command = [
            "ebook-convert",
            path.join(that.options.output, "index.html"),
            path.join(that.options.output, "index."+that.options.extension),
            _.chain(_options)
            .map(function(value, key) {
                if (value == null) return null;
                return key+"="+value;
            })
            .compact()
            .value()
            .join(" ")
        ].join(" ");

        console.log(command);

        exec(command, function (error, stdout, stderr) {
            if (error) {
                if (error.code == 127) {
                    error.message = "Need to install ebook-convert from Calibre";
                } else {
                    error.message = error.message + " "+stdout;
                }
                return d.reject(error);
            }
            d.resolve();
        });

        return d.promise;
    });
};

module.exports = Generator;
<commit_msg>Remove command log in ebook convert<commit_after>var util = require("util");
var path = require("path");
var Q = require("q");
var _ = require("lodash");
var exec = require('child_process').exec;

var fs = require("fs");
var parse = require("../../parse");
var BaseGenerator = require("../page");

/*
 *  This generator inherits from the single page generator
 *  and convert the page output to ebook
 */
var Generator = function() {
    BaseGenerator.apply(this, arguments);

    // Options for eBook generation
    this.options = _.defaults(this.options, {
        extension: "epub"
    });
};
util.inherits(Generator, BaseGenerator);

Generator.prototype.finish = function() {
    var that = this;

    return BaseGenerator.prototype.finish.apply(this)
    .then(function() {
        var d = Q.defer();

        if (!that.options.cover && fs.existsSync(path.join(that.options.output, "cover.jpg"))) {
            that.options.cover = path.join(that.options.output, "cover.jpg");
        }

        var _options = {
            "--cover": that.options.cover
        };

        var command = [
            "ebook-convert",
            path.join(that.options.output, "index.html"),
            path.join(that.options.output, "index."+that.options.extension),
            _.chain(_options)
            .map(function(value, key) {
                if (value == null) return null;
                return key+"="+value;
            })
            .compact()
            .value()
            .join(" ")
        ].join(" ");

        exec(command, function (error, stdout, stderr) {
            if (error) {
                if (error.code == 127) {
                    error.message = "Need to install ebook-convert from Calibre";
                } else {
                    error.message = error.message + " "+stdout;
                }
                return d.reject(error);
            }
            d.resolve();
        });

        return d.promise;
    });
};

module.exports = Generator;
<|endoftext|>


<commit_before>
import '../../polyfill'

import $ from 'jquery'
import co from 'co'
import SamplingMaster from '../../sampling-master'
import readBlob from '../../read-blob'
import ctx from 'audio-context'

import Compiler from 'bms/compiler'
import Timing from 'bms/timing'
import Notes from 'bms/notes'

export function main(element) {
  function handler() {
    alert('Please drag a BMS file along with ALL samples into this page!')
    return false
  }
  $(element).text('Technical Demo').on('click', handler)
  $('body')
  .on('dragover', () => false)
  .on('drop', e => {
    $(element).off('click', handler)
    let dndLoader = new DndLoader(e.originalEvent.dataTransfer.files)
    go(dndLoader, element)
    return false
  })
}

class DndLoader {
  constructor(files) {
    this._files = [].slice.call(files)
    console.log(this._files)
  }
  file(name) {
    for (let file of this._files) {
      if (file.name.toLowerCase() === name.toLowerCase()) {
        return Promise.resolve(file)
      }
    }
    return Promise.reject(new Error('unable to find ' + name))
  }
  get fileList() {
    return Promise.resolve(this._files.map(f => f.name))
  }
}

function go(loader, element) {

  let master = new SamplingMaster(ctx)

  co(function*() {
    log('Loading file list')
    let list = yield loader.fileList
    let bmsFile = list.filter(f => f.match(/\.bm.$/i))[0]
    log('Loading ' + bmsFile)
    let bms = yield loader.file(bmsFile)
    let text = yield readBlob(bms).as('text')
    let chart = Compiler.compile(text).chart
    var timing = Timing.fromBMSChart(chart)
    var notes = Notes.fromBMSChart(chart)
    log('Loading samples')
    var samples = yield loadSamples(notes, chart)
    log('Click to play!')
    $(element).on('click', function() {
      var num = 0
      master.unmute()
      for (let note of notes.all()) {
        setTimeout(() => {
          let sample = samples[note.keysound]
          if (!sample) {
            console.log('warn: unknown sample ' + note.keysound)
            return
          }
          let span = document.createElement('span')
          let c = num++
          span.style.fontSize = '1vw'
          span.style.textAlign = 'center'
          span.style.display = 'block'
          span.style.position = 'absolute'
          span.style.left = (c % 40) * 2.5 + '%'
          span.style.top = (~~(c / 40) % 10) * 3 + 'ex'
          span.innerHTML = '[' + note.keysound + '] '
          document.body.appendChild(span)
          let instance = sample.play()
          instance.onstop = function() {
            document.body.removeChild(span)
          }
        }, timing.beatToSeconds(note.beat) * 1000)
      }
      return false
    })
  }).done()

  function log(t) {
    element.textContent = t
  }

  function loadSamples(notes, chart) {
    var samples = {}
    var promises = []
    let completed = 0

    for (let note of notes.all()) {
      let keysound = note.keysound
      if (!(keysound in samples)) {
        samples[keysound] = null
        promises.push(
          loadKeysound(chart.headers.get('wav' + keysound))
            .then(blob => master.sample(blob))
            .then(sample => samples[keysound] = sample)
            .catch(e => console.error('Unable to load ' + keysound + ': ' + e))
            .tap(() => log('[loaded ' + (++completed) + '/' + promises.length +
              ' samples]'))
        )
      }
    }

    return Promise.all(promises).then(() => samples)
  }

  function loadKeysound(name) {
    if (typeof name !== 'string') return Promise.reject(new Error('Empty name'))
    return loader.file(name)
      .catch(() => loader.file(name.replace(/\.\w+$/, '.ogg')))
      .catch(() => loader.file(name.replace(/\.\w+$/, '.mp3')))
      .catch(() => loader.file(name.replace(/\.\w+$/, '.wav')))
  }

}
<commit_msg>fix(coming-soon/demo): remove the demo button when clicked<commit_after>
import '../../polyfill'

import $ from 'jquery'
import co from 'co'
import SamplingMaster from '../../sampling-master'
import readBlob from '../../read-blob'
import ctx from 'audio-context'

import Compiler from 'bms/compiler'
import Timing from 'bms/timing'
import Notes from 'bms/notes'

export function main(element) {
  function handler() {
    alert('Please drag a BMS file along with ALL samples into this page!')
    return false
  }
  $(element).text('Technical Demo').on('click', handler)
  $('body')
  .on('dragover', () => false)
  .on('drop', e => {
    $(element).off('click', handler)
    let dndLoader = new DndLoader(e.originalEvent.dataTransfer.files)
    go(dndLoader, element)
    return false
  })
}

class DndLoader {
  constructor(files) {
    this._files = [].slice.call(files)
    console.log(this._files)
  }
  file(name) {
    for (let file of this._files) {
      if (file.name.toLowerCase() === name.toLowerCase()) {
        return Promise.resolve(file)
      }
    }
    return Promise.reject(new Error('unable to find ' + name))
  }
  get fileList() {
    return Promise.resolve(this._files.map(f => f.name))
  }
}

function go(loader, element) {

  let master = new SamplingMaster(ctx)

  co(function*() {
    log('Loading file list')
    let list = yield loader.fileList
    let bmsFile = list.filter(f => f.match(/\.bm.$/i))[0]
    log('Loading ' + bmsFile)
    let bms = yield loader.file(bmsFile)
    let text = yield readBlob(bms).as('text')
    let chart = Compiler.compile(text).chart
    var timing = Timing.fromBMSChart(chart)
    var notes = Notes.fromBMSChart(chart)
    log('Loading samples')
    var samples = yield loadSamples(notes, chart)
    log('Click to play!')
    $(element).on('click', function() {
      $(element).remove()
      var num = 0
      master.unmute()
      for (let note of notes.all()) {
        setTimeout(() => {
          let sample = samples[note.keysound]
          if (!sample) {
            console.log('warn: unknown sample ' + note.keysound)
            return
          }
          let span = document.createElement('span')
          let c = num++
          span.style.fontSize = '1vw'
          span.style.textAlign = 'center'
          span.style.display = 'block'
          span.style.position = 'absolute'
          span.style.left = (c % 40) * 2.5 + '%'
          span.style.top = (~~(c / 40) % 10) * 3 + 'ex'
          span.innerHTML = '[' + note.keysound + '] '
          document.body.appendChild(span)
          let instance = sample.play()
          instance.onstop = function() {
            document.body.removeChild(span)
          }
        }, timing.beatToSeconds(note.beat) * 1000)
      }
      return false
    })
  }).done()

  function log(t) {
    element.textContent = t
  }

  function loadSamples(notes, chart) {
    var samples = {}
    var promises = []
    let completed = 0

    for (let note of notes.all()) {
      let keysound = note.keysound
      if (!(keysound in samples)) {
        samples[keysound] = null
        promises.push(
          loadKeysound(chart.headers.get('wav' + keysound))
            .then(blob => master.sample(blob))
            .then(sample => samples[keysound] = sample)
            .catch(e => console.error('Unable to load ' + keysound + ': ' + e))
            .tap(() => log('[loaded ' + (++completed) + '/' + promises.length +
              ' samples]'))
        )
      }
    }

    return Promise.all(promises).then(() => samples)
  }

  function loadKeysound(name) {
    if (typeof name !== 'string') return Promise.reject(new Error('Empty name'))
    return loader.file(name)
      .catch(() => loader.file(name.replace(/\.\w+$/, '.ogg')))
      .catch(() => loader.file(name.replace(/\.\w+$/, '.mp3')))
      .catch(() => loader.file(name.replace(/\.\w+$/, '.wav')))
  }

}
<|endoftext|>