<commit_before>var path = require('path');
var lib = require('./lib');
var Obj = require('./object');
var lexer = require('./lexer');
var compiler = require('./compiler');
var builtin_filters = require('./filters');
var builtin_loaders = require('./loaders');
var runtime = require('./runtime');
var globals = require('./globals');
var Frame = runtime.Frame;

var Environment = Obj.extend({
    init: function(loaders, opts) {
        // The dev flag determines the trace that'll be shown on errors.
        // If set to true, returns the full trace from the error point,
        // otherwise will return trace starting from Template.render
        // (the full trace from within nunjucks may confuse developers using
        //  the library)
        // defaults to false
        opts = opts || {};
        this.dev = !!opts.dev;
        this.lexerTags = opts.tags;

        // The autoescape flag sets global autoescaping. If true,
        // every string variable will be escaped by default.
        // If false, strings can be manually escaped using the `escape` filter.
        // defaults to false
        this.autoesc = !!opts.autoescape;

        if(!loaders) {
            // The filesystem loader is only available client-side
            if(builtin_loaders.FileSystemLoader) {
                this.loaders = [new builtin_loaders.FileSystemLoader('views')];
            }
            else {
                this.loaders = [new builtin_loaders.WebLoader('/views')];
            }
        }
        else {
            this.loaders = lib.isArray(loaders) ? loaders : [loaders];
        }

        this.initCache();
        this.filters = {};
        this.asyncFilters = [];
        this.extensions = {};
        this.extensionsList = [];

        for(var name in builtin_filters) {
            this.addFilter(name, builtin_filters[name]);
        }
    },

    initCache: function() {
        // Caching and cache busting
        var cache = {};

        lib.each(this.loaders, function(loader) {
            if(typeof loader.on === 'function'){
                loader.on('update', function(template) {
                    cache[template] = null;
                });
            }
        });

        this.cache = cache;
    },

    addExtension: function(name, extension) {
        extension._name = name;
        this.extensions[name] = extension;
        this.extensionsList.push(extension);
    },

    getExtension: function(name) {
        return this.extensions[name];
    },

    addGlobal: function(name, value) {
        globals[name] = value;
    },

    addFilter: function(name, func, async) {
        var wrapped = func;

        if(async) {
            this.asyncFilters.push(name);
        }
        this.filters[name] = wrapped;
    },

    getFilter: function(name) {
        if(!this.filters[name]) {
            throw new Error('filter not found: ' + name);
        }
        return this.filters[name];
    },

    getTemplate: function(name, eagerCompile, cb) {
        if(name && name.raw) {
            // this fixes autoescape for templates referenced in symbols
            name = name.raw;
        }

        if(lib.isFunction(eagerCompile)) {
            cb = eagerCompile;
            eagerCompile = false;
        }

        if(typeof name !== 'string') {
            throw new Error('template names must be a string: ' + name);
        }

        var tmpl = this.cache[name];

        if(tmpl) {
            if(eagerCompile) {
                tmpl.compile();
            }

            if(cb) {
                cb(null, tmpl);
            }
            else {
                return tmpl;
            }
        } else {
            var syncResult;

            lib.asyncIter(this.loaders, function(loader, i, next, done) {
                function handle(src) {
                    if(src) {
                        done(src);
                    }
                    else {
                        next();
                    }
                }

                if(loader.async) {
                    loader.getSource(name, function(err, src) {
                        if(err) { throw err; }
                        handle(src);
                    });
                }
                else {
                    handle(loader.getSource(name));
                }
            }, function(info) {
                if(!info) {
                    var err = new Error('template not found: ' + name);
                    if(cb) {
                        cb(err);
                    }
                    else {
                        throw err;
                    }
                }
                else {
                    var tmpl = new Template(info.src, this,
                                            info.path, eagerCompile);

                    if(!info.noCache) {
                        this.cache[name] = tmpl;
                    }

                    if(cb) {
                        cb(null, tmpl);
                    }
                    else {
                        syncResult = tmpl;
                    }
                }
            }.bind(this));

            return syncResult;
        }
    },

    express: function(app) {
        var env = this;

        function NunjucksView(name, opts) {
            this.name          = name;
            this.path          = name;
            this.defaultEngine = opts.defaultEngine;
            this.ext           = path.extname(name);
            if (!this.ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
            if (!this.ext) this.name += (this.ext = ('.' !== this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
        }

        NunjucksView.prototype.render = function(opts, cb) {
          env.render(this.name, opts, cb);
        };

        app.set('view', NunjucksView);
    },

    render: function(name, ctx, cb) {
        if(lib.isFunction(ctx)) {
            cb = ctx;
            ctx = null;
        }

        // We support a synchronous API to make it easier to migrate
        // existing code to async. This works because if you don't do
        // anything async work, the whole thing is actually run
        // synchronously.
        var syncResult = null;

        this.getTemplate(name, function(err, tmpl) {
            if(err && cb) {
                cb(err);
            }
            else if(err) {
                throw err;
            }
            else {
                tmpl.render(ctx, cb || function(err, res) {
                    if(err) { throw err; }
                    syncResult = res;
                });
            }
        });

        return syncResult;
    },

    renderString: function(src, ctx, cb) {
        var tmpl = new Template(src, this);
        return tmpl.render(ctx, cb);
    }
});

var Context = Obj.extend({
    init: function(ctx, blocks) {
        this.ctx = ctx;
        this.blocks = {};
        this.exported = [];

        for(var name in blocks) {
            this.addBlock(name, blocks[name]);
        }
    },

    lookup: function(name) {
        // This is one of the most called functions, so optimize for
        // the typical case where the name isn't in the globals
        if(name in globals && !(name in this.ctx)) {
            return globals[name];
        }
        else {
            return this.ctx[name];
        }
    },

    setVariable: function(name, val) {
        this.ctx[name] = val;
    },

    getVariables: function() {
        return this.ctx;
    },

    addBlock: function(name, block) {
        this.blocks[name] = this.blocks[name] || [];
        this.blocks[name].push(block);
    },

    getBlock: function(name) {
        if(!this.blocks[name]) {
            throw new Error('unknown block "' + name + '"');
        }

        return this.blocks[name][0];
    },

    getSuper: function(env, name, block, frame, runtime, cb) {
        var idx = lib.indexOf(this.blocks[name] || [], block);
        var blk = this.blocks[name][idx + 1];
        var context = this;

        if(idx == -1 || !blk) {
            throw new Error('no super block available for "' + name + '"');
        }

        blk(env, context, frame, runtime, cb);
    },

    addExport: function(name) {
        this.exported.push(name);
    },

    getExported: function() {
        var exported = {};
        for(var i=0; i<this.exported.length; i++) {
            var name = this.exported[i];
            exported[name] = this.ctx[name];
        }
        return exported;
    }
});

var Template = Obj.extend({
    init: function (src, env, path, eagerCompile) {
        this.env = env || new Environment();

        if(lib.isObject(src)) {
            switch(src.type) {
            case 'code': this.tmplProps = src.obj; break;
            case 'string': this.tmplStr = src.obj; break;
            }
        }
        else if(lib.isString(src)) {
            this.tmplStr = src;
        }
        else {
            throw new Error("src must be a string or an object describing " +
                            "the source");
        }

        this.path = path;

        if(eagerCompile) {
            lib.withPrettyErrors(this.path,
                                 this.env.dev,
                                 this._compile.bind(this));
        }
        else {
            this.compiled = false;
        }
    },

    render: function(ctx, frame, cb) {
        if (typeof ctx === 'function') {
            cb = ctx;
            ctx = {};
        }
        else if (typeof frame === 'function') {
            cb = frame;
            frame = null;
        }

        return lib.withPrettyErrors(this.path, this.env.dev, function() {
            this.compile();

            var context = new Context(ctx || {}, this.blocks);
            var syncResult = null;

            this.rootRenderFunc(this.env,
                                context,
                                frame || new Frame(),
                                runtime,
                                cb || function(err, res) {
                                    if(err) { throw err; }
                                    syncResult = res;
                                });

            return syncResult;
        }.bind(this));
    },

    getExported: function(cb) {
        this.compile();

        // Run the rootRenderFunc to populate the context with exported vars
        var context = new Context({}, this.blocks);
        this.rootRenderFunc(this.env,
                            context,
                            new Frame(),
                            runtime,
                            function() {
                                cb(null, context.getExported());
                            });
    },

    compile: function() {
        if(!this.compiled) {
            this._compile();
        }
    },

    _compile: function() {
        var props;

        if(this.tmplProps) {
            props = this.tmplProps;
        }
        else {
            var source = compiler.compile(this.tmplStr,
                                          this.env.asyncFilters,
                                          this.env.extensionsList,
                                          this.path,
                                          this.env.lexerTags);
            var func = new Function(source);
            props = func();
        }

        this.blocks = this._getBlocks(props);
        this.rootRenderFunc = props.root;
        this.compiled = true;
    },

    _getBlocks: function(props) {
        var blocks = {};

        for(var k in props) {
            if(k.slice(0, 2) == 'b_') {
                blocks[k.slice(2)] = props[k];
            }
        }

        return blocks;
    }
});

// test code
// var src = '{% macro foo() %}{% include "include.html" %}{% endmacro %}{{ foo() }}';
// var env = new Environment(new builtin_loaders.FileSystemLoader('../tests/templates', true), { dev: true });
// console.log(env.renderString(src, { name: 'poop' }));

module.exports = {
    Environment: Environment,
    Template: Template
};
<commit_msg>async rendering doesn't throw anymore when compiling errors (fixes https://github.com/mozilla/nunjucks/issues/233)<commit_after>var path = require('path');
var lib = require('./lib');
var Obj = require('./object');
var lexer = require('./lexer');
var compiler = require('./compiler');
var builtin_filters = require('./filters');
var builtin_loaders = require('./loaders');
var runtime = require('./runtime');
var globals = require('./globals');
var Frame = runtime.Frame;

var Environment = Obj.extend({
    init: function(loaders, opts) {
        // The dev flag determines the trace that'll be shown on errors.
        // If set to true, returns the full trace from the error point,
        // otherwise will return trace starting from Template.render
        // (the full trace from within nunjucks may confuse developers using
        //  the library)
        // defaults to false
        opts = opts || {};
        this.dev = !!opts.dev;
        this.lexerTags = opts.tags;

        // The autoescape flag sets global autoescaping. If true,
        // every string variable will be escaped by default.
        // If false, strings can be manually escaped using the `escape` filter.
        // defaults to false
        this.autoesc = !!opts.autoescape;

        if(!loaders) {
            // The filesystem loader is only available client-side
            if(builtin_loaders.FileSystemLoader) {
                this.loaders = [new builtin_loaders.FileSystemLoader('views')];
            }
            else {
                this.loaders = [new builtin_loaders.WebLoader('/views')];
            }
        }
        else {
            this.loaders = lib.isArray(loaders) ? loaders : [loaders];
        }

        this.initCache();
        this.filters = {};
        this.asyncFilters = [];
        this.extensions = {};
        this.extensionsList = [];

        for(var name in builtin_filters) {
            this.addFilter(name, builtin_filters[name]);
        }
    },

    initCache: function() {
        // Caching and cache busting
        var cache = {};

        lib.each(this.loaders, function(loader) {
            if(typeof loader.on === 'function'){
                loader.on('update', function(template) {
                    cache[template] = null;
                });
            }
        });

        this.cache = cache;
    },

    addExtension: function(name, extension) {
        extension._name = name;
        this.extensions[name] = extension;
        this.extensionsList.push(extension);
    },

    getExtension: function(name) {
        return this.extensions[name];
    },

    addGlobal: function(name, value) {
        globals[name] = value;
    },

    addFilter: function(name, func, async) {
        var wrapped = func;

        if(async) {
            this.asyncFilters.push(name);
        }
        this.filters[name] = wrapped;
    },

    getFilter: function(name) {
        if(!this.filters[name]) {
            throw new Error('filter not found: ' + name);
        }
        return this.filters[name];
    },

    getTemplate: function(name, eagerCompile, cb) {
        if(name && name.raw) {
            // this fixes autoescape for templates referenced in symbols
            name = name.raw;
        }

        if(lib.isFunction(eagerCompile)) {
            cb = eagerCompile;
            eagerCompile = false;
        }

        if(typeof name !== 'string') {
            throw new Error('template names must be a string: ' + name);
        }

        var tmpl = this.cache[name];

        if(tmpl) {
            if(eagerCompile) {
                tmpl.compile();
            }

            if(cb) {
                cb(null, tmpl);
            }
            else {
                return tmpl;
            }
        } else {
            var syncResult;

            lib.asyncIter(this.loaders, function(loader, i, next, done) {
                function handle(src) {
                    if(src) {
                        done(src);
                    }
                    else {
                        next();
                    }
                }

                if(loader.async) {
                    loader.getSource(name, function(err, src) {
                        if(err) { throw err; }
                        handle(src);
                    });
                }
                else {
                    handle(loader.getSource(name));
                }
            }, function(info) {
                if(!info) {
                    var err = new Error('template not found: ' + name);
                    if(cb) {
                        cb(err);
                    }
                    else {
                        throw err;
                    }
                }
                else {
                    var tmpl = new Template(info.src, this,
                                            info.path, eagerCompile);

                    if(!info.noCache) {
                        this.cache[name] = tmpl;
                    }

                    if(cb) {
                        cb(null, tmpl);
                    }
                    else {
                        syncResult = tmpl;
                    }
                }
            }.bind(this));

            return syncResult;
        }
    },

    express: function(app) {
        var env = this;

        function NunjucksView(name, opts) {
            this.name          = name;
            this.path          = name;
            this.defaultEngine = opts.defaultEngine;
            this.ext           = path.extname(name);
            if (!this.ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
            if (!this.ext) this.name += (this.ext = ('.' !== this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
        }

        NunjucksView.prototype.render = function(opts, cb) {
          env.render(this.name, opts, cb);
        };

        app.set('view', NunjucksView);
    },

    render: function(name, ctx, cb) {
        if(lib.isFunction(ctx)) {
            cb = ctx;
            ctx = null;
        }

        // We support a synchronous API to make it easier to migrate
        // existing code to async. This works because if you don't do
        // anything async work, the whole thing is actually run
        // synchronously.
        var syncResult = null;

        this.getTemplate(name, function(err, tmpl) {
            if(err && cb) {
                cb(err);
            }
            else if(err) {
                throw err;
            }
            else {
                tmpl.render(ctx, cb || function(err, res) {
                    if(err) { throw err; }
                    syncResult = res;
                });
            }
        });

        return syncResult;
    },

    renderString: function(src, ctx, cb) {
        var tmpl = new Template(src, this);
        return tmpl.render(ctx, cb);
    }
});

var Context = Obj.extend({
    init: function(ctx, blocks) {
        this.ctx = ctx;
        this.blocks = {};
        this.exported = [];

        for(var name in blocks) {
            this.addBlock(name, blocks[name]);
        }
    },

    lookup: function(name) {
        // This is one of the most called functions, so optimize for
        // the typical case where the name isn't in the globals
        if(name in globals && !(name in this.ctx)) {
            return globals[name];
        }
        else {
            return this.ctx[name];
        }
    },

    setVariable: function(name, val) {
        this.ctx[name] = val;
    },

    getVariables: function() {
        return this.ctx;
    },

    addBlock: function(name, block) {
        this.blocks[name] = this.blocks[name] || [];
        this.blocks[name].push(block);
    },

    getBlock: function(name) {
        if(!this.blocks[name]) {
            throw new Error('unknown block "' + name + '"');
        }

        return this.blocks[name][0];
    },

    getSuper: function(env, name, block, frame, runtime, cb) {
        var idx = lib.indexOf(this.blocks[name] || [], block);
        var blk = this.blocks[name][idx + 1];
        var context = this;

        if(idx == -1 || !blk) {
            throw new Error('no super block available for "' + name + '"');
        }

        blk(env, context, frame, runtime, cb);
    },

    addExport: function(name) {
        this.exported.push(name);
    },

    getExported: function() {
        var exported = {};
        for(var i=0; i<this.exported.length; i++) {
            var name = this.exported[i];
            exported[name] = this.ctx[name];
        }
        return exported;
    }
});

var Template = Obj.extend({
    init: function (src, env, path, eagerCompile) {
        this.env = env || new Environment();

        if(lib.isObject(src)) {
            switch(src.type) {
            case 'code': this.tmplProps = src.obj; break;
            case 'string': this.tmplStr = src.obj; break;
            }
        }
        else if(lib.isString(src)) {
            this.tmplStr = src;
        }
        else {
            throw new Error("src must be a string or an object describing " +
                            "the source");
        }

        this.path = path;

        if(eagerCompile) {
            lib.withPrettyErrors(this.path,
                                 this.env.dev,
                                 this._compile.bind(this));
        }
        else {
            this.compiled = false;
        }
    },

    render: function(ctx, frame, cb) {
        if (typeof ctx === 'function') {
            cb = ctx;
            ctx = {};
        }
        else if (typeof frame === 'function') {
            cb = frame;
            frame = null;
        }

        return lib.withPrettyErrors(this.path, this.env.dev, function() {
            try {
                this.compile();
            } catch (e) {
                if (cb) cb(e);
                else throw e;
                return;
            }

            var context = new Context(ctx || {}, this.blocks);
            var syncResult = null;

            this.rootRenderFunc(this.env,
                                context,
                                frame || new Frame(),
                                runtime,
                                cb || function(err, res) {
                                    if(err) { throw err; }
                                    syncResult = res;
                                });

            return syncResult;
        }.bind(this));
    },

    getExported: function(cb) {
        try {
            this.compile();
        } catch (e) {
            if (cb) cb(e);
            else throw e;
            return;
        }

        // Run the rootRenderFunc to populate the context with exported vars
        var context = new Context({}, this.blocks);
        this.rootRenderFunc(this.env,
                            context,
                            new Frame(),
                            runtime,
                            function() {
                                cb(null, context.getExported());
                            });
    },

    compile: function() {
        if(!this.compiled) {
            this._compile();
        }
    },

    _compile: function() {
        var props;

        if(this.tmplProps) {
            props = this.tmplProps;
        }
        else {
            var source = compiler.compile(this.tmplStr,
                                          this.env.asyncFilters,
                                          this.env.extensionsList,
                                          this.path,
                                          this.env.lexerTags);
            var func = new Function(source);
            props = func();
        }

        this.blocks = this._getBlocks(props);
        this.rootRenderFunc = props.root;
        this.compiled = true;
    },

    _getBlocks: function(props) {
        var blocks = {};

        for(var k in props) {
            if(k.slice(0, 2) == 'b_') {
                blocks[k.slice(2)] = props[k];
            }
        }

        return blocks;
    }
});

// test code
// var src = '{% macro foo() %}{% include "include.html" %}{% endmacro %}{{ foo() }}';
// var env = new Environment(new builtin_loaders.FileSystemLoader('../tests/templates', true), { dev: true });
// console.log(env.renderString(src, { name: 'poop' }));

module.exports = {
    Environment: Environment,
    Template: Template
};
<|endoftext|>


<commit_before>const StateMachine = function (plugins = []) {
	this.stackState = []
	this.stateDB = {}
	this.plugins = plugins
	this.stateData = {}
}

StateMachine.prototype.load = function(stateDB, defaultState) {
	this.stateDB = stateDB
	this.ReplaceState(defaultState)
};

StateMachine.prototype.OnUpdate = function(dt) {
	if(this.currentState == null)
		return

	// Update Plugin
	this._pluginEvent("OnUpdate", {dt: dt})

	// Update State Transition
	const nextStateName = this.currentState.OnUpdate(this.stateData, dt)

	// Replace State
	if(nextStateName != null)
		this.ReplaceState(nextStateName)
};

StateMachine.prototype.ReplaceState = function(nextStateName) {
	if(this.currentState) {
		this._pluginEvent("OnExit", {})
		this.currentState.OnExit(this.stateData)
	}

	// lookup new state
	this.currentState = this.stateDB[nextStateName]

	if(this.currentState) {
		this._pluginEvent("OnEnter", {stateName: nextStateName})
		this.currentState.OnEnter(this.stateData)
	}
};

StateMachine.prototype.OnEvent = function(name, args) {
	this._pluginEvent("OnEvent", {name: name, args: args})
};

StateMachine.prototype.AddPlugin = function(plugin) {
	this.plugins.push(plugin)
};

StateMachine.prototype._pluginEvent = function(eventName, args) {
	this.plugins.forEach(itm => {
		const fuc = itm[eventName]
		fuc && fuc(this.stateData, args)
	})
};

module.exports = StateMachine<commit_msg>[JS] add anyState and stackState machine<commit_after>const ANY_STATE_NAME = "AnyState"
const POP_STATE_NAME = "PopState"

const StateMachine = function(plugins = []) {
	this.stackState = []
	this.stateDB = {}
	this.plugins = plugins
	this.stateData = {}
}

StateMachine.prototype.load = function(stateDB, defaultState) {
	this.stateDB = stateDB
	this.anyState = stateDB[ANY_STATE_NAME]
	this.ReplaceState(defaultState)
};

StateMachine.prototype.OnUpdate = function(dt) {
	if (this.currentState == null)
		return

	// Update Plugin
	this._pluginEvent("OnUpdate", {
		dt: dt
	})

	let operation = this.ReplaceState

	// Update State Transition following
	//	1. AnyState transitions
	//	2. State transitions

	let nextStateName = this.updateAnyState()
	if (nextStateName != null) {
		operation = this.PushState
	} else {
		nextStateName = this.currentState.OnUpdate(this.stateData, dt)
	}

	// Should Pop state
	if (nextStateName == POP_STATE_NAME)
		operation = this.PopState

	// Replace State
	if (nextStateName != null)
		operation.call(this,nextStateName)
};

StateMachine.prototype.updateAnyState = function(dt) {
	if (this.anyState == null)
		return

	return this.anyState.OnUpdate(this.stateData, dt)
};

StateMachine.prototype.ReplaceState = function(nextStateName) {
	if (this.currentState) {

		// Ignore incase same state transition
		if (this.stateDB[nextStateName] == this.currentState)
			return

		this._pluginEvent("OnExit", {})
		this.currentState.OnExit(this.stateData)

		// pop stack
		this.stackState.pop()
	}

	// lookup new state
	this.currentState = this.stateDB[nextStateName]

	if (this.currentState) {
		this._pluginEvent("OnEnter", {
			stateName: nextStateName
		})
		this.currentState.OnEnter(this.stateData)

		// push state
		this.stackState.push(this.currentState)
	}
};

StateMachine.prototype.PushState = function(nextStateName) {
	if (this.currentState) {

		// Ignore incase same state transition
		if (this.stateDB[nextStateName] == this.currentState)
			return

		this._pluginEvent("OnExit", {})
		this.currentState.OnExit(this.stateData)
	}

	// lookup new state
	this.currentState = this.stateDB[nextStateName]

	if (this.currentState) {
		this._pluginEvent("OnEnter", {
			stateName: nextStateName
		})
		this.currentState.OnEnter(this.stateData)

		// push state
		this.stackState.push(this.currentState)
	}
};

StateMachine.prototype.PopState = function(nextStateName) {
	if (this.currentState) {

		// Ignore incase same state transition
		if (this.stateDB[nextStateName] == this.currentState)
			return

		this._pluginEvent("OnExit", {})
		this.currentState.OnExit(this.stateData)

		this.stackState.pop()
	}

	this.currentState = this.stackState[0]

	if (this.currentState) {
		this._pluginEvent("OnEnter", {
			stateName: nextStateName
		})
		this.currentState.OnEnter(this.stateData)

		// push state
		this.stackState.push(this.currentState)
	}
};

StateMachine.prototype.OnEvent = function(name, args) {
	this._pluginEvent("OnEvent", {
		name: name,
		args: args
	})
};

StateMachine.prototype.AddPlugin = function(plugin) {
	this.plugins.push(plugin)
};

StateMachine.prototype._pluginEvent = function(eventName, args) {
	this.plugins.forEach(itm => {
		const fuc = itm[eventName]
		fuc && fuc(this.stateData, args)
	})
};

module.exports = StateMachine<|endoftext|>


<commit_before>/*! Native Promise Only
    v0.5.0-a (c) Kyle Simpson
    MIT License: http://getify.mit-license.org
*/

(function UMD(name,context,definition){
  // special form of UMD for polyfilling across evironments
  context[name] = context[name] || definition();
})("Promise",typeof global !== "undefined" ? global : this,function DEF(){
  /*jshint validthis:true */
  "use strict";

  var sync_schedule = false, cycle, scheduling_queue,
    timer = (typeof setImmediate !== "undefined") ?
      function timer(fn) { return setImmediate(fn); } :
      setTimeout,
    builtInProp = Object.defineProperty ?
      function builtInProp(obj,name,val,config) {
        return Object.defineProperty(obj,name,{
          value: val,
          writable: true,
          configurable: config !== false
        });
      } :
      function builtInProp(obj,name,val) {
        obj[name] = val;
        return obj;
      }
  ;

  // Note: using a queue instead of array for efficiency
  function Queue() {
    var first, last, item;

    function Item(fn,self) {
      this.fn = fn;
      this.self = self;
      this.next = void 0;
    }

    return {
      add: function add(fn,self) {
        item = new Item(fn,self);
        if (last) {
          last.next = item;
        }
        else {
          first = item;
        }
        last = item;
        item = void 0;
      },
      drain: function drain() {
        var f = first;
        first = last = cycle = null;

        while (f) {
          f.fn.call(f.self);
          f = f.next;
        }
      }
    };
  }

  scheduling_queue = Queue();

  function schedule(fn,self) {
    if (sync_schedule) {
      sync_schedule = false;
      fn.call(self);
    }
    else {
      scheduling_queue.add(fn,self);
      if (!cycle) {
        cycle = timer(scheduling_queue.drain);
      }
    }
  }

  // promise duck typing?
  function isThenable(o) {
    var _then, o_type = typeof o;

    if (o !== null &&
      (
        o_type === "object" || o_type === "function"
      )
    ) {
      _then = o.then;
    }
    return typeof _then === "function" ? _then : false;
  }

  function notify() {
    var self = this, cb, chain, i;

    if (self.state === 0) {
      return sync_schedule = false;
    }

    for (i=0; i<self.chain.length; i++) {
      chain = self.chain[i];
      cb = (self.state === 1) ? chain.success : chain.failure;
      notifyIsolated(self,cb,chain);
    }
    self.chain.length = 0;
  }

  function notifyIsolated(self,cb,chain) {
    var ret, _then;
    try {
      if (cb === false) {
        sync_schedule = true;
        chain.reject(self.msg);
      }
      else {
        if (cb === true) ret = self.msg;
        else ret = cb.call(void 0,self.msg);

        sync_schedule = true;
        if (ret === chain.promise) {
          chain.reject(TypeError("Promise-chain cycle"));
        }
        else if ((_then = isThenable(ret))) {
          _then.call(ret,chain.resolve,chain.reject);
        }
        else {
          chain.resolve(ret);
        }
      }
    }
    catch (err) {
      sync_schedule = true;
      chain.reject(err);
    }
  }
  function checkYourself(self) {
    if (self.def) {
      if (self.triggered) {
        return sync_schedule = false;
      }
      self.triggered = true;
      self = self.def;
    }

    if (self.state !== 0) {
      return sync_schedule = false;
    }

    return self;
  }

  function resolve(msg) {
    var _then, def_wrapper, self = checkYourself(this);

    // self-check failed
    if (self === false) { return; }

    try {
      if ((_then = isThenable(msg))) {
        def_wrapper = new MakeDefWrapper(self);
        _then.call(msg,
          function $resolve$(){ resolve.apply(def_wrapper,arguments); },
          function $reject$(){ reject.apply(def_wrapper,arguments); }
        );
      }
      else {
        self.msg = msg;
        self.state = 1;
        schedule(notify,self);
      }
    }
    catch (err) {
      reject.call(def_wrapper || (new MakeDefWrapper(self)),err);
    }
  }

  function reject(msg) {
    var self = checkYourself(this);

    // self-check failed
    if (self === false) { return; }

    self.msg = msg;
    self.state = 2;
    schedule(notify,self);
  }

  function iteratePromises(Constructor,arr,resolver,rejecter) {
    for (var idx=0; idx<arr.length; idx++) {
      (function(idx){
        Constructor.resolve(arr[idx])
        .then(
          function $resolver$(msg){
            resolver(idx,msg);
          },
          rejecter
        );
      })(idx);
    }
  }

  function MakeDefWrapper(self) {
    this.def = self;
    this.triggered = false;
  }

  function MakeDef(self) {
    this.promise = self;
    this.state = 0;
    this.triggered = false;
    this.chain = [];
    this.msg = void 0;
  }

  function Promise(executor) {
    if (typeof executor !== "function") {
      throw TypeError("Not a function");
    }

    if (this.__NPO__ !== 0) {
      throw TypeError("Not a promise");
    }

    // instance shadowing the inherited "brand"
    // to signal an already "initialized" promise
    this.__NPO__ = 1;

    var self = this, def = new MakeDef(self);

    self.then = function then(success,failure) {
      var o = {
        success: typeof success === "function" ? success : true,
        failure: typeof failure === "function" ? failure : false
      };
      // Note: `then(..)` itself can be borrowed to be used against
      // a different promise constructor for making the chained promise,
      // by substituting a different `this` binding.
      o.promise = new this.constructor(function extractChain(resolve,reject) {
        if (typeof (resolve && reject) !== "function") {
          throw TypeError("Not a function");
        }

        o.resolve = resolve;
        o.reject = reject;
      });
      def.chain.push(o);

      schedule(notify,def);

      return o.promise;
    };
    // `catch` not allowed as identifier in older JS engines
    self["catch"] = function $catch$(failure) {
      return def.promise.then.call(this,void 0,failure);
    };

    try {
      executor.call(
        void 0,
        function publicResolve(msg){
          if (def.triggered) {
            return void(sync_schedule = false);
          }
          def.triggered = true;

          resolve.call(def,msg);
        },
        function publicReject(msg) {
          if (def.triggered) {
            return void(sync_schedule = false);
          }
          def.triggered = true;

          reject.call(def,msg);
        }
      );
    }
    catch (err) {
      reject.call(def,err);
    }
  }

  var PromisePrototype = builtInProp({},"constructor",Promise,
    /*configurable=*/false
  );

  builtInProp(
    Promise,"prototype",PromisePrototype,
    /*configurable=*/false
  );

  // built-in "brand" to signal an "uninitialized" promise
  builtInProp(PromisePrototype,"__NPO__",0,
    /*configurable=*/false
  );

  builtInProp(Promise,"resolve",function Promise$resolve(msg) {
    var Constructor = this;

    // spec mandated checks
    // note: best "isPromise" check that's practical for now
    if (typeof msg === "object" && "__NPO__" in msg) {
      return msg;
    }

    return new Constructor(function executor(resolve,reject){
      if (typeof (resolve && reject) !== "function") {
        throw TypeError("Not a function");
      }

      schedule(function immediateResolve(){
        sync_schedule = true;
        resolve(msg);
      });
    });
  });

  builtInProp(Promise,"reject",function Promise$reject(msg) {
    return new this(function executor(resolve,reject){
      if (typeof (resolve && reject) !== "function") {
        throw TypeError("Not a function");
      }

      reject(msg);
    });
  });

  builtInProp(Promise,"all",function Promise$all(arr) {
    var Constructor = this;

    // spec mandated checks
    if (!Array.isArray(arr)) {
      return Constructor.reject(TypeError("Not an array"));
    }
    if (arr.length === 0) {
      return Constructor.resolve([]);
    }

    return new Constructor(function executor(resolve,reject){
      if (typeof (resolve && reject) !== "function") {
        throw TypeError("Not a function");
      }

      var len = arr.length, msgs = Array(len), count = 0;

      iteratePromises(Constructor,arr,function resolver(idx,msg) {
        msgs[idx] = msg;
        if (++count === len) {
          resolve(msgs);
        }
      },reject);
    });
  });

  builtInProp(Promise,"race",function Promise$race(arr) {
    var Constructor = this;

    // spec mandated checks
    if (!Array.isArray(arr)) {
      return Constructor.reject(TypeError("Not an array"));
    }

    return new Constructor(function executor(resolve,reject){
      if (typeof (resolve && reject) !== "function") {
        throw TypeError("Not a function");
      }

      iteratePromises(Constructor,arr,function resolver(idx,msg){
        resolve(msg);
      },reject);
    });
  });

  return Promise;
});<commit_msg>Update promises.js polyfill to actual version<commit_after>/*! Native Promise Only
    v0.7.6-a (c) Kyle Simpson
    MIT License: http://getify.mit-license.org
*/

(function UMD(name,context,definition){
  // special form of UMD for polyfilling across evironments
  context[name] = context[name] || definition();
})("Promise",typeof global != "undefined" ? global : this,function DEF(){
  /*jshint validthis:true */
  "use strict";

  var builtInProp, cycle, scheduling_queue,
    ToString = Object.prototype.toString,
    timer = (typeof setImmediate != "undefined") ?
      function timer(fn) { return setImmediate(fn); } :
      setTimeout
  ;

  // damnit, IE8.
  try {
    Object.defineProperty({},"x",{});
    builtInProp = function builtInProp(obj,name,val,config) {
      return Object.defineProperty(obj,name,{
        value: val,
        writable: true,
        configurable: config !== false
      });
    };
  }
  catch (err) {
    builtInProp = function builtInProp(obj,name,val) {
      obj[name] = val;
      return obj;
    };
  }

  // Note: using a queue instead of array for efficiency
  scheduling_queue = (function Queue() {
    var first, last, item;

    function Item(fn,self) {
      this.fn = fn;
      this.self = self;
      this.next = void 0;
    }

    return {
      add: function add(fn,self) {
        item = new Item(fn,self);
        if (last) {
          last.next = item;
        }
        else {
          first = item;
        }
        last = item;
        item = void 0;
      },
      drain: function drain() {
        var f = first;
        first = last = cycle = void 0;

        while (f) {
          f.fn.call(f.self);
          f = f.next;
        }
      }
    };
  })();

  function schedule(fn,self) {
    scheduling_queue.add(fn,self);
    if (!cycle) {
      cycle = timer(scheduling_queue.drain);
    }
  }

  // promise duck typing
  function isThenable(o) {
    var _then, o_type = typeof o;

    if (o != null &&
      (
        o_type == "object" || o_type == "function"
      )
    ) {
      _then = o.then;
    }
    return typeof _then == "function" ? _then : false;
  }

  function notify() {
    for (var i=0; i<this.chain.length; i++) {
      notifyIsolated(
        this,
        (this.state === 1) ? this.chain[i].success : this.chain[i].failure,
        this.chain[i]
      );
    }
    this.chain.length = 0;
  }

  // NOTE: This is a separate function to isolate
  // the `try..catch` so that other code can be
  // optimized better
  function notifyIsolated(self,cb,chain) {
    var ret, _then;
    try {
      if (cb === false) {
        chain.reject(self.msg);
      }
      else {
        if (cb === true) {
          ret = self.msg;
        }
        else {
          ret = cb.call(void 0,self.msg);
        }

        if (ret === chain.promise) {
          chain.reject(TypeError("Promise-chain cycle"));
        }
        else if (_then = isThenable(ret)) {
          _then.call(ret,chain.resolve,chain.reject);
        }
        else {
          chain.resolve(ret);
        }
      }
    }
    catch (err) {
      chain.reject(err);
    }
  }

  function resolve(msg) {
    var _then, def_wrapper, self = this;

    // already triggered?
    if (self.triggered) { return; }

    self.triggered = true;

    // unwrap
    if (self.def) {
      self = self.def;
    }

    try {
      if (_then = isThenable(msg)) {
        def_wrapper = new MakeDefWrapper(self);
        _then.call(msg,
          function $resolve$(){ resolve.apply(def_wrapper,arguments); },
          function $reject$(){ reject.apply(def_wrapper,arguments); }
        );
      }
      else {
        self.msg = msg;
        self.state = 1;
        if (self.chain.length > 0) {
          schedule(notify,self);
        }
      }
    }
    catch (err) {
      reject.call(def_wrapper || (new MakeDefWrapper(self)),err);
    }
  }

  function reject(msg) {
    var self = this;

    // already triggered?
    if (self.triggered) { return; }

    self.triggered = true;

    // unwrap
    if (self.def) {
      self = self.def;
    }

    self.msg = msg;
    self.state = 2;
    if (self.chain.length > 0) {
      schedule(notify,self);
    }
  }

  function iteratePromises(Constructor,arr,resolver,rejecter) {
    for (var idx=0; idx<arr.length; idx++) {
      (function IIFE(idx){
        Constructor.resolve(arr[idx])
        .then(
          function $resolver$(msg){
            resolver(idx,msg);
          },
          rejecter
        );
      })(idx);
    }
  }

  function MakeDefWrapper(self) {
    this.def = self;
    this.triggered = false;
  }

  function MakeDef(self) {
    this.promise = self;
    this.state = 0;
    this.triggered = false;
    this.chain = [];
    this.msg = void 0;
  }

  function Promise(executor) {
    if (typeof executor != "function") {
      throw TypeError("Not a function");
    }

    if (this.__NPO__ !== 0) {
      throw TypeError("Not a promise");
    }

    // instance shadowing the inherited "brand"
    // to signal an already "initialized" promise
    this.__NPO__ = 1;

    var def = new MakeDef(this);

    this["then"] = function then(success,failure) {
      var o = {
        success: typeof success == "function" ? success : true,
        failure: typeof failure == "function" ? failure : false
      };
      // Note: `then(..)` itself can be borrowed to be used against
      // a different promise constructor for making the chained promise,
      // by substituting a different `this` binding.
      o.promise = new this.constructor(function extractChain(resolve,reject) {
        if (typeof resolve != "function" || typeof reject != "function") {
          throw TypeError("Not a function");
        }

        o.resolve = resolve;
        o.reject = reject;
      });
      def.chain.push(o);

      if (def.state !== 0) {
        schedule(notify,def);
      }

      return o.promise;
    };
    this["catch"] = function $catch$(failure) {
      return this.then(void 0,failure);
    };

    try {
      executor.call(
        void 0,
        function publicResolve(msg){
          resolve.call(def,msg);
        },
        function publicReject(msg) {
          reject.call(def,msg);
        }
      );
    }
    catch (err) {
      reject.call(def,err);
    }
  }

  var PromisePrototype = builtInProp({},"constructor",Promise,
    /*configurable=*/false
  );

  builtInProp(
    Promise,"prototype",PromisePrototype,
    /*configurable=*/false
  );

  // built-in "brand" to signal an "uninitialized" promise
  builtInProp(PromisePrototype,"__NPO__",0,
    /*configurable=*/false
  );

  builtInProp(Promise,"resolve",function Promise$resolve(msg) {
    var Constructor = this;

    // spec mandated checks
    // note: best "isPromise" check that's practical for now
    if (msg && typeof msg == "object" && msg.__NPO__ === 1) {
      return msg;
    }

    return new Constructor(function executor(resolve,reject){
      if (typeof resolve != "function" || typeof reject != "function") {
        throw TypeError("Not a function");
      }

      resolve(msg);
    });
  });

  builtInProp(Promise,"reject",function Promise$reject(msg) {
    return new this(function executor(resolve,reject){
      if (typeof resolve != "function" || typeof reject != "function") {
        throw TypeError("Not a function");
      }

      reject(msg);
    });
  });

  builtInProp(Promise,"all",function Promise$all(arr) {
    var Constructor = this;

    // spec mandated checks
    if (ToString.call(arr) != "[object Array]") {
      return Constructor.reject(TypeError("Not an array"));
    }
    if (arr.length === 0) {
      return Constructor.resolve([]);
    }

    return new Constructor(function executor(resolve,reject){
      if (typeof resolve != "function" || typeof reject != "function") {
        throw TypeError("Not a function");
      }

      var len = arr.length, msgs = Array(len), count = 0;

      iteratePromises(Constructor,arr,function resolver(idx,msg) {
        msgs[idx] = msg;
        if (++count === len) {
          resolve(msgs);
        }
      },reject);
    });
  });

  builtInProp(Promise,"race",function Promise$race(arr) {
    var Constructor = this;

    // spec mandated checks
    if (ToString.call(arr) != "[object Array]") {
      return Constructor.reject(TypeError("Not an array"));
    }

    return new Constructor(function executor(resolve,reject){
      if (typeof resolve != "function" || typeof reject != "function") {
        throw TypeError("Not a function");
      }

      iteratePromises(Constructor,arr,function resolver(idx,msg){
        resolve(msg);
      },reject);
    });
  });

  return Promise;
});<|endoftext|>


<commit_before>/*
 * ! ${copyright}
 */

sap.ui.define([
	'./TreeItemBaseRenderer', 'sap/ui/core/Renderer'
], function(TreeItemBaseRenderer, Renderer) {
	"use strict";

	/**
	 * @namespace
	 */
	var CustomTreeItemRenderer = Renderer.extend(TreeItemBaseRenderer);

	/**
	 * Renders the HTML for the given control, using the provided {@link sap.ui.core.RenderManager}.
	 *
	 * @param {sap.ui.core.RenderManager} oRenderManager RenderManager object
	 * @param {sap.ui.core.Control} oControl An object representation of the control that will be rendered
	 */
	CustomTreeItemRenderer.renderLIAttributes = function(rm, oLI) {
		rm.addClass("sapMCTI");
		TreeItemBaseRenderer.renderLIAttributes.apply(this, arguments);
	};

	CustomTreeItemRenderer.renderLIContent = function(rm, oLI) {
		oLI.getContent().forEach(function(oContent) {
			rm.renderControl(oContent);
		});
	};

	return CustomTreeItemRenderer;

}, /* bExport= */true);
<commit_msg>[INTERNAL] Semantic Rendering: table related controls switched to new Renderer Syntax CustomTreeItem control is the only remaining control which has been changed to the new Renderer Syntax JIRA: CPOUIFTEAMB-1542<commit_after>/*
 * ! ${copyright}
 */

sap.ui.define([
	'./TreeItemBaseRenderer', 'sap/ui/core/Renderer'
], function(TreeItemBaseRenderer, Renderer) {
	"use strict";

	/**
	 * @namespace
	 */
	var CustomTreeItemRenderer = Renderer.extend(TreeItemBaseRenderer);
	CustomTreeItemRenderer.apiVersion = 2;

	/**
	 * Renders the HTML for the given control, using the provided {@link sap.ui.core.RenderManager}.
	 *
	 * @param {sap.ui.core.RenderManager} oRenderManager RenderManager object
	 * @param {sap.ui.core.Control} oControl An object representation of the control that will be rendered
	 */
	CustomTreeItemRenderer.renderLIAttributes = function(rm, oLI) {
		rm.class("sapMCTI");
		TreeItemBaseRenderer.renderLIAttributes.apply(this, arguments);
	};

	CustomTreeItemRenderer.renderLIContent = function(rm, oLI) {
		oLI.getContent().forEach(function(oContent) {
			rm.renderControl(oContent);
		});
	};

	return CustomTreeItemRenderer;

}, /* bExport= */true);
<|endoftext|>


<commit_before>/**
 * Object representing a path.
 * @author Simon Chauvin
 */
FMENGINE.fmPath = function () {
    "use strict";
    var that = {};

    /**
     * Waypoints constituing the path.
     */
    that.waypoints = [];

    /**
     * Add a waypoint to the path.
     * @param {int} x x position.
     * @param {int} y y position.
     */
    that.add = function (x, y) {

    };

    /**
     * Remove a waypoint from the path.
     */
    that.remove = function () {

    };

    return that;
};<commit_msg>Removed path object and added path component<commit_after><|endoftext|>


<commit_before>module.exports = {

  prompts: false,
  plugins: {
    less: {
      referencesOthers: true,
      lessOptions: {
        compress: true,
        sourceMap: {
          sourceMapFileInline: true
        }
      }
    }
  },
  reloadPaths: ['src'],
  regeneratePaths: ['src'],
  regenerateDelay: 300,

  // These are variables will be accessible via our templates
  templateData: {

    // Conference info
    conf: {
      name: "INSITER",
      description: "Inside the Web - Teresina - PI",
      date: "10 de Junho de 2017",
      // If your event is free, just comment this line
      price: "R$ 50",
      venue: "Auditório do Sebrae",
      address: "Av. Campos Sáles, 1046 - Centro (Norte), Teresina - PI, 64000-300",
      city: "Teresina",
      state: "Piauí"
    },

    // The Call To Action button at the header,
    // If you don't want this, just remove the callToAction property.
    callToAction: {
      text: "Comprar ticket",
      link: "https://www.eventbrite.com.br/e/insiter-tickets-33716234164?aff=efbevent",
      advice: "Vagas limitadas!"
    },

    // Site info
    site: {
      theme: "default",
      url: "http://insiter.io",
      googleanalytics: "UA-31931741-2"
    },

    // Active sections on the website
    // to deactivate comment out with '//'
    // you can also change order here and it will reflect on page
    sections: [
      'about',
      'location',
      'speakers',
      'schedule',
      // 'sponsors',
      'partners',
      // 'contact'
    ],

    // Labels which you can translate to other languages
    labels: {
      about: "Sobre",
      location: "Local",
      speakers: "Palestrantes",
      schedule: "Programação",
      sponsors: "Patrocinadores",
      partners: "Parceiros",
      contact: "Contato"
    },

    // The entire schedule
    schedule: [
      {
        name: "Credenciamento",
        time: "08:00"
      },
      {
        name: "Daniel Romero",
        photo: "https://avatars0.githubusercontent.com/u/444911?v=3&s=460",
        bio: "Desenvolvedor, escritor técnico, palestrante e atualmente trabalha com práticas DevOps.",
        link: {
          href: "https://infoslack.pro/",
          text: "@infoslack"
        },
        presentation: {
          title: "Unikernels e o futuro da infraestrutura imutável",
          description: "Sistemas operacionais tradicionais (Linux, FreeBSD, Windows) serão extintos em servidores. Eles serão substituídos por hypervisors do tipo bare metal, otimizados de forma específica para o hardware e o deploy de nossas aplicações será feito através de um único arquivo binário. Nesta talk, veremos o que são Unikernels, os motivos de serem rápidos, seguros e que oportunidades ele reserva para o futuro.",
          time: "09:00"
        }
      },
      {
        name: "Fabio Akita",
        photo: "https://avatars2.githubusercontent.com/u/2840?v=3&s=460",
        bio: "Programador desde o começo dos anos 90, ativista de Ruby on Rails desde 2006, realizou quase 200 palestras pelo mundo e é co-fundador da Codeminer 42.",
        company: "Codeminer 42",
        link: {
          href: "http://www.akitaonrails.com/",
          text: "@akitaOnRails"
        },
        presentation: {
          title: "30 dias de Elixir e Crystal e de volta a Ruby",
          description: "Qual a forma correta de entender a diferença de performance das diferentes novas linguagens frente a casos reais de desenvolvimento. Baseado em benchmarks sintéticos, todos vão concordar que Ruby é \"lento\". Portanto deveríamos automaticamente abandonar Ruby e ir para outras linguagens mais \"rápidas\" como Go ou Crystal ou Elixir? Olhando um caso real, vamos entender porque essa resposta não é tão simples quanto parece",
          time: "09:50"
        }
      },
      {
        name: "Coffe Break",
        time: "10:40"
      },
      {
        name: "Jean Carlo",
        photo: "https://avatars3.githubusercontent.com/u/353504?v=3&s=460",
        bio: "Web craftsman and magician of computer machines. Developer at WORK.CO.",
        company: "WORK.CO",
        link: {
          href: "http://jcemer.com/",
          text: "@jcemer"
        },
        presentation: {
          title: "Como encarar o desenvolvimento front-end",
          description: "A todo tempo surgem novas formas de pensar e estruturar interfaces para a Internet. Esta palestra toma um olhar crítico a respeito de ferramentas, técnicas e código front-end em geral. Nosso objetivo será aprender a direcionar esforços para alcançar melhores resultados.",
          time: "13h00"
        }
      },
      {
        name: "Gabriel Sobrinho",
        photo: "https://avatars2.githubusercontent.com/u/26460?v=3&s=460",
        bio: "Desenvolvedor com mais de 10 anos de experiência em aplicações web, ativista de Ruby on Rails desde 2008 e fundador da Hite.",
        company: "Hite",
        link: {
          href: "http://gabrielsobrinho.com/",
          text: "@sobrinho"
        },
        presentation: {
          title: "Introdução a testes de software",
          description: "Uma introdução ao mundo dos testes, independe de linguagem de programação ou biblioteca. O que você deve testar, como testar e quando testar.",
          time: "17h00"
        }
      },
      {
        name: "Dmitry Rocha",
        photo: "https://avatars1.githubusercontent.com/u/53300?v=3&s=460",
        bio: "I'm passionate to solve problems on the right and less complicated way, I will work to turn life more easy with technology using my favorite tools, and at last I'm looking for my next favorite one.",
        company: "Codeminer 42",
        link: {
          href: "https://github.com/dmitryrck",
          text: "@dmitryrck"
        },
        presentation: {
          title: "Crystal: O que aconteceu quando tentaram compilar Ruby?",
          description: "Quando se fala em performance a primeira comparação é com C, mas C é a linguagem e o binário final é em código de máquina, então… o que aconteceu quando alguém tentou compilar Ruby? Disto surgiu Crystal: Fast as C, slick as Ruby. Nova linguagem ou um Ruby compilado?",
          time: "10h00"
        }
      },
      {
        name: "Coffee Break",
        time: "15:40"
      },
      {
        name: "Matias Leidemer",
        photo: "https://avatars1.githubusercontent.com/u/10559?v=3&s=460",
        bio: "Desenvolvedor com mais de 10 anos de experiência, apaixonado por Ruby, testes automatizados e código organizado. Trabalhou com diversas tecnologias, em empresas dentro e fora do Brasil. Atualmente é Web Development Engineer na Stickermule.",
        company: "Stickermule",
        link: {
          href: "http://www.leidemer.com/",
          text: "@matiasleidemer"
        },
        presentation: {
          title: "A definir",
          description: "",
          time: "16:10"
        }
      },
      {
        name: "Thiago Alves",
        photo: "https://avatars0.githubusercontent.com/u/5190217?v=3&s=460",
        bio: "Atua a 10 anos no mercado web. Apaixonado por JavaScript, atualmente é Desenvolvedor Front-End na Codeminer 42. Entende que apresentar palestras é uma das formas mais divertidas de aprender.",
        company: "Codeminer 42",
        link: {
          href: "https://twitter.com/taltk9",
          text: "@taltk9"
        },
        presentation: {
          title: "A definir",
          description: "",
          time: "17:00"
        }
      },
      {
        name: "Encerramento",
        time: "17:50"
      }
    ],

    // List of Sponsors
    sponsors: [
      {
        name: "Eventick",
        logo: "themes/yellow-swan/img/sponsor.png",
        url: "http://eventick.com.br"
      }
    ],

    // List of Partners
    partners: [
      {
        name: "Hite",
        logo: "assets/img/hite.png",
        url: "http://www.hite.com.br/"
      },
      {
        name: "Sticker Mule",
        logo: "assets/img/sticker-mule.png",
        url: "https://www.stickermule.com"
      }
    ],

    // Theme path
    getTheme: function() {
      return "themes/" + this.site.theme;
    },

    // Assets path
    getAssets: function() {
      return "assets";
    },

    // Site Path
    getUrl: function() {
    	return this.site.url;
    }
  }
};
<commit_msg>Add presentations<commit_after>module.exports = {

  prompts: false,
  plugins: {
    less: {
      referencesOthers: true,
      lessOptions: {
        compress: true,
        sourceMap: {
          sourceMapFileInline: true
        }
      }
    }
  },
  reloadPaths: ['src'],
  regeneratePaths: ['src'],
  regenerateDelay: 300,

  // These are variables will be accessible via our templates
  templateData: {

    // Conference info
    conf: {
      name: "INSITER",
      description: "Inside the Web - Teresina - PI",
      date: "10 de Junho de 2017",
      // If your event is free, just comment this line
      price: "R$ 50",
      venue: "Auditório do Sebrae",
      address: "Av. Campos Sáles, 1046 - Centro (Norte), Teresina - PI, 64000-300",
      city: "Teresina",
      state: "Piauí"
    },

    // The Call To Action button at the header,
    // If you don't want this, just remove the callToAction property.
    callToAction: {
      text: "Comprar ticket",
      link: "https://www.eventbrite.com.br/e/insiter-tickets-33716234164?aff=efbevent",
      advice: "Vagas limitadas!"
    },

    // Site info
    site: {
      theme: "default",
      url: "http://insiter.io",
      googleanalytics: "UA-31931741-2"
    },

    // Active sections on the website
    // to deactivate comment out with '//'
    // you can also change order here and it will reflect on page
    sections: [
      'about',
      'location',
      'speakers',
      'schedule',
      // 'sponsors',
      'partners',
      // 'contact'
    ],

    // Labels which you can translate to other languages
    labels: {
      about: "Sobre",
      location: "Local",
      speakers: "Palestrantes",
      schedule: "Programação",
      sponsors: "Patrocinadores",
      partners: "Parceiros",
      contact: "Contato"
    },

    // The entire schedule
    schedule: [
      {
        name: "Credenciamento",
        time: "08:00"
      },
      {
        name: "Daniel Romero",
        photo: "https://avatars0.githubusercontent.com/u/444911?v=3&s=460",
        bio: "Desenvolvedor, escritor técnico, palestrante e atualmente trabalha com práticas DevOps.",
        link: {
          href: "https://infoslack.pro/",
          text: "@infoslack"
        },
        presentation: {
          title: "Unikernels e o futuro da infraestrutura imutável",
          description: "Sistemas operacionais tradicionais (Linux, FreeBSD, Windows) serão extintos em servidores. Eles serão substituídos por hypervisors do tipo bare metal, otimizados de forma específica para o hardware e o deploy de nossas aplicações será feito através de um único arquivo binário. Nesta talk, veremos o que são Unikernels, os motivos de serem rápidos, seguros e que oportunidades ele reserva para o futuro.",
          time: "09:00"
        }
      },
      {
        name: "Fabio Akita",
        photo: "https://avatars2.githubusercontent.com/u/2840?v=3&s=460",
        bio: "Programador desde o começo dos anos 90, ativista de Ruby on Rails desde 2006, realizou quase 200 palestras pelo mundo e é co-fundador da Codeminer 42.",
        company: "Codeminer 42",
        link: {
          href: "http://www.akitaonrails.com/",
          text: "@akitaOnRails"
        },
        presentation: {
          title: "30 dias de Elixir e Crystal e de volta a Ruby",
          description: "Qual a forma correta de entender a diferença de performance das diferentes novas linguagens frente a casos reais de desenvolvimento. Baseado em benchmarks sintéticos, todos vão concordar que Ruby é \"lento\". Portanto deveríamos automaticamente abandonar Ruby e ir para outras linguagens mais \"rápidas\" como Go ou Crystal ou Elixir? Olhando um caso real, vamos entender porque essa resposta não é tão simples quanto parece",
          time: "09:50"
        }
      },
      {
        name: "Coffe Break",
        time: "10:40"
      },
      {
        name: "Jean Carlo",
        photo: "https://avatars3.githubusercontent.com/u/353504?v=3&s=460",
        bio: "Web craftsman and magician of computer machines. Developer at WORK.CO.",
        company: "WORK.CO",
        link: {
          href: "http://jcemer.com/",
          text: "@jcemer"
        },
        presentation: {
          title: "Como encarar o desenvolvimento front-end",
          description: "A todo tempo surgem novas formas de pensar e estruturar interfaces para a Internet. Esta palestra toma um olhar crítico a respeito de ferramentas, técnicas e código front-end em geral. Nosso objetivo será aprender a direcionar esforços para alcançar melhores resultados.",
          time: "13h00"
        }
      },
      {
        name: "Gabriel Sobrinho",
        photo: "https://avatars2.githubusercontent.com/u/26460?v=3&s=460",
        bio: "Desenvolvedor com mais de 10 anos de experiência em aplicações web, ativista de Ruby on Rails desde 2008 e fundador da Hite.",
        company: "Hite",
        link: {
          href: "http://gabrielsobrinho.com/",
          text: "@sobrinho"
        },
        presentation: {
          title: "Introdução a testes de software",
          description: "Uma introdução ao mundo dos testes, independe de linguagem de programação ou biblioteca. O que você deve testar, como testar e quando testar.",
          time: "17h00"
        }
      },
      {
        name: "Dmitry Rocha",
        photo: "https://avatars1.githubusercontent.com/u/53300?v=3&s=460",
        bio: "I'm passionate to solve problems on the right and less complicated way, I will work to turn life more easy with technology using my favorite tools, and at last I'm looking for my next favorite one.",
        company: "Codeminer 42",
        link: {
          href: "https://github.com/dmitryrck",
          text: "@dmitryrck"
        },
        presentation: {
          title: "Crystal: O que aconteceu quando tentaram compilar Ruby?",
          description: "Quando se fala em performance a primeira comparação é com C, mas C é a linguagem e o binário final é em código de máquina, então… o que aconteceu quando alguém tentou compilar Ruby? Disto surgiu Crystal: Fast as C, slick as Ruby. Nova linguagem ou um Ruby compilado?",
          time: "10h00"
        }
      },
      {
        name: "Coffee Break",
        time: "15:40"
      },
      {
        name: "Matias Leidemer",
        photo: "https://avatars1.githubusercontent.com/u/10559?v=3&s=460",
        bio: "Desenvolvedor com mais de 10 anos de experiência, apaixonado por Ruby, testes automatizados e código organizado. Trabalhou com diversas tecnologias, em empresas dentro e fora do Brasil. Atualmente é Web Development Engineer na Stickermule.",
        company: "Stickermule",
        link: {
          href: "http://www.leidemer.com/",
          text: "@matiasleidemer"
        },
        presentation: {
          title: "Tem um tipo no meu Javascript",
          description: "Com o advento das SPA (single page apps), o uso do Javascript não se limita apenas a validação de forms e chamadas ajax. Codificar regras de negócio complexas já faz parte do dia a dia de grande parte dos desenvolvedores JS. Mas, a medida que as linhas de código aumentam, como garantir que tudo está funcionando perfeitamete? Nesta talk falarei sobre o Flow e como ele pode ajudar na diminuição de erros de runtime e na definição de tipos específicos de negócio.                        ",
          time: "16:10"
        }
      },
      {
        name: "Thiago Alves",
        photo: "https://avatars0.githubusercontent.com/u/5190217?v=3&s=460",
        bio: "Atua a 10 anos no mercado web. Apaixonado por JavaScript, atualmente é Desenvolvedor Front-End na Codeminer 42. Entende que apresentar palestras é uma das formas mais divertidas de aprender.",
        company: "Codeminer 42",
        link: {
          href: "https://twitter.com/taltk9",
          text: "@taltk9"
        },
        presentation: {
          title: "Inside the Web",
          description: "Há tempos deixamos o Flash para trás e passamos a depender somente das APIs e recursos HTML, CSS e Javascript. Vieram animações CSS, WebGL e agora, WebVR. Realidade virtual no alcance do seu browser. Vamos falar um pouco sobre o assunto, como iniciar estudos na área, mostrar alguns exemplos e as possibilidades de mercado para a tecnologia junto a Web.",
          time: "17:00"
        }
      },
      {
        name: "Encerramento",
        time: "17:50"
      }
    ],

    // List of Sponsors
    sponsors: [
      {
        name: "Eventick",
        logo: "themes/yellow-swan/img/sponsor.png",
        url: "http://eventick.com.br"
      }
    ],

    // List of Partners
    partners: [
      {
        name: "Hite",
        logo: "assets/img/hite.png",
        url: "http://www.hite.com.br/"
      },
      {
        name: "Sticker Mule",
        logo: "assets/img/sticker-mule.png",
        url: "https://www.stickermule.com"
      }
    ],

    // Theme path
    getTheme: function() {
      return "themes/" + this.site.theme;
    },

    // Assets path
    getAssets: function() {
      return "assets";
    },

    // Site Path
    getUrl: function() {
    	return this.site.url;
    }
  }
};
<|endoftext|>


<commit_before>const {
	NotFound,
	BadRequest,
} = require('@feathersjs/errors');
const { equal } = require('../../../helper/compare').ObjectId;

const restrictToUsersCourses = async (context) => {
	const { userId } = context.params.account;
	const usersCourses = await context.app.service('courses').find({
		query: {
			$or: [
				{ userIds: userId },
				{ teacherIds: userId },
				{ substitutionIds: userId },
			],
		},
	});
	const usersCoursesIds = usersCourses.data.map((c) => c._id);

	if (context.method === 'create') {
		if (!context.data.courseId) {
			throw new BadRequest('courseId required');
		}
	}

	if (['create', 'patch', 'update'].includes(context.method)) {
		if (context.data.courseId && !usersCoursesIds.some((uid) => equal(uid, context.data.courseId))) {
			throw new NotFound('invalid courseId');
		}
	}

	if (['find', 'patch', 'update', 'remove'].includes(context.method)) {
		context.params.query.$and = (context.params.query.$and || []);
		context.params.query.$and.push({
			courseId: { $in: [usersCoursesIds] },
		});
	}
};

const denyIfNotInCourse = async (context) => {
	const { userId } = context.params.account;
	const course = await context.app.service('courses').get(context.result.courseId);
	const userInCourse = course.userIds.some((id) => equal(id, userId))
		|| course.teacherIds.some((id) => equal(id, userId))
		|| course.substitutionIds.some((id) => equal(id, userId));
	if (!userInCourse) throw new NotFound(`no record found for id '${context.id}'`);
	return context;
};

module.exports = { denyIfNotInCourse, restrictToUsersCourses };
<commit_msg>superhero ignores restrictToUsersOwnCourses<commit_after>const {
	NotFound,
	BadRequest,
} = require('@feathersjs/errors');
const {
	hasRoleNoHook,
} = require('../../../hooks');
const { equal } = require('../../../helper/compare').ObjectId;

const restrictToUsersCourses = async (context) => {
	const userIsSuperhero = await hasRoleNoHook(context, context.params.account.userId, 'superhero');
	if (userIsSuperhero) return context;

	const { userId } = context.params.account;
	const usersCourses = await context.app.service('courses').find({
		query: {
			$or: [
				{ userIds: userId },
				{ teacherIds: userId },
				{ substitutionIds: userId },
			],
		},
	});
	const usersCoursesIds = usersCourses.data.map((c) => c._id);

	if (context.method === 'create') {
		if (!context.data.courseId) {
			throw new BadRequest('courseId required');
		}
	}

	if (['create', 'patch', 'update'].includes(context.method)) {
		if (context.data.courseId && !usersCoursesIds.some((uid) => equal(uid, context.data.courseId))) {
			throw new NotFound('invalid courseId');
		}
	}

	if (['find', 'patch', 'update', 'remove'].includes(context.method)) {
		context.params.query.$and = (context.params.query.$and || []);
		context.params.query.$and.push({
			courseId: { $in: [usersCoursesIds] },
		});
	}
	return context;
};

const denyIfNotInCourse = async (context) => {
	const { userId } = context.params.account;
	const course = await context.app.service('courses').get(context.result.courseId);
	const userInCourse = course.userIds.some((id) => equal(id, userId))
		|| course.teacherIds.some((id) => equal(id, userId))
		|| course.substitutionIds.some((id) => equal(id, userId));
	if (!userInCourse) throw new NotFound(`no record found for id '${context.id}'`);
	return context;
};

module.exports = { denyIfNotInCourse, restrictToUsersCourses };
<|endoftext|>


<commit_before>import fetchByUri, { fetchByGeoLocation } from './vastgoed'
import getCenter from '../geo-json/geo-json'
import { rdToWgs84 } from '../coordinate-reference-system/crs-converter'
import SHARED_CONFIG from '../shared-config/shared-config'

import { getByUrl } from '../api/api'

jest.mock('../geo-json/geo-json')
jest.mock('../api/api')
jest.mock('../coordinate-reference-system/crs-converter')

describe('The vastgoed resource', () => {
  const vastgoedMock = {
    _display: 'display',
    object_naam: 'object_naam',
    bouwjaar: 1000,
    status: 'status',
    monumentstatus: 'monumentstatus',
    vhe_adres: 'Street 123',
    bag_verblijfsobject_gebruiksdoel_omschrijving: 'gebruiksdoel',
    huurtype: 'huurtype',
    oppervlakte: 123,
    bag_pand_geometrie: { type: 'Point' },
  }

  afterEach(() => {
    getByUrl.mockReset()
  })

  describe('By uri', () => {
    it('fetches a vastgoed instance', () => {
      const uri = `${SHARED_CONFIG.API_ROOT}vsd/vastgoed/123456`

      getByUrl.mockReturnValueOnce(Promise.resolve(vastgoedMock))
      getCenter.mockImplementation(() => ({ x: 1, y: 2 }))
      rdToWgs84.mockImplementation(() => ({ latitude: 3, longitude: 4 }))

      const promise = fetchByUri(uri).then(response => {
        expect(response).toEqual({
          label: vastgoedMock.object_naam,
          construction_year: vastgoedMock.bouwjaar.toString(),
          status: vastgoedMock.status,
          monumental_status: vastgoedMock.monumentstatus,
          address: vastgoedMock.vhe_adres,
          usage: vastgoedMock.bag_verblijfsobject_gebruiksdoel_omschrijving,
          usage_type: vastgoedMock.huurtype,
          size: vastgoedMock.oppervlakte,
          location: { latitude: 3, longitude: 4 },
          geometrie: vastgoedMock.bag_pand_geometrie,
        })
      })

      expect(getByUrl).toHaveBeenCalledWith(uri)
      return promise
    })

    it('fetches with empty result object', () => {
      const uri = `${SHARED_CONFIG.API_ROOT}vsd/vastgoed/123456`

      getByUrl.mockReturnValueOnce(Promise.resolve({}))

      const promise = fetchByUri(uri).then(response => {
        expect(response).toEqual({
          label: undefined,
          construction_year: 'onbekend',
          status: undefined,
          monumental_status: undefined,
          address: undefined,
          usage: undefined,
          usage_type: undefined,
          size: undefined,
          location: null,
          geometrie: undefined,
        })
      })

      expect(getByUrl).toHaveBeenCalledWith(uri)
      return promise
    })
  })

  describe('By location', () => {
    it('fetches the vastgoed geosearch', () => {
      const mockLocation = { latitude: 123, longitude: 456 }

      getByUrl.mockReturnValueOnce(Promise.resolve(vastgoedMock))

      const promise = fetchByGeoLocation(mockLocation)

      expect(getByUrl).toHaveBeenCalledWith(
        `${SHARED_CONFIG.API_ROOT}geosearch/vastgoed/?lat=${mockLocation.latitude}&lon=${
          mockLocation.longitude
        }&item=vastgoed&radius=0`,
      )

      return promise
    })
  })
})
<commit_msg>Updated tests<commit_after>import fetchByUri, { fetchByGeoLocation } from './vastgoed'
import getCenter from '../geo-json/geo-json'
import { rdToWgs84 } from '../coordinate-reference-system/crs-converter'
import SHARED_CONFIG from '../shared-config/shared-config'

import { getByUrl } from '../api/api'

jest.mock('../geo-json/geo-json')
jest.mock('../api/api')
jest.mock('../coordinate-reference-system/crs-converter')

describe('The vastgoed resource', () => {
  const vastgoedMock = {
    _display: 'display',
    object_naam: 'object_naam',
    bouwjaar: 1000,
    status: 'status',
    monumentstatus: 'monumentstatus',
    vhe_adres: 'Street 123',
    bag_verblijfsobject_gebruiksdoelen: 'gebruiksdoel',
    huurtype: 'huurtype',
    oppervlakte: 123,
    bag_pand_geometrie: { type: 'Point' },
  }

  afterEach(() => {
    getByUrl.mockReset()
  })

  describe('By uri', () => {
    it('fetches a vastgoed instance', () => {
      const uri = `${SHARED_CONFIG.API_ROOT}vsd/vastgoed/123456`

      getByUrl.mockReturnValueOnce(Promise.resolve(vastgoedMock))
      getCenter.mockImplementation(() => ({ x: 1, y: 2 }))
      rdToWgs84.mockImplementation(() => ({ latitude: 3, longitude: 4 }))

      const promise = fetchByUri(uri).then(response => {
        expect(response).toEqual({
          label: vastgoedMock.object_naam,
          construction_year: vastgoedMock.bouwjaar.toString(),
          status: vastgoedMock.status,
          monumental_status: vastgoedMock.monumentstatus,
          address: vastgoedMock.vhe_adres,
          usage: vastgoedMock.bag_verblijfsobject_gebruiksdoelen,
          usage_type: vastgoedMock.huurtype,
          size: vastgoedMock.oppervlakte,
          location: { latitude: 3, longitude: 4 },
          geometrie: vastgoedMock.bag_pand_geometrie,
        })
      })

      expect(getByUrl).toHaveBeenCalledWith(uri)
      return promise
    })

    it('fetches with empty result object', () => {
      const uri = `${SHARED_CONFIG.API_ROOT}vsd/vastgoed/123456`

      getByUrl.mockReturnValueOnce(Promise.resolve({}))

      const promise = fetchByUri(uri).then(response => {
        expect(response).toEqual({
          label: undefined,
          construction_year: 'onbekend',
          status: undefined,
          monumental_status: undefined,
          address: undefined,
          usage: undefined,
          usage_type: undefined,
          size: undefined,
          location: null,
          geometrie: undefined,
        })
      })

      expect(getByUrl).toHaveBeenCalledWith(uri)
      return promise
    })
  })

  describe('By location', () => {
    it('fetches the vastgoed geosearch', () => {
      const mockLocation = { latitude: 123, longitude: 456 }

      getByUrl.mockReturnValueOnce(Promise.resolve(vastgoedMock))

      const promise = fetchByGeoLocation(mockLocation)

      expect(getByUrl).toHaveBeenCalledWith(
        `${SHARED_CONFIG.API_ROOT}geosearch/vastgoed/?lat=${mockLocation.latitude}&lon=${
          mockLocation.longitude
        }&item=vastgoed&radius=0`,
      )

      return promise
    })
  })
})
<|endoftext|>


<commit_before>import EventOrderNormalizer from 'parser/core/EventOrderNormalizer';
import { EventType } from 'parser/core/Events';

function fakeEvent(abilityId, type, timestamp, sourceID, targetID) {
  return {
    ability: { guid: abilityId },
    type,
    timestamp,
    sourceID,
    targetID,
  };
}

class ConcreteEventOrderNormalizer extends EventOrderNormalizer {
  constructor(options, eventOrders) {
    super(options, eventOrders);
  }
}

/**
 * Listing of tests as specified by a 'test' object with fields:
 * @param it describes test
 * @param eventOrders the event orders specification to pass to EventOrdersNormalizer
 * @param events the events to normalize
 * @param resultOrder the expected order of the normalized events as specified by their original index
 * @param additionalChecks OPTIONAL a function which performs additional checks on the output,
 *     is passed the original events array, the results events array, and must return true iff it passes the check
 */
const tests = [
  {
    it: 'two out of order events should be reordered',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
      },
    ],
    events: [
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
    ],
    resultOrder: [1, 0],
    additionalChecks: (before, after) => after[1].__modified === true && !after[0].__modified,
  },
  {
    it: 'only exactly specified events should be reordered',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
      },
    ],
    events: [
      // pair already in correct order - shouldn't be moved
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2), // 0
      fakeEvent(15, EventType.Heal, 100, 1, 2), // 1
      // before eventID no match - shouldn't be moved
      fakeEvent(15, EventType.Heal, 200, 1, 2), // 2
      fakeEvent(21, EventType.ApplyBuff, 200, 1, 2), // 3
      // after eventID no match - shouldn't be moved
      fakeEvent(16, EventType.Heal, 300, 1, 2), // 4
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2), // 5
      // before event type no match - shouldn't be moved
      fakeEvent(15, EventType.Heal, 400, 1, 2), // 6
      fakeEvent(20, EventType.RemoveBuff, 400, 1, 2), // 7
      // after event type no match - shouldn't be moved
      fakeEvent(15, EventType.Damage, 500, 1, 2), // 8
      fakeEvent(20, EventType.ApplyBuff, 500, 1, 2), // 9
      // sourceID no match - shouldn't be moved
      fakeEvent(15, EventType.Heal, 700, 2, 2), // 10
      fakeEvent(20, EventType.ApplyBuff, 700, 1, 2), // 11
      // targetID no match - shouldn't be moved
      fakeEvent(15, EventType.Heal, 700, 1, 2), // 12
      fakeEvent(20, EventType.ApplyBuff, 700, 1, 3), // 13
      // all match, but out of timestamp range - shouldn't be moved
      fakeEvent(15, EventType.Heal, 599, 1, 2), // 14
      fakeEvent(20, EventType.ApplyBuff, 600, 1, 2), // 15
      // should be moved!
      fakeEvent(15, EventType.Heal, 700, 1, 2), // 16
      fakeEvent(20, EventType.ApplyBuff, 700, 1, 2), // 17
      // also should be moved, test it can iterate over intermediate events
      fakeEvent(15, EventType.Heal, 800, 1, 2), // 18
      fakeEvent(1, EventType.Damage, 800, 1, 2), // 19
      fakeEvent(2, EventType.Damage, 800, 1, 2), // 20
      fakeEvent(3, EventType.Damage, 800, 1, 2), // 21
      fakeEvent(4, EventType.Damage, 800, 1, 2), // 22
      fakeEvent(20, EventType.ApplyBuff, 800, 1, 2), // 23
    ],
    resultOrder: [
      0,
      1,
      2,
      3,
      4,
      5,
      6,
      7,
      8,
      9,
      10,
      11,
      12,
      13,
      14,
      15,
      17, //
      16, // first reorder
      19,
      20,
      21,
      22,
      23, //
      18, // second reorder - event pushed infront without touching intermediate events
    ],
  },
  {
    it: 'multiple event orders should be followed',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
      },
      {
        beforeEventId: 30,
        beforeEventType: EventType.ApplyDebuff,
        afterEventId: 25,
        afterEventType: EventType.Damage,
      },
    ],
    events: [
      fakeEvent(25, EventType.Damage, 100, 1, 3),
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      fakeEvent(30, EventType.ApplyDebuff, 100, 1, 3),
    ],
    resultOrder: [2, 1, 3, 0],
  },
  {
    it: 'eventID list should be followed',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: [15, 16, 17],
        afterEventType: EventType.Heal,
      },
    ],
    events: [
      // matches id
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // matches id
      fakeEvent(16, EventType.Heal, 200, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, 1, 2),
      // matches id
      fakeEvent(17, EventType.Heal, 300, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2),
      // doesn't match
      fakeEvent(18, EventType.Heal, 400, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 400, 1, 2),
    ],
    resultOrder: [1, 0, 3, 2, 5, 4, 6, 7],
  },
  {
    it: 'eventID null should be followed',
    eventOrders: [
      {
        beforeEventId: 50,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: null,
        afterEventType: EventType.Energize,
      },
    ],
    events: [
      // matches any ID
      fakeEvent(1337, EventType.Energize, 100, 1, 1),
      fakeEvent(50, EventType.ApplyBuff, 100, 1, 1),
      // matches any ID
      fakeEvent(1, EventType.Energize, 200, 1, 1),
      fakeEvent(50, EventType.ApplyBuff, 200, 1, 1),
      // even an undefined ID!
      fakeEvent(undefined, EventType.Energize, 300, 1, 1),
      fakeEvent(50, EventType.ApplyBuff, 300, 1, 1),
      // still needs to match type - won't swap
      fakeEvent(1337, EventType.Damage, 400, 1, 1),
      fakeEvent(50, EventType.ApplyBuff, 400, 1, 1),
    ],
    resultOrder: [1, 0, 3, 2, 5, 4, 6, 7],
  },
  {
    it: 'event type list should be followed',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: [EventType.ApplyBuff, EventType.RefreshBuff],
        afterEventId: 15,
        afterEventType: EventType.Heal,
      },
    ],
    events: [
      // matches type
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // matches type
      fakeEvent(15, EventType.Heal, 200, 1, 2),
      fakeEvent(20, EventType.RefreshBuff, 200, 1, 2),
      // doesn't match
      fakeEvent(15, EventType.Heal, 300, 1, 2),
      fakeEvent(20, EventType.RemoveBuff, 300, 1, 2),
    ],
    resultOrder: [1, 0, 3, 2, 4, 5],
  },
  {
    it: 'bufferMs option should work',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
        bufferMs: 50,
      },
    ],
    events: [
      // in range for swap
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // in range for swap
      fakeEvent(15, EventType.Heal, 190, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, 1, 2),
      // in range for swap
      fakeEvent(15, EventType.Heal, 250, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2),
      // out of range for swap
      fakeEvent(15, EventType.Heal, 330, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 400, 1, 2),
    ],
    resultOrder: [1, 0, 3, 2, 5, 4, 6, 7],
  },
  {
    it: 'anySource option should work',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
        anySource: true,
      },
    ],
    events: [
      // all same, should swap
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // different source, should swap
      fakeEvent(15, EventType.Heal, 200, 2, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, 1, 2),
      // undefined source, should swap
      fakeEvent(15, EventType.Heal, 200, undefined, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, undefined, 2),
      // different target, shouldn't swap
      fakeEvent(15, EventType.Heal, 300, 1, 3),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2),
    ],
    resultOrder: [1, 0, 3, 2, 5, 4, 6, 7],
  },
  {
    it: 'anyTarget option should work',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
        anyTarget: true,
      },
    ],
    events: [
      // all same, should swap
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // different source, shouldn't swap
      fakeEvent(15, EventType.Heal, 200, 2, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, 1, 2),
      // different target, should swap
      fakeEvent(15, EventType.Heal, 300, 1, 3),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2),
      // undefined target, should swap
      fakeEvent(15, EventType.Heal, 300, 1, undefined),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, undefined),
    ],
    resultOrder: [1, 0, 2, 3, 5, 4, 7, 6],
  },
  {
    it: 'updateTimestamp should work',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
        bufferMs: 50,
        updateTimestamp: true,
      },
    ],
    events: [
      fakeEvent(15, EventType.Heal, 50, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
    ],
    resultOrder: [1, 0],
    additionalChecks: (before, after) => after[1].timestamp === 100,
  },
];

// runs all the tests described above
describe('EventOrderNormalizer unit tests', () => {
  tests.forEach((test) => {
    it(test.it, () => {
      const parser = new ConcreteEventOrderNormalizer({}, test.eventOrders);

      // mark events with their original index
      for (let i = 0; i < test.events.length; i++) {
        test.events[i].__testId = i;
      }
      const before = JSON.parse(JSON.stringify(test.events)); // deep copy so 'before' events aren't modified
      const after = parser.normalize(test.events);
      //      console.log("Events Before: ");
      //      console.log(before);
      //      console.log("Events After: ");
      //      console.log(after);
      expect(after.map((e) => e.__testId)).toEqual(test.resultOrder);
      if (test.additionalChecks) {
        expect(test.additionalChecks(before, after)).toEqual(true);
      }
    });
  });
});
<commit_msg>More eslint fixes<commit_after>import EventOrderNormalizer from 'parser/core/EventOrderNormalizer';
import { EventType } from 'parser/core/Events';

function fakeEvent(abilityId, type, timestamp, sourceID, targetID) {
  return {
    ability: { guid: abilityId },
    type,
    timestamp,
    sourceID,
    targetID,
  };
}

class ConcreteEventOrderNormalizer extends EventOrderNormalizer {
  // eslint-disable-next-line no-useless-constructor
  constructor(options, eventOrders) {
    super(options, eventOrders);
  }
}

/**
 * Listing of tests as specified by a 'test' object with fields:
 * @param it describes test
 * @param eventOrders the event orders specification to pass to EventOrdersNormalizer
 * @param events the events to normalize
 * @param resultOrder the expected order of the normalized events as specified by their original index
 * @param additionalChecks OPTIONAL a function which performs additional checks on the output,
 *     is passed the original events array, the results events array, and must return true iff it passes the check
 */
const tests = [
  {
    it: 'two out of order events should be reordered',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
      },
    ],
    events: [
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
    ],
    resultOrder: [1, 0],
    additionalChecks: (before, after) => after[1].__modified === true && !after[0].__modified,
  },
  {
    it: 'only exactly specified events should be reordered',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
      },
    ],
    events: [
      // pair already in correct order - shouldn't be moved
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2), // 0
      fakeEvent(15, EventType.Heal, 100, 1, 2), // 1
      // before eventID no match - shouldn't be moved
      fakeEvent(15, EventType.Heal, 200, 1, 2), // 2
      fakeEvent(21, EventType.ApplyBuff, 200, 1, 2), // 3
      // after eventID no match - shouldn't be moved
      fakeEvent(16, EventType.Heal, 300, 1, 2), // 4
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2), // 5
      // before event type no match - shouldn't be moved
      fakeEvent(15, EventType.Heal, 400, 1, 2), // 6
      fakeEvent(20, EventType.RemoveBuff, 400, 1, 2), // 7
      // after event type no match - shouldn't be moved
      fakeEvent(15, EventType.Damage, 500, 1, 2), // 8
      fakeEvent(20, EventType.ApplyBuff, 500, 1, 2), // 9
      // sourceID no match - shouldn't be moved
      fakeEvent(15, EventType.Heal, 700, 2, 2), // 10
      fakeEvent(20, EventType.ApplyBuff, 700, 1, 2), // 11
      // targetID no match - shouldn't be moved
      fakeEvent(15, EventType.Heal, 700, 1, 2), // 12
      fakeEvent(20, EventType.ApplyBuff, 700, 1, 3), // 13
      // all match, but out of timestamp range - shouldn't be moved
      fakeEvent(15, EventType.Heal, 599, 1, 2), // 14
      fakeEvent(20, EventType.ApplyBuff, 600, 1, 2), // 15
      // should be moved!
      fakeEvent(15, EventType.Heal, 700, 1, 2), // 16
      fakeEvent(20, EventType.ApplyBuff, 700, 1, 2), // 17
      // also should be moved, test it can iterate over intermediate events
      fakeEvent(15, EventType.Heal, 800, 1, 2), // 18
      fakeEvent(1, EventType.Damage, 800, 1, 2), // 19
      fakeEvent(2, EventType.Damage, 800, 1, 2), // 20
      fakeEvent(3, EventType.Damage, 800, 1, 2), // 21
      fakeEvent(4, EventType.Damage, 800, 1, 2), // 22
      fakeEvent(20, EventType.ApplyBuff, 800, 1, 2), // 23
    ],
    resultOrder: [
      0,
      1,
      2,
      3,
      4,
      5,
      6,
      7,
      8,
      9,
      10,
      11,
      12,
      13,
      14,
      15,
      17, //
      16, // first reorder
      19,
      20,
      21,
      22,
      23, //
      18, // second reorder - event pushed infront without touching intermediate events
    ],
  },
  {
    it: 'multiple event orders should be followed',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
      },
      {
        beforeEventId: 30,
        beforeEventType: EventType.ApplyDebuff,
        afterEventId: 25,
        afterEventType: EventType.Damage,
      },
    ],
    events: [
      fakeEvent(25, EventType.Damage, 100, 1, 3),
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      fakeEvent(30, EventType.ApplyDebuff, 100, 1, 3),
    ],
    resultOrder: [2, 1, 3, 0],
  },
  {
    it: 'eventID list should be followed',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: [15, 16, 17],
        afterEventType: EventType.Heal,
      },
    ],
    events: [
      // matches id
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // matches id
      fakeEvent(16, EventType.Heal, 200, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, 1, 2),
      // matches id
      fakeEvent(17, EventType.Heal, 300, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2),
      // doesn't match
      fakeEvent(18, EventType.Heal, 400, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 400, 1, 2),
    ],
    resultOrder: [1, 0, 3, 2, 5, 4, 6, 7],
  },
  {
    it: 'eventID null should be followed',
    eventOrders: [
      {
        beforeEventId: 50,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: null,
        afterEventType: EventType.Energize,
      },
    ],
    events: [
      // matches any ID
      fakeEvent(1337, EventType.Energize, 100, 1, 1),
      fakeEvent(50, EventType.ApplyBuff, 100, 1, 1),
      // matches any ID
      fakeEvent(1, EventType.Energize, 200, 1, 1),
      fakeEvent(50, EventType.ApplyBuff, 200, 1, 1),
      // even an undefined ID!
      fakeEvent(undefined, EventType.Energize, 300, 1, 1),
      fakeEvent(50, EventType.ApplyBuff, 300, 1, 1),
      // still needs to match type - won't swap
      fakeEvent(1337, EventType.Damage, 400, 1, 1),
      fakeEvent(50, EventType.ApplyBuff, 400, 1, 1),
    ],
    resultOrder: [1, 0, 3, 2, 5, 4, 6, 7],
  },
  {
    it: 'event type list should be followed',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: [EventType.ApplyBuff, EventType.RefreshBuff],
        afterEventId: 15,
        afterEventType: EventType.Heal,
      },
    ],
    events: [
      // matches type
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // matches type
      fakeEvent(15, EventType.Heal, 200, 1, 2),
      fakeEvent(20, EventType.RefreshBuff, 200, 1, 2),
      // doesn't match
      fakeEvent(15, EventType.Heal, 300, 1, 2),
      fakeEvent(20, EventType.RemoveBuff, 300, 1, 2),
    ],
    resultOrder: [1, 0, 3, 2, 4, 5],
  },
  {
    it: 'bufferMs option should work',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
        bufferMs: 50,
      },
    ],
    events: [
      // in range for swap
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // in range for swap
      fakeEvent(15, EventType.Heal, 190, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, 1, 2),
      // in range for swap
      fakeEvent(15, EventType.Heal, 250, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2),
      // out of range for swap
      fakeEvent(15, EventType.Heal, 330, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 400, 1, 2),
    ],
    resultOrder: [1, 0, 3, 2, 5, 4, 6, 7],
  },
  {
    it: 'anySource option should work',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
        anySource: true,
      },
    ],
    events: [
      // all same, should swap
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // different source, should swap
      fakeEvent(15, EventType.Heal, 200, 2, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, 1, 2),
      // undefined source, should swap
      fakeEvent(15, EventType.Heal, 200, undefined, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, undefined, 2),
      // different target, shouldn't swap
      fakeEvent(15, EventType.Heal, 300, 1, 3),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2),
    ],
    resultOrder: [1, 0, 3, 2, 5, 4, 6, 7],
  },
  {
    it: 'anyTarget option should work',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
        anyTarget: true,
      },
    ],
    events: [
      // all same, should swap
      fakeEvent(15, EventType.Heal, 100, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
      // different source, shouldn't swap
      fakeEvent(15, EventType.Heal, 200, 2, 2),
      fakeEvent(20, EventType.ApplyBuff, 200, 1, 2),
      // different target, should swap
      fakeEvent(15, EventType.Heal, 300, 1, 3),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, 2),
      // undefined target, should swap
      fakeEvent(15, EventType.Heal, 300, 1, undefined),
      fakeEvent(20, EventType.ApplyBuff, 300, 1, undefined),
    ],
    resultOrder: [1, 0, 2, 3, 5, 4, 7, 6],
  },
  {
    it: 'updateTimestamp should work',
    eventOrders: [
      {
        beforeEventId: 20,
        beforeEventType: EventType.ApplyBuff,
        afterEventId: 15,
        afterEventType: EventType.Heal,
        bufferMs: 50,
        updateTimestamp: true,
      },
    ],
    events: [
      fakeEvent(15, EventType.Heal, 50, 1, 2),
      fakeEvent(20, EventType.ApplyBuff, 100, 1, 2),
    ],
    resultOrder: [1, 0],
    additionalChecks: (before, after) => after[1].timestamp === 100,
  },
];

// runs all the tests described above
describe('EventOrderNormalizer unit tests', () => {
  tests.forEach((test) => {
    it(test.it, () => {
      const parser = new ConcreteEventOrderNormalizer({}, test.eventOrders);

      // mark events with their original index
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < test.events.length; i++) {
        test.events[i].__testId = i;
      }
      const before = JSON.parse(JSON.stringify(test.events)); // deep copy so 'before' events aren't modified
      const after = parser.normalize(test.events);
      //      console.log("Events Before: ");
      //      console.log(before);
      //      console.log("Events After: ");
      //      console.log(after);
      expect(after.map((e) => e.__testId)).toEqual(test.resultOrder);
      if (test.additionalChecks) {
        expect(test.additionalChecks(before, after)).toEqual(true);
      }
    });
  });
});
<|endoftext|>