<commit_before>describe("CukeSniffer", function(){
    beforeEach(function(){
        CukeSniffer.init();
        $.fx.off = true;
        loadFixtures("complex_report.html.erb");
    });
    afterEach(function(){
        $(document).off("click", "[expand]");
        $(document).off("click", "[collapse]");
        $(document).off("click", ".panel-title");
        $(document).off("click", "#rulesTab");
        $(document).off("click", ".rule");
        $(document).off("click", ".rule :checkbox");
        $(document).off("click", "#ruleFilters .btn");
        $(document).off("click", ".deadStep > .row > .title," +
            " .feature > .row > .title, " +
            ".stepDefinition > .row > .title, " +
            ".hook .title");
        $(document).off("click", "#enableAllRules");
        $(document).off("click", "#disableAllRules");
        $(document).off("click", ".rule input[type='checkbox']");
    });
    describe("Rules", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all rules", function(){
                $("[expand]").click()
                expect($(".rule .details")).toBeVisible();
            });
            it("clicking collapse all hides all rules", function(){
                $("[expand]").click()
                expect($(".rule .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".rule .details")).not.toBeVisible();
            });
            it("clicking a rules expands its details", function(){
                var $rule = $(".rule:eq(0)");
                $rule.find("div:has([data-phrase])").click();
                expect($rule.find(".details")).toBeVisible();
            });
            it("clicking the checkbox for a rule does not expand it's details", function(){
                var $rule = $(".rule:eq(0)");
                $rule.find(":checkbox").click();
                expect($rule.find(".details")).not.toBeVisible();
            });
            it("clicking a rules again collapses its details", function(){
                var $rule = $(".rule:eq(0)");
                $rule.find("div:has([data-phrase])").click();
                expect($rule.find(".details")).toBeVisible();
                $rule.find("div:has([data-phrase])").click();
                expect($rule.find(".details")).not.toBeVisible();
            });
        });

        describe("filtering the rules", function(){
            describe("feature filter", function(){
                it("hides all feature only rules when unchecked", function(){
                    var $featureFilter = $(".btn:has([data-rule-type='feature'])")
                    $featureFilter.click();
                    expect($("[rule-feature]:not([rule-scenario], [rule-background])")).toBeHidden();
                    expect($("[rule-feature][rule-scenario]")).toBeVisible();
                    expect($("[rule-feature][rule-background]")).toBeVisible();
                });
                it("shows all feature rules when checked", function(){
                    var $featureFilter = $(".btn:has([data-rule-type='feature'])")
                    $featureFilter.click();
                    expect($("[rule-feature]:not([rule-scenario], [rule-background])")).toBeHidden();
                    $featureFilter.click();
                    expect($("[rule-feature]:not([rule-scenario], [rule-background])")).toBeVisible();
                });
            });
            describe("background filter", function(){
                it("hides all background only rules when unchecked", function(){
                    var $backgroundFilter = $(".btn:has([data-rule-type='background'])")
                    $backgroundFilter.click();
                    expect($("[rule-background]:not([rule-scenario], [rule-feature])")).toBeHidden();
                    expect($("[rule-background][rule-scenario]")).toBeVisible();
                    expect($("[rule-background][rule-feature]")).toBeVisible();
                });
                it("shows all background rules when checked", function(){
                    var $backgroundFilter = $(".btn:has([data-rule-type='background'])")
                    $backgroundFilter.click();
                    expect($("[rule-background]:not([rule-scenario], [rule-feature])")).toBeHidden();
                    $backgroundFilter.click();
                    expect($("[rule-background]:not([rule-scenario], [rule-feature])")).toBeVisible();
                });
            });
            describe("scenario filter", function(){
                it("hides all scenario only rules when unchecked", function(){
                    var $scenarioFilter = $(".btn:has([data-rule-type='scenario'])")
                    $scenarioFilter.click();
                    expect($("[rule-scenario]:not([rule-background], [rule-feature])")).toBeHidden();
                    expect($("[rule-scenario][rule-background]")).toBeVisible();
                    expect($("[rule-scenario][rule-feature]")).toBeVisible();
                });
                it("shows all scenario rules when checked", function(){
                    var $scenarioFilter = $(".btn:has([data-rule-type='scenario'])")
                    $scenarioFilter.click();
                    expect($("[rule-scenario]:not([rule-background], [rule-feature])")).toBeHidden();
                    $scenarioFilter.click();
                    expect($("[rule-scenario]:not([rule-background], [rule-feature])")).toBeVisible();
                });
            });
            describe("step definition filter", function(){
                it("hides all step definition only rules when unchecked", function(){
                    var $stepDefinitionFilter = $(".btn:has([data-rule-type='stepdefinition'])")
                    $stepDefinitionFilter.click();
                    expect($("[rule-stepdefinition]")).toBeHidden();
                });
                it("shows all step definition rules when checked", function(){
                    var $stepDefinitionFilter = $(".btn:has([data-rule-type='stepdefinition'])")
                    $stepDefinitionFilter.click();
                    expect($("[rule-stepdefinition]")).toBeHidden();
                    $stepDefinitionFilter.click();
                    expect($("[rule-stepdefinition]")).toBeVisible();
                });
            });
            describe("hook filter", function(){
                it("hides all hook only rules when unchecked", function(){
                    var $hookFilter = $(".btn:has([data-rule-type='hook'])")
                    $hookFilter.click();
                    expect($("[rule-hook]")).toBeHidden();
                });
                it("shows all hook rules when checked", function(){
                    var $hookFilter = $(".btn:has([data-rule-type='hook'])")
                    $hookFilter.click();
                    expect($("[rule-hook]")).toBeHidden();
                    $hookFilter.click();
                    expect($("[rule-hook]")).toBeVisible();
                });
            });
        })
    });
    describe("Dead Step Definitions", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all dead step", function(){
                $("[expand]").click()
                expect($(".deadStep > .row > .details")).toBeVisible();
            });
            it("clicking collapse all hides all dead step", function(){
                $("[expand]").click()
                expect($(".deadStep > .row > .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".deadStep > .row > .details")).not.toBeVisible();
            });
            it("clicking a dead step expands its details", function(){
                var $deadStep = $(".deadStep:eq(0)");
                $deadStep.find("> .row > .title").click();
                expect($deadStep.find("> .row > .details")).toBeVisible();
            });
            it("clicking a dead step again collapses its details", function(){
                var $deadStep = $(".deadStep:eq(0)");
                $deadStep.find("> .row > .title").click();
                expect($deadStep.find(".details")).toBeVisible();
                $deadStep.find("> .row > .title").click();
                expect($deadStep.find(".details")).not.toBeVisible();
            });
        });
    });
    describe("Features", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all features", function(){
                $("[expand]").click()
                expect($(".feature > .row > .details")).toBeVisible();
            });
            it("clicking collapse all hides all features", function(){
                $("[expand]").click()
                expect($(".feature > .row > .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".feature > .row > .details")).not.toBeVisible();
            });
            it("clicking a feature expands its details", function(){
                var $feature = $(".feature:eq(0)");
                $feature.find("> .row > .title").click();
                expect($feature.find("> .row > .details")).toBeVisible();
            });
            it("clicking a feature again collapses its details", function(){
                var $feature = $(".feature:eq(0)");
                $feature.find("> .row > .title").click();
                expect($feature.find(".details")).toBeVisible();
                $feature.find("> .row > .title").click();
                expect($feature.find(".details")).not.toBeVisible();
            });
        });
    });
    describe("Step Definitions", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all step definitions", function(){
                $("[expand]").click()
                expect($(".stepDefinition > .row > .details")).toBeVisible();
            });
            it("clicking collapse all hides all step definitions", function(){
                $("[expand]").click()
                expect($(".stepDefinition > .row > .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".stepDefinition > .row > .details")).not.toBeVisible();
            });
            it("clicking a step definitions expands its details", function(){
                var $stepDefinition = $(".stepDefinition:eq(0)");
                $stepDefinition.find("> .row > .title").click();
                expect($stepDefinition.find("> .row > .details")).toBeVisible();
            });
            it("clicking a step definitions again collapses its details", function(){
                var $stepDefinition = $(".stepDefinition:eq(0)");
                $stepDefinition.find("> .row > .title").click();
                expect($stepDefinition.find(".details")).toBeVisible();
                $stepDefinition.find("> .row > .title").click();
                expect($stepDefinition.find(".details")).not.toBeVisible();
            });
        });
    });
    describe("Hooks", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all hooks", function(){
                $("[expand]").click()
                expect($(".hook .details")).toBeVisible();
            });
            it("clicking collapse all hides all hooks", function(){
                $("[expand]").click()
                expect($(".hook .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".hook .details")).not.toBeVisible();
            });
            it("clicking a hook expands its details", function(){
                var $hook = $(".hook:eq(0)");
                $hook.find(".title").click();
                expect($hook.find(".details")).toBeVisible();
            });
            it("clicking a hook again collapses its details", function(){
                var $hook = $(".hook:eq(0)");
                $hook.find(".title").click();
                expect($hook.find(".details")).toBeVisible();
                $hook.find(".title").click();
                expect($hook.find(".details")).not.toBeVisible();
            });
        });
    });
});<commit_msg>stubbed out specs for new filter expansion and the disabling/enabling of rules<commit_after>describe("CukeSniffer", function(){
    beforeEach(function(){
        CukeSniffer.init();
        $.fx.off = true;
        loadFixtures("complex_report.html.erb");
    });
    afterEach(function(){
        $(document).off("click", "[expand]");
        $(document).off("click", "[collapse]");
        $(document).off("click", ".panel-title");
        $(document).off("click", "#rulesTab");
        $(document).off("click", ".rule");
        $(document).off("click", ".rule :checkbox");
        $(document).off("click", "#ruleFilters .btn");
        $(document).off("click", ".deadStep > .row > .title," +
            " .feature > .row > .title, " +
            ".stepDefinition > .row > .title, " +
            ".hook .title");
        $(document).off("click", "#enableAllRules");
        $(document).off("click", "#disableAllRules");
        $(document).off("click", ".rule input[type='checkbox']");
    });
    describe("Rules", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all rules", function(){
                $("[expand]").click()
                expect($(".rule .details")).toBeVisible();
            });
            it("clicking collapse all hides all rules", function(){
                $("[expand]").click()
                expect($(".rule .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".rule .details")).not.toBeVisible();
            });
            it("clicking a rules expands its details", function(){
                var $rule = $(".rule:eq(0)");
                $rule.find("div:has([data-phrase])").click();
                expect($rule.find(".details")).toBeVisible();
            });
            it("clicking the checkbox for a rule does not expand it's details", function(){
                var $rule = $(".rule:eq(0)");
                $rule.find(":checkbox").click();
                expect($rule.find(".details")).not.toBeVisible();
            });
            it("clicking a rules again collapses its details", function(){
                var $rule = $(".rule:eq(0)");
                $rule.find("div:has([data-phrase])").click();
                expect($rule.find(".details")).toBeVisible();
                $rule.find("div:has([data-phrase])").click();
                expect($rule.find(".details")).not.toBeVisible();
            });
        });

        describe("filtering the rules", function(){
            describe("by type", function(){
                describe("feature filter", function(){
                    it("hides all feature only rules when unchecked", function(){
                        var $featureFilter = $(".btn:has([data-rule-type='feature'])")
                        $featureFilter.click();
                        expect($("[rule-feature]:not([rule-scenario], [rule-background])")).toBeHidden();
                        expect($("[rule-feature][rule-scenario]")).toBeVisible();
                        expect($("[rule-feature][rule-background]")).toBeVisible();
                    });
                    it("shows all feature rules when checked", function(){
                        var $featureFilter = $(".btn:has([data-rule-type='feature'])")
                        $featureFilter.click();
                        expect($("[rule-feature]:not([rule-scenario], [rule-background])")).toBeHidden();
                        $featureFilter.click();
                        expect($("[rule-feature]:not([rule-scenario], [rule-background])")).toBeVisible();
                    });
                });
                describe("background filter", function(){
                    it("hides all background only rules when unchecked", function(){
                        var $backgroundFilter = $(".btn:has([data-rule-type='background'])")
                        $backgroundFilter.click();
                        expect($("[rule-background]:not([rule-scenario], [rule-feature])")).toBeHidden();
                        expect($("[rule-background][rule-scenario]")).toBeVisible();
                        expect($("[rule-background][rule-feature]")).toBeVisible();
                    });
                    it("shows all background rules when checked", function(){
                        var $backgroundFilter = $(".btn:has([data-rule-type='background'])")
                        $backgroundFilter.click();
                        expect($("[rule-background]:not([rule-scenario], [rule-feature])")).toBeHidden();
                        $backgroundFilter.click();
                        expect($("[rule-background]:not([rule-scenario], [rule-feature])")).toBeVisible();
                    });
                });
                describe("scenario filter", function(){
                    it("hides all scenario only rules when unchecked", function(){
                        var $scenarioFilter = $(".btn:has([data-rule-type='scenario'])")
                        $scenarioFilter.click();
                        expect($("[rule-scenario]:not([rule-background], [rule-feature])")).toBeHidden();
                        expect($("[rule-scenario][rule-background]")).toBeVisible();
                        expect($("[rule-scenario][rule-feature]")).toBeVisible();
                    });
                    it("shows all scenario rules when checked", function(){
                        var $scenarioFilter = $(".btn:has([data-rule-type='scenario'])")
                        $scenarioFilter.click();
                        expect($("[rule-scenario]:not([rule-background], [rule-feature])")).toBeHidden();
                        $scenarioFilter.click();
                        expect($("[rule-scenario]:not([rule-background], [rule-feature])")).toBeVisible();
                    });
                });
                describe("step definition filter", function(){
                    it("hides all step definition only rules when unchecked", function(){
                        var $stepDefinitionFilter = $(".btn:has([data-rule-type='stepdefinition'])")
                        $stepDefinitionFilter.click();
                        expect($("[rule-stepdefinition]")).toBeHidden();
                    });
                    it("shows all step definition rules when checked", function(){
                        var $stepDefinitionFilter = $(".btn:has([data-rule-type='stepdefinition'])")
                        $stepDefinitionFilter.click();
                        expect($("[rule-stepdefinition]")).toBeHidden();
                        $stepDefinitionFilter.click();
                        expect($("[rule-stepdefinition]")).toBeVisible();
                    });
                });
                describe("hook filter", function(){
                    it("hides all hook only rules when unchecked", function(){
                        var $hookFilter = $(".btn:has([data-rule-type='hook'])")
                        $hookFilter.click();
                        expect($("[rule-hook]")).toBeHidden();
                    });
                    it("shows all hook rules when checked", function(){
                        var $hookFilter = $(".btn:has([data-rule-type='hook'])")
                        $hookFilter.click();
                        expect($("[rule-hook]")).toBeHidden();
                        $hookFilter.click();
                        expect($("[rule-hook]")).toBeVisible();
                    });
                });
                it("remembers the type filter status as a cookie", function(){

                });
            });
            describe("by severity", function(){
                describe("info filter", function(){
                    it("hides all info level rules when unchecked", function(){

                    });
                    it("shows all info level rules when checked", function(){

                    });
                });
                describe("warning filter", function(){
                    it("hides all warning level rules when unchecked", function(){

                    });
                    it("shows all warning level rules when checked", function(){

                    });
                });
                describe("error filter", function(){
                    it("hides all error level rules when unchecked", function(){

                    });
                    it("shows all error level rules when checked", function(){

                    });
                });
                describe("fatal filter", function(){
                    it("hides all fatal level rules when unchecked", function(){

                    });
                    it("shows all fatal level rules when checked", function(){

                    });
                });
                it("remembers the severity filter status as a cookie", function(){

                });
            });
            describe("by text", function(){
                it("will filter the rules description on a keypress", function(){

                });
                it("will filter the rules details on a keypress", function(){

                });
                it("will clear the search when the input is cleared", function(){

                });
            });
        });

        describe("toggling rules", function(){
            describe("features section", function(){
                describe("disabling", function(){
                    it("will hide feature rules when uncheck unchecked", function(){

                    });

                    it("will hide background rules when unchecked", function(){

                    });

                    it("will hide the background section when its last rule is disabled", function() {

                    });

                    it("will hide scenario rules when unchecked", function(){

                    });

                    it("will hide the scenario section when its last rule is disabled", function() {

                    });

                    it("will hide the scenarios section when the last scenario is hidden due to disabled rules", function(){

                    });

                    it("will hide the feature row when there are no active rules being shown for the feature, background, or scenarios", function(){

                    });
                });
                describe("enabling", function(){
                    it("does nothing when a rule checkbox is disabled due to report generation configuration", function(){

                    });
                    it("shows a feature row when a feature rule is enabled and no other rules apply", function(){

                    });
                    it("shows a feature row when a background rule is enabled and no other rules apply", function(){

                    });
                    it("shows a feature row when a scenario rule is enabled and no other rules apply", function(){

                    });
                });
            });
            describe("step definitions section", function(){
                describe("disabling", function(){
                    it("hides a step definition rule when its rule is disabled", function(){

                    });
                    it("hides the step definition row when its last rule is disabled", function(){

                    });
                });
                describe("enabling", function(){
                    it("shows a step definition rule when its rule is enabled", function(){

                    });
                    it("shows the step definition row when its first rule is enabled", function(){

                    });
                });
            });
            describe("hooks section", function(){
                describe("disabling", function(){
                    it("hides a hook rule when its rule is disabled", function(){

                    });
                    it("hides the hook row when its last rule is disabled", function(){

                    });
                });
                describe("enabling", function(){
                    it("shows a hook rule when its rule is enabled", function(){

                    });
                    it("shows the hook row when its first rule is enabled", function(){

                    });
                });
            });
            it("remembers the disabled rules as a cookie", function(){

            });
        })
    });
    describe("Dead Step Definitions", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all dead step", function(){
                $("[expand]").click()
                expect($(".deadStep > .row > .details")).toBeVisible();
            });
            it("clicking collapse all hides all dead step", function(){
                $("[expand]").click()
                expect($(".deadStep > .row > .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".deadStep > .row > .details")).not.toBeVisible();
            });
            it("clicking a dead step expands its details", function(){
                var $deadStep = $(".deadStep:eq(0)");
                $deadStep.find("> .row > .title").click();
                expect($deadStep.find("> .row > .details")).toBeVisible();
            });
            it("clicking a dead step again collapses its details", function(){
                var $deadStep = $(".deadStep:eq(0)");
                $deadStep.find("> .row > .title").click();
                expect($deadStep.find(".details")).toBeVisible();
                $deadStep.find("> .row > .title").click();
                expect($deadStep.find(".details")).not.toBeVisible();
            });
        });
    });
    describe("Features", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all features", function(){
                $("[expand]").click()
                expect($(".feature > .row > .details")).toBeVisible();
            });
            it("clicking collapse all hides all features", function(){
                $("[expand]").click()
                expect($(".feature > .row > .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".feature > .row > .details")).not.toBeVisible();
            });
            it("clicking a feature expands its details", function(){
                var $feature = $(".feature:eq(0)");
                $feature.find("> .row > .title").click();
                expect($feature.find("> .row > .details")).toBeVisible();
            });
            it("clicking a feature again collapses its details", function(){
                var $feature = $(".feature:eq(0)");
                $feature.find("> .row > .title").click();
                expect($feature.find(".details")).toBeVisible();
                $feature.find("> .row > .title").click();
                expect($feature.find(".details")).not.toBeVisible();
            });
        });
    });
    describe("Step Definitions", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all step definitions", function(){
                $("[expand]").click()
                expect($(".stepDefinition > .row > .details")).toBeVisible();
            });
            it("clicking collapse all hides all step definitions", function(){
                $("[expand]").click()
                expect($(".stepDefinition > .row > .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".stepDefinition > .row > .details")).not.toBeVisible();
            });
            it("clicking a step definitions expands its details", function(){
                var $stepDefinition = $(".stepDefinition:eq(0)");
                $stepDefinition.find("> .row > .title").click();
                expect($stepDefinition.find("> .row > .details")).toBeVisible();
            });
            it("clicking a step definitions again collapses its details", function(){
                var $stepDefinition = $(".stepDefinition:eq(0)");
                $stepDefinition.find("> .row > .title").click();
                expect($stepDefinition.find(".details")).toBeVisible();
                $stepDefinition.find("> .row > .title").click();
                expect($stepDefinition.find(".details")).not.toBeVisible();
            });
        });
    });
    describe("Hooks", function(){
        describe("collapsing/expanding", function(){
            it("clicking expand all shows all hooks", function(){
                $("[expand]").click()
                expect($(".hook .details")).toBeVisible();
            });
            it("clicking collapse all hides all hooks", function(){
                $("[expand]").click()
                expect($(".hook .details")).toBeVisible();
                $("[collapse]").click()
                expect($(".hook .details")).not.toBeVisible();
            });
            it("clicking a hook expands its details", function(){
                var $hook = $(".hook:eq(0)");
                $hook.find(".title").click();
                expect($hook.find(".details")).toBeVisible();
            });
            it("clicking a hook again collapses its details", function(){
                var $hook = $(".hook:eq(0)");
                $hook.find(".title").click();
                expect($hook.find(".details")).toBeVisible();
                $hook.find(".title").click();
                expect($hook.find(".details")).not.toBeVisible();
            });
        });
    });
});<|endoftext|>


<commit_before>// EaselJS
var canvas, stage;

// GAME INFO
var questions = [];
var answers = [];
var currentAnswer; // Note: This is an object, to access the answer value use currentAnswer.answer
// Score
var BASE_GAIN = 10; // Minimum point gain on correct answer
var score = 0;
// Lives
var MAX_LIVES = 5;
var livesRemaining = MAX_LIVES;
// Time
var MAX_TIME = 20000; // 20 Seconds
var remainingTime = MAX_TIME;
var startTime;

// Layers
var foregroundLayer = new createjs.Container();
var backgroundLayer = new createjs.Container(); // Only contains questions
// DisplayObjects
var scoreDisplay;
var timerDisplay;
var livesDisplay;

var sfxEnabled; // Determined by loadSfx()

function init() {
    // Stage info
    canvas = document.getElementById("canvas");
    fullScreenCanvas(canvas);           // Sets width and height to fill screen
    stage = new createjs.Stage(canvas); // Creates a EaselJS Stage for drawing
    // Detection
    stage.enableMouseOver();    // TODO: Remove this later (change with touch or something?)

    // Initialize global variables for layout and sizing
    initializeVariables(canvas.width, canvas.height);

    console.log(layout.QUES_WIDTH);
    console.log(480);

    // Audio:
    // TODO: sfx and bgm

    // Initialization:
    // Add layers
    stage.addChild(backgroundLayer, foregroundLayer);
    // Timer stuff
    startTime = new Date().getTime();
    timerDisplay = foregroundLayer.addChild(new Timer());
    // Score stuff
    scoreDisplay = foregroundLayer.addChild(new Score());
    // Lives stuff
    livesDisplay = foregroundLayer.addChild(new Lives());

    initializeAnswers();
    initializeQuestions();

    updateCurrentAnswer();
    initializeAnswerPositions();
    initializeQuestionPositions();

    // Looper
    createjs.Ticker.setFPS(60);
    // Handles all the update logic
    createjs.Ticker.on("tick", handleTick);

    console.log(stage.children.length);
}

function handleTick(event) {
    if (!event.paused) {
        // Update (kinda)
        updateTimeRemaining();
        // Render
        stage.update();
    }
}

function updateTimeRemaining(){
    var currentTime = new Date().getTime();
    var elapsedTime = currentTime - startTime;
    // Update time left
    remainingTime = MAX_TIME - elapsedTime;

    // Check if question fail
    if (remainingTime < 0) {
        remainingTime = 0; // Might be unnecessary
        answerIncorrect();
    } else {
        // TODO: Nothing, or maybe something?
    }

    // Format to two decimal places (rounds too)
    var formattedTime = (remainingTime / 1000).toFixed(2);
    // Display the time left
    timerDisplay.txt.text = formattedTime;
}

//use this function when question is correct
function increaseScore(){
    score += Math.round(BASE_GAIN + (Math.round(remainingTime) /10000)) * 10;
    // TODO: Update the score
    scoreDisplay.txt.text = score;
}

// AUDIO
function correctSfx() {
    var sfx = new Audio("sound/hitsound1.wav"); // buffers automatically when created
    sfx.play();
}

function incorrectSfx() {
    var sfx = new Audio("sound/miss.mp3");
    sfx.play();
}

function buttonSound() {
    var sound = new Audio("sound/hitsound2.wav");
    sound.play();
}

function loadBgmSound() {
    var bgm = new Audio("sound/game_bgm.wav");
    bgm.loop = true;

    if (localStorage.getItem("bgm-muted") == "true") {
        bgm.pause();
    } else {
        bgm.play();
    }
}

function loadSfxSound() {
    if (localStorage.getItem("sfx-muted") == "true") {
        sfxEnabled = false;
    } else {
        sfxEnabled = true;
    }
}

// INITIALIZERS
// TODO: Fix this once generateAnswers is done
function initializeAnswers() {
    for (i = 0; i < 5; i++) {
        var nextAnswer = generateNextAnswer();
        nextAnswer.index = i; // We need the index so we can replace them properly
        answers.push(nextAnswer);
    }
}

function initializeQuestions() {
    for (i = 0; i < 3; i++) {
        questions.push(generateNextQuestion());
    }
}

// GAME LOGIC
// Creates the next answer
function generateNextAnswer() {
    var randInt;
    // Loop until there is no overlap
    outer:
        while (true) {
            // Get the new value
            randInt = getRandomInt(1, 20);

            // Check if it exists already
            for (j = 0; j < answers.length; j++) {
                var something = answers[j].answer;
                if (something == randInt) {
                    continue outer; // Yes - retry
                }
            }
            // No - return the value
            break;
        }
        // Create the next answer

    // Finalize setup
    var nextAnswer = foregroundLayer.addChild(new Answer(randInt)); // Create the actual object
    if (currentAnswer != null) {
        nextAnswer.index = currentAnswer.index; // Pass on parent index
        nextAnswer.x = currentAnswer.x;         // Pass on parent position
    }
    // Return the displayObject
    return nextAnswer;
}

// Gathers are all the necessary info before generating the next answer
function prepareNextQuestion() {
    // Obtain information about the current board
    var availableArray = [];
    // Note: foreach loop not working very well
    for (a=0; a<answers.length; a++) {
        if (answers[a].available == true) {
            availableArray.push(answers[a]);
        }
    }

    // Select one of the avaiable numbers
    var randAvailable = availableArray[getRandomInt(0, availableArray.length - 1)];
    // Toggle availibility off
    randAvailable.available = false;
    // Retrieve the answer
    return randAvailable.answer;
}

function generateNextQuestion() {

    var answer = prepareNextQuestion();

    var question;

    var randNum = getRandomInt(1, 4);
    switch (randNum) {
        case 1:
            question = generateSum(answer);
            break;
        case 2:
            question = generateMinus(answer);
            break;
        case 3:
            question = generateMultiplication(answer);
            break;
        case 4:
            question = generateDivision(answer);
            break;
        default:
            console.log("something went wrong with generateNextQuestion()");
            break;
    }

    // Return the display object
    return backgroundLayer.addChild(question);
}

function generateSum(answer) {
    var numA = getRandomInt(1, 10);
    // using numbers between 1 and 10 for now
    while (answer <= numA) {
        numA = getRandomInt(1, 10);
    }
    var numB = answer - numA;
    var question = new Question(numA, "+", numB, answer);
    return question;
}
function generateMinus(answer) {
    do {
        // Has to be 21 or it might loop infintely
        numA = getRandomInt(1, 21);
    } while (numA <= answer)

    var numB = numA - answer;
    var question = new Question(numA, "-", numB, answer);
    return question;
}
function generateMultiplication(answer) {
    do{
        var numA = getRandomInt(1,10);
    }while(answer%numA != 0)

    var numB = answer / numA;
    var question = new Question(numA, "*", numB, answer);
    return question;
}
function generateDivision(answer) {
    var numA = getRandomInt(1, 10);
    var numB = answer * numA;
    var question = new Question(numB, "/", numA, answer);
    return question;
}

// Move all objects up one position (overwritting the first)
function advanceRows(newQuestion) {
    // Animations: (Individually animate each one)
    // Bottom question
    createjs.Tween.get(questions[0])
        .to({ y:(questions[0].y + layout.QUES_HEIGHT), alpha: 0 }, 300, createjs.Ease.linear)
        .call( function() {
            this.visible = false;
        });
    // Next question
    createjs.Tween.get(questions[1])
        .to({ y:(questions[1].y + layout.QUES_HEIGHT), scaleY: 1.66 }, 300, createjs.Ease.linear); // Advance position
    createjs.Tween.get(questions[1].getChildAt(1))
        .to({ scaleX: 1.66 }, 300, createjs.Ease.linear); // Enlarge text (scaleY taken care above)
    // Last question
    createjs.Tween.get(questions[2])
        .to({ y:(questions[2].y + layout.QUES_HEIGHT) }, 300, createjs.Ease.linear);
    // New question
    createjs.Tween.get(newQuestion)
        .to({ y:layout.MID1}, 300, createjs.Ease.linear);

    // Advance the questions internally
    questions[0] = questions[1];
    questions[1] = questions[2];
    questions[2] = newQuestion
}

function advanceAnswers(nextAnswer) {
    // Animations:
    // Current answer
    createjs.Tween.get(currentAnswer)
        .to({ alpha: 0, scaleX: 0.6, scaleY: 0.6}, 200, createjs.Ease.linear)
        .call( function() { this.visible = false });
    // Next answer
    nextAnswer.alpha = 0;       // Start invisible
    nextAnswer.scaleX = 1.2;    // Start large
    nextAnswer.scaleY = 1.2;
    createjs.Tween.get(nextAnswer)
        .to({}, 100, createjs.Ease.linear)
        .to({ alpha: 1, scaleX: 1, scaleY: 1 }, 300, createjs.Ease.linear);

    // Advance (replace) the answer internally
    answers[nextAnswer.index] = nextAnswer; // Replace parent
}

// Answer checking
function checkAnswer(answer) {
    return (answer == questions[0].answer);
}

function answerCorrect() {
    // GAME-LOGIC(?)
    increaseScore();                        // Update the score
    startTime = new Date().getTime();       // Reset the time (Set the time stamp to now)

    // GAME-FUNCTIONS
    advanceAnswers(generateNextAnswer());   // Create the next answer, animate, and setup
    advanceRows(generateNextQuestion());    // Create the next question, animate, and setup
    updateCurrentAnswer();
}

function answerIncorrect() {
    // GAME-LOGIC(?)
    // Update lives
    livesRemaining--;
    livesDisplay.txt.text = livesRemaining;
    // Reset the time
    startTime = new Date().getTime();

    // GAME-FUNCTIONS
    advanceAnswers(generateNextAnswer());   // Create the next answer, animate, and setup
    advanceRows(generateNextQuestion());    // Create the next question, animate, and setup
    updateCurrentAnswer();

    // Check if user lost
    if (livesRemaining <= 0) {
        gameOver();
    }
}

function gameOver() {
    console.log("gameOver() called");
    // Pause the game
    createjs.Ticker.paused = true;
    // Show user's score
    $('#instance-score').text("Score: " + score);
    // Show the dialog
    $.mobile.changePage("#score-dialog", { role: "dialog" });
}

// Sets the currentAnswer to the answer object for the bottom most question.
function updateCurrentAnswer() {
    for (a = 0; a < answers.length; a++) {
        if (checkAnswer(answers[a].answer)) {
            currentAnswer = answers[a];
        }
    }
}

// POSITIONING
function initializeQuestionPositions() {
    for (q=0; q<3; q++) {
        switch (q) {
            case 0:
                questions[q].y = layout.MID3; // Lowest
                break;
            case 1:
                questions[q].y = layout.MID2;
                break;
            case 2:
                questions[q].y = layout.MID1; // Most upper
                break;
            default:
                console.log("Something went wrong with loadQuestions()");
                break;
        }
        console.log("Ques x: " + questions[q].x + " y: " + questions[q].y );
    }
}

function initializeAnswerPositions() {
    for (a = 0; a < 5; a++) {
        // x and y of the CENTER of the container. (not top left)
        answers[a].x = (layout.ANS_SIZE / 2) + (a)*(layout.ANS_SIZE);

        console.log("Ans x: " + answers[a].x + " y: " + answers[a].y);
    }
}<commit_msg>Initial sizing is now right. Minor bug fixes / code clean-up<commit_after>// EaselJS
var canvas, stage;

// GAME INFO
var questions = [];
var answers = [];
var currentAnswer; // Note: This is an object, to access the answer value use currentAnswer.answer
// Score
var BASE_GAIN = 10; // Minimum point gain on correct answer
var score = 0;
// Lives
var MAX_LIVES = 5;
var livesRemaining = MAX_LIVES;
// Time
var MAX_TIME = 20000; // 20 Seconds
var remainingTime = MAX_TIME;
var startTime;

// Layers
var foregroundLayer = new createjs.Container();
var backgroundLayer = new createjs.Container(); // Only contains questions
// DisplayObjects
var scoreDisplay;
var timerDisplay;
var livesDisplay;

var sfxEnabled; // Determined by loadSfx()

function init() {
    // Stage info
    canvas = document.getElementById("canvas");
    fullScreenCanvas(canvas);           // Sets width and height to fill screen
    stage = new createjs.Stage(canvas); // Creates a EaselJS Stage for drawing
    // Detection
    stage.enableMouseOver();    // TODO: Remove this later (change with touch or something?)

    // Initialize global variables for layout and sizing
    initializeVariables(canvas.width, canvas.height);

    console.log(layout.QUES_WIDTH);
    console.log(480);

    // Audio:
    // TODO: sfx and bgm

    // Initialization:
    // Add layers
    stage.addChild(backgroundLayer, foregroundLayer);
    // Timer stuff
    startTime = new Date().getTime();
    timerDisplay = foregroundLayer.addChild(new Timer());
    // Score stuff
    scoreDisplay = foregroundLayer.addChild(new Score());
    // Lives stuff
    livesDisplay = foregroundLayer.addChild(new Lives());

    initializeAnswers();
    initializeQuestions();

    updateCurrentAnswer();
    initializeAnswerPositions();
    initializeQuestionPositions();

    // Looper
    createjs.Ticker.setFPS(60);
    // Handles all the update logic
    createjs.Ticker.on("tick", handleTick);

    console.log(stage.children.length);
}

function handleTick(event) {
    if (!event.paused) {
        // Update (kinda)
        updateTimeRemaining();
        // Render
        stage.update();
    }
}

function updateTimeRemaining(){
    var currentTime = new Date().getTime();
    var elapsedTime = currentTime - startTime;
    // Update time left
    remainingTime = MAX_TIME - elapsedTime;

    // Check if question fail
    if (remainingTime < 0) {
        remainingTime = 0; // Might be unnecessary
        answerIncorrect();
    }

    // Format to two decimal places (rounds too)
    var formattedTime = (remainingTime / 1000).toFixed(2);
    // Display the time left
    timerDisplay.txt.text = formattedTime;
}

//use this function when question is correct
function increaseScore(){
    score += Math.round(BASE_GAIN + (Math.round(remainingTime) /10000)) * 10;
    scoreDisplay.txt.text = score;
}

// AUDIO
function correctSfx() {
    var sfx = new Audio("sound/hitsound1.wav"); // buffers automatically when created
    sfx.play();
}

function incorrectSfx() {
    var sfx = new Audio("sound/miss.mp3");
    sfx.play();
}

function buttonSound() {
    var sound = new Audio("sound/hitsound2.wav");
    sound.play();
}

function loadBgmSound() {
    var bgm = new Audio("sound/game_bgm.wav");
    bgm.loop = true;

    if (localStorage.getItem("bgm-muted") == "true") {
        bgm.pause();
    } else {
        bgm.play();
    }
}

function loadSfxSound() {
    if (localStorage.getItem("sfx-muted") == "true") {
        sfxEnabled = false;
    } else {
        sfxEnabled = true;
    }
}

// INITIALIZERS
function initializeAnswers() {
    for (i = 0; i < 5; i++) {
        var nextAnswer = generateNextAnswer();
        nextAnswer.index = i; // We need the index so we can replace them properly
        answers.push(nextAnswer);
    }
}

function initializeQuestions() {
    for (i = 0; i < 3; i++) {
        questions.push(generateNextQuestion());
    }
}

// GAME LOGIC
// Creates the next answer
function generateNextAnswer() {
    var randInt;
    // Loop until there is no overlap
    outer:
        while (true) {
            // Get the new value
            randInt = getRandomInt(1, 20);

            // Check if it exists already
            for (j = 0; j < answers.length; j++) {
                var something = answers[j].answer;
                if (something == randInt) {
                    continue outer; // Yes - retry
                }
            }
            // No - return the value
            break;
        }
        // Create the next answer

    // Finalize setup
    var nextAnswer = foregroundLayer.addChild(new Answer(randInt)); // Create the actual object
    if (currentAnswer != null) {
        nextAnswer.index = currentAnswer.index; // Pass on parent index
        nextAnswer.x = currentAnswer.x;         // Pass on parent position
    }
    // Return the displayObject
    return nextAnswer;
}

// Gathers are all the necessary info before generating the next answer
function prepareNextQuestion() {
    // Obtain information about the current board
    var availableArray = [];
    // Note: foreach loop not working very well
    for (a=0; a<answers.length; a++) {
        if (answers[a].available == true) {
            availableArray.push(answers[a]);
        }
    }

    // Select one of the avaiable numbers
    var randAvailable = availableArray[getRandomInt(0, availableArray.length - 1)];
    // Toggle availibility off
    randAvailable.available = false;
    // Retrieve the answer
    return randAvailable.answer;
}

function generateNextQuestion() {

    var answer = prepareNextQuestion();

    var question;

    var randNum = getRandomInt(1, 4);
    switch (randNum) {
        case 1:
            question = generateSum(answer);
            break;
        case 2:
            question = generateMinus(answer);
            break;
        case 3:
            question = generateMultiplication(answer);
            break;
        case 4:
            question = generateDivision(answer);
            break;
        default:
            console.log("something went wrong with generateNextQuestion()");
            break;
    }

    // Return the display object
    return backgroundLayer.addChild(question);
}

function generateSum(answer) {
    var numA = getRandomInt(1, 10);
    // using numbers between 1 and 10 for now
    while (answer <= numA) {
        numA = getRandomInt(1, 10);
    }
    var numB = answer - numA;
    var question = new Question(numA, "+", numB, answer);
    return question;
}
function generateMinus(answer) {
    do {
        // Has to be 21 or it might loop infintely
        numA = getRandomInt(1, 21);
    } while (numA <= answer)

    var numB = numA - answer;
    var question = new Question(numA, "-", numB, answer);
    return question;
}
function generateMultiplication(answer) {
    do{
        var numA = getRandomInt(1,10);
    }while(answer%numA != 0)

    var numB = answer / numA;
    var question = new Question(numA, "*", numB, answer);
    return question;
}
function generateDivision(answer) {
    var numA = getRandomInt(1, 10);
    var numB = answer * numA;
    var question = new Question(numB, "/", numA, answer);
    return question;
}

// Move all objects up one position (overwritting the first)
function advanceRows(newQuestion) {
    // Animations: (Individually animate each one)
    // Bottom question
    createjs.Tween.get(questions[0])
        .to({ y:(questions[0].y + layout.QUES_HEIGHT), alpha: 0 }, 300, createjs.Ease.linear)
        .call( function() {
            this.visible = false;
        });
    // Next question
    createjs.Tween.get(questions[1])
        .to({ y:(questions[1].y + layout.QUES_HEIGHT), scaleY: 1.66 }, 300, createjs.Ease.linear); // Advance position
    createjs.Tween.get(questions[1].getChildAt(1))
        .to({ scaleX: 1.66 }, 300, createjs.Ease.linear); // Enlarge text (scaleY taken care above)
    // Last question
    createjs.Tween.get(questions[2])
        .to({ y:(questions[2].y + layout.QUES_HEIGHT) }, 300, createjs.Ease.linear);
    // New question
    createjs.Tween.get(newQuestion)
        .to({ y:layout.MID1}, 300, createjs.Ease.linear);

    // Advance the questions internally
    questions[0] = questions[1];
    questions[1] = questions[2];
    questions[2] = newQuestion
}

function advanceAnswers(nextAnswer) {
    // Animations:
    // Current answer
    createjs.Tween.get(currentAnswer)
        .to({ alpha: 0, scaleX: 0.6, scaleY: 0.6}, 200, createjs.Ease.linear)
        .call( function() { this.visible = false });
    // Next answer
    nextAnswer.alpha = 0;       // Start invisible
    nextAnswer.scaleX = 1.2;    // Start large
    nextAnswer.scaleY = 1.2;
    createjs.Tween.get(nextAnswer)
        .to({}, 100, createjs.Ease.linear)
        .to({ alpha: 1, scaleX: 1, scaleY: 1 }, 300, createjs.Ease.linear);

    // Advance (replace) the answer internally
    answers[nextAnswer.index] = nextAnswer; // Replace parent
}

// Answer checking
function checkAnswer(answer) {
    return (answer == questions[0].answer);
}

function answerCorrect() {
    // GAME-LOGIC(?)
    increaseScore();                        // Update the score
    startTime = new Date().getTime();       // Reset the time (Set the time stamp to now)

    // GAME-FUNCTIONS
    advanceAnswers(generateNextAnswer());   // Create the next answer, animate, and setup
    advanceRows(generateNextQuestion());    // Create the next question, animate, and setup
    updateCurrentAnswer();
}

function answerIncorrect() {
    // GAME-LOGIC(?)
    // Update lives
    livesRemaining--;
    livesDisplay.txt.text = livesRemaining;
    // Reset the time
    startTime = new Date().getTime();

    // GAME-FUNCTIONS
    advanceAnswers(generateNextAnswer());   // Create the next answer, animate, and setup
    advanceRows(generateNextQuestion());    // Create the next question, animate, and setup
    updateCurrentAnswer();

    // Check if user lost
    if (livesRemaining <= 0) {
        gameOver();
    }
}

function gameOver() {
    console.log("gameOver() called");
    // Pause the game
    createjs.Ticker.paused = true;
    // Show user's score
    $('#instance-score').text("Score: " + score);
    // Show the dialog
    $.mobile.changePage("#score-dialog", { role: "dialog" });
}

// Sets the currentAnswer to the answer object for the bottom most question.
function updateCurrentAnswer() {
    for (a = 0; a < answers.length; a++) {
        if (checkAnswer(answers[a].answer)) {
            currentAnswer = answers[a];
        }
    }
}

// POSITIONING
function initializeQuestionPositions() {
    for (q=0; q<3; q++) {
        switch (q) {
            case 0:
                questions[q].y = layout.MID3; // Lowest
                questions[q].scaleY = 1.66;
                questions[q].getChildAt(1).scaleX = 1.66;
                break;
            case 1:
                questions[q].y = layout.MID2;
                break;
            case 2:
                questions[q].y = layout.MID1; // Most upper
                break;
            default:
                console.log("Something went wrong with loadQuestions()");
                break;
        }
        console.log("Ques x: " + questions[q].x + " y: " + questions[q].y );
    }
}

function initializeAnswerPositions() {
    for (a = 0; a < 5; a++) {
        // x and y of the CENTER of the container. (not top left)
        answers[a].x = (layout.ANS_SIZE / 2) + (a)*(layout.ANS_SIZE);

        console.log("Ans x: " + answers[a].x + " y: " + answers[a].y);
    }
}<|endoftext|>


<commit_before>define(['footwork'], function(fw) {
  return fw.viewModel.create({
    initialize: function() {
      window.defaultComponentLocationLoaded = true;
    }
  });
});
<commit_msg>debug output<commit_after>define(['footwork'], function(fw) {
  return fw.viewModel.create({
    initialize: function() {
      console.log('defaultComponentLocationLoaded');
      window.defaultComponentLocationLoaded = true;
    }
  });
});
<|endoftext|>


<commit_before>/*
 * grunt-release
 * https://github.com/geddski/grunt-release
 *
 * Copyright (c) 2013 Dave Geddes
 * Licensed under the MIT license.
 */

var util = require('util');
var Q = require('q');

module.exports = function(grunt) {
  grunt.registerTask('npmrelease', 'git push, npm publish', function(type) {

    //defaults
    var options = this.options({
      bump: true,
      push: true,
      pushTags: true,
      npm : true
    });

    var config = setup(options.file, type);
    var templateOptions = {
      data: {
        version: config.newVersion
      }
    };
    var commitMessage = grunt.config.getRaw('npmrelease.options.commitMessage') || 'release %s';
    var nowrite = options['no-write'] || grunt.option('no-write');
    var task = this;
    var done = this.async();

    if (nowrite) {
      grunt.log.ok('-------RELEASE DRY RUN-------');
    }

    Q()
      .then(ifEnabled('bump', bump))
      .then(ifEnabled('push', push))
      .then(ifEnabled('pushTags', pushTags))
      .then(ifEnabled('npm', publish))
      .catch(function(msg) {
        grunt.fail.warn(msg || 'release failed')
      })
      .finally(done);

    function setup(file, type) {
      var pkg = grunt.file.readJSON(file);
      var newVersion = type || 'patch';

      return {file: file, pkg: pkg, newVersion: newVersion};
    }

    function ifEnabled(option, fn) {
      if (options[option]) {
        return fn;
      }
    }

    function run(cmd, msg) {
      var deferred = Q.defer();
      grunt.verbose.writeln('Running: ' + cmd);

      if (nowrite) {
        grunt.log.ok(msg || cmd);
        deferred.resolve();
      } else {
        var shell = require('shelljs');
        var success = shell.exec(cmd, {silent:true}).code === 0;

        if (success) {
          grunt.log.ok(msg || cmd);
          deferred.resolve();
        } else {
          // fail and stop execution of further tasks
          deferred.reject('Failed when executing: `' + cmd + '`\n');
        }
      }
      return deferred.promise;
    }

    function getNpmTag() {
      var tag = grunt.option('npmtag') || options.npmtag;
      if (tag === true) {
        tag = config.newVersion;
      }
      return tag;
    }

    function push() {
      return run('git push', 'pushed to remote git repo');
    }

    function pushTags() {
      return run('git push --tags', 'pushed new tag '+ config.newVersion +' to remote git repo');
    }

    function bump() {
      var command = util.format('npm version %s -m "%s"', config.newVersion, commitMessage);
      return run(command, 'created new npm version: ' + command);
    }

    function publish() {
      var cmd = 'npm publish';
      var msg = 'published version '+ config.newVersion +' to npm';
      var npmtag = getNpmTag();
      if (npmtag) {
        cmd += ' --tag ' + npmtag;
        msg += ' with a tag of "' + npmtag + '"';
      }

      return run(cmd, msg);
    }
  });
};
<commit_msg>added pull step<commit_after>/*
 * grunt-release
 * https://github.com/geddski/grunt-release
 *
 * Copyright (c) 2013 Dave Geddes
 * Licensed under the MIT license.
 */

var util = require('util');
var Q = require('q');

module.exports = function(grunt) {
  grunt.registerTask('npmrelease', 'git push, npm publish', function(type) {

    //defaults
    var options = this.options({
      bump: true,
      push: true,
      pushTags: true,
      npm : true
    });

    var config = setup(options.file, type);
    var templateOptions = {
      data: {
        version: config.newVersion
      }
    };
    var commitMessage = grunt.config.getRaw('npmrelease.options.commitMessage') || 'release %s';
    var nowrite = options['no-write'] || grunt.option('no-write');
    var task = this;
    var done = this.async();

    if (nowrite) {
      grunt.log.ok('-------RELEASE DRY RUN-------');
    }

    Q()
      .then(ifEnabled('bump', bump))
      .then(ifEnabled('push', pull))
      .then(ifEnabled('push', push))
      .then(ifEnabled('pushTags', pushTags))
      .then(ifEnabled('npm', publish))
      .catch(function(msg) {
        grunt.fail.warn(msg || 'release failed')
      })
      .finally(done);

    function setup(file, type) {
      var pkg = grunt.file.readJSON(file);
      var newVersion = type || 'patch';

      return {file: file, pkg: pkg, newVersion: newVersion};
    }

    function ifEnabled(option, fn) {
      if (options[option]) {
        return fn;
      }
    }

    function run(cmd, msg) {
      var deferred = Q.defer();
      grunt.verbose.writeln('Running: ' + cmd);

      if (nowrite) {
        grunt.log.ok(msg || cmd);
        deferred.resolve();
      } else {
        var shell = require('shelljs');
        var success = shell.exec(cmd, {silent:true}).code === 0;

        if (success) {
          grunt.log.ok(msg || cmd);
          deferred.resolve();
        } else {
          // fail and stop execution of further tasks
          deferred.reject('Failed when executing: `' + cmd + '`\n');
        }
      }
      return deferred.promise;
    }

    function getNpmTag() {
      var tag = grunt.option('npmtag') || options.npmtag;
      if (tag === true) {
        tag = config.newVersion;
      }
      return tag;
    }

    function push() {
      return run('git push', 'pushed to remote git repo');
    }

    function pull() {
      return run('git pull', 'pulled from remote git repo');
    }

    function pushTags() {
      return run('git push --tags', 'pushed new tag '+ config.newVersion +' to remote git repo');
    }

    function bump() {
      var command = util.format('npm version %s -m "%s"', config.newVersion, commitMessage);
      return run(command, 'created new npm version: ' + command);
    }

    function publish() {
      var cmd = 'npm publish';
      var msg = 'published version '+ config.newVersion +' to npm';
      var npmtag = getNpmTag();
      if (npmtag) {
        cmd += ' --tag ' + npmtag;
        msg += ' with a tag of "' + npmtag + '"';
      }

      return run(cmd, msg);
    }
  });
};
<|endoftext|>


<commit_before>var Lang = A.Lang,
	getClassName = A.ClassNameManager.getClassName,

	IFRAME = 'iframe',

	CSS_IFRAME_NODE = getClassName('dialog', IFRAME, 'node'),

	BUFFER_CSS_CLASS = [CSS_IFRAME_NODE],

	TPL_EMPTY_NODE = '

',
	TPL_IFRAME = '';

var DialogIframePlugin = A.Component.create(
	{
		ATTRS: {
			closeOnEscape: {
				value: true
			},

			iframeCssClass: {
				setter: '_setIframeCssClass'
			},

			iframeId: {
				valueFn: function() {
					return A.guid();
				}
			},

			uri: {
			}
		},

		EXTENDS: A.Plugin.Base,
		NAME: IFRAME,
		NS: IFRAME,
		prototype: {
			initializer: function(config) {
				var instance = this;

				instance._host = instance.get('host');

				instance.publish(
					'load',
					{
						defaultFn: instance._defaultLoadIframeFn
					}
				);

				instance.afterHostMethod('renderUI', instance.renderUI);
				instance.afterHostMethod('bindUI', instance.bindUI);

				instance.afterHostMethod('render', instance._afterRender);
			},

			renderUI: function() {
				var instance = this;

				instance._previousBodyContent = instance._host.get('bodyContent');

				var bodyContent = A.Node.create(TPL_EMPTY_NODE);

				var iframeTpl = Lang.sub(
					TPL_IFRAME,
					{
						cssClass: instance.get('iframeCssClass'),
						id: instance.get('iframeId'),
						uri: instance.get('uri')
					}
				);

				var node = A.Node.create(iframeTpl);

				bodyContent.append(node);

				instance._host.set('bodyContent', bodyContent);

				instance._bodyNode = instance._host.bodyNode;
				instance.node = node;
			},

			bindUI: function() {
				var instance = this;

				instance.afterHostEvent('heightChange', instance._updateIframeSize, instance);
				instance.afterHostEvent('widthChange', instance._updateIframeSize, instance);

				instance.after('uriChange', instance._afterUriChange);

				instance.node.on('load', A.bind(instance.fire, instance, 'load'));
			},

			destructor: function() {
				var instance = this;

				instance._host.set('bodyContent', instance._previousBodyContent);

				instance.node.remove(true);
			},

			_adjustSize: A.cached(
				function(number) {
					return ((parseInt(number, 10) || 0) - 5);
				}
			),

			_afterRender: function() {
				var instance = this;

				instance._bodyNode.plug(A.LoadingMask).loadingmask.show();
			},

			_afterUriChange: function(event) {
				var instance = this;

				instance._uiSetUri(event.newVal);
			},

			_defaultLoadIframeFn: function(event) {
				var instance = this;

				var node = instance.node;

				try {
					var iframeDoc = node.get('contentWindow.document');

					iframeDoc.get('documentElement').setStyle('overflow', 'visible');

					var iframeBody = iframeDoc.get('body');

					iframeBody.addClass('controlPanel-popup');

					node.set('height', iframeBody.get('scrollHeight'));

					if (instance.get('closeOnEscape')) {
						A.on(
							'key',
							function(event) {
								instance._host.close();
							},
							[iframeDoc],
							'down:27'
						);
					}
				}
				catch (e) {
				}

				instance._bodyNode.loadingmask.hide();
			},

			_setIframeCssClass: function(value) {
				BUFFER_CSS_CLASS[1] = value;

				return BUFFER_CSS_CLASS.join(' ');
			},

			_uiSetUri: function(value) {
				var instance = this;

				instance.node.attr('src', value);
			},

			_updateIframeSize: function(event) {
				var instance = this;

				var adjustSize = instance._adjustSize;

				var bodyNode = instance._bodyNode;
				var node = instance.node;

				var updateIframeSizeUI = instance._updateIframeSizeUI;

				if (!updateIframeSizeUI) {
					updateIframeSizeUI = function() {
						var bodyHeight = bodyNode.getStyle('height');

						node.setStyle('height', adjustSize(bodyHeight));

						bodyNode.loadingmask.refreshMask();
					};

					instance._updateIframeSizeUI = updateIframeSizeUI;
				}

				setTimeout(updateIframeSizeUI, 50);
			}
		}
	}
);

A.Plugin.DialogIframe = DialogIframePlugin;<commit_msg>AUI-296 - Source formatting<commit_after>var Lang = A.Lang,
	getClassName = A.ClassNameManager.getClassName,

	IFRAME = 'iframe',

	CSS_IFRAME_NODE = getClassName('dialog', IFRAME, 'node'),

	BUFFER_CSS_CLASS = [CSS_IFRAME_NODE],

	TPL_EMPTY_NODE = '

',
	TPL_IFRAME = '';

var DialogIframePlugin = A.Component.create(
	{
		ATTRS: {
			closeOnEscape: {
				value: true
			},

			iframeCssClass: {
				setter: '_setIframeCssClass'
			},

			iframeId: {
				valueFn: function() {
					return A.guid();
				}
			},

			uri: {
			}
		},

		EXTENDS: A.Plugin.Base,
		NAME: IFRAME,
		NS: IFRAME,
		prototype: {
			initializer: function(config) {
				var instance = this;

				instance._host = instance.get('host');

				instance.publish(
					'load',
					{
						defaultFn: instance._defaultLoadIframeFn
					}
				);

				instance.afterHostMethod('renderUI', instance.renderUI);
				instance.afterHostMethod('bindUI', instance.bindUI);

				instance.afterHostMethod('render', instance._afterRender);
			},

			renderUI: function() {
				var instance = this;

				instance._previousBodyContent = instance._host.get('bodyContent');

				var bodyContent = A.Node.create(TPL_EMPTY_NODE);

				var iframeTpl = Lang.sub(
					TPL_IFRAME,
					{
						cssClass: instance.get('iframeCssClass'),
						id: instance.get('iframeId'),
						uri: instance.get('uri')
					}
				);

				var node = A.Node.create(iframeTpl);

				bodyContent.append(node);

				instance._host.set('bodyContent', bodyContent);

				instance._bodyNode = instance._host.bodyNode;
				instance.node = node;
			},

			bindUI: function() {
				var instance = this;

				instance.afterHostEvent('heightChange', instance._updateIframeSize, instance);
				instance.afterHostEvent('widthChange', instance._updateIframeSize, instance);

				instance.after('uriChange', instance._afterUriChange);

				instance.node.on('load', A.bind(instance.fire, instance, 'load'));
			},

			destructor: function() {
				var instance = this;

				instance._host.set('bodyContent', instance._previousBodyContent);

				instance.node.remove(true);
			},

			_adjustSize: A.cached(
				function(number) {
					return ((parseInt(number, 10) || 0) - 5);
				}
			),

			_afterRender: function() {
				var instance = this;

				instance._bodyNode.plug(A.LoadingMask).loadingmask.show();
			},

			_afterUriChange: function(event) {
				var instance = this;

				instance._uiSetUri(event.newVal);
			},

			_defaultLoadIframeFn: function(event) {
				var instance = this;

				var node = instance.node;

				try {
					var iframeDoc = node.get('contentWindow.document');

					iframeDoc.get('documentElement').setStyle('overflow', 'visible');

					var iframeBody = iframeDoc.get('body');

					node.set('height', iframeBody.get('scrollHeight'));

					if (instance.get('closeOnEscape')) {
						A.on(
							'key',
							function(event) {
								instance._host.close();
							},
							[iframeDoc],
							'down:27'
						);
					}
				}
				catch (e) {
				}

				instance._bodyNode.loadingmask.hide();
			},

			_setIframeCssClass: function(value) {
				BUFFER_CSS_CLASS[1] = value;

				return BUFFER_CSS_CLASS.join(' ');
			},

			_uiSetUri: function(value) {
				var instance = this;

				instance.node.attr('src', value);
			},

			_updateIframeSize: function(event) {
				var instance = this;

				var adjustSize = instance._adjustSize;

				var bodyNode = instance._bodyNode;
				var node = instance.node;

				var updateIframeSizeUI = instance._updateIframeSizeUI;

				if (!updateIframeSizeUI) {
					updateIframeSizeUI = function() {
						var bodyHeight = bodyNode.getStyle('height');

						node.setStyle('height', adjustSize(bodyHeight));

						bodyNode.loadingmask.refreshMask();
					};

					instance._updateIframeSizeUI = updateIframeSizeUI;
				}

				setTimeout(updateIframeSizeUI, 50);
			}
		}
	}
);

A.Plugin.DialogIframe = DialogIframePlugin;<|endoftext|>


<commit_before>var oscar = oscar || {};
oscar.messages = {
    addMessage: function(tag, msg) {
        var msgHTML = '
' +
        'x' + msg +
        '
';
        $('#messages').append($(msgHTML));
    },
    debug: function(msg) { oscar.messages.addMessage('debug', msg); },
    info: function(msg) { oscar.messages.addMessage('info', msg); },
    success: function(msg) { oscar.messages.addMessage('success', msg); },
    warning: function(msg) { oscar.messages.addMessage('warning', msg); },
    error: function(msg) { oscar.messages.addMessage('error:', msg); }
};
oscar.forms = {
    init: function() {
        // Forms with this behaviour are 'locked' once they are submitted to
        // prevent multiple submissions
        $('form[data-behaviours~="lock"]').submit(oscar.forms.submitIfNotLocked);
    },
    submitIfNotLocked: function(event) {
        $form = $(this);
        if ($form.data('locked')) {
            return false;
        }
        $form.data('locked', true);
    }
};
$(function(){oscar.forms.init();});

$(document).ready(function()
{
    // Product star rating  -- must improve this in python
    $('.product_pod, .span6, .promotion_single').each(function()
    {
        var sum_total_reviews = $(this).find(".review_count li").length * 5,
            sum_rating_count = 0;
        $(this).find('.review_count li').each(function()
        {
            sum_rating_count += parseFloat($(this).text());
        });
        var ave_rating = sum_rating_count / sum_total_reviews *10;
        if (ave_rating <= 2) {
            ave_rating = 'One';
        } else if (ave_rating <= 4) {
            ave_rating = 'Two';
        } else if (ave_rating <= 6) {
            ave_rating = 'Three';
        } else if (ave_rating <= 8) {
            ave_rating = 'Four';
        } else if (ave_rating <= 10) {
            ave_rating = 'Five';
        }
        $(this).find('.review_count')
          .after('
' + ave_rating + ' star(s) by user reviews. Add review
')
          .remove();
    });
    // Product star rating each review -- must improve this in python
    $('.review').each(function()
    {
        var user_rating = 0;
        $(this).find('span').each(function()
        {
            user_rating += parseFloat($(this).text());
        });
        if (user_rating == 1) {
            user_rating = 'One';
        }
        else if (user_rating == 2) {
            user_rating = 'Two';
        }
        else if (user_rating == 3) {
            user_rating = 'Three';
        }
        else if (user_rating == 4) {
            user_rating = 'Four';
        }
        else if (user_rating == 5) {
            user_rating = 'Five';
        }
        $(this).find('h3').addClass(user_rating).end().find('span').remove();
    });

    var window_width = $(window).width(), // Width of the window
        $sidebar = $('aside.span3'), // Width of main navigation
        $browse = $('#browse > .dropdown-menu'), // Height of main navigation
        $browse_open = $browse.parent().find('> a[data-toggle]');

        if (window_width > 480) {
            // This activates elastislide
            var es_carousel = $('.es-carousel-wrapper'),
            product_page = $('.product_page').length;
            console.log(es_carousel.length);
            // on prodct page
            if (es_carousel.length && product_page > 0) {
                es_carousel.elastislide({
                    imageW: 175,
                    minItems: 5,
                    onClick:  true
                });
                // This activates colorbox on the product page
                var lightbox_elements = $('a[rel=lightbox]');
                if (lightbox_elements.length) {
                    lightbox_elements.colorbox();
                }
            } else if (es_carousel.length) {
                es_carousel.elastislide({
                    imageW: 200,
                    minItems: 4,
                    onClick:  true
                });
            }
        }

    if (window_width > 980) {
      // set width of nav dropdown on the homepage
      $browse.css('width', $sidebar.outerWidth());
      // Remove click on browse button if menu is currently open
      if  ($browse_open.length < 1) {
        $browse.parent().find('> a').on('click', function()
        {
          return false;
        });
        // set margin top of aside allow space for open navigation
        $sidebar.css({
          marginTop: $browse.outerHeight()
        });
      }
    }

    // This activates the promotional banner carousel
    $('#myCarousel').carousel({
        interval: 6000
    });

    // This activates the Typeahead function in the search
    $('.typeahead').typeahead();

    // Acordion - remove the first in the list as it is duplication.
    var n = $('.accordion dt').length;
    if (n > 1) {
        $('.accordion dt:first, .accordion dd:first,').hide();
    }
    // Acordion
    $('.accordion dd').each(function(index)
    {
        $(this).css('height', $(this).height());
    });
    $(".accordion dt").click(function(){
        $(this).next("dd").slideToggle("slow").siblings("dd:visible").slideUp("slow");
        $(this).toggleClass("open");
        $(this).siblings("dt").removeClass("open");
    });
    $(".accordion dd").hide();

    /* scroll to sections */
    $('.top_page a').click(function (e) {
        var section = $(this).attr('href');
        var sectionPosition = Math.floor($(section).offset().top);
        var currentPosition = Math.floor($(document).scrollTop());
        // when scrolling downwards
        if (sectionPosition > currentPosition) {
            $('html, body').animate({
                scrollTop: sectionPosition}, 500, function() {
                $('html, body').animate({
                    scrollTop: sectionPosition
                });
            });
        }
        // when scrolling upwards
        else if (sectionPosition < currentPosition) {
            $('html, body').animate({
                scrollTop: sectionPosition}, 500, function() {
                $('html, body').animate({
                    scrollTop: sectionPosition
                });
            });
        }
        e.preventDefault();
    });

    //For IE - sets the width of a select in an overflow hidden container
    var selectBox = $('.product_pod select'),
        isIE = navigator.userAgent.toLowerCase().indexOf("msie");
    if (isIE > -1) {
      selectBox.on({
        mousedown: function(){
          $(this).addClass("select-open");
        },
        change: function(){
          $(this).removeClass("select-open");
        }
      });
    }

});

<commit_msg>Bah! Removed console.log<commit_after>var oscar = oscar || {};
oscar.messages = {
    addMessage: function(tag, msg) {
        var msgHTML = '
' +
        'x' + msg +
        '
';
        $('#messages').append($(msgHTML));
    },
    debug: function(msg) { oscar.messages.addMessage('debug', msg); },
    info: function(msg) { oscar.messages.addMessage('info', msg); },
    success: function(msg) { oscar.messages.addMessage('success', msg); },
    warning: function(msg) { oscar.messages.addMessage('warning', msg); },
    error: function(msg) { oscar.messages.addMessage('error:', msg); }
};
oscar.forms = {
    init: function() {
        // Forms with this behaviour are 'locked' once they are submitted to
        // prevent multiple submissions
        $('form[data-behaviours~="lock"]').submit(oscar.forms.submitIfNotLocked);
    },
    submitIfNotLocked: function(event) {
        $form = $(this);
        if ($form.data('locked')) {
            return false;
        }
        $form.data('locked', true);
    }
};
$(function(){oscar.forms.init();});

$(document).ready(function()
{
    // Product star rating  -- must improve this in python
    $('.product_pod, .span6, .promotion_single').each(function()
    {
        var sum_total_reviews = $(this).find(".review_count li").length * 5,
            sum_rating_count = 0;
        $(this).find('.review_count li').each(function()
        {
            sum_rating_count += parseFloat($(this).text());
        });
        var ave_rating = sum_rating_count / sum_total_reviews *10;
        if (ave_rating <= 2) {
            ave_rating = 'One';
        } else if (ave_rating <= 4) {
            ave_rating = 'Two';
        } else if (ave_rating <= 6) {
            ave_rating = 'Three';
        } else if (ave_rating <= 8) {
            ave_rating = 'Four';
        } else if (ave_rating <= 10) {
            ave_rating = 'Five';
        }
        $(this).find('.review_count')
          .after('
' + ave_rating + ' star(s) by user reviews. Add review
')
          .remove();
    });
    // Product star rating each review -- must improve this in python
    $('.review').each(function()
    {
        var user_rating = 0;
        $(this).find('span').each(function()
        {
            user_rating += parseFloat($(this).text());
        });
        if (user_rating == 1) {
            user_rating = 'One';
        }
        else if (user_rating == 2) {
            user_rating = 'Two';
        }
        else if (user_rating == 3) {
            user_rating = 'Three';
        }
        else if (user_rating == 4) {
            user_rating = 'Four';
        }
        else if (user_rating == 5) {
            user_rating = 'Five';
        }
        $(this).find('h3').addClass(user_rating).end().find('span').remove();
    });

    var window_width = $(window).width(), // Width of the window
        $sidebar = $('aside.span3'), // Width of main navigation
        $browse = $('#browse > .dropdown-menu'), // Height of main navigation
        $browse_open = $browse.parent().find('> a[data-toggle]');

        if (window_width > 480) {
            // This activates elastislide
            var es_carousel = $('.es-carousel-wrapper'),
            product_page = $('.product_page').length;
            // on prodct page
            if (es_carousel.length && product_page > 0) {
                es_carousel.elastislide({
                    imageW: 175,
                    minItems: 5,
                    onClick:  true
                });
                // This activates colorbox on the product page
                var lightbox_elements = $('a[rel=lightbox]');
                if (lightbox_elements.length) {
                    lightbox_elements.colorbox();
                }
            } else if (es_carousel.length) {
                es_carousel.elastislide({
                    imageW: 200,
                    minItems: 4,
                    onClick:  true
                });
            }
        }

    if (window_width > 980) {
      // set width of nav dropdown on the homepage
      $browse.css('width', $sidebar.outerWidth());
      // Remove click on browse button if menu is currently open
      if  ($browse_open.length < 1) {
        $browse.parent().find('> a').on('click', function()
        {
          return false;
        });
        // set margin top of aside allow space for open navigation
        $sidebar.css({
          marginTop: $browse.outerHeight()
        });
      }
    }

    // This activates the promotional banner carousel
    $('#myCarousel').carousel({
        interval: 6000
    });

    // This activates the Typeahead function in the search
    $('.typeahead').typeahead();

    // Acordion - remove the first in the list as it is duplication.
    var n = $('.accordion dt').length;
    if (n > 1) {
        $('.accordion dt:first, .accordion dd:first,').hide();
    }
    // Acordion
    $('.accordion dd').each(function(index)
    {
        $(this).css('height', $(this).height());
    });
    $(".accordion dt").click(function(){
        $(this).next("dd").slideToggle("slow").siblings("dd:visible").slideUp("slow");
        $(this).toggleClass("open");
        $(this).siblings("dt").removeClass("open");
    });
    $(".accordion dd").hide();

    /* scroll to sections */
    $('.top_page a').click(function (e) {
        var section = $(this).attr('href');
        var sectionPosition = Math.floor($(section).offset().top);
        var currentPosition = Math.floor($(document).scrollTop());
        // when scrolling downwards
        if (sectionPosition > currentPosition) {
            $('html, body').animate({
                scrollTop: sectionPosition}, 500, function() {
                $('html, body').animate({
                    scrollTop: sectionPosition
                });
            });
        }
        // when scrolling upwards
        else if (sectionPosition < currentPosition) {
            $('html, body').animate({
                scrollTop: sectionPosition}, 500, function() {
                $('html, body').animate({
                    scrollTop: sectionPosition
                });
            });
        }
        e.preventDefault();
    });

    //For IE - sets the width of a select in an overflow hidden container
    var selectBox = $('.product_pod select'),
        isIE = navigator.userAgent.toLowerCase().indexOf("msie");
    if (isIE > -1) {
      selectBox.on({
        mousedown: function(){
          $(this).addClass("select-open");
        },
        change: function(){
          $(this).removeClass("select-open");
        }
      });
    }

});

<|endoftext|>


<commit_before>/*
 Copyright 2018 Carmilla Mina Jankovic

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const ViewWrapper = require('../ViewWrapper');
const TransactionList = require('../lists/TransactionList');
const UserList = require('../lists/UserList');
const TeamList = require('../lists/TeamList');
const WalletInfo = require('./WalletInfo');

class WalletView extends ViewWrapper {
  constructor({
    effect,
    corners,
    classes = [],
    elementId = `wView-${Date.now()}`,
  }) {
    const walletInfo = new WalletInfo({
      sign: 'vcaps',
      corners,
      appendSign: true,
      showName: true,
      showTeam: true,
    });
    const transactionList = new TransactionList({ effect });
    const userList = new UserList({
      effect,
      includeSelf: true,
      shouldToggle: true,
      title: 'Users',
    });
    const teamList = new TeamList({
      effect,
      shouldToggle: true,
      title: 'Teams',
    });

    userList.onToggle = () => { teamList.hideList(); };
    teamList.onToggle = () => { userList.hideList(); };

    super({
      elementId,
      columns: [
        {
          components: [
            { component: teamList },
            { component: userList },
          ],
          classes: [
            'columnList',
            'columnWalletList',
          ],
        },
        {
          components: [{
            component: walletInfo,
          }, {
            component: transactionList,
          }],
          classes: ['columnTransactionList'],
        },
      ],
      classes: classes.concat(['walletView']),
    });
  }
}

module.exports = WalletView;
<commit_msg>Removed hardcoded currency sign<commit_after>/*
 Copyright 2018 Carmilla Mina Jankovic

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const ViewWrapper = require('../ViewWrapper');
const TransactionList = require('../lists/TransactionList');
const UserList = require('../lists/UserList');
const TeamList = require('../lists/TeamList');
const WalletInfo = require('./WalletInfo');
const labelHandler = require('../../labels/LabelHandler');

class WalletView extends ViewWrapper {
  constructor({
    effect,
    corners,
    classes = [],
    elementId = `wView-${Date.now()}`,
  }) {
    const walletInfo = new WalletInfo({
      corners,
      sign: labelHandler.getLabel({ baseObject: 'WalletDialog', label: 'currency' }),
      appendSign: true,
      showName: true,
      showTeam: true,
    });
    const transactionList = new TransactionList({ effect });
    const userList = new UserList({
      effect,
      includeSelf: true,
      shouldToggle: true,
      title: 'Users',
    });
    const teamList = new TeamList({
      effect,
      shouldToggle: true,
      title: 'Teams',
    });

    userList.onToggle = () => { teamList.hideList(); };
    teamList.onToggle = () => { userList.hideList(); };

    super({
      elementId,
      columns: [
        {
          components: [
            { component: teamList },
            { component: userList },
          ],
          classes: [
            'columnList',
            'columnWalletList',
          ],
        },
        {
          components: [{
            component: walletInfo,
          }, {
            component: transactionList,
          }],
          classes: ['columnTransactionList'],
        },
      ],
      classes: classes.concat(['walletView']),
    });
  }
}

module.exports = WalletView;
<|endoftext|>


<commit_before>import query from "@phenomic/api-client/lib/query";

import { encode } from "../api";

const debug = require("debug")("phenomic:core:prerender:resolve");

const defaultQueryKey = "default";
const mainKey = "id";

const arrayUnique = array => [...new Set(array)];

const flatten = (array: Array<any>) => {
  const flattenedArray = [];
  array.forEach(item => {
    Array.isArray(item)
      ? flattenedArray.push(...flatten(item))
      : flattenedArray.push(item);
  });

  return flattenedArray;
};

const getRouteQueries = route => {
  if (
    // reference is incorrect? (eg: import { Thing } instead of import Thing)
    !route.component ||
    // no export?
    (Object.keys(route.component).length === 0 &&
      route.component.constructor === Object)
  ) {
    throw new Error(
      `Route with path '${
        route.path
      }' have no component (or an undefined value).\n` +
        "Check the component reference and its origin. Are the import/export correct?"
    );
  }
  const initialRouteParams: Object = route.params || {};
  if (!route.component.getQueries) {
    debug(route.path, "have no queries");
    return {};
  }
  return route.component.getQueries({
    params: initialRouteParams
  });
};

const getMainQuery = route => {
  const routeQueries = getRouteQueries(route);
  const ids = Object.keys(routeQueries);
  const firstId = ids[0];
  const firstIdAsInt = parseInt(ids[0], 10);
  // parseInt("12.") == "12"
  if (
    // $FlowFixMe it's on purpose
    firstIdAsInt == firstId &&
    String(firstIdAsInt).length == firstId.length
  ) {
    console.warn(`The main path used for ${route.path} is ${firstId}`);
  }
  return { id: firstId, item: routeQueries[firstId] };
};

const resolveURLsForDynamicParams = async function(
  phenomicFetch: PhenomicFetch,
  route: PhenomicRoute
) {
  // deprecate notice
  // @todo remove for stable v1
  if (route.paginated) {
    console.log(
      "'paginated' parameter is deprecated. Pagination is now infered from the presence of :after param in the route."
    );
  }
  if (route.collection) {
    console.error(
      // $FlowFixMe removed from interface but it's for deprecation that we use it
      `${route.path} have an attached parameter 'collection=${
        route.collection
      }'.\n This parameter is now useless and can be safely removed`
    );
  }

  const mainQuery = getMainQuery(route);
  if (!mainQuery.item || !mainQuery.item.path) {
    debug("no valid path detected for", route.path);
    return route;
  }

  const pathConfig = { path: mainQuery.item.path };
  debug("route", route.path);

  // If the path doesn't contain any kind of parameter, no need to
  // iterate over the path
  if (!route.path.includes("*") && !route.path.includes(":")) {
    debug("not a dynamic route");
    return route;
  }
  debug(
    `fetching path '${
      mainQuery.id ? mainQuery.id : Object.keys(pathConfig).join(",")
    }' for route '${route.path}'`
  );
  // @todo memoize for perfs and avoid uncessary call
  const queries = getRouteQueries(route);
  debug(route.path, queries);
  let id = (queries[mainQuery.id] && queries[mainQuery.id].by) || mainKey;
  if (id === defaultQueryKey) {
    id = mainKey;
  }
  const queryParams = query(pathConfig);
  const queryResult = await phenomicFetch(queryParams);
  debug(
    route.path,
    `path fetched. ${queryResult.list.length} items (id: ${id})`
  );
  const path = route.path || "*";
  const list = queryResult.list.reduce((acc, item) => {
    if (!item[id]) {
      return acc;
    }
    if (Array.isArray(item[id])) {
      acc = acc.concat(item[id]);
    } else {
      acc.push(item[id]);
    }
    return acc;
  }, []);
  debug(path, "list (unique)", arrayUnique(list));
  const urlsData = arrayUnique(list).reduce((acc, value) => {
    let resolvedPath = path.replace(":" + id, value);
    let params = { [id]: value };

    // try *
    if (id === mainKey && resolvedPath === path) {
      resolvedPath = resolvedPath.replace("*", value);
      // react-router splat is considered as the id
      params = { splat: value };
    }

    debug("half resolved path", resolvedPath, params);

    if (path !== resolvedPath) {
      acc.push({
        ...route,
        path: resolvedPath,
        params
      });
    }

    return acc;
  }, []);

  debug(path, "urls data", urlsData);

  // if no data found, we still try to render something
  const finalUrlsData = urlsData.length ? urlsData : [{ path }];

  // try :after with id
  const reAfter = /:after\b/;

  return finalUrlsData.reduce((acc, routeData) => {
    if (!routeData.path.match(reAfter)) {
      acc.push(routeData);
    } else {
      queryResult.list.map(item => {
        // $FlowFixMe params[id] act as a truthy value
        if (routeData.params && routeData.params[id]) {
          if (
            (Array.isArray(item[id]) &&
              item[id].includes(routeData.params[id])) ||
            item[id] === routeData.params[id]
          ) {
            acc.push({
              ...routeData,
              path: routeData.path.replace(reAfter, encode(item.id))
            });
          }
        } else {
          acc.push({
            ...routeData,
            path: routeData.path.replace(reAfter, encode(item.id))
          });
        }
      });
    }

    return acc;
  }, []);
};

const normalizePath = (path: string) => path.replace(/^\//, "");

const resolveURLsToPrerender = async function(
  routes: Array<PhenomicRoute>,
  fetch: PhenomicFetch
) {
  const dynamicRoutes = await Promise.all(
    routes.map(route => resolveURLsForDynamicParams(fetch, route))
  );
  const flattenedDynamicRoutes = flatten(dynamicRoutes);
  const filtredDynamicRoutes = flattenedDynamicRoutes.filter(url => {
    if (url.path && url.path.includes("*")) {
      debug(
        `${
          url.path
        } is including a '*' but it has not been resolved: url is skipped`
      );
      return false;
    }
    return true;
  });
  // debug("filtred dynamic routes", filtredDynamicRoutes)

  const normalizedURLs = filtredDynamicRoutes.map(routeData =>
    normalizePath(routeData.path)
  );
  debug("normalize urls", normalizedURLs);
  const uniqsNormalizedPath = [...new Set(normalizedURLs)];
  return uniqsNormalizedPath;
};

export default resolveURLsToPrerender;
<commit_msg>🤫 `@phenomic/core`: rename back `key` in "prerender/resolve" as it's not id.<commit_after>import query from "@phenomic/api-client/lib/query";

import { encode } from "../api";

const debug = require("debug")("phenomic:core:prerender:resolve");

const defaultQueryKey = "default";
const mainKey = "id";

const arrayUnique = array => [...new Set(array)];

const flatten = (array: Array<any>) => {
  const flattenedArray = [];
  array.forEach(item => {
    Array.isArray(item)
      ? flattenedArray.push(...flatten(item))
      : flattenedArray.push(item);
  });

  return flattenedArray;
};

const getRouteQueries = route => {
  if (
    // reference is incorrect? (eg: import { Thing } instead of import Thing)
    !route.component ||
    // no export?
    (Object.keys(route.component).length === 0 &&
      route.component.constructor === Object)
  ) {
    throw new Error(
      `Route with path '${
        route.path
      }' have no component (or an undefined value).\n` +
        "Check the component reference and its origin. Are the import/export correct?"
    );
  }
  const initialRouteParams: Object = route.params || {};
  if (!route.component.getQueries) {
    debug(route.path, "have no queries");
    return {};
  }
  return route.component.getQueries({
    params: initialRouteParams
  });
};

const getMainQuery = route => {
  const routeQueries = getRouteQueries(route);
  const keys = Object.keys(routeQueries);
  const firstKey = keys[0];
  const firstKeyAsInt = parseInt(keys[0], 10);
  // parseInt("12.") == "12"
  if (
    // $FlowFixMe it's on purpose
    firstKeyAsInt == firstKey &&
    String(firstKeyAsInt).length == firstKey.length
  ) {
    console.warn(`The main path used for ${route.path} is ${firstKey}`);
  }
  return { key: firstKey, item: routeQueries[firstKey] };
};

const resolveURLsForDynamicParams = async function(
  phenomicFetch: PhenomicFetch,
  route: PhenomicRoute
) {
  // deprecate notice
  // @todo remove for stable v1
  if (route.paginated) {
    console.log(
      "'paginated' parameter is deprecated. Pagination is now infered from the presence of :after param in the route."
    );
  }
  if (route.collection) {
    console.error(
      // $FlowFixMe removed from interface but it's for deprecation that we use it
      `${route.path} have an attached parameter 'collection=${
        route.collection
      }'.\n This parameter is now useless and can be safely removed`
    );
  }

  const mainQuery = getMainQuery(route);
  if (!mainQuery.item || !mainQuery.item.path) {
    debug("no valid path detected for", route.path);
    return route;
  }

  const unlimitedQueryConfig = { path: mainQuery.item.path };
  debug("route", route.path);

  // If the path doesn't contain any kind of parameter, no need to
  // iterate over the path
  if (!route.path.includes("*") && !route.path.includes(":")) {
    debug("not a dynamic route");
    return route;
  }
  debug(
    `fetching path '${
      mainQuery.key
        ? mainQuery.key
        : Object.keys(unlimitedQueryConfig).join(",")
    }' for route '${route.path}'`
  );
  // @todo memoize for perfs and avoid uncessary call
  const queries = getRouteQueries(route);
  debug(route.path, queries);
  let key = (queries[mainQuery.key] && queries[mainQuery.key].by) || mainKey;
  if (key === defaultQueryKey) {
    key = mainKey;
  }
  const queryParams = query(unlimitedQueryConfig);
  const queryResult = await phenomicFetch(queryParams);
  debug(
    route.path,
    `path fetched. ${queryResult.list.length} items (id: ${key})`
  );
  const path = route.path || "*";
  const list = queryResult.list.reduce((acc, item) => {
    if (!item[key]) {
      return acc;
    }
    if (Array.isArray(item[key])) {
      acc = acc.concat(item[key]);
    } else {
      acc.push(item[key]);
    }
    return acc;
  }, []);
  debug(path, "list (unique)", arrayUnique(list));
  const urlsData = arrayUnique(list).reduce((acc, value) => {
    let resolvedPath = path.replace(":" + key, value);
    let params = { [key]: value };

    // try *
    if (key === mainKey && resolvedPath === path) {
      resolvedPath = resolvedPath.replace("*", value);
      // react-router splat is considered as the id
      params = { splat: value };
    }

    debug("half resolved path", resolvedPath, params);

    if (path !== resolvedPath) {
      acc.push({
        ...route,
        path: resolvedPath,
        params
      });
    }

    return acc;
  }, []);

  debug(path, "urls data", urlsData);

  // if no data found, we still try to render something
  const finalUrlsData = urlsData.length ? urlsData : [{ path }];
  // try :after with key
  const reAfter = /:after\b/;

  return finalUrlsData.reduce((acc, routeData) => {
    if (!routeData.path.match(reAfter)) {
      acc.push(routeData);
    } else {
      queryResult.list.map(item => {
        // $FlowFixMe params[key] act as a truthy value
        if (routeData.params && routeData.params[key]) {
          if (
            (Array.isArray(item[key]) &&
              item[key].includes(routeData.params[key])) ||
            item[key] === routeData.params[key]
          ) {
            acc.push({
              ...routeData,
              path: routeData.path.replace(reAfter, encode(item.id))
            });
          }
        } else {
          acc.push({
            ...routeData,
            path: routeData.path.replace(reAfter, encode(item.id))
          });
        }
      });
    }

    return acc;
  }, []);
};

const normalizePath = (path: string) => path.replace(/^\//, "");

const resolveURLsToPrerender = async function(
  routes: Array<PhenomicRoute>,
  fetch: PhenomicFetch
) {
  const dynamicRoutes = await Promise.all(
    routes.map(route => resolveURLsForDynamicParams(fetch, route))
  );
  const flattenedDynamicRoutes = flatten(dynamicRoutes);
  const filtredDynamicRoutes = flattenedDynamicRoutes.filter(url => {
    if (url.path && url.path.includes("*")) {
      debug(
        `${
          url.path
        } is including a '*' but it has not been resolved: url is skipped`
      );
      return false;
    }
    return true;
  });
  // debug("filtred dynamic routes", filtredDynamicRoutes)

  const normalizedURLs = filtredDynamicRoutes.map(routeData =>
    normalizePath(routeData.path)
  );
  debug("normalize urls", normalizedURLs);
  const uniqsNormalizedPath = [...new Set(normalizedURLs)];
  return uniqsNormalizedPath;
};

export default resolveURLsToPrerender;
<|endoftext|>