<commit_before>'use strict';

goog.provide('Blockly.Blocks.hedgehog');

goog.require('Blockly.Blocks');

// Common HSV hue for all blocks in this category.
Blockly.Blocks.hedgehog.HUE = 120;
Blockly.Constants.Loops.HUE = 120;

// Common Help URL for all blocks in this category
Blockly.Blocks.hedgehog.HELPURL = "http://hedgehog.pria.at/";

Blockly.Blocks['hedgehog_scope'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_SCOPE,
            "args0": [
                {
                    "type": "input_dummy"
                },
                {
                    "type": "input_statement",
                    "name": "IN"
                }
            ],
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_SCOPE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    }
};

Blockly.Blocks['hedgehog_move'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_MOVE,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "SPEED",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_MOVE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: function(e) {
        if (this.workspace.isDragging()) {
            return;  // Don't change state at the start of a drag.
        }
        var legal = false;
        // Is the block nested in a loop?
        var block = this;
        do {
            if (block.type == 'hedgehog_scope') {
                legal = true;
                break;
            }
            block = block.getSurroundParent();
        } while (block);
        if (legal) {
            this.setWarningText(null);
            if (!this.isInFlyout) {
                this.setDisabled(false);
            }
        } else {
            this.setWarningText(Blockly.Msg.HEDGEHOG_WARN);
            if (!this.isInFlyout && !this.getInheritedDisabled()) {
                this.setDisabled(true);
            }
        }
    }
};

Blockly.Blocks['hedgehog_move2'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_MOVE2,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT1",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "field_number",
                    "name": "PORT2",
                    "value": 1,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "SPEED",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_MOVE2_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_move_unlimited'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_MOVE_UNLIMITED,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "SPEED",
                    "check": "Number"
                },
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_MOVE_UNLIMITED_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_pullup'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_PULLUP,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 7,
                    "precision": 1
                },
                {
                    "type": "field_checkbox",
                    "name": "STATE",
                    "checked": true
                },
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_PULLUP_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_turn'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_TURN,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT1",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "field_number",
                    "name": "PORT2",
                    "value": 1,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "DIR",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_TURN_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_dir'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([[Blockly.Msg.HEDGEHOG_RIGHT, "1000"], [Blockly.Msg.HEDGEHOG_LEFT, "-1000"]]), "DIR");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_speed'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([[Blockly.Msg.HEDGEHOG_FORWARD, "1000"], [Blockly.Msg.HEDGEHOG_BACKWARD, "-1000"]]), "SPEED");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_read_analog'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_READ_ANALOG,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 7,
                    "precision": 1
                }
            ],
            "output": "Number",
            "tooltip": Blockly.Msg.HEDGEHOG_READ_ANALOG_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_servo'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_SERVO,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "ANGLE",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_SERVO_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_degrees'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        Blockly.FieldAngle.ROUND = 5;
        Blockly.FieldAngle.CLOCKWISE = true;
        Blockly.FieldAngle.OFFSET = 90;
        this.appendDummyInput()
            .appendField(new Blockly.FieldAngle(45), "ANGLE");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_sleep'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_SLEEP,
            "args0": [
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_SLEEP_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    }
};

Blockly.Blocks['hedgehog_read_digital'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_READ_DIGITAL,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 8,
                    "min": 8,
                    "max": 15,
                    "precision": 1
                }
            ],
            "output": "Boolean",
            "tooltip": Blockly.Msg.HEDGEHOG_READ_DIGITAL_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_create_scope'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_CREATE_SCOPE,
            "args0": [
                {
                    "type": "input_dummy"
                },
                {
                    "type": "input_statement",
                    "name": "IN"
                }
            ],
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_CREATE_SCOPE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    }
};

Blockly.Blocks['hedgehog_create2_scope'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_CREATE2_SCOPE,
            "args0": [
                {
                    "type": "input_dummy"
                },
                {
                    "type": "input_statement",
                    "name": "IN"
                }
            ],
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_CREATE_SCOPE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    }
};

Blockly.Blocks['hedgehog_create_drive_direct'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_CREATE_DRIVE_DIRECT,
            "args0": [
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "LSPEED",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "RSPEED",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_MOVE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: function(e) {
        if (this.workspace.isDragging()) {
            return;  // Don't change state at the start of a drag.
        }
        var legal = false;
        // Is the block nested in a loop?
        var block = this;
        do {
            if (block.type == 'hedgehog_create_scope') {
                legal = true;
                break;
            }
            block = block.getSurroundParent();
        } while (block);
        if (legal) {
            this.setWarningText(null);
            if (!this.isInFlyout) {
                this.setDisabled(false);
            }
        } else {
            this.setWarningText(Blockly.Msg.HEDGEHOG_CREATE_WARN);
            if (!this.isInFlyout && !this.getInheritedDisabled()) {
                this.setDisabled(true);
            }
        }
    }
};
<commit_msg>also allow the create drive block if nested within a create2 scope<commit_after>'use strict';

goog.provide('Blockly.Blocks.hedgehog');

goog.require('Blockly.Blocks');

// Common HSV hue for all blocks in this category.
Blockly.Blocks.hedgehog.HUE = 120;
Blockly.Constants.Loops.HUE = 120;

// Common Help URL for all blocks in this category
Blockly.Blocks.hedgehog.HELPURL = "http://hedgehog.pria.at/";

Blockly.Blocks['hedgehog_scope'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_SCOPE,
            "args0": [
                {
                    "type": "input_dummy"
                },
                {
                    "type": "input_statement",
                    "name": "IN"
                }
            ],
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_SCOPE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    }
};

Blockly.Blocks['hedgehog_move'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_MOVE,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "SPEED",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_MOVE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: function(e) {
        if (this.workspace.isDragging()) {
            return;  // Don't change state at the start of a drag.
        }
        var legal = false;
        // Is the block nested in a loop?
        var block = this;
        do {
            if (block.type == 'hedgehog_scope') {
                legal = true;
                break;
            }
            block = block.getSurroundParent();
        } while (block);
        if (legal) {
            this.setWarningText(null);
            if (!this.isInFlyout) {
                this.setDisabled(false);
            }
        } else {
            this.setWarningText(Blockly.Msg.HEDGEHOG_WARN);
            if (!this.isInFlyout && !this.getInheritedDisabled()) {
                this.setDisabled(true);
            }
        }
    }
};

Blockly.Blocks['hedgehog_move2'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_MOVE2,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT1",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "field_number",
                    "name": "PORT2",
                    "value": 1,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "SPEED",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_MOVE2_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_move_unlimited'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_MOVE_UNLIMITED,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "SPEED",
                    "check": "Number"
                },
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_MOVE_UNLIMITED_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_pullup'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_PULLUP,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 7,
                    "precision": 1
                },
                {
                    "type": "field_checkbox",
                    "name": "STATE",
                    "checked": true
                },
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_PULLUP_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_turn'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_TURN,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT1",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "field_number",
                    "name": "PORT2",
                    "value": 1,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "DIR",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_TURN_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_dir'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([[Blockly.Msg.HEDGEHOG_RIGHT, "1000"], [Blockly.Msg.HEDGEHOG_LEFT, "-1000"]]), "DIR");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_speed'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([[Blockly.Msg.HEDGEHOG_FORWARD, "1000"], [Blockly.Msg.HEDGEHOG_BACKWARD, "-1000"]]), "SPEED");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_read_analog'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_READ_ANALOG,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 7,
                    "precision": 1
                }
            ],
            "output": "Number",
            "tooltip": Blockly.Msg.HEDGEHOG_READ_ANALOG_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_servo'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_SERVO,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 0,
                    "min": 0,
                    "max": 3,
                    "precision": 1
                },
                {
                    "type": "input_value",
                    "name": "ANGLE",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_SERVO_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_degrees'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        Blockly.FieldAngle.ROUND = 5;
        Blockly.FieldAngle.CLOCKWISE = true;
        Blockly.FieldAngle.OFFSET = 90;
        this.appendDummyInput()
            .appendField(new Blockly.FieldAngle(45), "ANGLE");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_sleep'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_SLEEP,
            "args0": [
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_SLEEP_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    }
};

Blockly.Blocks['hedgehog_read_digital'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_READ_DIGITAL,
            "args0": [
                {
                    "type": "field_number",
                    "name": "PORT",
                    "value": 8,
                    "min": 8,
                    "max": 15,
                    "precision": 1
                }
            ],
            "output": "Boolean",
            "tooltip": Blockly.Msg.HEDGEHOG_READ_DIGITAL_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: Blockly.Blocks['hedgehog_move'].onchange
};

Blockly.Blocks['hedgehog_create_scope'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_CREATE_SCOPE,
            "args0": [
                {
                    "type": "input_dummy"
                },
                {
                    "type": "input_statement",
                    "name": "IN"
                }
            ],
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_CREATE_SCOPE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    }
};

Blockly.Blocks['hedgehog_create2_scope'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_CREATE2_SCOPE,
            "args0": [
                {
                    "type": "input_dummy"
                },
                {
                    "type": "input_statement",
                    "name": "IN"
                }
            ],
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_CREATE_SCOPE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    }
};

Blockly.Blocks['hedgehog_create_drive_direct'] = {
    init: function() {
        this.jsonInit({
            "message0": Blockly.Msg.HEDGEHOG_CREATE_DRIVE_DIRECT,
            "args0": [
                {
                    "type": "input_value",
                    "name": "TIME",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "LSPEED",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "RSPEED",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "previousStatement": null,
            "nextStatement": null,
            "tooltip": Blockly.Msg.HEDGEHOG_MOVE_TOOLTIP,
            "colour": Blockly.Blocks.hedgehog.HUE,
            "helpUrl": Blockly.Blocks.hedgehog.HELPURL
        });
    },
    onchange: function(e) {
        if (this.workspace.isDragging()) {
            return;  // Don't change state at the start of a drag.
        }
        var legal = false;
        // Is the block nested in a loop?
        var block = this;
        do {
            if (block.type === 'hedgehog_create_scope' || block.type === 'hedgehog_create2_scope') {
                legal = true;
                break;
            }
            block = block.getSurroundParent();
        } while (block);
        if (legal) {
            this.setWarningText(null);
            if (!this.isInFlyout) {
                this.setDisabled(false);
            }
        } else {
            this.setWarningText(Blockly.Msg.HEDGEHOG_CREATE_WARN);
            if (!this.isInFlyout && !this.getInheritedDisabled()) {
                this.setDisabled(true);
            }
        }
    }
};
<|endoftext|>


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

/*!
* \SweetSearch.js
* \core source for auto-complete UI
* \copyright Copyright (c) 2016, SK PLANET. All Rights Reserved.
* \license This project is released under the MIT License.
* \contributor Jisu Youn (jisu.youn@gmail.com)
* \warning dont'use this source in other library source.
*/

class SweetSearch extends CommonComponent {
  COMPONENT_CONFIG() {
    return {
	  PLUGINS: ['RecentWordPlugin', 'TTViewPlugin'],
	    SELECTOR: {
		  inputFieldWrap: '.input-wrap',
		  inputField: '.input-field',
		  autoCompleteWrap: '.auto-complete-wrap',
		  closeLayer: '.close-layer',
		  clearQueryBtn: '.clear-query',
		  autoULWrap: '.auto-complete-wrap .ul-wrap',
		  realForm: '#search-form'
		},
		DEFAULT_EVENT: [
		  'FN_AFTER_INSERT_AUTO_WORD',
		  'FN_AFTER_SELECT_AUTO_WORD',
		  'FN_AFTER_FOCUS',
		  'FN_RUN_AJAX_EXECUTE'
		],
		DEFAULT_PLUGIN_EVENT: [
		  'FN_AFTER_FOCUS',
		  'FN_AFTER_INPUT',
		  'FN_AFTER_SUBMIT',
		  'FN_AFTER_AC_SHOW',
		  'FN_AFTER_AC_NONE'
		],
		DEFAULT_OPTION: {
		  'AjaxRequestType': 'jsonp',
		  'sAutoCompleteURL': '',
		  'jsonp_callbackName': ''
		}
	}
  }

  constructor(elTarget, htOption) {
    super(elTarget, htOption);
  }

  initValue(htOption) {
    let _el = this.elTarget;
    let s = this.COMPONENT_CONFIG().SELECTOR;

    this.elInputFieldWrap = _el.querySelector(s.inputFieldWrap);
    this.elInputField = _el.querySelector(s.inputField);
    this.elAutoCompleteLayer = _el.querySelector(s.autoCompleteWrap);
    this.elClearQueryBtn = _el.querySelector(s.clearQueryBtn);
    this.elForm = _el.querySelector(s.realForm);
    this.elCloseButton = this.elAutoCompleteLayer.querySelector(s.closeLayer);
    this.elAutoULWrap = this.elAutoCompleteLayer.querySelector(s.autoULWrap);
    this.htCachedData = {};
  }

  registerEvents() {
    this.elInputFieldWrap.addEventListener('touchend',  (evt) => this.handlerInputWrap(evt));
    this.elInputField.addEventListener('keypress',      (evt) => this.handlerInputKeyPress(evt));
    this.elInputField.addEventListener('keydown',       (evt) => this.handlerInputKeydown(evt));
    this.elInputField.addEventListener('input',         (evt) => this.handlerInputKeyInput(evt));
    this.elCloseButton.addEventListener('touchend',     (evt) => this.handlerCloseLayer(evt));
    this.elClearQueryBtn.addEventListener('touchend',   (evt) => this.handlerClearInputValue(evt));
    this.elAutoULWrap.addEventListener('touchstart',    (evt) => this.handlerSelectAutoCompletedWordTouchStart(evt));
    this.elAutoULWrap.addEventListener('touchend',      (evt) => this.handlerSelectAutoCompletedWordTouchEnd(evt));
  }

  /***** START EventHandler *****/
  handlerInputWrap(evt) {
    super.runCustomFn('USER', 'FN_AFTER_FOCUS');
    super.runCustomFn('PLUGIN', 'FN_AFTER_FOCUS');
    this.elInputField.focus();
  }

  //if need something executing of inputed value
  handlerInputKeyPress(evt) {}

  //if need something executing of inputed special key value.(e.g. keycode 8: backspace)
  handlerInputKeydown(evt) {}

  handlerInputKeyInput(evt) {
    let sInputData = this.elInputField.value;
    if (sInputData.length > 0 ) _cu.setCSS(this.elClearQueryBtn, 'display', 'inline-block');
    else _cu.closeLayer(this.elClearQueryBtn);

    super.runCustomFn('PLUGIN', 'FN_AFTER_INPUT');

    if (typeof this.htCachedData[sInputData] === 'undefined') this.autoCompleteRequestManager(sInputData);
    else this.execAfterAutoCompleteAjax(sInputData, this.htCachedData[sInputData]);
  }

  handlerClearInputValue(evt) {
    this.elInputField.value = '';
    this.handlerCloseLayer();
    _cu.closeLayer(this.elClearQueryBtn);
	//evt.stopPropagation();
  }

  handlerCloseLayer(evt) {
    _cu.closeLayer(this.elAutoCompleteLayer);
  }

  handlerSelectAutoCompletedWordTouchStart(evt) {
    this.htTouchStartSelectedWord = {'x' : evt.changedTouches[0].pageX, 'y' : evt.changedTouches[0].pageY};
  }

  handlerSelectAutoCompletedWordTouchEnd(evt) {
    let nowPageY = evt.changedTouches[0].pageY;

    if (this.isExecuteTouchScroll(nowPageY)) return;

    let sQueryText = super.runCustomFn('USER', 'FN_AFTER_SELECT_AUTO_WORD', evt.target);
    _cu.closeLayer(this.elAutoCompleteLayer);
	//if keyword is selected, save to storage.
    super.runCustomFn('PLUGIN', 'FN_AFTER_SUBMIT', sQueryText);
  }

  isExecuteTouchScroll(pageY) {
    var nDiff = this.htTouchStartSelectedWord.y - pageY;
    if (nDiff !== 0) return true;
    return false;
  }

  execAfterAutoCompleteAjax(sQuery, sResult) {
    super.runCustomFn('USER', 'FN_AFTER_INSERT_AUTO_WORD', sQuery, sResult);

    if (this.elAutoCompleteLayer.querySelector('li') !== null) {
      _cu.showLayer(this.elAutoCompleteLayer);
      super.runCustomFn('PLUGIN', 'FN_AFTER_AC_SHOW');
    } else  {
      _cu.closeLayer(this.elAutoCompleteLayer);
      super.runCustomFn('PLUGIN', 'FN_AFTER_AC_NONE');
    }

	//save history
    this.htCachedData[sQuery] = sResult;
  }

  autoCompleteRequestManager(sQuery) {
    let url = null;
    let type = this.option.AjaxRequestType;

    switch (type) {
      case 'jsonp': {
        url = this.option.sAutoCompleteURL;
        this.makeAutoCompleteJSONPRequest(sQuery,url);
        break;
      }
      case 'ajax': {
        url = this.option.sAutoCompleteURL;
        this.makeAutoCompleteAjaxRequest(sQuery,url);
        break;
      }
      case 'user': {
        super.runCustomFn('USER', 'FN_RUN_AJAX_EXECUTE', sQuery, this.execAfterAutoCompleteAjax.bind(this, sQuery));
        break;
      }
      default: {
        super.runCustomFn('USER', 'FN_RUN_AJAX_EXECUTE', sQuery);
      }
    }
  }

  makeAutoCompleteJSONPRequest(sQuery, sURL) {
    let sCallbackName = this.option.jsonp_callbackName;
    _cu.sendSimpleJSONP(sURL, sQuery, sCallbackName, this.execAfterAutoCompleteAjax.bind(this,sQuery));
  }

  //query name is 'qs'.
  makeAutoCompleteAjaxRequest(sQuery, sURL) {
    sURL = sURL+'?qs='+sQuery;
    let aHeaders = '';
    _cu.sendSimpleAjax(sURL, this.execAfterAutoCompleteAjax.bind(this, sQuery),
      JSON.stringify({
        sQuery: sQuery,
        nTime: Date.now()
      }),
    'get', aHeaders, sQuery);
  }
}
<commit_msg>Fix. Close autoCompleteLayer after empty input value<commit_after>/*
* The MIT License (MIT)
* Copyright (c) 2016 SK PLANET. All Rights Reserved. *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the 'Software'), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. *
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. */

/*!
* \SweetSearch.js
* \core source for auto-complete UI
* \copyright Copyright (c) 2016, SK PLANET. All Rights Reserved.
* \license This project is released under the MIT License.
* \contributor Jisu Youn (jisu.youn@gmail.com)
* \warning dont'use this source in other library source.
*/

class SweetSearch extends CommonComponent {
  COMPONENT_CONFIG() {
    return {
	  PLUGINS: ['RecentWordPlugin', 'TTViewPlugin'],
	    SELECTOR: {
		  inputFieldWrap: '.input-wrap',
		  inputField: '.input-field',
		  autoCompleteWrap: '.auto-complete-wrap',
		  closeLayer: '.close-layer',
		  clearQueryBtn: '.clear-query',
		  autoULWrap: '.auto-complete-wrap .ul-wrap',
		  realForm: '#search-form'
		},
		DEFAULT_EVENT: [
		  'FN_AFTER_INSERT_AUTO_WORD',
		  'FN_AFTER_SELECT_AUTO_WORD',
		  'FN_AFTER_FOCUS',
		  'FN_RUN_AJAX_EXECUTE'
		],
		DEFAULT_PLUGIN_EVENT: [
		  'FN_AFTER_FOCUS',
		  'FN_AFTER_INPUT',
		  'FN_AFTER_SUBMIT',
		  'FN_AFTER_AC_SHOW',
		  'FN_AFTER_AC_NONE'
		],
		DEFAULT_OPTION: {
		  'AjaxRequestType': 'jsonp',
		  'sAutoCompleteURL': '',
		  'jsonp_callbackName': ''
		}
	}
  }

  constructor(elTarget, htOption) {
    super(elTarget, htOption);
  }

  initValue(htOption) {
    let _el = this.elTarget;
    let s = this.COMPONENT_CONFIG().SELECTOR;

    this.elInputFieldWrap = _el.querySelector(s.inputFieldWrap);
    this.elInputField = _el.querySelector(s.inputField);
    this.elAutoCompleteLayer = _el.querySelector(s.autoCompleteWrap);
    this.elClearQueryBtn = _el.querySelector(s.clearQueryBtn);
    this.elForm = _el.querySelector(s.realForm);
    this.elCloseButton = this.elAutoCompleteLayer.querySelector(s.closeLayer);
    this.elAutoULWrap = this.elAutoCompleteLayer.querySelector(s.autoULWrap);
    this.htCachedData = {};
  }

  registerEvents() {
    this.elInputFieldWrap.addEventListener('touchend',  (evt) => this.handlerInputWrap(evt));
    this.elInputField.addEventListener('keypress',      (evt) => this.handlerInputKeyPress(evt));
    this.elInputField.addEventListener('keydown',       (evt) => this.handlerInputKeydown(evt));
    this.elInputField.addEventListener('input',         (evt) => this.handlerInputKeyInput(evt));
    this.elCloseButton.addEventListener('touchend',     (evt) => this.handlerCloseLayer(evt));
    this.elClearQueryBtn.addEventListener('touchend',   (evt) => this.handlerClearInputValue(evt));
    this.elAutoULWrap.addEventListener('touchstart',    (evt) => this.handlerSelectAutoCompletedWordTouchStart(evt));
    this.elAutoULWrap.addEventListener('touchend',      (evt) => this.handlerSelectAutoCompletedWordTouchEnd(evt));
  }

  /***** START EventHandler *****/
  handlerInputWrap(evt) {
    super.runCustomFn('USER', 'FN_AFTER_FOCUS');
    super.runCustomFn('PLUGIN', 'FN_AFTER_FOCUS');
    this.elInputField.focus();
  }

  //if need something executing of inputed value
  handlerInputKeyPress(evt) {}

  //if need something executing of inputed special key value.(e.g. keycode 8: backspace)
  handlerInputKeydown(evt) {}

  handlerInputKeyInput(evt) {
    let sInputData = this.elInputField.value;
    if (sInputData.length > 0 ) _cu.setCSS(this.elClearQueryBtn, 'display', 'inline-block');
    else {
	    _cu.closeLayer(this.elClearQueryBtn);
	    _cu.closeLayer(this.elAutoCompleteLayer);
	}

    super.runCustomFn('PLUGIN', 'FN_AFTER_INPUT');

    if (typeof this.htCachedData[sInputData] === 'undefined') this.autoCompleteRequestManager(sInputData);
    else this.execAfterAutoCompleteAjax(sInputData, this.htCachedData[sInputData]);
  }

  handlerClearInputValue(evt) {
    this.elInputField.value = '';
    this.handlerCloseLayer();
    _cu.closeLayer(this.elClearQueryBtn);
	//evt.stopPropagation();
  }

  handlerCloseLayer(evt) {
    _cu.closeLayer(this.elAutoCompleteLayer);
  }

  handlerSelectAutoCompletedWordTouchStart(evt) {
    this.htTouchStartSelectedWord = {'x' : evt.changedTouches[0].pageX, 'y' : evt.changedTouches[0].pageY};
  }

  handlerSelectAutoCompletedWordTouchEnd(evt) {
    let nowPageY = evt.changedTouches[0].pageY;

    if (this.isExecuteTouchScroll(nowPageY)) return;

    let sQueryText = super.runCustomFn('USER', 'FN_AFTER_SELECT_AUTO_WORD', evt.target);
    _cu.closeLayer(this.elAutoCompleteLayer);
	//if keyword is selected, save to storage.
    super.runCustomFn('PLUGIN', 'FN_AFTER_SUBMIT', sQueryText);
  }

  isExecuteTouchScroll(pageY) {
    var nDiff = this.htTouchStartSelectedWord.y - pageY;
    if (nDiff !== 0) return true;
    return false;
  }

  execAfterAutoCompleteAjax(sQuery, sResult) {
    super.runCustomFn('USER', 'FN_AFTER_INSERT_AUTO_WORD', sQuery, sResult);

    if (this.elAutoCompleteLayer.querySelector('li') !== null) {
      _cu.showLayer(this.elAutoCompleteLayer);
      super.runCustomFn('PLUGIN', 'FN_AFTER_AC_SHOW');
    } else  {
      _cu.closeLayer(this.elAutoCompleteLayer);
      super.runCustomFn('PLUGIN', 'FN_AFTER_AC_NONE');
    }

	//save history
    this.htCachedData[sQuery] = sResult;
  }

  autoCompleteRequestManager(sQuery) {
    let url = null;
    let type = this.option.AjaxRequestType;

    switch (type) {
      case 'jsonp': {
        url = this.option.sAutoCompleteURL;
        this.makeAutoCompleteJSONPRequest(sQuery,url);
        break;
      }
      case 'ajax': {
        url = this.option.sAutoCompleteURL;
        this.makeAutoCompleteAjaxRequest(sQuery,url);
        break;
      }
      case 'user': {
        super.runCustomFn('USER', 'FN_RUN_AJAX_EXECUTE', sQuery, this.execAfterAutoCompleteAjax.bind(this, sQuery));
        break;
      }
      default: {
        super.runCustomFn('USER', 'FN_RUN_AJAX_EXECUTE', sQuery);
      }
    }
  }

  makeAutoCompleteJSONPRequest(sQuery, sURL) {
    let sCallbackName = this.option.jsonp_callbackName;
    _cu.sendSimpleJSONP(sURL, sQuery, sCallbackName, this.execAfterAutoCompleteAjax.bind(this,sQuery));
  }

  //query name is 'qs'.
  makeAutoCompleteAjaxRequest(sQuery, sURL) {
    sURL = sURL+'?qs='+sQuery;
    let aHeaders = '';
    _cu.sendSimpleAjax(sURL, this.execAfterAutoCompleteAjax.bind(this, sQuery),
      JSON.stringify({
        sQuery: sQuery,
        nTime: Date.now()
      }),
    'get', aHeaders, sQuery);
  }
}
<|endoftext|>


<commit_before>import store2 from 'store2';
import { EventEmitter } from 'events';

const STORE_NAMESPACE = 'soundboard';

class SettingsManager {

  store;

  eventEmitter;

  constructor() {
    this.store = store2.namespace(STORE_NAMESPACE);
    this.eventEmitter = new EventEmitter();
  }

  set(key, value, overwrite = true) {
    this.eventEmitter.emit(key, value);
    return this.store.set(key, value, overwrite);
  }

  get(key, alt) {
    return this.store.get(key, alt);
  }

  getAll() {
    return {
      theme: this.store.get('theme', 'default'),
    };
  }

  setAll(settings) {
    Object.keys(settings).forEach((key) => {
      this.eventEmitter.emit(key, settings[key]);
    });

    this.store.setAll(settings);
  }

  on(key, callback) {
    this.eventEmitter.on(key, callback);
  }

}

export default SettingsManager;
<commit_msg>Improve default handling in SettingsManager<commit_after>import store2 from 'store2';
import EventEmitter from 'events';

const STORE_NAMESPACE = 'soundboard';

const DEFAULT_SETTINGS = {
  theme: 'default',
};

class SettingsManager extends EventEmitter {

  store;

  constructor() {
    // Init store with namespace
    this.store = store2.namespace(STORE_NAMESPACE);
    // Set default settings, without overwrite
    this.store.setAll(DEFAULT_SETTINGS, false);
  }

  set(key, value, overwrite = true) {
    this.emit(key, value);
    return this.store.set(key, value, overwrite);
  }

  get(key) {
    return this.store.get(key);
  }

  getAll() {
    return this.store.getAll();
  }

  setAll(settings) {
    Object.keys(settings).forEach((key) => {
      this.emit(key, settings[key]);
    });

    this.store.setAll(settings);
  }

}

export default SettingsManager;
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import Const from './Const';
import classSet from 'classnames';
import SelectRowHeaderColumn from './SelectRowHeaderColumn';

class Checkbox extends Component {
  componentDidMount() { this.update(this.props.checked); }
  componentWillReceiveProps(props) { this.update(props.checked); }
  update(checked) {
    ReactDOM.findDOMNode(this).indeterminate = checked === 'indeterminate';
  }
  render() {
    return (
      <input className='react-bs-select-all'
        type='checkbox'
        checked={ this.props.checked }
        onChange={ this.props.onChange } />
    );
  }
}

class TableHeader extends Component {

  render() {
    const containerClasses = classSet('react-bs-container-header', 'table-header-wrapper');
    const tableClasses = classSet('table', 'table-hover', {
      'table-bordered': this.props.bordered,
      'table-condensed': this.props.condensed
    });
    let selectRowHeaderCol = null;
    if (!this.props.hideSelectColumn) selectRowHeaderCol = this.renderSelectRowHeader();
    this._attachClearSortCaretFunc();

    return (

              { selectRowHeaderCol }
              { this.props.children }

    );
  }

  renderSelectRowHeader() {
    if (this.props.rowSelectType === Const.ROW_SELECT_SINGLE) {
      return (<SelectRowHeaderColumn />);
    } else if (this.props.rowSelectType === Const.ROW_SELECT_MULTI) {
      return (
        <SelectRowHeaderColumn>
          <Checkbox
            onChange={ this.props.onSelectAllRow }
            checked={ this.props.isSelectAll }/>
        </SelectRowHeaderColumn>
      );
    } else {
      return null;
    }
  }

  _attachClearSortCaretFunc() {
    const { sortIndicator, children, sortName, sortOrder, onSort } = this.props;
    if (Array.isArray(children)) {
      for (let i = 0; i < children.length; i++) {
        const { dataField, dataSort } = children[i].props;
        const sort = (dataSort && dataField === sortName) ? sortOrder : undefined;
        this.props.children[i] =
          React.cloneElement(children[i],
            { key: i, onSort, sort, sortIndicator });
      }
    } else {
      const { dataField, dataSort } = children.props;
      const sort = (dataSort && dataField === sortName) ? sortOrder : undefined;
      this.props.children =
        React.cloneElement(children,
          { key: 0, onSort, sort, sortIndicator });
    }
  }
}
TableHeader.propTypes = {
  style: PropTypes.object,
  rowSelectType: PropTypes.string,
  onSort: PropTypes.func,
  onSelectAllRow: PropTypes.func,
  sortName: PropTypes.string,
  sortOrder: PropTypes.string,
  hideSelectColumn: PropTypes.bool,
  bordered: PropTypes.bool,
  condensed: PropTypes.bool,
  isFiltered: PropTypes.bool,
  isSelectAll: PropTypes.oneOf([ true, 'indeterminate', false ]),
  sortIndicator: PropTypes.bool
};

export default TableHeader;
<commit_msg>fix #424<commit_after>import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import Const from './Const';
import classSet from 'classnames';
import SelectRowHeaderColumn from './SelectRowHeaderColumn';

class Checkbox extends Component {
  componentDidMount() { this.update(this.props.checked); }
  componentWillReceiveProps(props) { this.update(props.checked); }
  update(checked) {
    ReactDOM.findDOMNode(this).indeterminate = checked === 'indeterminate';
  }
  render() {
    return (
      <input className='react-bs-select-all'
        type='checkbox'
        checked={ this.props.checked }
        onChange={ this.props.onChange } />
    );
  }
}

class TableHeader extends Component {

  render() {
    const containerClasses = classSet('react-bs-container-header', 'table-header-wrapper');
    const tableClasses = classSet('table', 'table-hover', {
      'table-bordered': this.props.bordered,
      'table-condensed': this.props.condensed
    });
    let selectRowHeaderCol = null;
    if (!this.props.hideSelectColumn) selectRowHeaderCol = this.renderSelectRowHeader();
    let i = 0;
    return (

              { selectRowHeaderCol }
              {
                React.Children.map(this.props.children, (elm) => {
                  const { sortIndicator, sortName, sortOrder, onSort } = this.props;
                  const { dataField, dataSort } = elm.props;
                  const sort = (dataSort && dataField === sortName) ? sortOrder : undefined;
                  return React.cloneElement(elm, { key: i++, onSort, sort, sortIndicator });
                })
              }

    );
  }

  renderSelectRowHeader() {
    if (this.props.rowSelectType === Const.ROW_SELECT_SINGLE) {
      return (<SelectRowHeaderColumn />);
    } else if (this.props.rowSelectType === Const.ROW_SELECT_MULTI) {
      return (
        <SelectRowHeaderColumn>
          <Checkbox
            onChange={ this.props.onSelectAllRow }
            checked={ this.props.isSelectAll }/>
        </SelectRowHeaderColumn>
      );
    } else {
      return null;
    }
  }
}
TableHeader.propTypes = {
  style: PropTypes.object,
  rowSelectType: PropTypes.string,
  onSort: PropTypes.func,
  onSelectAllRow: PropTypes.func,
  sortName: PropTypes.string,
  sortOrder: PropTypes.string,
  hideSelectColumn: PropTypes.bool,
  bordered: PropTypes.bool,
  condensed: PropTypes.bool,
  isFiltered: PropTypes.bool,
  isSelectAll: PropTypes.oneOf([ true, 'indeterminate', false ]),
  sortIndicator: PropTypes.bool
};

export default TableHeader;
<|endoftext|>


<commit_before>function ajaxChimpCallback(a) {
    if ("success" === a.result) {
        $(".beta-request-result").show();
        $(".beta-request-form").hide();
        $(".beta-request-title").hide();
        $.featherlight.current().close();
    }
    else
    {
        a.msg.indexOf("already subscribed") >= 0 ? ($(".beta-request-form").hide(), $(".beta-request-title").hide(), $(".beta-request-already-subscribed").show()) : $(".beta-request-error").show(), $(".beta-request-btn").html("Invite me")
    }
};
function contactLightbox()
{
    var configuration = ({
        afterOpen: function(event)
        {
            $('body').toggleClass('body-open-modal');
            setContactTabindex();
            sendContactMessage();
        },
        afterClose: function(event)
        {
            $('body').toggleClass('body-open-modal');
        }
    });
    $('body').on('click', '.open-contact-form', function(event)
    {
        event.preventDefault();
        $.featherlight('#contactLightbox', configuration);
    });
}
function setContactTabindex()
{
    var $form = $('.featherlight-content form.sendingContactMessage');
    $form.find('input[name=from_name]').focus().attr('tabindex', 1);
    $form.find('input[name=from_email]').attr('tabindex', 2);
    $form.find('textarea[name=message]').attr('tabindex', 3);
}
function setBetaTabIndex()
{
    var $form = $('.beta-request-form');
    $form.find('.first-name').focus().attr('tabindex', 1);
    $form.find('.email').attr('tabindex', 2);
}
function sendContactMessage()
{
    $('.featherlight-content form.sendingContactMessage').validate({
        rules: {
            from_name: "required",
            from_email: {
                required: true,
                email: true
            },
            message: "required"
        },
        messages: {
            from_name: "Please enter your name",
            from_email: "Please enter a valid email address",
            message: "Please enter a message."
        },
        submitHandler: function(form, event) {
            event.preventDefault();

            var $form = $('.featherlight-content form.sendingContactMessage'),
                service_id = "default_service",
                template_id = "trado_contact_message",
                currentModal = $.featherlight.current();
                params = $form.serializeArray().reduce(function(obj, item) {
                    obj[item.name] = item.value;
                    return obj;
                }, {});

            $form.find('input').prop('disabled', true);
            $form.find('textarea').prop('disabled', true);
            $form.find("button").text("Sending...");
            $('#errors, #success').html('');

            emailjs.send(service_id,template_id,params)
                .then(function(){
                    $form.find('#success').html('
Message has been sent. We will get back to you within 24 hours.
');
                    setTimeout(function(){
                        currentModal.close();
                        $form.find('input').prop('disabled', false);
                        $form.find('textarea').prop('disabled', false);
                        $form.find("button").text("Send");
                    }, 5000);
                }, function(err) {
                    $form.find('input').prop('disabled', false);
                    $form.find('textarea').prop('disabled', false);
                    $form.find("#errors").html('
' + JSON.parse(err.text).service_error + '
');
                    $form.find("button").text("Send");
                });
        }
    });
}
function scrollingNavbar()
{
    $(window).on('scroll', function() {
        var y_scroll_pos = window.pageYOffset;
        var scroll_pos_test = 150;             // set to whatever you want it to be

        if(y_scroll_pos > scroll_pos_test)
        {
            $('header.scrolling').fadeIn();
            $('#home-layout .slicknav_menu').addClass('home-scrolling');
        }
        else
        {
            $('header.scrolling').stop().fadeOut();
            $('#home-layout .slicknav_menu').removeClass('home-scrolling');
        }
    });
    $('.menu').slicknav({
        label: "",
        brand: ""
    });
}
function betaLightbox()
{
    $(".beta-request-form").ajaxChimp({
        url: "http://tomdallimore.us9.list-manage.com/subscribe/post?u=b141eef8b30b7dc5813bd752a&id=95c7eadbb9",
        callback: ajaxChimpCallback
    });
    $(".beta-request-form").submit(function() {
        ga("send", "event", "invite", "request");
        $(".beta-request-btn").html("");
        $(".beta-request-error").hide();
        $(".beta-request-already-subscribed").hide();
    });
    if (!readCookie('tradoPopup'))
    {
        var configuration = ({
            afterOpen: function(event)
            {
                $('body').toggleClass('body-open-modal');
                setBetaTabIndex();
                sendContactMessage();
            },
            afterClose: function(event)
            {
                $('body').toggleClass('body-open-modal');
            }
        });
        setTimeout( function()
        {
            $.featherlight('#newsletterLightbox', configuration);
            createCookie('tradoPopup','1',1);
        }, 3000);
    }
}
$(document).ready(function() {

    contactLightbox();
    betaLightbox();
    scrollingNavbar();

    if(!$('html').hasClass('touch'))
    {
        $(".first-name").first().focus();
    }else{
        bouncefix.add('html');
    }
    $('[data-ga="true"]').click(function()
    {
        var dataCategory    = $(this).attr('data-event-category'),
            dataAction      = $(this).attr('data-event-action');
        if(dataCategory == '' || dataAction == '')
        {
            return false;
        }
        else
        {
            ga("send", "event", dataCategory, dataAction);
        }
    });
});
jQuery.fn.capitalize = function() {
    return $(this).each(function(a, b) {
        $(b).keyup(function(a) {
            var b = a.target,
                c = $(this).val(),
                d = b.selectionStart,
                e = b.selectionEnd;
            $(this).val(c.replace(/^(.)|(\s|\-)(.)/g, function(a) {
                return a.toUpperCase()
            })), b.setSelectionRange(d, e)
        })
    }), this
};
$(".first-name").capitalize();
$('#documentation .content, #documentation .sidebar').theiaStickySidebar(
{
    additionalMarginTop: 120
});

// cookies
function createCookie(name,value,days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + value + expires + "; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}<commit_msg>Fixed https error.<commit_after>function ajaxChimpCallback(a) {
    if ("success" === a.result) {
        $(".beta-request-result").show();
        $(".beta-request-form").hide();
        $(".beta-request-title").hide();
        $.featherlight.current().close();
    }
    else
    {
        a.msg.indexOf("already subscribed") >= 0 ? ($(".beta-request-form").hide(), $(".beta-request-title").hide(), $(".beta-request-already-subscribed").show()) : $(".beta-request-error").show(), $(".beta-request-btn").html("Invite me")
    }
};
function contactLightbox()
{
    var configuration = ({
        afterOpen: function(event)
        {
            $('body').toggleClass('body-open-modal');
            setContactTabindex();
            sendContactMessage();
        },
        afterClose: function(event)
        {
            $('body').toggleClass('body-open-modal');
        }
    });
    $('body').on('click', '.open-contact-form', function(event)
    {
        event.preventDefault();
        $.featherlight('#contactLightbox', configuration);
    });
}
function setContactTabindex()
{
    var $form = $('.featherlight-content form.sendingContactMessage');
    $form.find('input[name=from_name]').focus().attr('tabindex', 1);
    $form.find('input[name=from_email]').attr('tabindex', 2);
    $form.find('textarea[name=message]').attr('tabindex', 3);
}
function setBetaTabIndex()
{
    var $form = $('.beta-request-form');
    $form.find('.first-name').focus().attr('tabindex', 1);
    $form.find('.email').attr('tabindex', 2);
}
function sendContactMessage()
{
    $('.featherlight-content form.sendingContactMessage').validate({
        rules: {
            from_name: "required",
            from_email: {
                required: true,
                email: true
            },
            message: "required"
        },
        messages: {
            from_name: "Please enter your name",
            from_email: "Please enter a valid email address",
            message: "Please enter a message."
        },
        submitHandler: function(form, event) {
            event.preventDefault();

            var $form = $('.featherlight-content form.sendingContactMessage'),
                service_id = "default_service",
                template_id = "trado_contact_message",
                currentModal = $.featherlight.current();
                params = $form.serializeArray().reduce(function(obj, item) {
                    obj[item.name] = item.value;
                    return obj;
                }, {});

            $form.find('input').prop('disabled', true);
            $form.find('textarea').prop('disabled', true);
            $form.find("button").text("Sending...");
            $('#errors, #success').html('');

            emailjs.send(service_id,template_id,params)
                .then(function(){
                    $form.find('#success').html('
Message has been sent. We will get back to you within 24 hours.
');
                    setTimeout(function(){
                        currentModal.close();
                        $form.find('input').prop('disabled', false);
                        $form.find('textarea').prop('disabled', false);
                        $form.find("button").text("Send");
                    }, 5000);
                }, function(err) {
                    $form.find('input').prop('disabled', false);
                    $form.find('textarea').prop('disabled', false);
                    $form.find("#errors").html('
' + JSON.parse(err.text).service_error + '
');
                    $form.find("button").text("Send");
                });
        }
    });
}
function scrollingNavbar()
{
    $(window).on('scroll', function() {
        var y_scroll_pos = window.pageYOffset;
        var scroll_pos_test = 150;             // set to whatever you want it to be

        if(y_scroll_pos > scroll_pos_test)
        {
            $('header.scrolling').fadeIn();
            $('#home-layout .slicknav_menu').addClass('home-scrolling');
        }
        else
        {
            $('header.scrolling').stop().fadeOut();
            $('#home-layout .slicknav_menu').removeClass('home-scrolling');
        }
    });
    $('.menu').slicknav({
        label: "",
        brand: ""
    });
}
function betaLightbox()
{
    $(".beta-request-form").ajaxChimp({
        url: "https://tomdallimore.us9.list-manage.com/subscribe/post?u=b141eef8b30b7dc5813bd752a&id=95c7eadbb9",
        callback: ajaxChimpCallback
    });
    $(".beta-request-form").submit(function() {
        ga("send", "event", "invite", "request");
        $(".beta-request-btn").html("");
        $(".beta-request-error").hide();
        $(".beta-request-already-subscribed").hide();
    });
    if (!readCookie('tradoPopup'))
    {
        var configuration = ({
            afterOpen: function(event)
            {
                $('body').toggleClass('body-open-modal');
                setBetaTabIndex();
                sendContactMessage();
            },
            afterClose: function(event)
            {
                $('body').toggleClass('body-open-modal');
            }
        });
        setTimeout( function()
        {
            $.featherlight('#newsletterLightbox', configuration);
            createCookie('tradoPopup','1',1);
        }, 3000);
    }
}
$(document).ready(function() {

    contactLightbox();
    betaLightbox();
    scrollingNavbar();

    if(!$('html').hasClass('touch'))
    {
        $(".first-name").first().focus();
    }else{
        bouncefix.add('html');
    }
    $('[data-ga="true"]').click(function()
    {
        var dataCategory    = $(this).attr('data-event-category'),
            dataAction      = $(this).attr('data-event-action');
        if(dataCategory == '' || dataAction == '')
        {
            return false;
        }
        else
        {
            ga("send", "event", dataCategory, dataAction);
        }
    });
});
jQuery.fn.capitalize = function() {
    return $(this).each(function(a, b) {
        $(b).keyup(function(a) {
            var b = a.target,
                c = $(this).val(),
                d = b.selectionStart,
                e = b.selectionEnd;
            $(this).val(c.replace(/^(.)|(\s|\-)(.)/g, function(a) {
                return a.toUpperCase()
            })), b.setSelectionRange(d, e)
        })
    }), this
};
$(".first-name").capitalize();
$('#documentation .content, #documentation .sidebar').theiaStickySidebar(
{
    additionalMarginTop: 120
});

// cookies
function createCookie(name,value,days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + value + expires + "; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}<|endoftext|>


<commit_before>//BoardEngine Depends on a pieceEngine.js and cellEngine.js

// BoardEngine() will return a new Board.
var BoardEngine = function () {  // jshint ignore:line
    "use strict";

    function Board() {
        this.height = 22;
        this.width = 10;
        this.usedCells = [[]];
        this.newBoard();
        this.settings = {
            canHold: true,
            useGhost: true,
            canPreview: true,
            fullScreen: false,
            announcer: true,
            useAutoSave: false
        };
        this.gameOver = false;
        this.justHeld = false;
        this.score = new Score(); // jshint ignore:line
        this.fallingPiece = false;
        this.heldPiece = false;
        this.started = false;
        this.pieceEngine = new PieceEngine();  // jshint ignore:line
    }
    //Get a 2d array of the usedCells for mapping.
    Board.prototype.getCurrentBoard = function () {
        var board = [];
        for (var i = 0; i < this.height; i++) {
            board[i] = [];
            for (var j = 0; j < this.width; j++) {
                board[i].push(this.usedCells[i][j].copy());
            }
        }
        if (this.fallingPiece) {
            if (this.settings.useGhost) {
                this.fallingPiece.ghost(this).cells().map(function (cell) {
                    board[cell.y][cell.x] = cell.copy();
                });
            }
            this.fallingPiece.cells().map(function (cell) {
                board[cell.y][cell.x] = cell.copy();
            });
        }
        return board;
    };
    //Get one and only one cell with provided x and y.
    Board.prototype.getCell = function (cellGiven) {
        var cellToReturn = null;
        if (this.cellOnBoard(cellGiven)) {
            cellToReturn = this.usedCells[cellGiven.y][cellGiven.x].copy();
        } else {
            cellToReturn = new Cell(cellGiven.x, cellGiven.y);  // jshint ignore:line
            cellToReturn.type = 4;
        }
        return cellToReturn;
    };

    Board.prototype.canAddCell = function (cell) {
        var cellToUse = this.getCell(cell);
        return this.cellOnBoard(cell) && cellToUse.type !== 4 && cell.collides(cellToUse) && cellToUse.type === 3;
    };
    Board.prototype.canAddCells = function (cells) {
        var cellsCanBeAdded = true;
        for (var i = 0; i < cells.length; i++) {
            if (!this.canAddCell(cells[i])) {
                cellsCanBeAdded = false;
            }
        }
        return cellsCanBeAdded;
    };
    Board.prototype.addCell = function (cell) {
        var added = false;
        if (this.canAddCell(cell)) {
            var cellCopy = cell.copy();
            cellCopy.type = 2;
            this.usedCells[cell.y][cell.x] = cellCopy;
            added = true;
        }
        return added;
    };
    Board.prototype.cellOnBoard = function (cellGiven) {
        return cellGiven.x < this.width && cellGiven.y < this.height && cellGiven.x >= 0 && cellGiven.y >= 0;
    };
    //Takes A defined Piece and adds it if it can be placed;
    Board.prototype.addPiece = function (piece) {
        var added = false;
        if (this.canAddPiece(piece)) {
            var pieceCells = piece.cells();
            for (var i = 0; i < pieceCells.length; i++) {
                this.addCell(pieceCells[i]);
            }
            added = true;
        }
        this.clearLines();
        if (piece.equals(this.fallingPiece) && added) {
            this.newFallingPiece();
        }
        return added;
    };
    //Clears all Lines that are full.
    Board.prototype.clearLines = function () {
        var blankRow = function () {
            var row = [];
            for (var j = 0; j < 10; j++) {
                row[j] = new Cell(0, j, "lightgrey", "empty", 3);  // jshint ignore:line
            }
            return row;
        };
        var occupiedRows = [];
        this.usedCells.map(function (row, rowIndex) {
            var allOccupied = true;
            row.map(function (cell) {
                if (cell.type !== 2) {
                    allOccupied = false;
                }
            });
            if (allOccupied) {
                occupiedRows.push(rowIndex);
            }
            return allOccupied;
        });
        if (occupiedRows.length > 0) {
            this.score.didScore(occupiedRows.length);
        }
        for (var i = 0; i < occupiedRows.length; i++) {
            this.usedCells.splice(occupiedRows[i], 1);
            this.usedCells.unshift(blankRow());
            this.usedCells.map(function (row, y) {
                row.map(function (cell, x) {
                    cell.x = x;
                    cell.y = y;
                });
            });  // jshint ignore:line
        }
    };
    //Takes a piece and tells you if it can be added;
    Board.prototype.canAddPiece = function (piece) {
        var pieceCells = piece.cells();
        return this.canAddCells(pieceCells);
    };

    Board.prototype.holdPiece = function () {
        if (!this.justHeld && this.settings.canHold) {
            var previousHeld = this.heldPiece;
            this.heldPiece = this.fallingPiece.tetromino;
            if (previousHeld) {
                this.fallingPiece = new this.pieceEngine.newPiece(previousHeld);
            } else {
                this.newFallingPiece();
            }
            this.justHeld = true;
        }
    };

    Board.prototype.newFallingPiece = function () {
        if (!this.isGameOver()) {
            this.fallingPiece = this.pieceEngine.draw();
            this.justHeld = false;
            //this.ghostPiece = this.fallingPiece.ghost(this);
        }
    };

    Board.prototype.dropFallingPiece = function () {
        this.fallingPiece.dropPiece(this);
        this.addPiece(this.fallingPiece);
        this.score.didScore(0);
        return true;
    };
    Board.prototype.rotateFallingClockWise = function () {
        return this.fallingPiece.rotateClockWise(this);
    };
    Board.prototype.rotateFallingCounterClockWise = function () {
        return this.fallingPiece.rotateCounterClockWise(this);
    };
    Board.prototype.shiftFallingLeft = function () {
        return this.fallingPiece.shiftLeft(this);
    };
    Board.prototype.shiftFallingRight = function () {
        return this.fallingPiece.shiftRight(this);
    };
    Board.prototype.moveFallingDown = function () {
        var moved = this.fallingPiece.movePieceDown(this);
        if (moved) {
            this.score.didScore(5);
        }
        return moved;
    };
    Board.prototype.restart = function () {
        this.newBoard();
        this.gameOver = false;
        this.justHeld = false;
        this.level = 0;
        this.fallingPiece = false;
        this.heldPiece = false;
        this.score = new Score();   // jshint ignore:line
        this.started = false;
    };
    Board.prototype.newBoard = function () {
        for (var i = 0; i < this.height; i++) {
            this.usedCells[i] = [];
            for (var j = 0; j < this.width; j++) {
                this.usedCells[i][j] = new Cell(j, i, "lightgrey", "empty", 3);  // jshint ignore:line
            }
        }
    };
    Board.prototype.getFallingPiece = function () {
        return this.fallingPiece;
    };
    Board.prototype.isGameOver = function () {
        var isGameOver = false;
        var rows = [this.usedCells[0], this.usedCells[1]];
        rows.map(function (row) {
            row.map(function (cell) {
                if (cell.type === 2) {
                    isGameOver = true;
                }
            });
        });
        if (isGameOver) {
            this.gameOver = isGameOver;
        }
        return isGameOver;
    };
    Board.prototype.fromJson = function (previousBoardJSON) {
        previousBoardJSON = JSON.parse(previousBoardJSON);
        this.height = previousBoardJSON.height;
        this.width = previousBoardJSON.width;
        this.usedCells = previousBoardJSON.usedCells.map(function (row) {
            return row.map(function (cell) {
                return new Cell().fromJson(cell);  // jshint ignore:line
            });
        });
        this.settings = {
            canHold: previousBoardJSON.settings.canHold,
            useGhost: previousBoardJSON.settings.useGhost,
            canPreview: previousBoardJSON.settings.canPreview,
            fullScreen: previousBoardJSON.settings.fullScreen,
            announcer: previousBoardJSON.settings.announcer,
            useAutoSave: previousBoardJSON.settings.useAutoSave
        };
        this.gameOver = previousBoardJSON.gameOver;
        this.justHeld = previousBoardJSON.justHeld;
        this.score = new Score().fromJson(previousBoardJSON.score);  // jshint ignore:line
        this.fallingPiece = new this.pieceEngine.newPiece().fromJson(previousBoardJSON.fallingPiece);
        this.heldPiece = previousBoardJSON.heldPiece;
        this.started = previousBoardJSON.started;
        return this;
    };
    return new Board();
};
<commit_msg>Update boardEngine.js<commit_after>//BoardEngine Depends on a pieceEngine.js and cellEngine.js

// BoardEngine() will return a new Board.
var BoardEngine = function () {  // jshint ignore:line
    "use strict";

    function Board() {
        this.height = 22;
        this.width = 10;
        this.usedCells = [[]];
        this.newBoard();
        this.settings = {
            canHold: true,
            useGhost: true,
            canPreview: true,
            fullScreen: false,
            announcer: true,
            useAutoSave: false
        };
        this.gameOver = false;
        this.justHeld = false;
        this.score = new Score(); // jshint ignore:line
        this.fallingPiece = false;
        this.heldPiece = false;
        this.started = false;
        this.pieceEngine = new PieceEngine();  // jshint ignore:line
    }
    //Get a 2d array of the usedCells for mapping.
    Board.prototype.getCurrentBoard = function () {
        var board = [];
        for (var i = 0; i < this.height; i++) {
            board[i] = [];
            for (var j = 0; j < this.width; j++) {
                board[i].push(this.usedCells[i][j].copy());
            }
        }
        if (this.fallingPiece) {
            if (this.settings.useGhost) {
                this.fallingPiece.ghost(this).cells().map(function (cell) {
                    board[cell.y][cell.x] = cell.copy();
                });
            }
            this.fallingPiece.cells().map(function (cell) {
                board[cell.y][cell.x] = cell.copy();
            });
        }
        return board;
    };
    //Get one and only one cell with provided x and y.
    Board.prototype.getCell = function (cellGiven) {
        var cellToReturn = null;
        if (this.cellOnBoard(cellGiven)) {
            cellToReturn = this.usedCells[cellGiven.y][cellGiven.x].copy();
        } else {
            cellToReturn = new Cell(cellGiven.x, cellGiven.y);  // jshint ignore:line
            cellToReturn.type = 4;
        }
        return cellToReturn;
    };

    Board.prototype.canAddCell = function (cell) {
        var cellToUse = this.getCell(cell);
        return this.cellOnBoard(cell) && cellToUse.type !== 4 && cell.collides(cellToUse) && cellToUse.type === 3;
    };
    Board.prototype.canAddCells = function (cells) {
        var cellsCanBeAdded = true;
        for (var i = 0; i < cells.length; i++) {
            if (!this.canAddCell(cells[i])) {
                cellsCanBeAdded = false;
            }
        }
        return cellsCanBeAdded;
    };
    Board.prototype.addCell = function (cell) {
        var added = false;
        if (this.canAddCell(cell)) {
            var cellCopy = cell.copy();
            cellCopy.type = 2;
            this.usedCells[cell.y][cell.x] = cellCopy;
            added = true;
        }
        return added;
    };
    Board.prototype.cellOnBoard = function (cellGiven) {
        return cellGiven.x < this.width && cellGiven.y < this.height && cellGiven.x >= 0 && cellGiven.y >= 0;
    };
    //Takes A defined Piece and adds it if it can be placed;
    Board.prototype.addPiece = function (piece) {
        var added = false;
        if (this.canAddPiece(piece)) {
            var pieceCells = piece.cells();
            for (var i = 0; i < pieceCells.length; i++) {
                this.addCell(pieceCells[i]);
            }
            added = true;
        }
        this.clearLines();
        if (piece.equals(this.fallingPiece) && added) {
            this.newFallingPiece();
        }
        return added;
    };
    //Clears all Lines that are full.
    Board.prototype.clearLines = function () {
        var blankRow = function () {
            var row = [];
            for (var j = 0; j < 10; j++) {
                row[j] = new Cell(0, j, "lightgrey", "empty", 3);  // jshint ignore:line
            }
            return row;
        };
        var occupiedRows = [];
        this.usedCells.map(function (row, rowIndex) {
            var allOccupied = true;
            row.map(function (cell) {
                if (cell.type !== 2) {
                    allOccupied = false;
                }
            });
            if (allOccupied) {
                occupiedRows.push(rowIndex);
            }
            return allOccupied;
        });
        if (occupiedRows.length > 0) {
            this.score.didScore(occupiedRows.length);
        }
        for (var i = 0; i < occupiedRows.length; i++) {
            this.usedCells.splice(occupiedRows[i], 1);
            this.usedCells.unshift(blankRow());
            this.usedCells.map(function (row, y) {
                row.map(function (cell, x) {
                    cell.x = x;
                    cell.y = y;
                });
            });  // jshint ignore:line
        }
    };
    //Takes a piece and tells you if it can be added;
    Board.prototype.canAddPiece = function (piece) {
        var pieceCells = piece.cells();
        return this.canAddCells(pieceCells);
    };

    Board.prototype.holdPiece = function () {
        if (!this.justHeld && this.settings.canHold) {
            var previousHeld = this.heldPiece;
            this.heldPiece = this.fallingPiece.tetromino;
            if (previousHeld) {
                console.log(this.pieceEngine);
                this.fallingPiece = new this.pieceEngine.newPiece(previousHeld);
            } else {
                this.newFallingPiece();
            }
            this.justHeld = true;
        }
    };

    Board.prototype.newFallingPiece = function () {
        if (!this.isGameOver()) {
            this.fallingPiece = this.pieceEngine.draw();
            this.justHeld = false;
            //this.ghostPiece = this.fallingPiece.ghost(this);
        }
    };

    Board.prototype.dropFallingPiece = function () {
        this.fallingPiece.dropPiece(this);
        this.addPiece(this.fallingPiece);
        this.score.didScore(0);
        return true;
    };
    Board.prototype.rotateFallingClockWise = function () {
        return this.fallingPiece.rotateClockWise(this);
    };
    Board.prototype.rotateFallingCounterClockWise = function () {
        return this.fallingPiece.rotateCounterClockWise(this);
    };
    Board.prototype.shiftFallingLeft = function () {
        return this.fallingPiece.shiftLeft(this);
    };
    Board.prototype.shiftFallingRight = function () {
        return this.fallingPiece.shiftRight(this);
    };
    Board.prototype.moveFallingDown = function () {
        var moved = this.fallingPiece.movePieceDown(this);
        if (moved) {
            this.score.didScore(5);
        }
        return moved;
    };
    Board.prototype.restart = function () {
        this.newBoard();
        this.gameOver = false;
        this.justHeld = false;
        this.level = 0;
        this.fallingPiece = false;
        this.heldPiece = false;
        this.score = new Score();   // jshint ignore:line
        this.started = false;
    };
    Board.prototype.newBoard = function () {
        for (var i = 0; i < this.height; i++) {
            this.usedCells[i] = [];
            for (var j = 0; j < this.width; j++) {
                this.usedCells[i][j] = new Cell(j, i, "lightgrey", "empty", 3);  // jshint ignore:line
            }
        }
    };
    Board.prototype.getFallingPiece = function () {
        return this.fallingPiece;
    };
    Board.prototype.isGameOver = function () {
        var isGameOver = false;
        var rows = [this.usedCells[0], this.usedCells[1]];
        rows.map(function (row) {
            row.map(function (cell) {
                if (cell.type === 2) {
                    isGameOver = true;
                }
            });
        });
        if (isGameOver) {
            this.gameOver = isGameOver;
        }
        return isGameOver;
    };
    Board.prototype.fromJson = function (previousBoardJSON) {
        previousBoardJSON = JSON.parse(previousBoardJSON);
        this.height = previousBoardJSON.height;
        this.width = previousBoardJSON.width;
        this.usedCells = previousBoardJSON.usedCells.map(function (row) {
            return row.map(function (cell) {
                return new Cell().fromJson(cell);  // jshint ignore:line
            });
        });
        this.settings = {
            canHold: previousBoardJSON.settings.canHold,
            useGhost: previousBoardJSON.settings.useGhost,
            canPreview: previousBoardJSON.settings.canPreview,
            fullScreen: previousBoardJSON.settings.fullScreen,
            announcer: previousBoardJSON.settings.announcer,
            useAutoSave: previousBoardJSON.settings.useAutoSave
        };
        this.gameOver = previousBoardJSON.gameOver;
        this.justHeld = previousBoardJSON.justHeld;
        this.score = new Score().fromJson(previousBoardJSON.score);  // jshint ignore:line
        this.fallingPiece = new this.pieceEngine.newPiece().fromJson(previousBoardJSON.fallingPiece);
        this.heldPiece = previousBoardJSON.heldPiece;
        this.started = previousBoardJSON.started;
        return this;
    };
    return new Board();
};
<|endoftext|>


<commit_before>import React from 'react/addons';
import Router from 'react-router';
import Header from './Header.react';
import {ContentRepository} from '../utils/ContentRepositoryUtil';
import ContentRepositoryActions from '../actions/ContentRepositoryActions';
import ContentRepositoryStore from '../stores/ContentRepositoryStore';

var EditContentRepository = React.createClass({
  mixins: [Router.Navigation],

  getInitialState: function () {
    return {
      isNew: true,
      contentRepositoryPath: "/Users/ashl6947/writing/docs-quickstart",
      controlRepositoryLocation: "/Users/ashl6947/writing/nexus-control",
      preparer: "sphinx"
    };
  },

  componentDidMount: function () {
    let id = this.props.params.id;

    if (id !== undefined) {
      let repo = ContentRepositoryStore.getState().repositories[id];

      this.setState({
        isNew: false,
        contentRepositoryPath: repo.contentRepositoryPath,
        controlRepositoryLocation: repo.controlRepositoryLocation,
        preparer: repo.preparer
      });
    }
  },

  handleRepositoryPathChange: function (e) {
    this.setState({contentRepositoryPath: e.target.value});
  },

  handleControlRepositoryChange: function (e) {
    this.setState({controlRepositoryLocation: e.target.value});
  },

  handlePreparerChange: function (e) {
    this.setState({preparer: e.target.value});
  },

  handleCancel: function () {
    this.transitionTo("repositoryList");
  },

  // "Create" or "Save"
  handleCommit: function () {
    if (this.state.isNew) {
      ContentRepositoryActions.launch(this.state.controlRepositoryLocation,
        this.state.contentRepositoryPath, this.state.preparer);
    } else {
      console.log(`Edit to ${this.props.params.id} committed`);
    }

    this.transitionTo("repositoryList");
  },

  render: function () {
    return (

New Content Repository

Repository Path

Filesystem path to the content repository.

            <input id="input-repository-path" type="text" className="line" value={this.state.contentRepositoryPath} placeholder="/some/path" onChange={this.handleRepositoryPathChange}></input>

Control Repository Location

              Location of the control repository. May be either a git URL or a local filesystem path.

            <input id="control-repository" type="text" className="line" value={this.state.controlRepositoryLocation} placeholder="https://github.com/deconst/deconst-docs-control.git" onChange={this.handleControlRepositoryChange}></input>

Preparer

Preparer to use to prepare the content.

            <select id="preparer" value={this.state.preparer} onChange={this.handlePreparerChange}>
              <option value="sphinx">Sphinx</option>
              <option value="jekyll">Jekyll</option>
            </select>

            <button className="btn btn-large btn-default" onClick={this.handleCancel}>Cancel</button>
            <button className="btn btn-large btn-primary" onClick={this.handleCommit}>Create</button>

    )
  }
});

module.exports = EditContentRepository;
<commit_msg>Change the edit component text when creating.<commit_after>import React from 'react/addons';
import Router from 'react-router';
import Header from './Header.react';
import {ContentRepository} from '../utils/ContentRepositoryUtil';
import ContentRepositoryActions from '../actions/ContentRepositoryActions';
import ContentRepositoryStore from '../stores/ContentRepositoryStore';

var EditContentRepository = React.createClass({
  mixins: [Router.Navigation],

  getInitialState: function () {
    return {
      isNew: true,
      contentRepositoryPath: "/Users/ashl6947/writing/docs-quickstart",
      controlRepositoryLocation: "/Users/ashl6947/writing/nexus-control",
      preparer: "sphinx"
    };
  },

  componentDidMount: function () {
    let id = this.props.params.id;

    if (id !== undefined) {
      let repo = ContentRepositoryStore.getState().repositories[id];

      this.setState({
        isNew: false,
        contentRepositoryPath: repo.contentRepositoryPath,
        controlRepositoryLocation: repo.controlRepositoryLocation,
        preparer: repo.preparer
      });
    }
  },

  handleRepositoryPathChange: function (e) {
    this.setState({contentRepositoryPath: e.target.value});
  },

  handleControlRepositoryChange: function (e) {
    this.setState({controlRepositoryLocation: e.target.value});
  },

  handlePreparerChange: function (e) {
    this.setState({preparer: e.target.value});
  },

  handleCancel: function () {
    this.transitionTo("repositoryList");
  },

  // "Create" or "Save"
  handleCommit: function () {
    if (this.state.isNew) {
      ContentRepositoryActions.launch(this.state.controlRepositoryLocation,
        this.state.contentRepositoryPath, this.state.preparer);
    } else {
      console.log(`Edit to ${this.props.params.id} committed`);
    }

    this.transitionTo("repositoryList");
  },

  render: function () {
    let banner = this.state.isNew ? "Add a Content Repository" : "Edit the Content Repository";
    let commit = this.state.isNew ? "Create" : "Save";

    return (

{banner}

Content Repository Path

Filesystem path to the content repository.

            <input type="text" className="line" value={this.state.contentRepositoryPath} placeholder="/some/path" onChange={this.handleRepositoryPathChange}></input>

Control Repository Location

              Location of the control repository. May be either a git URL or a local filesystem path.

            <input type="text" className="line" value={this.state.controlRepositoryLocation} placeholder="https://github.com/deconst/deconst-docs-control.git" onChange={this.handleControlRepositoryChange}></input>

Preparer

Preparer to use to prepare the content.

            <select value={this.state.preparer} onChange={this.handlePreparerChange}>
              <option value="sphinx">Sphinx</option>
              <option value="jekyll">Jekyll</option>
            </select>

            <button className="btn btn-large btn-default" onClick={this.handleCancel}>Cancel</button>
            <button className="btn btn-large btn-primary" onClick={this.handleCommit}>{commit}</button>

    )
  }
});

module.exports = EditContentRepository;
<|endoftext|>


<commit_before>import React from "react";
import ReactDOM from "react-dom";
import Question from "./Question";
import {
  QuestionType,
  QuestionSubmissionType,
  QuestionDependencyType,
  ChoiceType
} from "../../types";
import { List, Map } from "immutable";
import { shallow } from "enzyme";

import type {
  QuestionSubmissionsMapType
} from "../../types/QuestionSubmissionsMapType";

import type {
  QuestionSubmissionMapValueType
} from "../../types/QuestionSubmissionMapValueType";

const question = new QuestionType({
  key: "first",
  label: "first",
  type: "string"
});

const requiredQuestion = new QuestionType({
  key: "first",
  label: "first",
  type: "string",
  required: true
});

it("renders without crashing", () => {
  const div = document.createElement("div");
  ReactDOM.render(
    <Question
      question={question}
      submission={new QuestionSubmissionType()}
      submissions={new Map()}
      setSubmission={() => {}}
    />,
    div
  );
});

it("renders the label", () => {
  const subject = shallow(
    <Question
      question={question}
      submission={new QuestionSubmissionType()}
      submissions={new Map()}
      setSubmission={() => {}}
    />
  );

  expect(subject.find("label").text()).toMatch(/first/);
});

describe("Required Questions", () => {
  it("renders the required text when the question is required", () => {
    const subject = shallow(
      <Question
        question={requiredQuestion}
        submission={new QuestionSubmissionType()}
        submissions={new Map()}
        setSubmission={() => {}}
      />
    );

    expect(subject.find("label").text()).toMatch(/first/);
    expect(subject.find("small").text()).toMatch(/required/);
  });

  it("does not render required when the question is not required", () => {
    const subject = shallow(
      <Question
        question={question}
        submission={new QuestionSubmissionType()}
        submissions={new Map()}
        setSubmission={() => {}}
      />
    );

    expect(subject.find("label").text()).toMatch(/first/);
    expect(subject.find("small").length).toEqual(0);
  });
});

describe("QuestionDependency", () => {
  const choice1 = new ChoiceType({
    id: "10",
    name: "first"
  });

  describe("display: true", () => {
    const questionDependencyDisplayTrue = new QuestionDependencyType({
      id: "1",
      display: true,
      choices: List([choice1]),
      and: false
    });

    const questionWithDependencyDisplayTrue = new QuestionType({
      key: "first",
      label: "firstWithDependency",
      type: "string",
      required: false,
      questionDependency: questionDependencyDisplayTrue
    });

    const submissions = new Map({
      someQuestionId: "10"
    });

    it("renders the question if its dependencies are satisfied", () => {
      const subject = shallow(
        <Question
          question={questionWithDependencyDisplayTrue}
          submission={new QuestionSubmissionType()}
          submissions={submissions}
          setSubmission={() => {}}
        />
      );

      expect(subject.find("label").text()).toMatch(/firstWithDependency/);
    });
  });

  describe("display: false", () => {
    const questionDependencyDisplayTrue = new QuestionDependencyType({
      id: "1",
      display: false,
      choices: List([choice1]),
      and: false
    });

    const questionWithDependencyDisplayTrue = new QuestionType({
      key: "first",
      label: "firstWithDependency",
      type: "string",
      required: false,
      questionDependency: questionDependencyDisplayTrue
    });

    const submissions = List([
      new QuestionSubmissionType({
        id: 1,
        value: "first",
        questionType: "string"
      })
    ]);

    it("hides the question if its dependencies are satisfied", () => {
      const subject = shallow(
        <Question
          question={questionWithDependencyDisplayTrue}
          submission={new QuestionSubmissionType()}
          submissions={submissions}
          setSubmission={() => {}}
        />
      );

      expect(subject.find("label").length).toEqual(0);
    });
  });
});
<commit_msg>Fix tests<commit_after>import React from "react";
import ReactDOM from "react-dom";
import Question from "./Question";
import {
  QuestionType,
  QuestionSubmissionType,
  QuestionDependencyType,
  ChoiceType
} from "../../types";
import { List, Map } from "immutable";
import { shallow } from "enzyme";

import type {
  QuestionSubmissionsMapType
} from "../../types/QuestionSubmissionsMapType";

import type {
  QuestionSubmissionMapValueType
} from "../../types/QuestionSubmissionMapValueType";

const question = new QuestionType({
  key: "first",
  label: "first",
  type: "string"
});

const requiredQuestion = new QuestionType({
  key: "first",
  label: "first",
  type: "string",
  required: true
});

it("renders without crashing", () => {
  const div = document.createElement("div");
  ReactDOM.render(
    <Question
      question={question}
      submission={new QuestionSubmissionType()}
      submissions={new Map()}
      setSubmission={() => {}}
    />,
    div
  );
});

it("renders the label", () => {
  const subject = shallow(
    <Question
      question={question}
      submission={new QuestionSubmissionType()}
      submissions={new Map()}
      setSubmission={() => {}}
    />
  );

  expect(subject.find("label").text()).toMatch(/first/);
});

describe("Required Questions", () => {
  it("renders the required text when the question is required", () => {
    const subject = shallow(
      <Question
        question={requiredQuestion}
        submission={new QuestionSubmissionType()}
        submissions={new Map()}
        setSubmission={() => {}}
      />
    );

    expect(subject.find("label").text()).toMatch(/first/);
    expect(subject.find("small").text()).toMatch(/required/);
  });

  it("does not render required when the question is not required", () => {
    const subject = shallow(
      <Question
        question={question}
        submission={new QuestionSubmissionType()}
        submissions={new Map()}
        setSubmission={() => {}}
      />
    );

    expect(subject.find("label").text()).toMatch(/first/);
    expect(subject.find("small").length).toEqual(0);
  });
});

describe("QuestionDependency", () => {
  const choice1 = new ChoiceType({
    id: "10",
    name: "first"
  });

  describe("display: true", () => {
    const questionDependencyDisplayTrue = new QuestionDependencyType({
      id: "1",
      display: true,
      choices: List([choice1]),
      and: false
    });

    const questionWithDependencyDisplayTrue = new QuestionType({
      key: "first",
      label: "firstWithDependency",
      type: "string",
      required: false,
      questionDependency: questionDependencyDisplayTrue
    });

    const submissions = new Map({
      "1": new List([new QuestionSubmissionType({ id: "1", value: "value" })])
    });

    it("renders the question if its dependencies are satisfied", () => {
      const subject = shallow(
        <Question
          question={questionWithDependencyDisplayTrue}
          submission={new QuestionSubmissionType()}
          submissions={submissions}
          setSubmission={() => {}}
        />
      );

      expect(subject.find("label").text()).toMatch(/firstWithDependency/);
    });
  });

  describe("display: false", () => {
    const questionDependencyDisplayTrue = new QuestionDependencyType({
      id: "1",
      display: false,
      choices: List([choice1]),
      and: false
    });

    const questionWithDependencyDisplayTrue = new QuestionType({
      key: "first",
      label: "firstWithDependency",
      type: "string",
      required: false,
      questionDependency: questionDependencyDisplayTrue
    });

    const submissions = List([
      new QuestionSubmissionType({
        id: 1,
        value: "first",
        questionType: "string"
      })
    ]);

    it("hides the question if its dependencies are satisfied", () => {
      const subject = shallow(
        <Question
          question={questionWithDependencyDisplayTrue}
          submission={new QuestionSubmissionType()}
          submissions={submissions}
          setSubmission={() => {}}
        />
      );

      expect(subject.find("label").length).toEqual(0);
    });
  });
});
<|endoftext|>