<commit_before>iD.ui.intro.line = function(context, reveal) {

    var event = d3.dispatch('done'),
        timeouts = [];

    var step = {
        title: 'intro.lines.title'
    };

    function one(target, e, f) {
        d3.selection.prototype.one.call(target, e, f);
    }

    function timeout(f, t) {
        timeouts.push(window.setTimeout(f, t));
    }

    step.enter = function() {

        var centroid = [-85.62830, 41.95699];
        var midpoint = [-85.62975395449628, 41.95787501510204];
        var start = [-85.6297754121684, 41.9583158176903];
        var intersection = [-85.62974496187628, 41.95742515554585];

        context.map().centerZoom(start, 18);
        reveal('button.add-line', t('intro.lines.add'), {tooltipClass: 'intro-lines-add'});

        context.on('enter.intro', addLine);

        function addLine(mode) {
            if (mode.id !== 'add-line') return;
            context.on('enter.intro', drawLine);

            var padding = 150 * Math.pow(2, context.map().zoom() - 18);
            var pointBox = iD.ui.intro.pad(start, padding, context);
            reveal(pointBox, t('intro.lines.start'));

            context.map().on('move.intro', function() {
                padding = 150 * Math.pow(2, context.map().zoom() - 18);
                pointBox = iD.ui.intro.pad(start, padding, context);
                reveal(pointBox, t('intro.lines.start'), {duration: 0});
            });
        }

        function drawLine(mode) {
            if (mode.id !== 'draw-line') return;
            context.history().on('change.intro', addIntersection);
            context.on('enter.intro', retry);

            var padding = 300 * Math.pow(2, context.map().zoom() - 19);
            var pointBox = iD.ui.intro.pad(midpoint, padding, context);
            reveal(pointBox, t('intro.lines.intersect'));

            context.map().on('move.intro', function() {
                padding = 300 * Math.pow(2, context.map().zoom() - 19);
                pointBox = iD.ui.intro.pad(midpoint, padding, context);
                reveal(pointBox, t('intro.lines.intersect'), {duration: 0});
            });
        }

        // ended line before creating intersection
        function retry(mode) {
            if (mode.id !== 'select') return;
            var pointBox = iD.ui.intro.pad(intersection, 30);
            reveal(pointBox, t('intro.lines.restart'));
            timeout(function() {
                context.replace(iD.actions.DeleteMultiple(mode.selectedIDs()));
                step.exit();
                step.enter();
            }, 3000);
        }

        function addIntersection(changes) {
            if ( _.any(changes.created(), function(d) {
                return d.type === 'node' && context.graph().parentWays(d).length > 1;
            })) {
                context.history().on('change.intro', null);
                context.on('enter.intro', enterSelect);

                var padding = 900 * Math.pow(2, context.map().zoom() - 19);
                var pointBox = iD.ui.intro.pad(centroid, padding, context);
                reveal(pointBox, t('intro.lines.finish'));

                context.map().on('move.intro', function() {
                    padding = 900 * Math.pow(2, context.map().zoom() - 19);
                    pointBox = iD.ui.intro.pad(centroid, padding, context);
                    reveal(pointBox, t('intro.lines.finish'), {duration: 0});
                });
            }
        }

        function enterSelect(mode) {
            if (mode.id !== 'select') return;
            context.map().on('move.intro', null);
            context.on('enter.intro', null);
            d3.select('#curtain').style('pointer-events', 'all');

            timeout(function() {
                d3.select('#curtain').style('pointer-events', 'none');
                var road = d3.select('.preset-category-road .preset-list-button');
                reveal(road.node(), t('intro.lines.road'));
                road.one('click.intro', roadCategory);
            }, 500);
        }

        function roadCategory() {
            timeout(function() {
                var grid = d3.select('.subgrid');
                reveal(grid.node(), t('intro.lines.residential'));
                grid.selectAll('.preset-highway-residential .preset-list-button')
                    .one('click.intro', roadDetails);
            }, 200);
        }

        function roadDetails() {
            reveal('.pane', t('intro.lines.describe'));
            context.on('exit.intro', event.done);
        }

    };

    step.exit = function() {
        d3.select('#curtain').style('pointer-events', 'none');
        timeouts.forEach(window.clearTimeout);
        context.on('enter.intro', null);
        context.on('exit.intro', null);
        context.map().on('move.intro', null);
        context.history().on('change.intro', null);
    };

    return d3.rebind(step, event, 'on');
};
<commit_msg>walkthrough: increase timeout for revealing road subgrid 200ms seems to be too low, because the fade-in transition seems to take 250ms and an the unfinished animation can cause troubles. this fixes #1742<commit_after>iD.ui.intro.line = function(context, reveal) {

    var event = d3.dispatch('done'),
        timeouts = [];

    var step = {
        title: 'intro.lines.title'
    };

    function one(target, e, f) {
        d3.selection.prototype.one.call(target, e, f);
    }

    function timeout(f, t) {
        timeouts.push(window.setTimeout(f, t));
    }

    step.enter = function() {

        var centroid = [-85.62830, 41.95699];
        var midpoint = [-85.62975395449628, 41.95787501510204];
        var start = [-85.6297754121684, 41.9583158176903];
        var intersection = [-85.62974496187628, 41.95742515554585];

        context.map().centerZoom(start, 18);
        reveal('button.add-line', t('intro.lines.add'), {tooltipClass: 'intro-lines-add'});

        context.on('enter.intro', addLine);

        function addLine(mode) {
            if (mode.id !== 'add-line') return;
            context.on('enter.intro', drawLine);

            var padding = 150 * Math.pow(2, context.map().zoom() - 18);
            var pointBox = iD.ui.intro.pad(start, padding, context);
            reveal(pointBox, t('intro.lines.start'));

            context.map().on('move.intro', function() {
                padding = 150 * Math.pow(2, context.map().zoom() - 18);
                pointBox = iD.ui.intro.pad(start, padding, context);
                reveal(pointBox, t('intro.lines.start'), {duration: 0});
            });
        }

        function drawLine(mode) {
            if (mode.id !== 'draw-line') return;
            context.history().on('change.intro', addIntersection);
            context.on('enter.intro', retry);

            var padding = 300 * Math.pow(2, context.map().zoom() - 19);
            var pointBox = iD.ui.intro.pad(midpoint, padding, context);
            reveal(pointBox, t('intro.lines.intersect'));

            context.map().on('move.intro', function() {
                padding = 300 * Math.pow(2, context.map().zoom() - 19);
                pointBox = iD.ui.intro.pad(midpoint, padding, context);
                reveal(pointBox, t('intro.lines.intersect'), {duration: 0});
            });
        }

        // ended line before creating intersection
        function retry(mode) {
            if (mode.id !== 'select') return;
            var pointBox = iD.ui.intro.pad(intersection, 30);
            reveal(pointBox, t('intro.lines.restart'));
            timeout(function() {
                context.replace(iD.actions.DeleteMultiple(mode.selectedIDs()));
                step.exit();
                step.enter();
            }, 3000);
        }

        function addIntersection(changes) {
            if ( _.any(changes.created(), function(d) {
                return d.type === 'node' && context.graph().parentWays(d).length > 1;
            })) {
                context.history().on('change.intro', null);
                context.on('enter.intro', enterSelect);

                var padding = 900 * Math.pow(2, context.map().zoom() - 19);
                var pointBox = iD.ui.intro.pad(centroid, padding, context);
                reveal(pointBox, t('intro.lines.finish'));

                context.map().on('move.intro', function() {
                    padding = 900 * Math.pow(2, context.map().zoom() - 19);
                    pointBox = iD.ui.intro.pad(centroid, padding, context);
                    reveal(pointBox, t('intro.lines.finish'), {duration: 0});
                });
            }
        }

        function enterSelect(mode) {
            if (mode.id !== 'select') return;
            context.map().on('move.intro', null);
            context.on('enter.intro', null);
            d3.select('#curtain').style('pointer-events', 'all');

            timeout(function() {
                d3.select('#curtain').style('pointer-events', 'none');
                var road = d3.select('.preset-category-road .preset-list-button');
                reveal(road.node(), t('intro.lines.road'));
                road.one('click.intro', roadCategory);
            }, 500);
        }

        function roadCategory() {
            timeout(function() {
                var grid = d3.select('.subgrid');
                reveal(grid.node(), t('intro.lines.residential'));
                grid.selectAll('.preset-highway-residential .preset-list-button')
                    .one('click.intro', roadDetails);
            }, 500);
        }

        function roadDetails() {
            reveal('.pane', t('intro.lines.describe'));
            context.on('exit.intro', event.done);
        }

    };

    step.exit = function() {
        d3.select('#curtain').style('pointer-events', 'none');
        timeouts.forEach(window.clearTimeout);
        context.on('enter.intro', null);
        context.on('exit.intro', null);
        context.map().on('move.intro', null);
        context.history().on('change.intro', null);
    };

    return d3.rebind(step, event, 'on');
};
<|endoftext|>


<commit_before>var assert = require("assert");
var _ = require("underscore");

var parser = require("./parser.js");
var normalize = require("./normalize.js");
var rewrite = require("./rewrite-symbols.js");
var compile = require("./code-gen.js");

var exec = function(source, context) {
    if (_.isArray(source)) {
        source = source.join('\n');
    }
    var parseTree = parser.parse(source);
    var ast = normalize(parseTree);
    var rewritten = rewrite(ast);
    var gen = compile(rewritten);
    var js = gen.toString();
    var prelude = _.map(context, function(value, key) {
        return "var " + key + " = context." + key + ";\n";
    }).join("");
    jsFunc = new Function('context', prelude + js);
    jsFunc(context);
};

describe("aletheia", function() {

    describe("if", function() {
        it("should execute for true", function() {
            var called = false;
            var callback = function() {
                called = true;
            };
            var prgm = [
                "if true [",
                "    callback undefined",
                "]"
            ];
            exec(prgm, {callback: callback});
            assert(called);
        });
    });

    describe("while", function() {
        it("should count to 10", function() {
            var result = [];
            var callback = function(param) {
                result.push(param);
            };
            var endResult;
            var endCallback = function(param) {
                endResult = param;
            };
            var prgm = [
                "mutable i = 0",
                "while [ret (i < 10)] [",
                "    callback i",
                "    mutate i = i + 1",
                "]",
                "endCallback i"
            ];
            exec(prgm, {callback: callback, endCallback: endCallback});
            assert.deepEqual(result, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
            assert.deepEqual(endResult, 10);
        });

        it("should be able to count in fibonacci", function() {
            var fib;
            var storeResult = function(setFib) {
                fib = setFib;
            };
            var prgm = [
                "fib = [ n |",
                "    mutable a = 1",
                "    mutable b = 0",
                "    mutable i = 0",
                "    while [ret (i < n)] [",
                "        old_b = b",
                "        mutate b = a + b",
                "        mutate a = old_b",
                "        mutate i = i + 1",
                "    ]",
                "    ret b",
                "]",
                "storeResult fib"
            ];
            exec(prgm, {storeResult: storeResult});
            assert.equal(fib(0), 0);
            assert.equal(fib(1), 1);
            assert.equal(fib(2), 1);
            assert.equal(fib(3), 2);
            assert.equal(fib(4), 3);
            assert.equal(fib(5), 5);
            assert.equal(fib(6), 8);
            assert.equal(fib(7), 13);
            assert.equal(fib(8), 21);
        });
    });

    describe("table literal", function() {
        it("should compile a simple table literal", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                "callback {",
                "    a: 5",
                "    b: 6",
                "}"
            ];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, {a: 5, b: 6});
        });

        it("should compile a newline-delimited array literal", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                "callback {",
                "    4",
                "    5",
                "    6",
                "}"
            ];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, [4, 5, 6]);
        });
    });

    describe("table access", function() {
        it("should be able to access with dot notation", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                "table = {",
                "    a: 5",
                "    b: 6",
                "}",
                "callback table.a"
            ];
            exec(prgm, {callback: callback});
            assert.equal(result, 5);
        });

        it("should be able to access with @ notation", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                "table = {",
                "    a: 5",
                "    b: 6",
                "}",
                'callback table@"b"'
            ];
            exec(prgm, {callback: callback});
            assert.equal(result, 6);
        });

        it("should be able to access expressions with @ notation", function() {
            var result;
            var array = [1, 3, 6, 10, 15];
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                'callback array@(1+2)'
            ];
            exec(prgm, {array: array, callback: callback});
            assert.equal(result, 10);
        });
    });

    describe("boolean operators", function() {
        describe("and", function() {
            it("should return true for two truths", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 2 and 3 + 3 == 6)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, true);
            });

            it("should return false for two falsehoods", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 5 and 3 + 3 == 5)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, false);
            });
        });
    });

    describe("arithmetic", function() {
        it("should evaluate addition", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback (1 + 2)"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, 3);
        });

        it("should evaluate subtraction", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback (1 - 2)"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, -1);
        });

        it("should evaluate subtraction without spaces", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback (1-2)"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, -1);
        });

        it("should handle negative literals", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback -2"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, -2);
        });

        it("should handle negating expressions", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback (-(1 + 3))"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, -4);
        });
    });
});
<commit_msg>more boolean operation tests<commit_after>var assert = require("assert");
var _ = require("underscore");

var parser = require("./parser.js");
var normalize = require("./normalize.js");
var rewrite = require("./rewrite-symbols.js");
var compile = require("./code-gen.js");

var exec = function(source, context) {
    if (_.isArray(source)) {
        source = source.join('\n');
    }
    var parseTree = parser.parse(source);
    var ast = normalize(parseTree);
    var rewritten = rewrite(ast);
    var gen = compile(rewritten);
    var js = gen.toString();
    var prelude = _.map(context, function(value, key) {
        return "var " + key + " = context." + key + ";\n";
    }).join("");
    jsFunc = new Function('context', prelude + js);
    jsFunc(context);
};

describe("aletheia", function() {

    describe("if", function() {
        it("should execute for true", function() {
            var called = false;
            var callback = function() {
                called = true;
            };
            var prgm = [
                "if true [",
                "    callback undefined",
                "]"
            ];
            exec(prgm, {callback: callback});
            assert(called);
        });
    });

    describe("while", function() {
        it("should count to 10", function() {
            var result = [];
            var callback = function(param) {
                result.push(param);
            };
            var endResult;
            var endCallback = function(param) {
                endResult = param;
            };
            var prgm = [
                "mutable i = 0",
                "while [ret (i < 10)] [",
                "    callback i",
                "    mutate i = i + 1",
                "]",
                "endCallback i"
            ];
            exec(prgm, {callback: callback, endCallback: endCallback});
            assert.deepEqual(result, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
            assert.deepEqual(endResult, 10);
        });

        it("should be able to count in fibonacci", function() {
            var fib;
            var storeResult = function(setFib) {
                fib = setFib;
            };
            var prgm = [
                "fib = [ n |",
                "    mutable a = 1",
                "    mutable b = 0",
                "    mutable i = 0",
                "    while [ret (i < n)] [",
                "        old_b = b",
                "        mutate b = a + b",
                "        mutate a = old_b",
                "        mutate i = i + 1",
                "    ]",
                "    ret b",
                "]",
                "storeResult fib"
            ];
            exec(prgm, {storeResult: storeResult});
            assert.equal(fib(0), 0);
            assert.equal(fib(1), 1);
            assert.equal(fib(2), 1);
            assert.equal(fib(3), 2);
            assert.equal(fib(4), 3);
            assert.equal(fib(5), 5);
            assert.equal(fib(6), 8);
            assert.equal(fib(7), 13);
            assert.equal(fib(8), 21);
        });
    });

    describe("table literal", function() {
        it("should compile a simple table literal", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                "callback {",
                "    a: 5",
                "    b: 6",
                "}"
            ];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, {a: 5, b: 6});
        });

        it("should compile a newline-delimited array literal", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                "callback {",
                "    4",
                "    5",
                "    6",
                "}"
            ];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, [4, 5, 6]);
        });
    });

    describe("table access", function() {
        it("should be able to access with dot notation", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                "table = {",
                "    a: 5",
                "    b: 6",
                "}",
                "callback table.a"
            ];
            exec(prgm, {callback: callback});
            assert.equal(result, 5);
        });

        it("should be able to access with @ notation", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                "table = {",
                "    a: 5",
                "    b: 6",
                "}",
                'callback table@"b"'
            ];
            exec(prgm, {callback: callback});
            assert.equal(result, 6);
        });

        it("should be able to access expressions with @ notation", function() {
            var result;
            var array = [1, 3, 6, 10, 15];
            var callback = function(param) {
                result = param;
            };
            var prgm = [
                'callback array@(1+2)'
            ];
            exec(prgm, {array: array, callback: callback});
            assert.equal(result, 10);
        });
    });

    describe("boolean operators", function() {
        describe("and", function() {
            it("should return true for two truths", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 2 and 3 + 3 == 6)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, true);
            });

            it("should return false for two falsehoods", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 5 and 3 + 3 == 5)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, false);
            });

            it("should return false for a truth and a falsehood", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 2 and 3 + 3 == 5)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, false);
            });

            it("should return false for a falsehood and a truth", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 5 and 3 + 3 == 6)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, false);
            });
        });

        describe("or", function() {
            it("should return true for two truths", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 2 or 3 + 3 == 6)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, true);
            });

            it("should return false for two falsehoods", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 5 or 3 + 3 == 5)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, false);
            });

            it("should return true for a truth and a falsehood", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 2 or 3 + 3 == 5)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, true);
            });

            it("should return true for a falsehood and a truth", function() {
                var result;
                var callback = function(value) {
                    result = value;
                };
                var prgm = [
                    "callback (1 + 1 == 5 or 3 + 3 == 6)"
                ];
                exec(prgm, {callback: callback});
                assert.equal(result, true);
            });
        });

    });

    describe("arithmetic", function() {
        it("should evaluate addition", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback (1 + 2)"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, 3);
        });

        it("should evaluate subtraction", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback (1 - 2)"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, -1);
        });

        it("should evaluate subtraction without spaces", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback (1-2)"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, -1);
        });

        it("should handle negative literals", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback -2"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, -2);
        });

        it("should handle negating expressions", function() {
            var result;
            var callback = function(param) {
                result = param;
            };
            var prgm = ["callback (-(1 + 3))"];
            exec(prgm, {callback: callback});
            assert.deepEqual(result, -4);
        });
    });
});
<|endoftext|>


<commit_before>var inzoart = (function(){
	var time, src, images;
	// Guardar todas las imagenes en un array.
	// Ocultar la ultima y mostrar la siguiente a la ultima
	// En una variable guardar la imagen que se encuentra visible y su posición dentro del array

	function init(element, options){

		images = options.images || {};
		var length = images.length;
		var count = 1;
		var domElement = document.getElementById(element);

		for(var i = 0;i<length; i++){
			var img = document.createElement("IMG");
			img.src = images[i];
			domElement.appendChild(img);
			img.setAttribute("style","display:none");
			img.setAttribute("data-position", i);
			if(i==1){
				img.setAttribute("style","display:inline");
			}
		}

		setInterval(function(){
			var imgs = document.getElementsByTagName("IMG");
			var imgsLength = imgs.length;
			for(var i = 0; i<imgsLength; i++){
				imgs[i].setAttribute("style", "display:none");
			}
			imgs[count].setAttribute("style", "display:inline");

			count = count == imgsLength -1 ? 0 : count+1;
		}, 3000);
	}

	function fadeOut(element) {
		if(!element)
			return;
		var opacity = 1;
		var interval = setInterval(function(){
			if(opacity){
				element.setAttribute("opacity", opacity);
				opacity = opacity - 0.1;
			} else {
				clearInterval(interval);
			}
		},100);

	}

	return {
		slider: init
	}
})();<commit_msg>Delete inzoartSliderold.js<commit_after><|endoftext|>


<commit_before>elation.require(['janusweb.janusbase'], function() {

  THREE.SBSTexture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
    THREE.Texture.call( this, image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

    this.repeat.x = 0.5;
    this.reverse = false;
  }
  THREE.SBSTexture.prototype = Object.create( THREE.Texture.prototype );
  THREE.SBSTexture.prototype.constructor = THREE.SBSTexture;
  THREE.SBSTexture.prototype.setEye = function(eye) {
    if (eye == 'left') {
      this.offset.x = (this.reverse ? 0.5 : 0);
    } else {
      this.offset.x = (this.reverse ? 0 : 0.5);
    }
    this.eye = eye;
  }
  THREE.SBSTexture.prototype.swap = function() {
    if (this.eye == 'right') {
      this.setEye('left');
    } else {
      this.setEye('right');
    }
  }
  THREE.SBSTexture.prototype.animate = function() {
    this.swap();
    setTimeout(this.animate.bind(this), 100);
  }

  THREE.SBSVideoTexture = function ( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
    THREE.VideoTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

    this.repeat.x = 0.5;
    this.reverse = false;
  }
  THREE.SBSVideoTexture.prototype = Object.create( THREE.Texture.prototype );
  THREE.SBSVideoTexture.prototype.constructor = THREE.SBSVideoTexture;

  elation.component.add('engine.things.janusimage', function() {
    this.postinit = function() {
      elation.engine.things.janusimage.extendclass.postinit.call(this);
      this.defineProperties({
        image_id: { type: 'string', set: this.setMaterialDirty },
        sbs3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
        ou3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
        reverse3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
      });
    }
    this.createObject3D = function() {
      var geo = this.createGeometry();
      var mat = this.createMaterial();
      return new THREE.Mesh(geo, mat);

/*
        var geo = this.createGeometry();
        var mat = this.createMaterial();
        return new THREE.Mesh(geo, mat);
      } else {
        console.log('ERROR - could not find image ' + this.properties.image_id);
      }
*/
    }
    this.createGeometry = function() {
      var aspect = this.getAspect(),
          thickness = 0.1; //Math.max(this.scale.x, this.scale.z) / (10 * this.scale.z);
      var box = new THREE.BoxBufferGeometry(2, 2 * aspect, thickness);
      box.applyMatrix(new THREE.Matrix4().makeTranslation(0, 0, thickness / this.scale.z));

      // Flip the back face for images
      var uvs = box.attributes.uv;
      var start = 20,
          count = 4;
      for (var i = start; i < start + count; i++) {
        uvs.array[i*2] = 1.0 - uvs.array[i*2];
      }

      return box;
    }
    this.createMaterial = function() {
      var matargs = {
        color: this.properties.color,
        transparent: false,
        alphaTest: 0.2
      };

      this.asset = this.getAsset('image', this.image_id);
      if (this.asset) {
        this.texture = this.asset.getInstance();
        if (this.texture) {
          elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
          elation.events.add(this.texture, 'update', elation.bind(this, this.refresh));

          matargs.transparent = this.asset.hasalpha;
        }
      }
      if (this.texture) {
        var sidemattex = this.texture.clone();
        this.sidetex = sidemattex;
        sidemattex.repeat.x = .0001;
        matargs.map = this.texture;
      }
      var sidematargs = {
        map: sidemattex,
        color: this.properties.color,
        transparent: matargs.transparent,
        alphaTest: 0.2
      };

      var mat = (this.properties.lighting ? new THREE.MeshPhongMaterial(matargs) : new THREE.MeshBasicMaterial(matargs));
      var sidemat = (this.properties.lighting ? new THREE.MeshPhongMaterial(sidematargs) : new THREE.MeshBasicMaterial(sidematargs));
      var facemat = [sidemat,sidemat,sidemat,sidemat,mat,mat];
      this.facematerial = facemat;
      this.frontmaterial = mat;
      this.sidematerial = sidemat;
      if (this.texture) {
        // Update diffuse map whenever the asset updates (gif frames, etc)
        elation.events.add(this.texture, 'asset_update', elation.bind(this, function(ev) { this.frontmaterial.map = ev.data; }));
      }
      return facemat;
    }
    this.setMaterialDirty = function() {
      this.materialNeedsUpdate = true;
    }
    this.handleFrameUpdates = function() {
      elation.engine.things.janusobject.extendclass.handleFrameUpdates.call(this);
      if (this.materialNeedsUpdate) {
        this.updateMaterial();
      }
    }
    this.updateMaterial = function() {
      this.asset = this.getAsset('image', this.image_id);
      this.materialNeedsUpdate = false;
      var newtexture = false;
      if (this.asset) {
        newtexture = this.asset.getInstance();
      }
      if (newtexture && newtexture !== this.texture) {
        this.texture = newtexture;
        if (newtexture.image) {
          this.imageloaded();
        } else {
          elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
        }
        elation.events.add(this.texture, 'asset_update', elation.bind(this, function(ev) { this.frontmaterial.map = ev.data; }));
      }
    }
    this.getAspect = function() {
      var aspect = 1;
      if (this.asset && this.asset.rawimage) {
        var size = this.getSize(this.asset.rawimage);
        aspect = size.height / size.width;
      }
      if (this.sbs3d || (this.asset && this.asset.sbs3d)) aspect *= 2;
      if (this.ou3d || (this.asset && this.asset.ou3d)) aspect /= 2;
      return aspect;
    }
    this.getSize = function(image) {
      return {width: image.width, height: image.height};
    }
    this.adjustAspectRatio = function() {
      var img = this.texture.image;
      var geo = this.createGeometry();
      this.objects['3d'].geometry = geo;
    }
    this.imageloaded = function(ev) {
      if (!this.frontmaterial) return;

      this.frontmaterial.map = this.texture;
      this.frontmaterial.needsUpdate = true;
      this.adjustAspectRatio();
      this.sidetex.image = this.texture.image;
      this.sidetex.needsUpdate = true;

      if (this.properties.sbs3d) {
        // TODO - to really support 3d video, we need to set offset based on which eye is being rendered
        var texture = new THREE.SBSTexture(this.texture.image);
        texture.reverse = this.properties.reverse3d;
        texture.needsUpdate = true;
        this.texture = texture;
        this.frontmaterial.map = texture;
        /*
        this.sidematerial.map = texture.clone();
        this.sidematerial.map.needsUpdate = true;
        this.sidematerial.map.repeat.x = .0001;
        */
      }

      this.refresh();
    }
    this.getProxyObject = function() {
      var proxy = elation.engine.things.janusimage.extendclass.getProxyObject.call(this);
      proxy._proxydefs = {
        id:  [ 'property', 'image_id'],
      };
      return proxy;
    }
  }, elation.engine.things.janusbase);
});
<commit_msg>Update collider to respect aspect ratio, pass arguments to superclass functions calls<commit_after>elation.require(['janusweb.janusbase'], function() {

  THREE.SBSTexture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
    THREE.Texture.call( this, image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

    this.repeat.x = 0.5;
    this.reverse = false;
  }
  THREE.SBSTexture.prototype = Object.create( THREE.Texture.prototype );
  THREE.SBSTexture.prototype.constructor = THREE.SBSTexture;
  THREE.SBSTexture.prototype.setEye = function(eye) {
    if (eye == 'left') {
      this.offset.x = (this.reverse ? 0.5 : 0);
    } else {
      this.offset.x = (this.reverse ? 0 : 0.5);
    }
    this.eye = eye;
  }
  THREE.SBSTexture.prototype.swap = function() {
    if (this.eye == 'right') {
      this.setEye('left');
    } else {
      this.setEye('right');
    }
  }
  THREE.SBSTexture.prototype.animate = function() {
    this.swap();
    setTimeout(this.animate.bind(this), 100);
  }

  THREE.SBSVideoTexture = function ( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
    THREE.VideoTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

    this.repeat.x = 0.5;
    this.reverse = false;
  }
  THREE.SBSVideoTexture.prototype = Object.create( THREE.Texture.prototype );
  THREE.SBSVideoTexture.prototype.constructor = THREE.SBSVideoTexture;

  elation.component.add('engine.things.janusimage', function() {
    this.postinit = function() {
      elation.engine.things.janusimage.extendclass.postinit.call(this);
      this.defineProperties({
        image_id: { type: 'string', set: this.setMaterialDirty },
        sbs3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
        ou3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
        reverse3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
      });
    }
    this.createObject3D = function() {
      var geo = this.createGeometry();
      var mat = this.createMaterial();
      return new THREE.Mesh(geo, mat);

/*
        var geo = this.createGeometry();
        var mat = this.createMaterial();
        return new THREE.Mesh(geo, mat);
      } else {
        console.log('ERROR - could not find image ' + this.properties.image_id);
      }
*/
    }
    this.createGeometry = function() {
      var aspect = this.getAspect(),
          thickness = 0.1; //Math.max(this.scale.x, this.scale.z) / (10 * this.scale.z);
      var box = new THREE.BoxBufferGeometry(2, 2 * aspect, thickness);
      box.applyMatrix(new THREE.Matrix4().makeTranslation(0, 0, thickness / this.scale.z));

      // Flip the back face for images
      var uvs = box.attributes.uv;
      var start = 20,
          count = 4;
      for (var i = start; i < start + count; i++) {
        uvs.array[i*2] = 1.0 - uvs.array[i*2];
      }

      return box;
    }
    this.createMaterial = function() {
      var matargs = {
        color: this.properties.color,
        transparent: false,
        alphaTest: 0.2
      };

      this.asset = this.getAsset('image', this.image_id);
      if (this.asset) {
        this.texture = this.asset.getInstance();
        if (this.texture) {
          elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
          elation.events.add(this.texture, 'update', elation.bind(this, this.refresh));

          matargs.transparent = this.asset.hasalpha;
        }
      }
      if (this.texture) {
        var sidemattex = this.texture.clone();
        this.sidetex = sidemattex;
        sidemattex.repeat.x = .0001;
        matargs.map = this.texture;
      }
      var sidematargs = {
        map: sidemattex,
        color: this.properties.color,
        transparent: matargs.transparent,
        alphaTest: 0.2
      };

      var mat = (this.properties.lighting ? new THREE.MeshPhongMaterial(matargs) : new THREE.MeshBasicMaterial(matargs));
      var sidemat = (this.properties.lighting ? new THREE.MeshPhongMaterial(sidematargs) : new THREE.MeshBasicMaterial(sidematargs));
      var facemat = [sidemat,sidemat,sidemat,sidemat,mat,mat];
      this.facematerial = facemat;
      this.frontmaterial = mat;
      this.sidematerial = sidemat;
      if (this.texture) {
        // Update diffuse map whenever the asset updates (gif frames, etc)
        elation.events.add(this.texture, 'asset_update', elation.bind(this, function(ev) { this.frontmaterial.map = ev.data; }));
      }
      return facemat;
    }
    this.setMaterialDirty = function() {
      this.materialNeedsUpdate = true;
    }
    this.handleFrameUpdates = function(ev) {
      elation.engine.things.janusobject.extendclass.handleFrameUpdates.call(this, ev);
      if (this.materialNeedsUpdate) {
        this.updateMaterial();
      }
    }
    this.updateMaterial = function() {
      this.asset = this.getAsset('image', this.image_id);
      this.materialNeedsUpdate = false;
      var newtexture = false;
      if (this.asset) {
        newtexture = this.asset.getInstance();
      }
      if (newtexture && newtexture !== this.texture) {
        this.texture = newtexture;
        if (newtexture.image) {
          this.imageloaded();
        } else {
          elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
        }
        elation.events.add(this.texture, 'asset_update', elation.bind(this, function(ev) { this.frontmaterial.map = ev.data; }));
      }
    }
    this.getAspect = function() {
      var aspect = 1;
      if (this.asset && this.asset.rawimage) {
        var size = this.getSize(this.asset.rawimage);
        aspect = size.height / size.width;
      }
      if (this.sbs3d || (this.asset && this.asset.sbs3d)) aspect *= 2;
      if (this.ou3d || (this.asset && this.asset.ou3d)) aspect /= 2;
      return aspect;
    }
    this.getSize = function(image) {
      return {width: image.width, height: image.height};
    }
    this.adjustAspectRatio = function() {
      var img = this.texture.image;
      var geo = this.createGeometry();
      geo.computeBoundingBox();
      this.colliders.children[0].geometry = geo;
      this.objects['3d'].geometry = geo;
    }
    this.imageloaded = function(ev) {
      if (!this.frontmaterial) return;

      this.frontmaterial.map = this.texture;
      this.frontmaterial.needsUpdate = true;
      this.adjustAspectRatio();
      this.sidetex.image = this.texture.image;
      this.sidetex.needsUpdate = true;

      if (this.properties.sbs3d) {
        // TODO - to really support 3d video, we need to set offset based on which eye is being rendered
        var texture = new THREE.SBSTexture(this.texture.image);
        texture.reverse = this.properties.reverse3d;
        texture.needsUpdate = true;
        this.texture = texture;
        this.frontmaterial.map = texture;
        /*
        this.sidematerial.map = texture.clone();
        this.sidematerial.map.needsUpdate = true;
        this.sidematerial.map.repeat.x = .0001;
        */
      }

      this.refresh();
    }
    this.getProxyObject = function(classdef) {
      var proxy = elation.engine.things.janusimage.extendclass.getProxyObject.call(this, classdef);
      proxy._proxydefs = {
        id:  [ 'property', 'image_id'],
      };
      return proxy;
    }
  }, elation.engine.things.janusbase);
});
<|endoftext|>


<commit_before>elation.require(['janusweb.janusbase'], function() {

  THREE.SBSTexture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
    THREE.Texture.call( this, image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

    this.repeat.x = 0.5;
    this.reverse = false;
  }
  THREE.SBSTexture.prototype = Object.create( THREE.Texture.prototype );
  THREE.SBSTexture.prototype.constructor = THREE.SBSTexture;
  THREE.SBSTexture.prototype.setEye = function(eye) {
    if (eye == 'left') {
      this.offset.x = (this.reverse ? 0.5 : 0);
    } else {
      this.offset.x = (this.reverse ? 0 : 0.5);
    }
    this.eye = eye;
  }
  THREE.SBSTexture.prototype.swap = function() {
    if (this.eye == 'right') {
      this.setEye('left');
    } else {
      this.setEye('right');
    }
  }
  THREE.SBSTexture.prototype.animate = function() {
    this.swap();
    setTimeout(this.animate.bind(this), 100);
  }

  THREE.SBSVideoTexture = function ( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
    THREE.VideoTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

    this.repeat.x = 0.5;
    this.reverse = false;
  }
  THREE.SBSVideoTexture.prototype = Object.create( THREE.Texture.prototype );
  THREE.SBSVideoTexture.prototype.constructor = THREE.SBSVideoTexture;

  elation.component.add('engine.things.janusimage', function() {
    this.postinit = function() {
      elation.engine.things.janusimage.extendclass.postinit.call(this);
      this.defineProperties({
        image_id: { type: 'string', set: this.setMaterialDirty },
        sbs3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
        ou3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
        reverse3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
      });
    }
    this.createObject3D = function() {
      var geo = this.createGeometry();
      var mat = this.createMaterial();
      return new THREE.Mesh(geo, mat);

/*
        var geo = this.createGeometry();
        var mat = this.createMaterial();
        return new THREE.Mesh(geo, mat);
      } else {
        console.log('ERROR - could not find image ' + this.properties.image_id);
      }
*/
    }
    this.createGeometry = function() {
      var aspect = this.getAspect(),
          thickness = 0.1; //Math.max(this.scale.x, this.scale.z) / (10 * this.scale.z);
      var box = new THREE.BoxBufferGeometry(2, 2 * aspect, thickness);
      box.applyMatrix(new THREE.Matrix4().makeTranslation(0, 0, thickness / this.scale.z));

      // Flip the back face for images
      var uvs = box.attributes.uv;
      var start = 20,
          count = 4;
      for (var i = start; i < start + count; i++) {
        uvs.array[i*2] = 1.0 - uvs.array[i*2];
      }

      return box;
    }
    this.createMaterial = function() {
      var matargs = {
        color: this.properties.color,
        transparent: false,
        alphaTest: 0.2
      };

      this.asset = this.getAsset('image', this.image_id);
      if (this.asset) {
        this.texture = this.asset.getInstance();
        if (this.texture) {
          elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
          elation.events.add(this.texture, 'update', elation.bind(this, this.refresh));

          matargs.transparent = this.asset.hasalpha;
        }
      }
      if (this.texture) {
        var sidemattex = this.texture.clone();
        this.sidetex = sidemattex;
        sidemattex.repeat.x = .0001;
        matargs.map = this.texture;
      }
      var sidematargs = {
        map: sidemattex,
        color: this.properties.color,
        transparent: matargs.transparent,
        alphaTest: 0.2
      };

      var mat = (this.properties.lighting ? new THREE.MeshPhongMaterial(matargs) : new THREE.MeshBasicMaterial(matargs));
      var sidemat = (this.properties.lighting ? new THREE.MeshPhongMaterial(sidematargs) : new THREE.MeshBasicMaterial(sidematargs));
      var facemat = [sidemat,sidemat,sidemat,sidemat,mat,mat];
      this.facematerial = facemat;
      this.frontmaterial = mat;
      this.sidematerial = sidemat;
      if (this.texture) {
        // Update diffuse map whenever the asset updates (gif frames, etc)
        elation.events.add(this.texture, 'asset_update', elation.bind(this, function(ev) { this.frontmaterial.map = ev.data; }));
      }
      return facemat;
    }
    this.setMaterialDirty = function() {
      this.materialNeedsUpdate = true;
    }
    this.handleFrameUpdates = function(ev) {
      elation.engine.things.janusobject.extendclass.handleFrameUpdates.call(this, ev);
      if (this.materialNeedsUpdate) {
        this.updateMaterial();
      }
    }
    this.updateMaterial = function() {
      this.asset = this.getAsset('image', this.image_id);
      this.materialNeedsUpdate = false;
      var newtexture = false;
      if (this.asset) {
        newtexture = this.asset.getInstance();
      }
      if (newtexture && newtexture !== this.texture) {
        this.texture = newtexture;
        if (newtexture.image) {
          this.imageloaded();
        } else {
          elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
        }
        elation.events.add(this.texture, 'asset_update', elation.bind(this, function(ev) { this.frontmaterial.map = ev.data; }));
      }
    }
    this.getAspect = function() {
      var aspect = 1;
      if (this.asset && this.asset.rawimage) {
        var size = this.getSize(this.asset.rawimage);
        aspect = size.height / size.width;
      }
      if (this.sbs3d || (this.asset && this.asset.sbs3d)) aspect *= 2;
      if (this.ou3d || (this.asset && this.asset.ou3d)) aspect /= 2;
      return aspect;
    }
    this.getSize = function(image) {
      return {width: image.width, height: image.height};
    }
    this.adjustAspectRatio = function() {
      var img = this.texture.image;
      var geo = this.createGeometry();
      geo.computeBoundingBox();
      this.colliders.children[0].geometry = geo;
      this.objects['3d'].geometry = geo;
    }
    this.imageloaded = function(ev) {
      if (!this.frontmaterial) return;

      this.frontmaterial.map = this.texture;
      this.frontmaterial.needsUpdate = true;
      this.adjustAspectRatio();
      this.sidetex.image = this.texture.image;
      this.sidetex.needsUpdate = true;

      if (this.properties.sbs3d) {
        // TODO - to really support 3d video, we need to set offset based on which eye is being rendered
        var texture = new THREE.SBSTexture(this.texture.image);
        texture.reverse = this.properties.reverse3d;
        texture.needsUpdate = true;
        this.texture = texture;
        this.frontmaterial.map = texture;
        /*
        this.sidematerial.map = texture.clone();
        this.sidematerial.map.needsUpdate = true;
        this.sidematerial.map.repeat.x = .0001;
        */
      }

      this.refresh();
    }
    this.getProxyObject = function(classdef) {
      if (!this._proxyobject) {
        this._proxyobject = elation.engine.things.janusimage.extendclass.getProxyObject.call(this, classdef);
        this._proxyobject._proxydefs = {
          id:  [ 'property', 'image_id'],
        };
      }
      return this._proxyobject;
    }
  }, elation.engine.things.janusbase);
});
<commit_msg>sbs3d fixes<commit_after>elation.require(['janusweb.janusbase'], function() {

  THREE.SBSTexture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
    THREE.Texture.call( this, image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

    this.repeat.x = 0.5;
    this.reverse = false;
  }
  THREE.SBSTexture.prototype = Object.create( THREE.Texture.prototype );
  THREE.SBSTexture.prototype.constructor = THREE.SBSTexture;
  THREE.SBSTexture.prototype.setEye = function(eye) {
    if (eye == 'left') {
      this.offset.x = (this.reverse ? 0.5 : 0);
    } else {
      this.offset.x = (this.reverse ? 0 : 0.5);
    }
    this.eye = eye;
  }
  THREE.SBSTexture.prototype.swap = function() {
    if (this.eye == 'right') {
      this.setEye('left');
    } else {
      this.setEye('right');
    }
  }
  THREE.SBSTexture.prototype.animate = function() {
    this.swap();
    setTimeout(this.animate.bind(this), 100);
  }

  THREE.SBSVideoTexture = function ( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
    THREE.VideoTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

    this.repeat.x = 0.5;
    this.reverse = false;
  }
  THREE.SBSVideoTexture.prototype = Object.create( THREE.Texture.prototype );
  THREE.SBSVideoTexture.prototype.constructor = THREE.SBSVideoTexture;

  elation.component.add('engine.things.janusimage', function() {
    this.postinit = function() {
      elation.engine.things.janusimage.extendclass.postinit.call(this);
      this.defineProperties({
        image_id: { type: 'string', set: this.setMaterialDirty },
        sbs3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
        ou3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
        reverse3d: { type: 'boolean', default: false, set: this.setMaterialDirty },
      });
    }
    this.createObject3D = function() {
      var geo = this.createGeometry();
      var mat = this.createMaterial();
      return new THREE.Mesh(geo, mat);

/*
        var geo = this.createGeometry();
        var mat = this.createMaterial();
        return new THREE.Mesh(geo, mat);
      } else {
        console.log('ERROR - could not find image ' + this.properties.image_id);
      }
*/
    }
    this.createGeometry = function() {
      var aspect = this.getAspect(),
          thickness = 0.1; //Math.max(this.scale.x, this.scale.z) / (10 * this.scale.z);
      var box = new THREE.BoxBufferGeometry(2, 2 * aspect, thickness);
      box.applyMatrix(new THREE.Matrix4().makeTranslation(0, 0, thickness / this.scale.z));

      // Flip the back face for images
      var uvs = box.attributes.uv;
      var start = 20,
          count = 4;
      for (var i = start; i < start + count; i++) {
        uvs.array[i*2] = 1.0 - uvs.array[i*2];
      }

      return box;
    }
    this.createMaterial = function() {
      var matargs = {
        color: this.properties.color,
        transparent: false,
        alphaTest: 0.2
      };

      this.asset = this.getAsset('image', this.image_id);
      if (this.asset) {
        this.texture = this.asset.getInstance();
        if (this.texture) {
          elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
          elation.events.add(this.texture, 'update', elation.bind(this, this.refresh));

          matargs.transparent = this.asset.hasalpha;
        }
      }
      if (this.texture) {
        var sidemattex = this.texture.clone();
        this.sidetex = sidemattex;
        sidemattex.repeat.x = .0001;
        matargs.map = this.texture;
      }
      var sidematargs = {
        map: sidemattex,
        color: this.properties.color,
        transparent: matargs.transparent,
        alphaTest: 0.2
      };

      var mat = (this.properties.lighting ? new THREE.MeshPhongMaterial(matargs) : new THREE.MeshBasicMaterial(matargs));
      var sidemat = (this.properties.lighting ? new THREE.MeshPhongMaterial(sidematargs) : new THREE.MeshBasicMaterial(sidematargs));
      var facemat = [sidemat,sidemat,sidemat,sidemat,mat,mat];
      this.facematerial = facemat;
      this.frontmaterial = mat;
      this.sidematerial = sidemat;
      if (this.texture) {
        // Update diffuse map whenever the asset updates (gif frames, etc)
        elation.events.add(this.texture, 'asset_update', elation.bind(this, function(ev) { this.frontmaterial.map = ev.data; }));
      }
      return facemat;
    }
    this.setMaterialDirty = function() {
      this.materialNeedsUpdate = true;
    }
    this.handleFrameUpdates = function(ev) {
      elation.engine.things.janusobject.extendclass.handleFrameUpdates.call(this, ev);
      if (this.materialNeedsUpdate) {
        this.updateMaterial();
      }
    }
    this.updateMaterial = function() {
      this.asset = this.getAsset('image', this.image_id);
      this.materialNeedsUpdate = false;
      var newtexture = false;
      if (this.asset) {
        newtexture = this.asset.getInstance();
      }
      if (newtexture && newtexture !== this.texture) {
        this.texture = newtexture;
        if (newtexture.image) {
          this.imageloaded();
        } else {
          elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
        }
        elation.events.add(this.texture, 'asset_update', elation.bind(this, function(ev) { this.frontmaterial.map = ev.data; }));
      }
    }
    this.getAspect = function() {
      var aspect = 1;
      if (this.asset && this.asset.rawimage) {
        var size = this.getSize(this.asset.rawimage);
        aspect = size.height / size.width;
      }
      if (this.sbs3d || (this.asset && this.asset.sbs3d)) aspect *= 2;
      if (this.ou3d || (this.asset && this.asset.ou3d)) aspect /= 2;
      return aspect;
    }
    this.getSize = function(image) {
      return {width: image.width, height: image.height};
    }
    this.adjustAspectRatio = function() {
      var img = this.texture.image;
      var geo = this.createGeometry();
      geo.computeBoundingBox();
      this.colliders.children[0].geometry = geo;
      this.objects['3d'].geometry = geo;
    }
    this.imageloaded = function(ev) {
      if (!this.frontmaterial) return;

      this.frontmaterial.map = this.texture;
      this.frontmaterial.needsUpdate = true;
      this.adjustAspectRatio();
      this.sidetex.image = this.texture.image;
      this.sidetex.needsUpdate = true;

      if (this.properties.sbs3d || this.asset.sbs3d) {
        // TODO - to really support 3d video, we need to set offset based on which eye is being rendered
        var texture = new THREE.SBSTexture(this.texture.image);
        texture.reverse = this.properties.reverse3d;
        texture.needsUpdate = true;
        this.texture = texture;
        this.frontmaterial.map = texture;
        /*
        this.sidematerial.map = texture.clone();
        this.sidematerial.map.needsUpdate = true;
        this.sidematerial.map.repeat.x = .0001;
        */
        this.objects['3d'].onBeforeRender = () => { texture.swap(); }
      }

      this.refresh();
    }
    this.getProxyObject = function(classdef) {
      if (!this._proxyobject) {
        this._proxyobject = elation.engine.things.janusimage.extendclass.getProxyObject.call(this, classdef);
        this._proxyobject._proxydefs = {
          id:  [ 'property', 'image_id'],
        };
      }
      return this._proxyobject;
    }
  }, elation.engine.things.janusbase);
});
<|endoftext|>


<commit_before>import set from 'lodash.set';
import clone from 'lodash.clone';
import get from 'lodash.get';
import partialRight from 'lodash.partialright';
import Bacon from 'bacon.animationframe';
require('./bufferUntilValue');

import {
  FRAME_RATE,
  WORLD_HEIGHT,
  BIRD_RADIUS,
  GROUND_HEIGHT,
  PIPE_DISTANCE,
  PAUSE_KEY,
  HOLE_HEIGHT,
  PIPE_WIDTH
} from './constants';

import {record, selectedState$, isManual$, futureInput$} from './store'

import {initialBird, updateBird, birdTouchesPipe, birdTouchesGround} from './bird'
import {initialWorld, updateWorld} from './world'
import {initialPipes, updatePipes} from './pipes'

// User events
const userClicks = Bacon.fromEvent(window, 'click');
const paused = Bacon.fromEvent(window, 'keydown')
  .filter(ev => ev.keyCode === PAUSE_KEY)
  .scan(false, paused => !paused);

// Game tick
const tick = Bacon.scheduleAnimationFrame().bufferWithTime(FRAME_RATE)
  .filter(paused.or(isManual$).not());

const userClicksForFrame = userClicks.bufferUntilValue(tick)

// Input caused by game state
const gameOutput = new Bacon.Bus();

const birdTouchedGround = gameOutput
  .flatMap(([, bird]) => {
    if(birdTouchesGround(bird) && bird.groundTouchTime === 0) {
      return Bacon.later(1000, true);
    }
    return false;
  });

const birdTouchedPipe = gameOutput.map(birdTouchesPipe);

const output = Bacon.zipWith(
  (birdTouchedGround, birdTouchedPipe) => ({birdTouchedGround, birdTouchedPipe}),
  birdTouchedGround.startWith(false),
  birdTouchedPipe.startWith(false))

const input = Bacon.zipWith((userClicksForFrame) => ({clicks: userClicksForFrame}), userClicksForFrame)

const io = Bacon.zipAsArray(
  input.filter(isManual$.not()),
  output
);

function scanStreams(fn) {
  var cachedChar;
  var accumulator;

  return (sourceVal, value) => {
    if(!cachedChar) {
      cachedChar = sourceVal;
      accumulator = sourceVal;
    }
    if(sourceVal !== cachedChar) {
      accumulator = sourceVal;
      cachedChar = sourceVal;
    }
    accumulator = fn(accumulator, value);
    return accumulator;
  }
}

const futureState$ = Bacon.combineWith(scanStreams((state, input) => {
  let [world, bird, pipes] = state.state;
  const {tick} = state;
  let {output} = state;

  world = updateWorld(world, [input, output]);
  bird = updateBird(bird, [[input, output], world]);
  pipes = updatePipes(pipes, [world, bird]);

  output = {
    birdTouchedGround: birdTouchesGround(bird),
    birdTouchedPipe: birdTouchesPipe([world, bird, pipes])
  }

  return {
    state: [world, bird, pipes],
    tick,
    output,
    input
  }
}), selectedState$, futureInput$)

// Game world update
const updatedWorld = io.scan(initialWorld, updateWorld);
const updatedBird = Bacon.zipAsArray(io, updatedWorld).scan(initialBird, updateBird);
const updatedPipes = Bacon.zipAsArray(updatedWorld, updatedBird).scan(initialPipes, updatePipes);

const updatedGameWorld = Bacon.zipAsArray(updatedWorld, updatedBird, updatedPipes);

const game = updatedGameWorld.filter(isManual$.not())
  .merge(selectedState$.map('.state'))

Bacon.zipWith((state, tick, input, output) => ({state, tick, input, output}), game, tick, input, output)
  .filter(isManual$.not())
  .onValue(record);

game.onValue(world => gameOutput.push(world));

// Rendering
function connect() {
  const renderer = require('./render');
  return [game.onValues(renderer),
          Bacon.combineAsArray(
            futureState$.map('.state'),
            game
          ).onValues(renderer.renderFuture)];
}

let destroyRenderers = connect();
module.hot.accept('./render', () => {
  destroyRenderers.forEach(fn => fn());
  destroyRenderers = connect();
});
<commit_msg>only use hot loading when its available<commit_after>import set from 'lodash.set';
import clone from 'lodash.clone';
import get from 'lodash.get';
import partialRight from 'lodash.partialright';
import Bacon from 'bacon.animationframe';
require('./bufferUntilValue');

import {
  FRAME_RATE,
  WORLD_HEIGHT,
  BIRD_RADIUS,
  GROUND_HEIGHT,
  PIPE_DISTANCE,
  PAUSE_KEY,
  HOLE_HEIGHT,
  PIPE_WIDTH
} from './constants';

import {record, selectedState$, isManual$, futureInput$} from './store'

import {initialBird, updateBird, birdTouchesPipe, birdTouchesGround} from './bird'
import {initialWorld, updateWorld} from './world'
import {initialPipes, updatePipes} from './pipes'

// User events
const userClicks = Bacon.fromEvent(window, 'click');
const paused = Bacon.fromEvent(window, 'keydown')
  .filter(ev => ev.keyCode === PAUSE_KEY)
  .scan(false, paused => !paused);

// Game tick
const tick = Bacon.scheduleAnimationFrame().bufferWithTime(FRAME_RATE)
  .filter(paused.or(isManual$).not());

const userClicksForFrame = userClicks.bufferUntilValue(tick)

// Input caused by game state
const gameOutput = new Bacon.Bus();

const birdTouchedGround = gameOutput
  .flatMap(([, bird]) => {
    if(birdTouchesGround(bird) && bird.groundTouchTime === 0) {
      return Bacon.later(1000, true);
    }
    return false;
  });

const birdTouchedPipe = gameOutput.map(birdTouchesPipe);

const output = Bacon.zipWith(
  (birdTouchedGround, birdTouchedPipe) => ({birdTouchedGround, birdTouchedPipe}),
  birdTouchedGround.startWith(false),
  birdTouchedPipe.startWith(false))

const input = Bacon.zipWith((userClicksForFrame) => ({clicks: userClicksForFrame}), userClicksForFrame)

const io = Bacon.zipAsArray(
  input.filter(isManual$.not()),
  output
);

function scanStreams(fn) {
  var cachedChar;
  var accumulator;

  return (sourceVal, value) => {
    if(!cachedChar) {
      cachedChar = sourceVal;
      accumulator = sourceVal;
    }
    if(sourceVal !== cachedChar) {
      accumulator = sourceVal;
      cachedChar = sourceVal;
    }
    accumulator = fn(accumulator, value);
    return accumulator;
  }
}

const futureState$ = Bacon.combineWith(scanStreams((state, input) => {
  let [world, bird, pipes] = state.state;
  const {tick} = state;
  let {output} = state;

  world = updateWorld(world, [input, output]);
  bird = updateBird(bird, [[input, output], world]);
  pipes = updatePipes(pipes, [world, bird]);

  output = {
    birdTouchedGround: birdTouchesGround(bird),
    birdTouchedPipe: birdTouchesPipe([world, bird, pipes])
  }

  return {
    state: [world, bird, pipes],
    tick,
    output,
    input
  }
}), selectedState$, futureInput$)

// Game world update
const updatedWorld = io.scan(initialWorld, updateWorld);
const updatedBird = Bacon.zipAsArray(io, updatedWorld).scan(initialBird, updateBird);
const updatedPipes = Bacon.zipAsArray(updatedWorld, updatedBird).scan(initialPipes, updatePipes);

const updatedGameWorld = Bacon.zipAsArray(updatedWorld, updatedBird, updatedPipes);

const game = updatedGameWorld.filter(isManual$.not())
  .merge(selectedState$.map('.state'))

Bacon.zipWith((state, tick, input, output) => ({state, tick, input, output}), game, tick, input, output)
  .filter(isManual$.not())
  .onValue(record);

game.onValue(world => gameOutput.push(world));

// Rendering
function connect() {
  const renderer = require('./render');
  return [game.onValues(renderer),
          Bacon.combineAsArray(
            futureState$.map('.state'),
            game
          ).onValues(renderer.renderFuture)];
}

let destroyRenderers = connect();

if(module.hot) {
  module.hot.accept('./render', () => {
    destroyRenderers.forEach(fn => fn());
    destroyRenderers = connect();
  });
}
<|endoftext|>


<commit_before>/*global $:true,jQuery:true*/
/*jslint debug: true, devel: true, evil: true, vars: true, undef: true */
if (typeof DEBUG === 'undefined') { DEBUG = true; } // removed on uglify
(function ($) {

    // global variables setup
    var globals = {};

    var getSettings = function () {
        return globals;
    };

    var setSettings = function (options) {
        // public / defaults
        globals = $.extend({
            'content'           : '',
            'immediateDisplay'  : false,
            'modalTopPadding'   : 75,
            'modalHomeBg'       : 'jhm-modal-bg',
            'modalHomeDiv'      : 'jhm-modal',
            'modalHomeClose'    : 'jhm-modal-close',
			'modalHomeCloseMsg'    : 'x',
            'modalHomeLoader'  : 'jhm-modal-loading',
            'modalHomeContent'  : 'jhm-modal-content',
            'modalHomeOpenEvent'    : 'jhm.modal.open',
            'modalHomeCloseEvent'   : 'jhm.modal.close',
            'ajaxFailureContent'    : 'Failed to load resource'
        }, options);

        return globals;
    };

	var methods = {
		init : function (options) {
			var settings = setSettings(options);

            if (DEBUG) { console.log(this, settings); }

            if (this.length > 0 && this.html() !== '') {
                settings.content = this.html();
                setSettings(settings);
            }

            var modalBG = $('.' + settings.modalHomeBg),
                modal = $('.' + settings.modalHomeDiv);

            if (modalBG.length === 0) {
                modalBG = createBg();
            }
            if (modal.length === 0) {
                modal = createModal();
            }

            // load static html
            if (settings.content.length > 0) {
                settings.immediateDisplay = true;
                populateModal(settings.content);
            }

            $('.' + settings.modalHomeClose).on('click', function () {
                if (DEBUG) { console.log('close click'); }
                modal.trigger(settings.modalHomeCloseEvent);
            });

            if (DEBUG) {console.log('setup events'); }
            // close event
            modal.on(settings.modalHomeCloseEvent, function () {
                if (DEBUG) { console.log(settings.modalHomeCloseEvent + ' event'); }
                hideModal(modal);
                modal.off(settings.modalHomeCloseEvent);
            });
            // open event
            modal.on(settings.modalHomeOpenEvent, function () {
				if (DEBUG) { console.log(settings.modalHomeOpenEvent + ' event'); }
                revealModal(modal);
                modal.off(settings.modalHomeOpenEvent);
            });
            // esc press event
            $('body').on('keyup', function (e) {
                if (e.which === 27) {
                    modal.trigger(settings.modalHomeCloseEvent);
                }
			});
            // bg click close
            $('.' + settings.modalHomeBg).on('click', function () {
                modal.trigger(settings.modalHomeCloseEvent);
            });

            // show immediately
            if (settings.immediateDisplay === true) {
                modal.trigger(settings.modalHomeOpenEvent);
            }

            return { 'modal': modal, 'modalBg': modalBG };
		},
        ajax: function (options) {
            if (DEBUG) { console.log('ajax init'); }
            var container = $.fn.modalHome(options),
                settings = getSettings();

            showLoader();
            container.modal.trigger(settings.modalHomeOpenEvent);

            $.ajax({
                url: options.url
            }).done(function (data) {
                if (DEBUG) { console.log('ajax success', options.success); }
                hideLoader();
                populateModal(data);

                if ($.isFunction(options.success)) {
                    options.success(data);
                }
            }).error(function (data) {
                if (DEBUG) { console.log('ajax failure', data, data.statusCode()); }
                hideLoader();
                populateModal(settings.ajaxFailureContent);

                if ($.isFunction(options.failure)) {
                    options.failure(data);
                }
            });
        },
        hide: function () {
            var settings = getSettings();

            $('.' + settings.modalHomeDiv).trigger(settings.modalHomeCloseEvent);
        }
	};

    // private functions
    var createBg = function () {
        var settings = getSettings();
        return $('body').append('
');
    };

    var createModal = function (content) {
        var settings = getSettings();
        return $('.' + settings.modalHomeBg).before('

' + settings.modalHomeCloseMsg + '

');
    };

    var revealModal = function (modal) {
        var settings = getSettings(),
            scrollTop = parseInt($(document).scrollTop(), 10);
        if (DEBUG) { console.log('reveal'); }

        $('.' + settings.modalHomeBg).show();
        if (DEBUG) { console.log('window top: ', scrollTop, 'top padding: ', settings.modalTopPadding); }
        $('.' + settings.modalHomeDiv).css({top: scrollTop + settings.modalTopPadding});
        $('.' + settings.modalHomeDiv).fadeIn(500);

    };

    var hideModal = function (modal) {
        var settings = getSettings();
        if (DEBUG) { console.log('hide'); }

        $('.' + settings.modalHomeDiv).fadeOut(500);
        $('.' + settings.modalHomeBg).delay(500).hide();
    };

    var populateModal = function (content) {
        var settings = getSettings();
        if (DEBUG) { console.log('populate content', content); }
        $('.' + settings.modalHomeContent).empty();
        $('.' + settings.modalHomeContent).html(content);
    };

    var showLoader = function () {
        var settings = getSettings();

        $('.' + settings.modalHomeContent).hide();
        $('.' + settings.modalHomeLoader).show();

    };

    var hideLoader = function () {
        var settings = getSettings();

        $('.' + settings.modalHomeContent).show();
        $('.' + settings.modalHomeLoader).hide();
    };

	$.fn.modalHome = function (method) {
		var $this = $(this);

		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error('Method ' + method + ' does not exist on jQuery.modalHome');
		}

		return this;
	};
}(jQuery));<commit_msg>Refactoring DOM logic. New elements are created each time now to avoid previous custom settings bleeding over into new windows.<commit_after>/*global $:true,jQuery:true*/
/*jslint debug: true, devel: true, evil: true, vars: true, undef: true */
if (typeof DEBUG === 'undefined') { DEBUG = true; } // removed on uglify
(function ($) {

    // global variables setup
    var globals = {};
	var defaults = {
		'content'           : '',
		'immediateDisplay'  : false,
		'modalTopPadding'   : 75,
		'modalHomeBg'       : 'jhm-modal-bg',
		'modalHomeDiv'      : 'jhm-modal',
		'modalHomeClose'    : 'jhm-modal-close',
		'modalHomeCloseMsg'    : 'x',
		'modalHomeLoader'  : 'jhm-modal-loading',
		'modalHomeContent'  : 'jhm-modal-content',
		'modalHomeOpenEvent'    : 'jhm.modal.open',
		'modalHomeCloseEvent'   : 'jhm.modal.close',
		'ajaxFailureContent'    : 'Failed to load resource'
	};

    var getSettings = function () {
        return globals;
    };

    var setSettings = function (options) {
        globals = $.extend({}, defaults, options);
		if (DEBUG) { console.log("Set Settings: ", defaults, options, globals); }

        return globals;
    };

	var methods = {
		init : function (options) {
			var settings = setSettings(options);

            if (this.length > 0 && this.html() !== '') {
                settings.content = this.html();
                setSettings(settings);
            }

			// init modal DOM objects
            var modalBG = $('.' + settings.modalHomeBg),
                modal = $('.' + settings.modalHomeDiv);

            if (modalBG.length === 0) {
                modalBG = createBg();
            }
            if (modal.length === 0) {
                modal = createModal();
            }

            // load static html
            if (settings.content.length > 0) {
                settings.immediateDisplay = true;
                populateModal(settings.content);
            }

            $('.' + settings.modalHomeClose).on('click', function () {
                if (DEBUG) { console.log('close click'); }
                modal.trigger(settings.modalHomeCloseEvent);
            });

            if (DEBUG) {console.log('setup events'); }
            // close event
            modal.on(settings.modalHomeCloseEvent, function () {
                if (DEBUG) { console.log(settings.modalHomeCloseEvent + ' event'); }
                hideModal(modal);
                modal.off(settings.modalHomeCloseEvent);
            });
            // open event
            modal.on(settings.modalHomeOpenEvent, function () {
				if (DEBUG) { console.log(settings.modalHomeOpenEvent + ' event'); }
                revealModal(modal);
                modal.off(settings.modalHomeOpenEvent);
            });
            // esc press event
            $('body').on('keyup', function (e) {
                if (e.which === 27) {
                    modal.trigger(settings.modalHomeCloseEvent);
                }
			});
            // bg click close
            $('.' + settings.modalHomeBg).on('click', function () {
                modal.trigger(settings.modalHomeCloseEvent);
            });

            // show immediately
            if (settings.immediateDisplay === true) {
                modal.trigger(settings.modalHomeOpenEvent);
            }

            return { 'modal': modal, 'modalBg': modalBG };
		},
        ajax: function (options) {
            if (DEBUG) { console.log('ajax init'); }
            var container = $.fn.modalHome(options),
                settings = getSettings();

            showLoader();
            container.modal.trigger(settings.modalHomeOpenEvent);

            $.ajax({
                url: options.url
            }).done(function (data) {
                if (DEBUG) { console.log('ajax success', options.success); }
                hideLoader();
                populateModal(data);

                if ($.isFunction(options.success)) {
                    options.success(data);
                }
            }).error(function (data) {
                if (DEBUG) { console.log('ajax failure', data, data.statusCode()); }
                hideLoader();
                populateModal(settings.ajaxFailureContent);

                if ($.isFunction(options.failure)) {
                    options.failure(data);
                }
            });
        },
        hide: function () {
            hideModal();
        }
	};

    // private functions
    var createBg = function () {
        var settings = getSettings();
        return $('body').append('
');
    };

    var createModal = function (content) {
        var settings = getSettings();
        return $('.' + settings.modalHomeBg).before('

' + settings.modalHomeCloseMsg + '

');
    };

    var revealModal = function (modal) {
        var settings = getSettings(),
            scrollTop = parseInt($(document).scrollTop(), 10);
        if (DEBUG) { console.log('reveal'); }

        $('.' + settings.modalHomeBg).show();
        if (DEBUG) { console.log('window top: ', scrollTop, 'top padding: ', settings.modalTopPadding); }
        $('.' + settings.modalHomeDiv).css({top: scrollTop + settings.modalTopPadding});
        $('.' + settings.modalHomeDiv).fadeIn(500);

    };

    var hideModal = function (modal) {
        var settings = getSettings();
        if (DEBUG) { console.log('hide'); }

        $('.' + settings.modalHomeDiv).fadeOut(500).remove();
        $('.' + settings.modalHomeBg).delay(500).hide().remove();
    };

    var populateModal = function (content) {
        var settings = getSettings();
        if (DEBUG) { console.log('populate content', content); }
        $('.' + settings.modalHomeContent).empty();
        $('.' + settings.modalHomeContent).html(content);
		$('.' + settings.modalHomeClose).html(settings.modalHomeCloseMsg);
    };

    var showLoader = function () {
        var settings = getSettings();

        $('.' + settings.modalHomeContent).hide();
        $('.' + settings.modalHomeLoader).show();

    };

    var hideLoader = function () {
        var settings = getSettings();

        $('.' + settings.modalHomeContent).show();
        $('.' + settings.modalHomeLoader).hide();
    };

	$.fn.modalHome = function (method) {
		var $this = $(this);

		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error('Method ' + method + ' does not exist on jQuery.modalHome');
		}

		return this;
	};
}(jQuery));<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";

const fs = require("fs");
const path = require("path");
const { spawnSync } = require("child_process");

const libwabt = require("../../build/libwabt.js");

try {
    var V86 = require("../../build/libv86-debug.js").V86;
}
catch(e) {
    console.error(e);
    console.error("Failed to import build/libv86-debug.js. Run " +
                  "`make build/libv86-debug.js` first.");
    process.exit(1);
}

const LOG_LEVEL = 0;

const GIT_DIFF_FLAGS = [ "--no-index", "--patience", "--color=always"];

const TEST_DIR = path.join(__dirname, "tests");
const BUILD_DIR = path.join(TEST_DIR, "build");

function run_all()
{
    const asm_files = fs.readdirSync(TEST_DIR).filter(filename => filename.endsWith(".asm"));

    const files = asm_files.map(asm_file => {
        const name = asm_file.slice(0, -4);
        return {
            name,
            expect_file: path.relative(".", path.join(TEST_DIR, name + ".wast")),
            actual_file: path.relative(".", path.join(BUILD_DIR, name + ".actual.wast")),
            actual_wasm: path.relative(".", path.join(BUILD_DIR, name + ".wasm")),
            asm_file: path.join(TEST_DIR, name + ".asm"),
            executable_file: path.join(BUILD_DIR, name + ".bin"),
        };
    });

    files.forEach(run_test);
}

function run_test({ name, executable_file, expect_file, actual_file, actual_wasm, asm_file })
{
    const emulator = new V86({
        autostart: false,
        memory_size: 2 * 1024 * 1024,
        log_level: LOG_LEVEL,
    });

    const executable = fs.readFileSync(executable_file);
    const asm = fs.readFileSync(asm_file);

    const is_32 = asm.includes("BITS 32\n");

    emulator.add_listener("emulator-loaded", function()
        {
            const cpu = emulator.v86.cpu;

            const hook_not_called_timeout = setTimeout(() => {
                throw new Error("Hook for code generation not called");
            }, 1000);

            cpu.test_hook_did_generate_wasm = function(wasm)
            {
                const wast = disassemble_wasm(wasm);

                clearTimeout(hook_not_called_timeout);
                fs.writeFileSync(actual_file, wast);
                fs.writeFileSync(actual_wasm, wasm);

                cpu.test_hook_did_generate_wasm = function()
                {
                    cpu.test_hook_did_generate_wasm = function() {};
                    throw new Error("Hook for wasm generation called multiple times");
                };

                if(!fs.existsSync(expect_file))
                {
                    // enhanced workflow: If file doesn't exist yet print full diff
                    var expect_file_for_diff = "/dev/null";
                }
                else
                {
                    expect_file_for_diff = expect_file;
                }

                const result = spawnSync("git",
                    [].concat(
                        "diff",
                        GIT_DIFF_FLAGS,
                        expect_file_for_diff,
                        actual_file
                    ),
                    { encoding: "utf8" });

                if(result.status)
                {
                    console.log(result.stdout);
                    console.log(result.stderr);
                    const fail_str = `%s.asm failed:
The code generator produced different code. If you believe this change is intentional,
verify the diff above and run the following command to accept the change:

    cp %s %s

When done, re-run this test to confirm that all expect-tests pass.
`;

                    console.log(fail_str, name, actual_file, expect_file);

                    process.exit(1);
                }
                else
                {
                    console.log("%s ok", name);
                    console.assert(!result.stdout);
                    console.assert(!result.stderr);
                }
            };

            if(is_32)
            {
                cpu.is_32[0] = true;
                cpu.stack_size_32[0] = true;
            }

            const START_ADDRESS = 0x1000;

            cpu.mem8.set(executable, START_ADDRESS);
            cpu.jit_force_generate_unsafe(START_ADDRESS);
        });
}

function disassemble_wasm(wasm)
{
    // Need to make a small copy otherwise libwabt goes nuts trying to copy
    // the whole underlying buffer
    wasm = wasm.slice();

    try
    {
        var module = libwabt.readWasm(wasm, { readDebugNames: false });
        module.generateNames();
        module.applyNames();
        return module.toText({ foldExprs: true, inlineExport: true });
    }
    finally
    {
        module && module.destroy();
    }
}

run_all();
<commit_msg>expect-tests: Improve error message and var name<commit_after>#!/usr/bin/env node
"use strict";

const fs = require("fs");
const path = require("path");
const { spawnSync } = require("child_process");

const libwabt = require("../../build/libwabt.js");

try {
    var V86 = require("../../build/libv86-debug.js").V86;
}
catch(e) {
    console.error(e);
    console.error("Failed to import build/libv86-debug.js. Run " +
                  "`make build/libv86-debug.js` first.");
    process.exit(1);
}

const LOG_LEVEL = 0;

const GIT_DIFF_FLAGS = [ "--no-index", "--patience", "--color=always"];

const TEST_DIR = path.join(__dirname, "tests");
const BUILD_DIR = path.join(TEST_DIR, "build");

function run_all()
{
    const asm_files = fs.readdirSync(TEST_DIR).filter(filename => filename.endsWith(".asm"));

    const files = asm_files.map(asm_file => {
        const name = asm_file.slice(0, -4);
        return {
            name,
            expect_file: path.relative(".", path.join(TEST_DIR, name + ".wast")),
            actual_file: path.relative(".", path.join(BUILD_DIR, name + ".actual.wast")),
            actual_wasm: path.relative(".", path.join(BUILD_DIR, name + ".wasm")),
            asm_file: path.join(TEST_DIR, name + ".asm"),
            executable_file: path.join(BUILD_DIR, name + ".bin"),
        };
    });

    files.forEach(run_test);
}

function run_test({ name, executable_file, expect_file, actual_file, actual_wasm, asm_file })
{
    const emulator = new V86({
        autostart: false,
        memory_size: 2 * 1024 * 1024,
        log_level: LOG_LEVEL,
    });

    const executable = fs.readFileSync(executable_file);
    const asm = fs.readFileSync(asm_file);

    const is_32 = asm.includes("BITS 32\n");

    emulator.add_listener("emulator-loaded", function()
        {
            const cpu = emulator.v86.cpu;

            const hook_not_called_timeout = setTimeout(() => {
                throw new Error("Hook for code generation not called");
            }, 1000);

            cpu.test_hook_did_generate_wasm = function(wasm)
            {
                const wast = disassemble_wasm(wasm);

                clearTimeout(hook_not_called_timeout);
                fs.writeFileSync(actual_file, wast);
                fs.writeFileSync(actual_wasm, wasm);

                cpu.test_hook_did_generate_wasm = function()
                {
                    cpu.test_hook_did_generate_wasm = function() {};
                    throw new Error("Hook for wasm generation called multiple times");
                };

                if(!fs.existsSync(expect_file))
                {
                    // enhanced workflow: If file doesn't exist yet print full diff
                    var expect_file_for_diff = "/dev/null";
                }
                else
                {
                    expect_file_for_diff = expect_file;
                }

                const result = spawnSync("git",
                    [].concat(
                        "diff",
                        GIT_DIFF_FLAGS,
                        expect_file_for_diff,
                        actual_file
                    ),
                    { encoding: "utf8" });

                if(result.status)
                {
                    console.log(result.stdout);
                    console.log(result.stderr);
                    const failure_message = `${name}.asm failed:
The code generator produced different code. If you believe this change is intentional,
verify the diff above and run the following command to accept the change:

    cp ${actual_file} ${expect_file}

When done, re-run this test to confirm that all expect-tests pass.
`;

                    console.log(failure_message);

                    process.exit(1);
                }
                else
                {
                    console.log("%s ok", name);
                    console.assert(!result.stdout);
                    console.assert(!result.stderr);
                }
            };

            if(is_32)
            {
                cpu.is_32[0] = true;
                cpu.stack_size_32[0] = true;
            }

            const START_ADDRESS = 0x1000;

            cpu.mem8.set(executable, START_ADDRESS);
            cpu.jit_force_generate_unsafe(START_ADDRESS);
        });
}

function disassemble_wasm(wasm)
{
    // Need to make a small copy otherwise libwabt goes nuts trying to copy
    // the whole underlying buffer
    wasm = wasm.slice();

    try
    {
        var module = libwabt.readWasm(wasm, { readDebugNames: false });
        module.generateNames();
        module.applyNames();
        return module.toText({ foldExprs: true, inlineExport: true });
    }
    finally
    {
        module && module.destroy();
    }
}

run_all();
<|endoftext|>