<commit_before>/* This software is licensed under a BSD license; see the LICENSE file for details. */

// Check that the object namespace hasn't been polluted by monkey patching (we
// use objects as hashtables without conscience).
for (var _ in { }) {
    assert(false, "ERROR: The JavaScript object namespace has been polluted (perhaps by a library such as prototype.js?.");
}

var serverURI = "server.py";

var body = document.getElementsByTagName("body")[0];

var counter = parseInt(readCookie("counter"));
var randomCounter = false;
if (counter == NaN) {
    counter = Math.floor(Math.random() * 10000);
    randomCounter = true;
}

var sendingResults = document.createElement("p");
sendingResults.className = "sending-results";
var spinSpan = document.createElement("div");
spinSpan.appendChild(document.createTextNode(""));
spinSpan.style.width = "1.5em";
spinSpan.style.cssFloat = "left";
spinSpan.style.styleFloat = "left";
sendingResults.appendChild(spinSpan);
var sendingResultsMessage = document.createElement("div");
sendingResultsMessage.appendChild(document.createTextNode(" Sending results to server..."));
sendingResults.appendChild(sendingResultsMessage);

// Convert the "defaults" variable to a list of [item, hashtable] pairs.
var ht_defaults = [];
if (typeof(defaults) != "undefined") {
    assert_is_arraylike(defaults, "'defaults' variable must be set to an Array.");
    assert(defaults.length % 2 == 0, "'defaults' Array must have an even number of elements.");

    for (var i = 0; i < defaults.length; i += 2) {
        assert(typeof(defaults[i]) == "function", "Odd members of the 'defaults' array must be object constructor functions.");
        assert_is_dict(defaults[i + 1], "Even members of the 'defaults' array must be dictionaries.");

        ht_defaults.push([defaults[i], defaults[i + 1]]);
    }
}

// We don't have object-keyed hashtables at our disposal, so
// here's a utility function for traversing the ht_defaults alist.
function get_defaults_for(obj) {
    for (var i = 0; i < ht_defaults.length; ++i) {
        if (ht_defaults[i][0] == obj) {
            // Copy the dictionary (had a nasty bug from not doing this...).
            return copy_dict(ht_defaults[i][1]);
        }
    }
    return {}
}

function Item(itemNumber, elementNumber, controller, options) {
    this.itemNumber = itemNumber;
    this.elementNumber = elementNumber;
    this.controller = controller;
    this.options = options;
}

// Now create our initial list of item sets (lists of Items), merging in default options.
assert(typeof(items) != "undefined", "You must define the 'items' variable.");
assert_is_arraylike(items, "The 'items' variable must be set to an Array.");
var listOfItemSets = [];
var itemNumber = 0;
iter(items, function(it) {
    assert_is_arraylike(it, "Every element in the 'items' Array must be an Array.");

    assert(((it.length - 1) % 2) == 0, "Following the item/group specifier, each element of the 'items' array must contain an even number of elements.")
    var typeAndGroup = it[0];
    var currentItemSet = [];
    for (var setIndex = 1, elementNumber = 0; setIndex < it.length; setIndex += 2, ++elementNumber) {
        var controller = it[setIndex];
        var options = it[setIndex + 1];

        var type;
        var group = null;
        assert(typeof(typeAndGroup) == "object" || typeof(typeAndGroup) == "number" || typeof(typeAndGroup) == "string",
               "Type and group specifier must be an Array, number or string");
        if (typeof(typeAndGroup) == "object") {
            assert(typeAndGroup.length == 2, "Type and group specifier must have two elements");
            type = typeAndGroup[0];
            group = typeAndGroup[1];
        }
        else {
            type = typeAndGroup;
        }

        var opts = get_defaults_for(controller);
        opts = merge_dicts(opts, options);

        // Check that all obligatory options have been specified.
        if (controller.obligatory) {
            assert_is_arraylike(controller.obligatory, "The 'obligatory' field must be an Array of strings.");
            iter(controller.obligatory, function(o) {
                assert(typeof(o) == "string", "All members of the 'obligatory' Array must be strings.");
                assert(opts[o] != undefined, "The obligatory option '" + o + "' was not specified for " + controller.name);
            });
        }

        currentItemSet.push(new Item(itemNumber, elementNumber, controller, opts));
    }
    currentItemSet.type = type;
    currentItemSet.group = group;
    listOfItemSets.push(currentItemSet);

    ++itemNumber;
 });

function Utils(valuesFromPreviousElement) {
    this.timeoutIds = [];

    this.setTimeout = function(func, time) {
        var id = setTimeout(func, time);
        this.timeoutIds.push(id);
        return id;
    }

    this.clearTimeout = function(id) {
        // Check that this is an id from a timeout set with the
        // setTimeout method of this object.
        // COMMENTING THIS CHECK OUT FOR PERFORMANCE REASONS.
        /*var foundIt = false;
        for (i = 0; i < this.timeoutIds; ++i) {
            if (this.timeoutIds[i] == id) {
                foundIt = this.timeoutIds[i];
                break;
            }
        }
        if (foundIt == null)
            assert(false, "Attempt to clear timer that wasn't set propetly");
        */

        clearTimeout(id);

        var newArray = [];
        for (var j = 0; j < this.timeoutIds.length; ++j) {
            if (this.timeoutIds[j] != id)
                newArray.push(this.timeoutIds[j]);
        }
        this.timeoutIds = newArray;
    }

    this.gc = function() {
        for (var i = 0; i < this.timeoutIds.length; ++i) {
            clearTimeout(this.timeoutIds[i]);
        }
    }

    this.valuesForNextElement = {};

    this.setValueForNextElement = function(key, value) {
        assert(typeof(key) == "string", "First argument to 'setValueForNextElement' must be a string");
        this.valuesForNextElement[key] = value;
    }

    this.getValueFromPreviousElement = function(key) {
        return valuesFromPreviousElement[key];
    }

    this.getValuesFromPreviousElement = function() {
        return copy_dict(valuesFromPreviousElement);
    }
}

var practiceBox;
if (conf_practiceItemTypes && conf_practiceItemTypes.length > 0) {
    practiceBox = document.createElement("p");
    practiceBox.className = "practice-box";
    practiceBox.appendChild(document.createTextNode(""));
    body.appendChild(practiceBox);
}

var mainDiv = document.createElement("div");
mainDiv.style.clear = "both";
body.appendChild(mainDiv);

var mungGroupsExtras = { };
var runningOrder = runShuffleSequence(mungGroups(listOfItemSets, counter, mungGroupsExtras), conf_shuffleSequence);
assert(runningOrder.length > 0 && runningOrder[0].length > 0,
       "There must be some items in the running order!");

var progressBarHeight;
var progressBarMaxWidth;
var currentProgressBarWidth = 0.0;
var showProgress;
var barContainer;
var nPoints = 0;
if (conf_showProgressBar) {
    for (var i = 0; i < runningOrder.length; ++i) {
        for (var j = 0; j < runningOrder[i].length; ++j) {
            if (runningOrder[i][j].controller.countsForProgressBar === undefined ||
                runningOrder[i][j].controller.countsForProgressBar) {
                ++nPoints;
            }
        }
    }

    progressBarHeight = "0.8em";
    progressBarMaxWidth = nPoints * 5 < 300 ? nPoints * 5 : 300;
    showProgress = document.createElement("div");
    showProgress.className = "lpad";
    showProgress.style.marginTop = "2em";
    barContainer = document.createElement("div");
    barContainer.className = "bar-container"
    barContainer.style.height = progressBarHeight;
    barContainer.style.width = progressBarMaxWidth;
    var bar = document.createElement("div");
    bar.className = "bar";
    bar.style.width = "0px";
    bar.style.height = progressBarHeight;
    barContainer.appendChild(bar);
    var p = document.createElement("p");
    p.className = "progress-text"
    p.appendChild(document.createTextNode("progress"));
    showProgress.appendChild(barContainer);
    showProgress.appendChild(p);
    body.insertBefore(showProgress, body.firstChild);
}
function updateProgressBar() {
    if (conf_showProgressBar) {
        currentProgressBarWidth += progressBarMaxWidth / nPoints;
        bar.style.width = Math.round(currentProgressBarWidth) + "px";
    }
}
function hideProgressBar() {
    if (conf_showProgressBar) {
        showProgress.style.visibility = "hidden";
    }
}
function showProgressBar() {
    if (conf_showProgressBar) {
        showProgress.style.visibility = "visible";
    }
}

var posInRunningOrder = 0;
var posInCurrentItemSet = 0;
var currentUtilsInstance = null;
var currentControllerInstance = null;
// A list of result lines.
var allResults = [];

function finishedCallback(resultsLines) {
    var currentItem = runningOrder[posInRunningOrder][posInCurrentItemSet];

    if (resultsLines != null) {
        for (var i = 0; i < resultsLines.length; ++i) {
            var group = runningOrder[posInRunningOrder].group;
            if (group && group.length)
                group = group[0]
            var preamble = [ currentControllerInstance.name ? currentControllerInstance.name : "UNKNOWN",
                             currentItem.itemNumber,
                             currentItem.elementNumber,
                             runningOrder[posInRunningOrder].type,
                             group == null ? "NULL" : group ];
            for (var j = 0; j < resultsLines[i].length; ++j) {
                preamble.push(resultsLines[i][j]);
            }
            allResults.push(preamble);
        }
    }

    // Update progress bar if applicable.
    if (currentItem.controller.countsForProgressBar === undefined ||
        currentItem.controller.countsForProgressBar) {
        updateProgressBar();
    }

    ++posInCurrentItemSet;
    if (posInCurrentItemSet >= runningOrder[posInRunningOrder].length) {
        ++posInRunningOrder;
        if (posInRunningOrder >= runningOrder.length) {
            // We've finished the experiment.
            indicateThatResultsAreBeingSent();
            sendResults(allResults,
                        function() { indicateThatResultsWereSent(true); },
                        function() { indicateThatResultsWereSent(false); });
            return;
        }
        posInCurrentItemSet = 0;
    }

    currentItem = runningOrder[posInRunningOrder][posInCurrentItemSet];

    var pForItem;
    if (dget(currentControllerInstance.options, "displayMode", "overwrite") != "append") {
        var newMainDiv = document.createElement("div");
        body.replaceChild(newMainDiv, mainDiv);
        mainDiv = newMainDiv;
        pForItem = document.createElement("p");
        mainDiv.appendChild(pForItem);
    }
    else {
        // Append the Item instead of overwriting the previous one.
        pForItem = document.createElement("p");
        mainDiv.appendChild(pForItem);
    }
    pForItem.style.clear = "both";

    // Is this a practice item?
    if (practiceBox) {
//        alert(currentItem.type + ":" + conf_practiceItemTypes);
        if (list_contains(runningOrder[posInRunningOrder].type, conf_practiceItemTypes)) {
//            alert("PB2");
            practiceBox.replaceChild(document.createTextNode(conf_practiceMessage), practiceBox.firstChild);
        }
        else {
            practiceBox.replaceChild(document.createTextNode(""), practiceBox.firstChild);
        }
    }

    currentUtilsInstance.gc();
    currentUtilsInstance = new Utils(currentUtilsInstance.valuesForNextElement);
    currentControllerInstance =
        new (currentItem.controller)
    (pForItem, currentItem.options, finishedCallback, currentUtilsInstance);

    // Should we show the progress bar with this item?
    if (currentControllerInstance.hideProgressBar)
        hideProgressBar();
    else
        showProgressBar();
}
currentUtilsInstance = new Utils({});
currentControllerInstance =
    new (runningOrder[0][0].controller)
        (mainDiv, runningOrder[0][0].options, finishedCallback, currentUtilsInstance);
// Should we show the progress bar with the first item?
if (currentControllerInstance.hideProgressBar)
    hideProgressBar();

document.onkeydown = function(e) {
    // Record the time ASAP.
    var time = new Date().getTime();

    // For IE.
    if (! e) {
        e = window.event;
    }

    if (currentControllerInstance.handleKey) {
        // Should return false if they keypress wasn't handled.
        return currentControllerInstance.handleKey(e.keyCode, time);
    }
}

function indicateThatResultsAreBeingSent()
{
    // Clear "practice" notice if it's still up.
    practiceBox.replaceChild(document.createTextNode(""), practiceBox.firstChild);

    body.replaceChild(sendingResults, mainDiv);
    var spinChars = ["\u2013", "\\", "|", "/"]
    var spinCharsPos = 0
    function timerCallback()
    {
        // Stop the callback if spinSpan no longer has any children.
        if (spinSpan.childNodes.length == 0) { return; }

        spinSpan.replaceChild(document.createTextNode(spinChars[spinCharsPos]),
                              spinSpan.firstChild);
        ++spinCharsPos;
        if (spinCharsPos == spinChars.length) {
            spinCharsPos = 0;
        }
        setTimeout(timerCallback, 200);
    }
    timerCallback();
}

function indicateThatResultsWereSent(success)
{
    spinSpan.removeChild(spinSpan.firstChild); // This will cause the callback to stop.
    if (success) {
        sendingResultsMessage.replaceChild(
            document.createTextNode(conf_completionMessage),
            sendingResultsMessage.firstChild
        );
    }
    else {
        sendingResultsMessage.replaceChild(
            document.createTextNode(conf_completionErrorMessage),
            sendingResultsMessage.firstChild
        );
    }
}

// Make a post request to a given address. Address may either be a domain
// or an IP.
function sendResults(resultsLines, success, failure)
{
    var xmlhttp = getXMLHttpRequest();
    if (! xmlhttp) {
        failure();
    }

    // Prepare the post data.
    var data = JSON.stringify([randomCounter ? true : false, counter, resultsLines]);

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4) {
            if (xmlhttp.status == 200) {
                // Great, we successfully sent the results to the server.
                success();
            }
            else {
                // There was an error sending the results to the server.
                failure();
            }
        }
    };
    xmlhttp.open("POST", serverURI, true);
    xmlhttp.send(data);
}

<commit_msg>Fix bug in main.js where equality test was used instead of isNaN(...)<commit_after>/* This software is licensed under a BSD license; see the LICENSE file for details. */

// Check that the object namespace hasn't been polluted by monkey patching (we
// use objects as hashtables without conscience).
for (var _ in { }) {
    assert(false, "ERROR: The JavaScript object namespace has been polluted (perhaps by a library such as prototype.js?.");
}

var serverURI = "server.py";

var body = document.getElementsByTagName("body")[0];

var counter = parseInt(readCookie("counter"));
var randomCounter = false;
if (isNaN(counter)) {
    counter = Math.floor(Math.random() * 10000);
    randomCounter = true;
}

var sendingResults = document.createElement("p");
sendingResults.className = "sending-results";
var spinSpan = document.createElement("div");
spinSpan.appendChild(document.createTextNode(""));
spinSpan.style.width = "1.5em";
spinSpan.style.cssFloat = "left";
spinSpan.style.styleFloat = "left";
sendingResults.appendChild(spinSpan);
var sendingResultsMessage = document.createElement("div");
sendingResultsMessage.appendChild(document.createTextNode(" Sending results to server..."));
sendingResults.appendChild(sendingResultsMessage);

// Convert the "defaults" variable to a list of [item, hashtable] pairs.
var ht_defaults = [];
if (typeof(defaults) != "undefined") {
    assert_is_arraylike(defaults, "'defaults' variable must be set to an Array.");
    assert(defaults.length % 2 == 0, "'defaults' Array must have an even number of elements.");

    for (var i = 0; i < defaults.length; i += 2) {
        assert(typeof(defaults[i]) == "function", "Odd members of the 'defaults' array must be object constructor functions.");
        assert_is_dict(defaults[i + 1], "Even members of the 'defaults' array must be dictionaries.");

        ht_defaults.push([defaults[i], defaults[i + 1]]);
    }
}

// We don't have object-keyed hashtables at our disposal, so
// here's a utility function for traversing the ht_defaults alist.
function get_defaults_for(obj) {
    for (var i = 0; i < ht_defaults.length; ++i) {
        if (ht_defaults[i][0] == obj) {
            // Copy the dictionary (had a nasty bug from not doing this...).
            return copy_dict(ht_defaults[i][1]);
        }
    }
    return {}
}

function Item(itemNumber, elementNumber, controller, options) {
    this.itemNumber = itemNumber;
    this.elementNumber = elementNumber;
    this.controller = controller;
    this.options = options;
}

// Now create our initial list of item sets (lists of Items), merging in default options.
assert(typeof(items) != "undefined", "You must define the 'items' variable.");
assert_is_arraylike(items, "The 'items' variable must be set to an Array.");
var listOfItemSets = [];
var itemNumber = 0;
iter(items, function(it) {
    assert_is_arraylike(it, "Every element in the 'items' Array must be an Array.");

    assert(((it.length - 1) % 2) == 0, "Following the item/group specifier, each element of the 'items' array must contain an even number of elements.")
    var typeAndGroup = it[0];
    var currentItemSet = [];
    for (var setIndex = 1, elementNumber = 0; setIndex < it.length; setIndex += 2, ++elementNumber) {
        var controller = it[setIndex];
        var options = it[setIndex + 1];

        var type;
        var group = null;
        assert(typeof(typeAndGroup) == "object" || typeof(typeAndGroup) == "number" || typeof(typeAndGroup) == "string",
               "Type and group specifier must be an Array, number or string");
        if (typeof(typeAndGroup) == "object") {
            assert(typeAndGroup.length == 2, "Type and group specifier must have two elements");
            type = typeAndGroup[0];
            group = typeAndGroup[1];
        }
        else {
            type = typeAndGroup;
        }

        var opts = get_defaults_for(controller);
        opts = merge_dicts(opts, options);

        // Check that all obligatory options have been specified.
        if (controller.obligatory) {
            assert_is_arraylike(controller.obligatory, "The 'obligatory' field must be an Array of strings.");
            iter(controller.obligatory, function(o) {
                assert(typeof(o) == "string", "All members of the 'obligatory' Array must be strings.");
                assert(opts[o] != undefined, "The obligatory option '" + o + "' was not specified for " + controller.name);
            });
        }

        currentItemSet.push(new Item(itemNumber, elementNumber, controller, opts));
    }
    currentItemSet.type = type;
    currentItemSet.group = group;
    listOfItemSets.push(currentItemSet);

    ++itemNumber;
 });

function Utils(valuesFromPreviousElement) {
    this.timeoutIds = [];

    this.setTimeout = function(func, time) {
        var id = setTimeout(func, time);
        this.timeoutIds.push(id);
        return id;
    }

    this.clearTimeout = function(id) {
        // Check that this is an id from a timeout set with the
        // setTimeout method of this object.
        // COMMENTING THIS CHECK OUT FOR PERFORMANCE REASONS.
        /*var foundIt = false;
        for (i = 0; i < this.timeoutIds; ++i) {
            if (this.timeoutIds[i] == id) {
                foundIt = this.timeoutIds[i];
                break;
            }
        }
        if (foundIt == null)
            assert(false, "Attempt to clear timer that wasn't set propetly");
        */

        clearTimeout(id);

        var newArray = [];
        for (var j = 0; j < this.timeoutIds.length; ++j) {
            if (this.timeoutIds[j] != id)
                newArray.push(this.timeoutIds[j]);
        }
        this.timeoutIds = newArray;
    }

    this.gc = function() {
        for (var i = 0; i < this.timeoutIds.length; ++i) {
            clearTimeout(this.timeoutIds[i]);
        }
    }

    this.valuesForNextElement = {};

    this.setValueForNextElement = function(key, value) {
        assert(typeof(key) == "string", "First argument to 'setValueForNextElement' must be a string");
        this.valuesForNextElement[key] = value;
    }

    this.getValueFromPreviousElement = function(key) {
        return valuesFromPreviousElement[key];
    }

    this.getValuesFromPreviousElement = function() {
        return copy_dict(valuesFromPreviousElement);
    }
}

var practiceBox;
if (conf_practiceItemTypes && conf_practiceItemTypes.length > 0) {
    practiceBox = document.createElement("p");
    practiceBox.className = "practice-box";
    practiceBox.appendChild(document.createTextNode(""));
    body.appendChild(practiceBox);
}

var mainDiv = document.createElement("div");
mainDiv.style.clear = "both";
body.appendChild(mainDiv);

var mungGroupsExtras = { };
var runningOrder = runShuffleSequence(mungGroups(listOfItemSets, counter, mungGroupsExtras), conf_shuffleSequence);
assert(runningOrder.length > 0 && runningOrder[0].length > 0,
       "There must be some items in the running order!");

var progressBarHeight;
var progressBarMaxWidth;
var currentProgressBarWidth = 0.0;
var showProgress;
var barContainer;
var nPoints = 0;
if (conf_showProgressBar) {
    for (var i = 0; i < runningOrder.length; ++i) {
        for (var j = 0; j < runningOrder[i].length; ++j) {
            if (runningOrder[i][j].controller.countsForProgressBar === undefined ||
                runningOrder[i][j].controller.countsForProgressBar) {
                ++nPoints;
            }
        }
    }

    progressBarHeight = "0.8em";
    progressBarMaxWidth = nPoints * 5 < 300 ? nPoints * 5 : 300;
    showProgress = document.createElement("div");
    showProgress.className = "lpad";
    showProgress.style.marginTop = "2em";
    barContainer = document.createElement("div");
    barContainer.className = "bar-container"
    barContainer.style.height = progressBarHeight;
    barContainer.style.width = progressBarMaxWidth;
    var bar = document.createElement("div");
    bar.className = "bar";
    bar.style.width = "0px";
    bar.style.height = progressBarHeight;
    barContainer.appendChild(bar);
    var p = document.createElement("p");
    p.className = "progress-text"
    p.appendChild(document.createTextNode("progress"));
    showProgress.appendChild(barContainer);
    showProgress.appendChild(p);
    body.insertBefore(showProgress, body.firstChild);
}
function updateProgressBar() {
    if (conf_showProgressBar) {
        currentProgressBarWidth += progressBarMaxWidth / nPoints;
        bar.style.width = Math.round(currentProgressBarWidth) + "px";
    }
}
function hideProgressBar() {
    if (conf_showProgressBar) {
        showProgress.style.visibility = "hidden";
    }
}
function showProgressBar() {
    if (conf_showProgressBar) {
        showProgress.style.visibility = "visible";
    }
}

var posInRunningOrder = 0;
var posInCurrentItemSet = 0;
var currentUtilsInstance = null;
var currentControllerInstance = null;
// A list of result lines.
var allResults = [];

function finishedCallback(resultsLines) {
    var currentItem = runningOrder[posInRunningOrder][posInCurrentItemSet];

    if (resultsLines != null) {
        for (var i = 0; i < resultsLines.length; ++i) {
            var group = runningOrder[posInRunningOrder].group;
            if (group && group.length)
                group = group[0]
            var preamble = [ currentControllerInstance.name ? currentControllerInstance.name : "UNKNOWN",
                             currentItem.itemNumber,
                             currentItem.elementNumber,
                             runningOrder[posInRunningOrder].type,
                             group == null ? "NULL" : group ];
            for (var j = 0; j < resultsLines[i].length; ++j) {
                preamble.push(resultsLines[i][j]);
            }
            allResults.push(preamble);
        }
    }

    // Update progress bar if applicable.
    if (currentItem.controller.countsForProgressBar === undefined ||
        currentItem.controller.countsForProgressBar) {
        updateProgressBar();
    }

    ++posInCurrentItemSet;
    if (posInCurrentItemSet >= runningOrder[posInRunningOrder].length) {
        ++posInRunningOrder;
        if (posInRunningOrder >= runningOrder.length) {
            // We've finished the experiment.
            indicateThatResultsAreBeingSent();
            sendResults(allResults,
                        function() { indicateThatResultsWereSent(true); },
                        function() { indicateThatResultsWereSent(false); });
            return;
        }
        posInCurrentItemSet = 0;
    }

    currentItem = runningOrder[posInRunningOrder][posInCurrentItemSet];

    var pForItem;
    if (dget(currentControllerInstance.options, "displayMode", "overwrite") != "append") {
        var newMainDiv = document.createElement("div");
        body.replaceChild(newMainDiv, mainDiv);
        mainDiv = newMainDiv;
        pForItem = document.createElement("p");
        mainDiv.appendChild(pForItem);
    }
    else {
        // Append the Item instead of overwriting the previous one.
        pForItem = document.createElement("p");
        mainDiv.appendChild(pForItem);
    }
    pForItem.style.clear = "both";

    // Is this a practice item?
    if (practiceBox) {
//        alert(currentItem.type + ":" + conf_practiceItemTypes);
        if (list_contains(runningOrder[posInRunningOrder].type, conf_practiceItemTypes)) {
//            alert("PB2");
            practiceBox.replaceChild(document.createTextNode(conf_practiceMessage), practiceBox.firstChild);
        }
        else {
            practiceBox.replaceChild(document.createTextNode(""), practiceBox.firstChild);
        }
    }

    currentUtilsInstance.gc();
    currentUtilsInstance = new Utils(currentUtilsInstance.valuesForNextElement);
    currentControllerInstance =
        new (currentItem.controller)
    (pForItem, currentItem.options, finishedCallback, currentUtilsInstance);

    // Should we show the progress bar with this item?
    if (currentControllerInstance.hideProgressBar)
        hideProgressBar();
    else
        showProgressBar();
}
currentUtilsInstance = new Utils({});
currentControllerInstance =
    new (runningOrder[0][0].controller)
        (mainDiv, runningOrder[0][0].options, finishedCallback, currentUtilsInstance);
// Should we show the progress bar with the first item?
if (currentControllerInstance.hideProgressBar)
    hideProgressBar();

document.onkeydown = function(e) {
    // Record the time ASAP.
    var time = new Date().getTime();

    // For IE.
    if (! e) {
        e = window.event;
    }

    if (currentControllerInstance.handleKey) {
        // Should return false if they keypress wasn't handled.
        return currentControllerInstance.handleKey(e.keyCode, time);
    }
}

function indicateThatResultsAreBeingSent()
{
    // Clear "practice" notice if it's still up.
    practiceBox.replaceChild(document.createTextNode(""), practiceBox.firstChild);

    body.replaceChild(sendingResults, mainDiv);
    var spinChars = ["\u2013", "\\", "|", "/"]
    var spinCharsPos = 0
    function timerCallback()
    {
        // Stop the callback if spinSpan no longer has any children.
        if (spinSpan.childNodes.length == 0) { return; }

        spinSpan.replaceChild(document.createTextNode(spinChars[spinCharsPos]),
                              spinSpan.firstChild);
        ++spinCharsPos;
        if (spinCharsPos == spinChars.length) {
            spinCharsPos = 0;
        }
        setTimeout(timerCallback, 200);
    }
    timerCallback();
}

function indicateThatResultsWereSent(success)
{
    spinSpan.removeChild(spinSpan.firstChild); // This will cause the callback to stop.
    if (success) {
        sendingResultsMessage.replaceChild(
            document.createTextNode(conf_completionMessage),
            sendingResultsMessage.firstChild
        );
    }
    else {
        sendingResultsMessage.replaceChild(
            document.createTextNode(conf_completionErrorMessage),
            sendingResultsMessage.firstChild
        );
    }
}

// Make a post request to a given address. Address may either be a domain
// or an IP.
function sendResults(resultsLines, success, failure)
{
    var xmlhttp = getXMLHttpRequest();
    if (! xmlhttp) {
        failure();
    }

    // Prepare the post data.
    var data = JSON.stringify([randomCounter ? true : false, counter, resultsLines]);

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4) {
            if (xmlhttp.status == 200) {
                // Great, we successfully sent the results to the server.
                success();
            }
            else {
                // There was an error sending the results to the server.
                failure();
            }
        }
    };
    xmlhttp.open("POST", serverURI, true);
    xmlhttp.send(data);
}

<|endoftext|>


<commit_before>// The contents of this file will be executed before any of
// your view controllers are ever executed, including the index.
// You have access to all functionality on the `Alloy` namespace.
//
// This is a great place to do any initialization for your app
// or create any global variables/functions that you'd like to
// make available throughout your app. You can easily make things
// accessible globally by attaching them to the `Alloy.Globals`
// object. For example:
//
// Alloy.Globals.someGlobalFunction = function(){};
<commit_msg>Added useful core.js functions to alloy.js making them globally available with Alloy.Globals.foo<commit_after>// The contents of this file will be executed before any of
// your view controllers are ever executed, including the index.
// You have access to all functionality on the `Alloy` namespace.
//
// This is a great place to do any initialization for your app
// or create any global variables/functions that you'd like to
// make available throughout your app. You can easily make things
// accessible globally by attaching them to the `Alloy.Globals`
// object. For example:
//
// Alloy.Globals.someGlobalFunction = function(){};

/**
 * App core functions
 */
var __isLargeScreen, __isHighDensityScreen, __isAndroid, __isiPad, properties = {},
  empty = {},
  currentPage = null,
  windowStack = [],
  navGroup, density = Ti.Platform.displayCaps.density;
/***************************
 * Public methods & variables
 ***************************/

/**
 * Set properties for app
 * @param {String} name Name of property
 * @param {String} value Value of property
 */
Alloy.Globals.addProperty = function(name, value) {
  properties[name] = value;
};

/**
 * Helper method to show all properties in the core app
 */
Alloy.Globals.properties = function() {
  return properties;
};

/**
 * Helper method to show one property in the core app
 * @param {String} name
 */
Alloy.Globals.property = function(name) {
  return properties[name];
};

Alloy.Globals.extend = function(obj) {
  var args = Array.prototype.slice.call(arguments, 1);
  for(var i = 0; i < args.length; i++) {
    var source = args[i];
    for(var prop in source) {
      if(source[prop] !== 0) {
        obj[prop] = source[prop];
      }
    }
  }
  return obj;
};

/**
 * test to see if this is a tablet
 */
Alloy.Globals.isLargeScreen = function() {
  if(__isLargeScreen === undefined) {
    __isLargeScreen = (Ti.Platform.displayCaps.platformWidth >= 700);
  }
  return __isLargeScreen;
};
/**
 * test for high density
 */
Alloy.Globals.isHighDensityScreen = function() {
  if(__isHighDensityScreen === undefined) {
    __isHighDensityScreen = (Ti.Platform.displayCaps.density === 'high');
  }
  return __isHighDensityScreen;
};

/**
 * test for android
 */
Alloy.Globals.isAndroid = function() {
  if(__isAndroid === undefined) {
    __isAndroid = (Ti.Platform.osname === 'android');
  }
  return __isAndroid;
};

/**
 * test for iPad
 */
Alloy.Globals.isiPad = function() {
  if(__isiPad === undefined) {
    __isiPad = (Ti.Platform.osname == 'ipad');
  }
  return __isiPad;
};

/**
 * test for landscpae orientation
 */
Alloy.Globals.isLandscape = function(orient) {
  orient = orient || Ti.UI.orientation;
  return orient == Ti.UI.LANDSCAPE_LEFT || orient == Ti.UI.LANDSCAPE_RIGHT;
};

/**
 * test for a portrait orientation
 */
Alloy.Globals.isPortrait = function(orient) {
  orient = orient || Ti.UI.orientation;
  return orient == Ti.UI.PORTRAIT || orient == Ti.UI.UPSIDE_PORTRAIT;
};

/*
 * Branching logic based on density
 */
Alloy.Globals.density = function( /*Object*/ map) {
  var def = map.def || null; //default function or value
  if(typeof map[density] != 'undefined') {
    if(typeof map[density] == 'function') {
      return map[density]();
    } else {
      return map[density];
    }
  } else {
    if(typeof def == 'function') {
      return def();
    } else {
      return def;
    }
  }
};

/**
 * converts special characters into nice chars for display
 * @param {string} str
 */
Alloy.Globals.cleanSpecialChars = function(str) {
  if(str === null) {
    return '';
  }
  if(typeof str === 'string') {
    return str.replace(/"/g, '"').replace(/\&amp\;/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/'/g, "'");
  }
  return '';
};
<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var BoardSchema   = new Schema({
  name: {type: String, default: "808 Drum Kit"},
  created: {type: String, default: Date()},
  updated: {type: String, default: Date()},
  pads: {
    type: Array,
    default: [
      {
        "hotkey": "1",
        "src": "http://assets.noahyarian.com/sounds/808/BD/BD0075.wav",
        "name": "808 Bass Drum"
      },
      {
        "hotkey": "2",
        "src": "http://assets.noahyarian.com/sounds/808/SD/SD0010.wav",
        "name": "808 Snare Drum"
      },
      {
        "hotkey": "3",
        "src": "http://assets.noahyarian.com/sounds/808/CH/CH.wav",
        "name": "808 Closed Hat"
      },
      {
        "hotkey": "4",
        "src": "http://assets.noahyarian.com/sounds/808/CP/CP.wav",
        "name": "808 Hand Clap"
      },
      {
        "hotkey": "Q",
        "src": "http://assets.noahyarian.com/sounds/808/LT/LT00.wav",
        "name": "808 Low Tom"
      },
      {
        "hotkey": "W",
        "src": "http://assets.noahyarian.com/sounds/808/MT/MT00.wav",
        "name": "808 Mid Tom"
      },
      {
        "hotkey": "E",
        "src": "http://assets.noahyarian.com/sounds/808/HT/HT00.wav",
        "name": "808 Hi Tom"
      },
      {
        "hotkey": "R",
        "src": "http://assets.noahyarian.com/sounds/808/RS/RS.wav",
        "name": "808 Rim Shot"
      },
      {
        "hotkey": "A",
        "src": "http://assets.noahyarian.com/sounds/808/LC/LC00.wav",
        "name": "808 Low Conga"
      },
      {
        "hotkey": "S",
        "src": "http://assets.noahyarian.com/sounds/808/MC/MC00.wav",
        "name": "808 Mid Conga"
      },
      {
        "hotkey": "D",
        "src": "http://assets.noahyarian.com/sounds/808/HC/HC00.wav",
        "name": "808 Hi Conga"
      },
      {
        "hotkey": "F",
        "src": "http://assets.noahyarian.com/sounds/808/CB/CB.wav",
        "name": "808 Cow Bell"
      }
    ]
  }
});

module.exports = mongoose.model('Board', BoardSchema);
<commit_msg>wav file extensions to uppercase<commit_after>'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var BoardSchema   = new Schema({
  name: {type: String, default: "808 Drum Kit"},
  created: {type: String, default: Date()},
  updated: {type: String, default: Date()},
  pads: {
    type: Array,
    default: [
      {
        "hotkey": "1",
        "src": "http://assets.noahyarian.com/sounds/808/BD/BD0075.WAV",
        "name": "808 Bass Drum"
      },
      {
        "hotkey": "2",
        "src": "http://assets.noahyarian.com/sounds/808/SD/SD0010.WAV",
        "name": "808 Snare Drum"
      },
      {
        "hotkey": "3",
        "src": "http://assets.noahyarian.com/sounds/808/CH/CH.WAV",
        "name": "808 Closed Hat"
      },
      {
        "hotkey": "4",
        "src": "http://assets.noahyarian.com/sounds/808/CP/CP.WAV",
        "name": "808 Hand Clap"
      },
      {
        "hotkey": "Q",
        "src": "http://assets.noahyarian.com/sounds/808/LT/LT00.WAV",
        "name": "808 Low Tom"
      },
      {
        "hotkey": "W",
        "src": "http://assets.noahyarian.com/sounds/808/MT/MT00.WAV",
        "name": "808 Mid Tom"
      },
      {
        "hotkey": "E",
        "src": "http://assets.noahyarian.com/sounds/808/HT/HT00.WAV",
        "name": "808 Hi Tom"
      },
      {
        "hotkey": "R",
        "src": "http://assets.noahyarian.com/sounds/808/RS/RS.WAV",
        "name": "808 Rim Shot"
      },
      {
        "hotkey": "A",
        "src": "http://assets.noahyarian.com/sounds/808/LC/LC00.WAV",
        "name": "808 Low Conga"
      },
      {
        "hotkey": "S",
        "src": "http://assets.noahyarian.com/sounds/808/MC/MC00.WAV",
        "name": "808 Mid Conga"
      },
      {
        "hotkey": "D",
        "src": "http://assets.noahyarian.com/sounds/808/HC/HC00.WAV",
        "name": "808 Hi Conga"
      },
      {
        "hotkey": "F",
        "src": "http://assets.noahyarian.com/sounds/808/CB/CB.WAV",
        "name": "808 Cow Bell"
      }
    ]
  }
});

module.exports = mongoose.model('Board', BoardSchema);
<|endoftext|>


<commit_before>const ENUMS = {

  PLATFORM: {
    ANDROID: 0,
    IOS: 1,
    WINDOWS: 2,
    BLACKBERRY: 3,
    FIREFOX: 4
  },

  RISK: {
    NONE: 0,
    LOW: 1,
    MEDIUM: 2,
    HIGH: 3,
    CRITICAL: 4
  },

  ANALYSIS: {
    ERROR: 0,
    WAITING: 1,
    RUNNING: 2,
    COMPLETED: 3
  },

  OFFER: {
    NONE: 0,
    CUSTOM: 2
  },

  NOTIFY: {
    INFO: 0,
    SUCCESS: 2,
    WARNING: 3,
    ALERT: 4,
    ERROR: 5
  },

  DYNAMIC_STATUS: {
    NONE: 0,
    BOOTING: 1,
    READY: 2,
    SHUTTING_DOWN: 3,
    DOWNLOADING: 4,
    INSTALLING: 5,
    LAUNCHING: 6,
    HOOKING: 7
  },

  MANUAL: {
    NONE: 0,
    REQUESTED: 1,
    ASSESSING: 2,
    DONE: 3
  },

  ORGANIZATION_ROLES: {
    MEMBER: 0,
    OWNER: 1,
    ADMIN: 2
  },

  SUBMISSION_STATUS: {
    DOWNLOAD_PREPARE: 0,
    DOWNLOADING: 1,
    DOWNLOAD_FAILED: 2,
    VALIDATE_PREPARE: 3,
    VALIDATING: 4,
    VALIDATE_FAILED: 5,
    ANALYZE_PREPARE: 6,
    ANALYZING: 7
  },

  SUBMISSION_SOURCE: {
    UPLOAD: 0,
    STORE: 1,
    SCM: 2
  },

  VULNERABILITY_TYPE: {
    STATIC: 1,
    DYNAMIC: 2,
    MANUAL: 3,
    API: 4
  },

  PAYMENT_DURATION: {
    MONTHLY: 1,
    QUARTERLY: 3,
    HALFYEARLY: 6,
    YEARLY: 10
  },

  DEVICE_TYPE: {
    NO_PREFERENCE: 0,
    PHONE_REQUIRED: 1,
    TABLET_REQUIRED: 2
  },

  PRODUCT: {
    APPKNOX: 0,
    DEVKNOX: 1
  },

  MFA_METHOD: {
    NONE: 0,
    TOTP: 1
  },

  APP_ACTION: {
    NO_PREFERENCE: 0,
    HALT: 1,
    PROCEED: 2
  },

  APP_ENV: {
    NO_PREFERENCE: 0,
    STAGING: 1,
    PRODUCTION: 2
  },

  ATTACK_VECTOR: {
    NETWORK: "N",
    ADJACENT: "A",
    LOCAL: "L",
    PHYSICAL: "P"
  },

  ATTACK_COMPLEXITY: {
    LOW: "L",
    HIGH: "H"
  },

  PRIVILEGES_REQUIRED: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  IMPACTS: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  USER_INTERACTION: {
    NOT_REQUIRED: "N",
    REQUIRED: "R"
  },

  SCOPE: {
    UNCHANGED: "U",
    CHANGED: "C"
  },

  CONFIDENTIALITY_IMPACT: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  INTEGRITY_IMPACT: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  AVAILABILITY_IMPACT: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  ANALYSIS_STATUS: {
     ERROR: 0,
     WAITING: 1,
     RUNNING: 2,
     COMPLETED: 3
   },

  SCAN_STATUS: {
     ERROR: 0,
     WAITING: 1,
     RUNNING: 2,
     COMPLETED: 3
   },
};

// Populate `CHOICES`
for (let enumName in ENUMS) {
  const enumValues = ENUMS[enumName];
  const choices = [];
  const values = [];
  enumValues['UNKNOWN'] = -1;
  for (let key in enumValues) {
    const value = enumValues[key];
    choices.push({key, value});
    values.push(value);
  }
  ENUMS[enumName]['CHOICES'] = choices;
  ENUMS[enumName]['VALUES'] = values;
}

export default ENUMS;
<commit_msg>Added base choices & values to enums<commit_after>const ENUMS = {

  PLATFORM: {
    ANDROID: 0,
    IOS: 1,
    WINDOWS: 2,
    BLACKBERRY: 3,
    FIREFOX: 4
  },

  RISK: {
    NONE: 0,
    LOW: 1,
    MEDIUM: 2,
    HIGH: 3,
    CRITICAL: 4
  },

  ANALYSIS: {
    ERROR: 0,
    WAITING: 1,
    RUNNING: 2,
    COMPLETED: 3
  },

  OFFER: {
    NONE: 0,
    CUSTOM: 2
  },

  NOTIFY: {
    INFO: 0,
    SUCCESS: 2,
    WARNING: 3,
    ALERT: 4,
    ERROR: 5
  },

  DYNAMIC_STATUS: {
    NONE: 0,
    BOOTING: 1,
    READY: 2,
    SHUTTING_DOWN: 3,
    DOWNLOADING: 4,
    INSTALLING: 5,
    LAUNCHING: 6,
    HOOKING: 7
  },

  MANUAL: {
    NONE: 0,
    REQUESTED: 1,
    ASSESSING: 2,
    DONE: 3
  },

  ORGANIZATION_ROLES: {
    MEMBER: 0,
    OWNER: 1,
    ADMIN: 2
  },

  SUBMISSION_STATUS: {
    DOWNLOAD_PREPARE: 0,
    DOWNLOADING: 1,
    DOWNLOAD_FAILED: 2,
    VALIDATE_PREPARE: 3,
    VALIDATING: 4,
    VALIDATE_FAILED: 5,
    ANALYZE_PREPARE: 6,
    ANALYZING: 7
  },

  SUBMISSION_SOURCE: {
    UPLOAD: 0,
    STORE: 1,
    SCM: 2
  },

  VULNERABILITY_TYPE: {
    STATIC: 1,
    DYNAMIC: 2,
    MANUAL: 3,
    API: 4
  },

  PAYMENT_DURATION: {
    MONTHLY: 1,
    QUARTERLY: 3,
    HALFYEARLY: 6,
    YEARLY: 10
  },

  DEVICE_TYPE: {
    NO_PREFERENCE: 0,
    PHONE_REQUIRED: 1,
    TABLET_REQUIRED: 2
  },

  PRODUCT: {
    APPKNOX: 0,
    DEVKNOX: 1
  },

  MFA_METHOD: {
    NONE: 0,
    TOTP: 1
  },

  APP_ACTION: {
    NO_PREFERENCE: 0,
    HALT: 1,
    PROCEED: 2
  },

  APP_ENV: {
    NO_PREFERENCE: 0,
    STAGING: 1,
    PRODUCTION: 2
  },

  ATTACK_VECTOR: {
    NETWORK: "N",
    ADJACENT: "A",
    LOCAL: "L",
    PHYSICAL: "P"
  },

  ATTACK_COMPLEXITY: {
    LOW: "L",
    HIGH: "H"
  },

  PRIVILEGES_REQUIRED: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  IMPACTS: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  USER_INTERACTION: {
    NOT_REQUIRED: "N",
    REQUIRED: "R"
  },

  SCOPE: {
    UNCHANGED: "U",
    CHANGED: "C"
  },

  CONFIDENTIALITY_IMPACT: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  INTEGRITY_IMPACT: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  AVAILABILITY_IMPACT: {
    NONE: "N",
    LOW: "L",
    HIGH: "H"
  },

  ANALYSIS_STATUS: {
     ERROR: 0,
     WAITING: 1,
     RUNNING: 2,
     COMPLETED: 3
   },

  SCAN_STATUS: {
     ERROR: 0,
     WAITING: 1,
     RUNNING: 2,
     COMPLETED: 3
   },
};

// Populate `CHOICES`
for (let enumName in ENUMS) {
  const enumValues = ENUMS[enumName];
  const base_choices = [];
  const base_values = [];
  const choices = [];
  const values = [];
  for (let key in enumValues) {
    const value = enumValues[key];
    base_choices.push({key, value});
    base_values.push(value);
    choices.push({key, value});
    values.push(value);
  }
  enumValues['UNKNOWN'] = -1;
  choices.push({key: 'UNKNOWN',value: enumValues['UNKNOWN']});
  values.push(enumValues['UNKNOWN']);
  ENUMS[enumName]['BASE_CHOICES'] = base_choices;
  ENUMS[enumName]['BASE_VALUES'] = base_values;
  ENUMS[enumName]['CHOICES'] = choices;
  ENUMS[enumName]['VALUES'] = values;
}

export default ENUMS;
<|endoftext|>


<commit_before>import Relay from 'react-relay';

var sourceFragment = Relay.QL`
  fragment on Source {
    id,
    dbid,
    name,
    image,
    user_id,
    description,
    permissions,
    verification_statuses,
    accounts(first: 10000) {
      edges {
        node {
          url,
          provider
        }
      }
    },
    tags(first: 10000) {
      edges {
        node {
          tag,
          id
        }
      }
    },
    annotations(first: 10000) {
      edges {
        node {
          id,
          content,
          annotation_type,
          created_at,
          permissions,
          annotator {
            name,
            profile_image
          }
        }
      }
    },
    medias(first: 10000) {
      edges {
        node {
          id,
          dbid,
          url,
          published,
          jsondata,
          annotations_count,
          domain,
          last_status,
          permissions,
          verification_statuses
        }
      }
    }
  }
`;

module.exports = sourceFragment;
<commit_msg>Ticket #5155: Sources should be able to embed medias on comments too<commit_after>import Relay from 'react-relay';

var sourceFragment = Relay.QL`
  fragment on Source {
    id,
    dbid,
    name,
    image,
    user_id,
    description,
    permissions,
    verification_statuses,
    accounts(first: 10000) {
      edges {
        node {
          url,
          provider
        }
      }
    },
    tags(first: 10000) {
      edges {
        node {
          tag,
          id
        }
      }
    },
    annotations(first: 10000) {
      edges {
        node {
          id,
          content,
          annotation_type,
          created_at,
          permissions,
          medias(first: 10000) {
            edges {
              node {
                id,
                dbid,
                published,
                url,
                jsondata,
                project_id,
                last_status,
                annotations_count,
                permissions,
                verification_statuses,
                domain,
                user {
                  name,
                  source {
                    dbid
                  }
                }
              }
            }
          },
          annotator {
            name,
            profile_image
          }
        }
      }
    },
    medias(first: 10000) {
      edges {
        node {
          id,
          dbid,
          url,
          published,
          jsondata,
          annotations_count,
          domain,
          last_status,
          permissions,
          verification_statuses
        }
      }
    }
  }
`;

module.exports = sourceFragment;
<|endoftext|>


<commit_before>'use strict';

var util = require('util'),
  path = require('path'),
  yeoman = require('yeoman-generator'),
  chalk = require('chalk');

var BespokeGenerator = module.exports = function BespokeGenerator(args, options, config) {
  yeoman.generators.Base.apply(this, arguments);

  this.on('end', function () {
    this.installDependencies({ skipInstall: options['skip-install'] });
  });

  this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(BespokeGenerator, yeoman.generators.NamedBase);

BespokeGenerator.prototype.askFor = function askFor() {
  var cb = this.async();

  // welcome message
  var welcome =
    "\n" +
    chalk.cyan.bold("\noooooooooo.                                          oooo                          o8o          ") +
    chalk.cyan.bold("\n`888'   `Y8b                                         `888                          `\"'          ") +
    chalk.cyan.bold("\n 888     888  .ooooo.   .oooo.o oo.ooooo.   .ooooo.   888  oooo   .ooooo.         oooo  .oooo.o ") +
    chalk.cyan.bold("\n 888oooo888' d88' `88b d88(  \"8  888' `88b d88' `88b  888 .8P'   d88' `88b        `888 d88(  \"8 ") +
    chalk.cyan.bold("\n 888    `88b 888ooo888 `\"Y88b.   888   888 888   888  888888.    888ooo888         888 `\"Y88b.  ") +
    chalk.cyan.bold("\n 888    .88P 888    .o o.  )88b  888   888 888   888  888 `88b.  888    .o .o.     888 o.  )88b ") +
    chalk.cyan.bold("\no888bood8P'  `Y8bod8P' 8\"\"888P'  888bod8P' `Y8bod8P' o888o o888o `Y8bod8P' Y8P     888 8\"\"888P' ") +
    chalk.cyan.bold("\n                                 888                                               888          ") +
    chalk.cyan.bold("\n                                o888o                                          .o. 88P          ") +
    chalk.cyan.bold("\n                                                                               `Y888P           ") +
    "\n" +
    chalk.green.bold("Thanks for choosing Bespoke.js for your presentation! :)   -@markdalgleish") +
    "\n";

  console.log(welcome);

  var prompts = [
    {
      name: 'title',
      message: 'What is the title of your presentation?',
      default: 'Hello World'
    },
    {
      type: 'confirm',
      name: 'bullets',
      message: 'Would you like bullet list support?',
      default: true
    },
    {
      type: 'confirm',
      name: 'scale',
      message: 'Would you like responsive slide scaling?',
      default: true
    },
    {
      type: 'confirm',
      name: 'hash',
      message: 'Would you like hash routing support?',
      default: true
    },
    {
      type: 'confirm',
      name: 'progress',
      message: 'Would you like an animated progress bar?',
      default: true
    },
    {
      type: 'confirm',
      name: 'state',
      message: 'Would you like slide-specific deck styles?',
      default: true
    },
    {
      type: 'confirm',
      name: 'syntax',
      message: 'Would you like syntax highlighting?',
      default: true
    }
  ];

  this.prompt(prompts, function (props) {
    this.bullets = props.bullets;
    this.scale = props.scale;
    this.hash = props.hash;
    this.progress = props.progress;
    this.state = props.state;
    this.syntax = props.syntax;
    this.title = props.title;
    this.shortName = this._.slugify(props.title);

    cb();
  }.bind(this));
};

BespokeGenerator.prototype.setupProjectFiles = function setupProjectFiles() {
  this.template('Gruntfile.js', 'Gruntfile.js');
  this.template('README.md', 'README.md');

  this.copy('bowerrc', '.bowerrc');
  this.copy('gitignore', '.gitignore');
  this.copy('jshintrc', '.jshintrc');
  this.copy('editorconfig', '.editorconfig');
}

BespokeGenerator.prototype.setupPackageJson = function setupPackageJson() {
  var packageJson = {
    'name': this.shortName + '-bespoke',
    'version': '0.0.0',
    'dependencies': {},
    'devDependencies': {
      'grunt': '~0.4.1',
      'grunt-contrib-clean': '~0.4.0',
      'grunt-contrib-copy': '~0.4.1',
      'grunt-contrib-watch': '~0.5.1',
      'grunt-contrib-jade': '~0.5.0',
      'grunt-contrib-stylus': '~0.5.0',
      'grunt-contrib-coffee': '~0.7.0',
      'grunt-contrib-connect': '~0.3.0',
      'grunt-open': '~0.2.1',
      'grunt-concurrent': '~0.3.0',
      'grunt-gh-pages': '~0.6.0',
      'connect-livereload': '~0.2.0'
    },
    'engines': {
      'node': '>=0.8.0'
    }
  };
  this.write('package.json', JSON.stringify(packageJson, null, 2));
};

BespokeGenerator.prototype.setupBowerJson = function setupBowerJson() {
  var bowerJson = {
    'name': this.shortName + '-bespoke',
    'version': '0.0.0',
    'dependencies': {
      'bespoke.js': '~0.3.0'
    }
  };
  if (this.bullets) bowerJson.dependencies['bespoke-bullets'] = '~0.2.0';
  if (this.scale) bowerJson.dependencies['bespoke-scale'] = '~0.2.0';
  if (this.hash) bowerJson.dependencies['bespoke-hash'] = '~0.1.0';
  if (this.progress) bowerJson.dependencies['bespoke-progress'] = '~0.1.0';
  if (this.state) bowerJson.dependencies['bespoke-state'] = '~0.2.0';
  if (this.syntax) bowerJson.dependencies['prism'] = 'gh-pages';
  this.write('bower.json', JSON.stringify(bowerJson, null, 2));
};

BespokeGenerator.prototype.setupBowerComponentPaths = function setupBowerComponentPaths() {
  this.bowerComponentPaths = ['bespoke.js/dist/bespoke.min.js'];
  if (this.bullets) this.bowerComponentPaths.push('bespoke-bullets/dist/bespoke-bullets.min.js');
  if (this.scale) this.bowerComponentPaths.push('bespoke-scale/dist/bespoke-scale.min.js');
  if (this.hash) this.bowerComponentPaths.push('bespoke-hash/dist/bespoke-hash.min.js');
  if (this.progress) this.bowerComponentPaths.push('bespoke-progress/dist/bespoke-progress.min.js');
  if (this.state) this.bowerComponentPaths.push('bespoke-state/dist/bespoke-state.min.js');
  if (this.syntax) this.bowerComponentPaths.push('prism/prism.js');
};

BespokeGenerator.prototype.setupPlugins = function setupPlugins() {
  var plugins = {};
  if (this.bullets) plugins['bullets'] = 'li, .bullet';
  if (this.scale) plugins['scale'] = true;
  if (this.hash) plugins['hash'] = true;
  if (this.progress) plugins['progress'] = true;
  if (this.state) plugins['state'] = true;
  this.hasPlugins = this.bullets || this.hash || this.state;
  this.pluginsJson = JSON.stringify(plugins, null, 2)
    .replace(/\"/g,"'") // Switch to single quotes
    .replace(/\'([a-z0-9_$]+)\'(:)/gi, '$1$2') // Unquote object keys
};

BespokeGenerator.prototype.setupFiles = function setupFiles() {
  this.mkdir('src');
  this.mkdir('src/scripts');
  this.mkdir('src/styles');

  this.template('src/index.jade', 'src/index.jade');
  this.template('src/scripts/main.js', 'src/scripts/main.js');
  this.template('src/styles/main.styl', 'src/styles/main.styl');
};<commit_msg>Add bespoke-forms<commit_after>'use strict';

var util = require('util'),
  path = require('path'),
  yeoman = require('yeoman-generator'),
  chalk = require('chalk');

var BespokeGenerator = module.exports = function BespokeGenerator(args, options, config) {
  yeoman.generators.Base.apply(this, arguments);

  this.on('end', function () {
    this.installDependencies({ skipInstall: options['skip-install'] });
  });

  this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(BespokeGenerator, yeoman.generators.NamedBase);

BespokeGenerator.prototype.askFor = function askFor() {
  var cb = this.async();

  // welcome message
  var welcome =
    "\n" +
    chalk.cyan.bold("\noooooooooo.                                          oooo                          o8o          ") +
    chalk.cyan.bold("\n`888'   `Y8b                                         `888                          `\"'          ") +
    chalk.cyan.bold("\n 888     888  .ooooo.   .oooo.o oo.ooooo.   .ooooo.   888  oooo   .ooooo.         oooo  .oooo.o ") +
    chalk.cyan.bold("\n 888oooo888' d88' `88b d88(  \"8  888' `88b d88' `88b  888 .8P'   d88' `88b        `888 d88(  \"8 ") +
    chalk.cyan.bold("\n 888    `88b 888ooo888 `\"Y88b.   888   888 888   888  888888.    888ooo888         888 `\"Y88b.  ") +
    chalk.cyan.bold("\n 888    .88P 888    .o o.  )88b  888   888 888   888  888 `88b.  888    .o .o.     888 o.  )88b ") +
    chalk.cyan.bold("\no888bood8P'  `Y8bod8P' 8\"\"888P'  888bod8P' `Y8bod8P' o888o o888o `Y8bod8P' Y8P     888 8\"\"888P' ") +
    chalk.cyan.bold("\n                                 888                                               888          ") +
    chalk.cyan.bold("\n                                o888o                                          .o. 88P          ") +
    chalk.cyan.bold("\n                                                                               `Y888P           ") +
    "\n" +
    chalk.green.bold("Thanks for choosing Bespoke.js for your presentation! :)   -@markdalgleish") +
    "\n";

  console.log(welcome);

  var prompts = [
    {
      name: 'title',
      message: 'What is the title of your presentation?',
      default: 'Hello World'
    },
    {
      type: 'confirm',
      name: 'bullets',
      message: 'Would you like bullet list support?',
      default: true
    },
    {
      type: 'confirm',
      name: 'scale',
      message: 'Would you like responsive slide scaling?',
      default: true
    },
    {
      type: 'confirm',
      name: 'hash',
      message: 'Would you like hash routing support?',
      default: true
    },
    {
      type: 'confirm',
      name: 'progress',
      message: 'Would you like an animated progress bar?',
      default: true
    },
    {
      type: 'confirm',
      name: 'state',
      message: 'Would you like slide-specific deck styles?',
      default: true
    },
    {
      type: 'confirm',
      name: 'forms',
      message: 'Will your presentation include interactive form elements?',
      default: true
    },
    {
      type: 'confirm',
      name: 'syntax',
      message: 'Would you like syntax highlighting?',
      default: true
    }
  ];

  this.prompt(prompts, function (props) {
    this.bullets = props.bullets;
    this.scale = props.scale;
    this.hash = props.hash;
    this.progress = props.progress;
    this.state = props.state;
    this.forms = props.forms;
    this.syntax = props.syntax;
    this.title = props.title;
    this.shortName = this._.slugify(props.title);

    cb();
  }.bind(this));
};

BespokeGenerator.prototype.setupProjectFiles = function setupProjectFiles() {
  this.template('Gruntfile.js', 'Gruntfile.js');
  this.template('README.md', 'README.md');

  this.copy('bowerrc', '.bowerrc');
  this.copy('gitignore', '.gitignore');
  this.copy('jshintrc', '.jshintrc');
  this.copy('editorconfig', '.editorconfig');
}

BespokeGenerator.prototype.setupPackageJson = function setupPackageJson() {
  var packageJson = {
    'name': this.shortName + '-bespoke',
    'version': '0.0.0',
    'dependencies': {},
    'devDependencies': {
      'grunt': '~0.4.1',
      'grunt-contrib-clean': '~0.4.0',
      'grunt-contrib-copy': '~0.4.1',
      'grunt-contrib-watch': '~0.5.1',
      'grunt-contrib-jade': '~0.5.0',
      'grunt-contrib-stylus': '~0.5.0',
      'grunt-contrib-coffee': '~0.7.0',
      'grunt-contrib-connect': '~0.3.0',
      'grunt-open': '~0.2.1',
      'grunt-concurrent': '~0.3.0',
      'grunt-gh-pages': '~0.6.0',
      'connect-livereload': '~0.2.0'
    },
    'engines': {
      'node': '>=0.8.0'
    }
  };
  this.write('package.json', JSON.stringify(packageJson, null, 2));
};

BespokeGenerator.prototype.setupBowerJson = function setupBowerJson() {
  var bowerJson = {
    'name': this.shortName + '-bespoke',
    'version': '0.0.0',
    'dependencies': {
      'bespoke.js': '~0.3.0'
    }
  };
  if (this.bullets) bowerJson.dependencies['bespoke-bullets'] = '~0.2.0';
  if (this.scale) bowerJson.dependencies['bespoke-scale'] = '~0.2.0';
  if (this.hash) bowerJson.dependencies['bespoke-hash'] = '~0.1.0';
  if (this.progress) bowerJson.dependencies['bespoke-progress'] = '~0.1.0';
  if (this.state) bowerJson.dependencies['bespoke-state'] = '~0.2.0';
  if (this.forms) bowerJson.dependencies['bespoke-forms'] = '~0.1.0';
  if (this.syntax) bowerJson.dependencies['prism'] = 'gh-pages';
  this.write('bower.json', JSON.stringify(bowerJson, null, 2));
};

BespokeGenerator.prototype.setupBowerComponentPaths = function setupBowerComponentPaths() {
  this.bowerComponentPaths = ['bespoke.js/dist/bespoke.min.js'];
  if (this.bullets) this.bowerComponentPaths.push('bespoke-bullets/dist/bespoke-bullets.min.js');
  if (this.scale) this.bowerComponentPaths.push('bespoke-scale/dist/bespoke-scale.min.js');
  if (this.hash) this.bowerComponentPaths.push('bespoke-hash/dist/bespoke-hash.min.js');
  if (this.progress) this.bowerComponentPaths.push('bespoke-progress/dist/bespoke-progress.min.js');
  if (this.state) this.bowerComponentPaths.push('bespoke-state/dist/bespoke-state.min.js');
  if (this.forms) this.bowerComponentPaths.push('bespoke-forms/dist/bespoke-forms.min.js');
  if (this.syntax) this.bowerComponentPaths.push('prism/prism.js');
};

BespokeGenerator.prototype.setupPlugins = function setupPlugins() {
  var plugins = {};
  if (this.bullets) plugins['bullets'] = 'li, .bullet';
  if (this.scale) plugins['scale'] = true;
  if (this.hash) plugins['hash'] = true;
  if (this.progress) plugins['progress'] = true;
  if (this.state) plugins['state'] = true;
  if (this.forms) plugins['forms'] = true;
  this.hasPlugins = this.bullets || this.hash || this.state;
  this.pluginsJson = JSON.stringify(plugins, null, 2)
    .replace(/\"/g,"'") // Switch to single quotes
    .replace(/\'([a-z0-9_$]+)\'(:)/gi, '$1$2') // Unquote object keys
};

BespokeGenerator.prototype.setupFiles = function setupFiles() {
  this.mkdir('src');
  this.mkdir('src/scripts');
  this.mkdir('src/styles');

  this.template('src/index.jade', 'src/index.jade');
  this.template('src/scripts/main.js', 'src/scripts/main.js');
  this.template('src/styles/main.styl', 'src/styles/main.styl');
};<|endoftext|>


<commit_before>'use strict';
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const download = require('download');
var fs = require('fs');
var del = require('del');
var _ = require('lodash');
var walk = require('walk');
var path = require('path');

module.exports = class extends Generator {
	prompting() {
		// Have Yeoman greet the user.
		this.log(yosay(
			'Welcome to the world-class ' + chalk.red('generator-npm-wp-s-theme') + ' generator!'
		));

		return this.prompt(
			[
					{
						type: 'input',
						name: 'proxy',
						message: 'Localhost address',
						default: 'localhost'
				},
					{
						type: 'input',
						name: 'domain',
						message: 'If you want to add a domain site',
						default: ''
				},
					{
						type: 'input',
						name: 'themeName',
						message: 'Theme Name',
						default: 'Theme Name'
				},
					{
						type: 'input',
						name: 'themeSlug',
						message: 'Theme slug',
						default: 'Theme slug'
				},
					{
						type: 'input',
						name: 'themeURI',
						message: 'Theme URI',
						default: 'https://example.com/themeURI/'
				},
					{
						type: 'input',
						name: 'author',
						message: 'Author',
						default: 'Author'
				},
					{
						type: 'input',
						name: 'authorURI',
						message: 'Author URI',
						default: 'https://example.com/authorURI/'
				},
					{
						type: 'input',
						name: 'authorEmail',
						message: 'Author email',
						default: 'info@example.com'
				},
					{
						type: 'input',
						name: 'description',
						message: 'Description',
						default: 'Description'
				},
					{
						type: 'input',
						name: 'bugreport',
						message: 'Bug Report',
						default: 'https://example.com/bugreport/'
				},
					{
						type: 'confirm',
						name: 'gitignore',
						message: 'Would you like to add a ' + chalk.white('.gitignore') + ' file?',
						default: true
				},
					{
						type: 'confirm',
						name: 'editorconfig',
						message: 'Would you like to add a ' + chalk.white('.editorconfig') + ' file?',
						default: true
				},
					{
						type: 'confirm',
						name: 'stylelintrc',
						message: 'Would you like to add a ' + chalk.white('.stylelintrc') + ' file?',
						default: true
				},
					{
						type: 'confirm',
						name: 'npmrc',
						message: 'Would you like to add a ' + chalk.white('.npmrc') + ' file?',
						default: true
				},
					{
						type: 'confirm',
						name: 'npmsetup',
						message: 'Would you like to setup a configuration ready to use?',
						default: true
				}
			]
			)
			.then((answers) => {
				this.proxy = answers.proxy;
				this.domain = answers.domain;
				this.themeName = answers.themeName;
				this.themeSlug = answers.themeSlug;
				this.themeURI = answers.themeURI;
				this.author = answers.author;
				this.authorURI = answers.authorURI;
				this.authorEmail = answers.authorEmail;
				this.description = answers.description;
				this.bugreport = answers.bugreport;
				this.gitignore = answers.gitignore;
				this.stylelintrc = answers.stylelintrc;
				this.npmrc = answers.npmrc;
				this.npmsetup = answers.npmsetup;
			});
	}

	writing() {
		// Download _s theme
		var done = this.async();
		var dir = this.destinationRoot();
		var unusedFiles = ['.travis.yml', 'codesniffer.ruleset.xml', 'README.md'];

		// Download _s theme
		this.log(chalk.yellow('\nLet\'s download the latest version of Underscores...'));

		Promise.all([
							'github.com/Automattic/_s/archive/master.tar.gz'
						].map(x => download(x, '.', {
				extract: true,
				strip: 1
			})))

			//		download('https://github.com/Automattic/_s/archive/master.tar.gz', '.', {
			//				extract: true,
			//				strip: 1
			//			})
			.then(() => {
				this.log(chalk.blue('End download!'));
			})
			.then(() => {
				// create custom catalogs & files
				this.log(chalk.yellow('\nAdd custom catalogs & files...'));

				if (!fs.existsSync('sass/theme.scss')) {
					fs.writeFileSync('sass/theme.scss', '/*!\n Theme Name: _s \n*/', 'utf-8');
				}
				if (!fs.existsSync('css')) {
					fs.mkdirSync('css');
				}
				if (!fs.existsSync('fonts')) {
					fs.mkdirSync('fonts');
				}
				if (!fs.existsSync('images')) {
					fs.mkdirSync('images');
				}
				this.log(chalk.blue('Done!'));
			})
			.then(() => {
				// Delete unused files
				this.log(chalk.yellow('\nDeleting some unused files...'));

				unusedFiles = _.map(unusedFiles, function (file) {
					return dir + '/' + file;
				});

				del(unusedFiles).catch(function (error) {
						done(error);
					})
					.then(paths => {
						this.log(chalk.cyan(paths.join('\n')));
						done();
					});
				this.log(chalk.blue('Done!'));
			})
			.then(() => {
				// Parsing theme files
				var _this = this;
				var walker;
				var options;
				options = {
					followLinks: false
				};
				this.log(chalk.yellow('\nParsing theme files...'));

				walker = walk.walk('../');

				this.log(chalk.white('	Please wait...'));

				walker.on("file", function (root, fileStats, next) {
					var filePath = root + '/' + fileStats.name;

					if (path.extname(fileStats.name) == '.php') {
						fs.readFile(filePath, 'utf8', function (err, data) {
							if (err) {
								done(error);
							}

							var result;

							result = data.replace(/'_s'/g, "'" + _this.themeSlug + "'");
							result = result.replace(/_s_/g, _this.themeSlug + "_");
							result = result.replace(/ _s/g, ' ' + _this.themeName);
							result = result.replace(/_s-/g, _this.themeSlug + '-');

							fs.writeFile(filePath, result, 'utf8', function (err) {
								if (err) {
									done(error);
								}
							});

							next();
						});
					} else if (path.extname(fileStats.name) == '.css' || fileStats.name == 'style.scss' || fileStats.name == 'woocommerce.scss' || fileStats.name == 'theme.scss') {
						fs.readFile(filePath, 'utf8', function (err, data) {
							if (err) {
								done(error);
							}

							var result;

							result = data.replace(/(Theme Name: )(.+)/g, '$1' + _this.themeName);
							result = result.replace(/(Theme URI: )(.+)/g, '$1' + _this.themeURI);
							result = result.replace(/(Author: )(.+)/g, '$1' + _this.author);
							result = result.replace(/(Author URI: )(.+)/g, '$1' + _this.authorURI);
							result = result.replace(/(Description: )(.+)/g, '$1' + _this.description);
							result = result.replace(/(Text Domain: )(.+)/g, '$1' + _this.themeSlug);
							result = result.replace(/_s is based on Underscores/g, _this.themeName + ' is based on Underscores');
							result = result.replace(/\@import "variables-site\/variables-site";/g, '\n\n// bower:scss' + '\n\n// endbower' + '\n\n@import "variables-site\/variables-site";');
							result = result.replace(/\@import "media\/media";/g, '@import "media\/media";' + '\n\n/*--------------------------------------------------------------\n\n' + '# Theme\n' + '--------------------------------------------------------------*/\n' + '@import "theme";\n');

							fs.writeFile(filePath, result, 'utf8', function (err) {
								if (err) {
									done(error);
								}
							});

							next();
						});
					} else if (fileStats.name === 'readme.txt') {
						fs.readFile(filePath, 'utf8', function (err, data) {
							if (err) {
								done(error);
							}

							var result;

							result = data.replace(/=== _s ===/g, '=== ' + _this.themeName + ' ===');
							result = result.replace(/A starter theme called _s, or underscores./g, _this.description);
							result = result.replace(/(== Description ==\n\n)(.+)/g, '$1' + 'Long description here');
							result = result.replace(/== Frequently Asked Questions ==[\s\S]*?== Credits ==/g, '== Credits ==');

							fs.writeFile(filePath, result, 'utf8', function (err) {
								if (err) {
									done(error);
								}
							});

							next();
						});
					} else if (fileStats.name === '_s.pot') {
						fs.readFile(filePath, 'utf8', function (err, data) {
							if (err) {
								done(error);
							}

							var result;

							result = data.replace(/Copyright (C) 2016 Automattic/g, 'Copyright (C) 2017 ' + _this.author);
							result = result.replace(/Project-Id-Version: _s/g, 'Project-Id-Version: ' + _this.themeName);
							result = result.replace(/Report-Msgid-Bugs-To: https:\/\/wordpress.org\/tags\/_s/g, 'Report-Msgid-Bugs-To: ' + _this.bugreport);
							result = result.replace(/Language-Team: LANGUAGE <LL@li\.org>/g, 'Language-Team: ' + _this.author + '<' + _this.authorEmail + '>');
							result = result.replace(/@ _s/g, '@ ' + _this.themeSlug);

							fs.writeFile(filePath, result, 'utf8', function (err) {
								if (err) {
									done(error);
								}
							});

							fs.rename(filePath, './languages/' + _this.themeSlug + '.pot');

							next();
						});
					} else {
						next();
					}
				});

				walker.on("errors", function (root, nodeStatsArray, next) {
					done(error);
					next();
				});

				walker.on("end", function () {
					done();
				});

				this.log(chalk.blue('Parsing done!'));
			});

		// Copying configuration files
		this.log(chalk.yellow('\nCopying configuration files...'));
		if (this.gitignore) {
			this.fs.copy(
				this.templatePath('_gitignore'),
				this.destinationPath('.gitignore')
			);
		}
		if (this.editorconfig) {
			this.fs.copy(
				this.templatePath('_editorconfig'),
				this.destinationPath('.editorconfig')
			);
		}

		if (this.stylelintrc) {
			this.fs.copy(
				this.templatePath('_stylelintrc'),
				this.destinationPath('.stylelintrc')
			);
		}
		if (this.npmrc) {
			this.fs.copy(
				this.templatePath('_npmrc'),
				this.destinationPath('.npmrc')
			);
		}
		if (this.npmsetup) {
			this.fs.copyTpl(
				this.templatePath('_package.json'),
				this.destinationPath('package.json'), {
					package_name: this.themeSlug,
					package_description: this.description,
					package_author: this.author,
					proxy_address: this.proxy,
					proxy_domain: this.domain,
					theme_name: this.themeName,
					theme_domain: this.themeSlug,
					theme_bugreport: this.bugreport,
					author_uri: this.authorURI,
					author_email: this.authorEmail
				}
			);
		}
		this.log(chalk.blue('Done!'));
	}

	install() {
		if (this.npmsetup) {
			this.log(chalk.yellow('\nInstalling required packages...'));

			this.npmInstall(['autoprefixer'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('autoprefixer'));

			this.npmInstall(['browser-sync'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('browser-sync'));

			this.npmInstall(['imagemin-cli'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('imagemin-cli'));

			this.npmInstall(['jscs'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('jscs'));

			this.npmInstall(['mkdirp'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('mkdirp'));

			this.npmInstall(['node-sass'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('node-sass'));

			this.npmInstall(['npm-run-all'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('npm-run-all'));

			this.npmInstall(['onchange'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('onchange'));

			this.npmInstall(['postcss-cli'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('postcss-cli'));

			this.npmInstall(['rimraf'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('rimraf'));

			this.npmInstall(['copyfiles'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('copyfiles'));

			this.npmInstall(['uglify-js'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('uglify-js'));

			this.npmInstall(['wiredep-cli'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('wiredep-cli'));

			this.npmInstall(['cross-zip-cli'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('cross-zip-cli'));
		};
//		this.installDependencies({
//			npm: true,
//			bower: true,
//			yarn: false
//		});
	}
	end() {
		if (this.npmsetup) {

//			var exec = require('child_process').exec;
//			exec('npm link gulp', function(err, stdout) { console.log('link gulp', stdout); });

//			this.log('\nRun ' + chalk.green('npm run watch ') + ' to start the development and ' + chalk.green('npm run build') + ' to create a files in /dist/' + chalk.white('' + this.themeSlug) + ' ready for production.');

		}
		this.log(chalk.green('\nAll Done!!\n------------------------\n'));
	}
};
<commit_msg>Remove comments<commit_after>'use strict';
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const download = require('download');
var fs = require('fs');
var del = require('del');
var _ = require('lodash');
var walk = require('walk');
var path = require('path');

module.exports = class extends Generator {
	prompting() {
		// Have Yeoman greet the user.
		this.log(yosay(
			'Welcome to the world-class ' + chalk.red('generator-npm-wp-s-theme') + ' generator!'
		));

		return this.prompt(
			[
					{
						type: 'input',
						name: 'proxy',
						message: 'Localhost address',
						default: 'localhost'
				},
					{
						type: 'input',
						name: 'domain',
						message: 'If you want to add a domain site',
						default: ''
				},
					{
						type: 'input',
						name: 'themeName',
						message: 'Theme Name',
						default: 'Theme Name'
				},
					{
						type: 'input',
						name: 'themeSlug',
						message: 'Theme slug',
						default: 'Theme slug'
				},
					{
						type: 'input',
						name: 'themeURI',
						message: 'Theme URI',
						default: 'https://example.com/themeURI/'
				},
					{
						type: 'input',
						name: 'author',
						message: 'Author',
						default: 'Author'
				},
					{
						type: 'input',
						name: 'authorURI',
						message: 'Author URI',
						default: 'https://example.com/authorURI/'
				},
					{
						type: 'input',
						name: 'authorEmail',
						message: 'Author email',
						default: 'info@example.com'
				},
					{
						type: 'input',
						name: 'description',
						message: 'Description',
						default: 'Description'
				},
					{
						type: 'input',
						name: 'bugreport',
						message: 'Bug Report',
						default: 'https://example.com/bugreport/'
				},
					{
						type: 'confirm',
						name: 'gitignore',
						message: 'Would you like to add a ' + chalk.white('.gitignore') + ' file?',
						default: true
				},
					{
						type: 'confirm',
						name: 'editorconfig',
						message: 'Would you like to add a ' + chalk.white('.editorconfig') + ' file?',
						default: true
				},
					{
						type: 'confirm',
						name: 'stylelintrc',
						message: 'Would you like to add a ' + chalk.white('.stylelintrc') + ' file?',
						default: true
				},
					{
						type: 'confirm',
						name: 'npmrc',
						message: 'Would you like to add a ' + chalk.white('.npmrc') + ' file?',
						default: true
				},
					{
						type: 'confirm',
						name: 'npmsetup',
						message: 'Would you like to setup a configuration ready to use?',
						default: true
				}
			]
			)
			.then((answers) => {
				this.proxy = answers.proxy;
				this.domain = answers.domain;
				this.themeName = answers.themeName;
				this.themeSlug = answers.themeSlug;
				this.themeURI = answers.themeURI;
				this.author = answers.author;
				this.authorURI = answers.authorURI;
				this.authorEmail = answers.authorEmail;
				this.description = answers.description;
				this.bugreport = answers.bugreport;
				this.gitignore = answers.gitignore;
				this.stylelintrc = answers.stylelintrc;
				this.npmrc = answers.npmrc;
				this.npmsetup = answers.npmsetup;
			});
	}

	writing() {
		// Download _s theme
		var done = this.async();
		var dir = this.destinationRoot();
		var unusedFiles = ['.travis.yml', 'codesniffer.ruleset.xml', 'README.md'];

		// Download _s theme
		this.log(chalk.yellow('\nLet\'s download the latest version of Underscores...'));

		Promise.all([
							'github.com/Automattic/_s/archive/master.tar.gz'
						].map(x => download(x, '.', {
				extract: true,
				strip: 1
			})))

			//		download('https://github.com/Automattic/_s/archive/master.tar.gz', '.', {
			//				extract: true,
			//				strip: 1
			//			})
			.then(() => {
				this.log(chalk.blue('End download!'));
			})
			.then(() => {
				// create custom catalogs & files
				this.log(chalk.yellow('\nAdd custom catalogs & files...'));

				if (!fs.existsSync('sass/theme.scss')) {
					fs.writeFileSync('sass/theme.scss', '/*!\n Theme Name: _s \n*/', 'utf-8');
				}
				if (!fs.existsSync('css')) {
					fs.mkdirSync('css');
				}
				if (!fs.existsSync('fonts')) {
					fs.mkdirSync('fonts');
				}
				if (!fs.existsSync('images')) {
					fs.mkdirSync('images');
				}
				this.log(chalk.blue('Done!'));
			})
			.then(() => {
				// Delete unused files
				this.log(chalk.yellow('\nDeleting some unused files...'));

				unusedFiles = _.map(unusedFiles, function (file) {
					return dir + '/' + file;
				});

				del(unusedFiles).catch(function (error) {
						done(error);
					})
					.then(paths => {
						this.log(chalk.cyan(paths.join('\n')));
						done();
					});
				this.log(chalk.blue('Done!'));
			})
			.then(() => {
				// Parsing theme files
				var _this = this;
				var walker;
				var options;
				options = {
					followLinks: false
				};
				this.log(chalk.yellow('\nParsing theme files...'));

				walker = walk.walk('../');

				this.log(chalk.white('	Please wait...'));

				walker.on("file", function (root, fileStats, next) {
					var filePath = root + '/' + fileStats.name;

					if (path.extname(fileStats.name) == '.php') {
						fs.readFile(filePath, 'utf8', function (err, data) {
							if (err) {
								done(error);
							}

							var result;

							result = data.replace(/'_s'/g, "'" + _this.themeSlug + "'");
							result = result.replace(/_s_/g, _this.themeSlug + "_");
							result = result.replace(/ _s/g, ' ' + _this.themeName);
							result = result.replace(/_s-/g, _this.themeSlug + '-');

							fs.writeFile(filePath, result, 'utf8', function (err) {
								if (err) {
									done(error);
								}
							});

							next();
						});
					} else if (path.extname(fileStats.name) == '.css' || fileStats.name == 'style.scss' || fileStats.name == 'woocommerce.scss' || fileStats.name == 'theme.scss') {
						fs.readFile(filePath, 'utf8', function (err, data) {
							if (err) {
								done(error);
							}

							var result;

							result = data.replace(/(Theme Name: )(.+)/g, '$1' + _this.themeName);
							result = result.replace(/(Theme URI: )(.+)/g, '$1' + _this.themeURI);
							result = result.replace(/(Author: )(.+)/g, '$1' + _this.author);
							result = result.replace(/(Author URI: )(.+)/g, '$1' + _this.authorURI);
							result = result.replace(/(Description: )(.+)/g, '$1' + _this.description);
							result = result.replace(/(Text Domain: )(.+)/g, '$1' + _this.themeSlug);
							result = result.replace(/_s is based on Underscores/g, _this.themeName + ' is based on Underscores');
							result = result.replace(/\@import "variables-site\/variables-site";/g, '\n\n// bower:scss' + '\n\n// endbower' + '\n\n@import "variables-site\/variables-site";');
							result = result.replace(/\@import "media\/media";/g, '@import "media\/media";' + '\n\n/*--------------------------------------------------------------\n\n' + '# Theme\n' + '--------------------------------------------------------------*/\n' + '@import "theme";\n');

							fs.writeFile(filePath, result, 'utf8', function (err) {
								if (err) {
									done(error);
								}
							});

							next();
						});
					} else if (fileStats.name === 'readme.txt') {
						fs.readFile(filePath, 'utf8', function (err, data) {
							if (err) {
								done(error);
							}

							var result;

							result = data.replace(/=== _s ===/g, '=== ' + _this.themeName + ' ===');
							result = result.replace(/A starter theme called _s, or underscores./g, _this.description);
							result = result.replace(/(== Description ==\n\n)(.+)/g, '$1' + 'Long description here');
							result = result.replace(/== Frequently Asked Questions ==[\s\S]*?== Credits ==/g, '== Credits ==');

							fs.writeFile(filePath, result, 'utf8', function (err) {
								if (err) {
									done(error);
								}
							});

							next();
						});
					} else if (fileStats.name === '_s.pot') {
						fs.readFile(filePath, 'utf8', function (err, data) {
							if (err) {
								done(error);
							}

							var result;

							result = data.replace(/Copyright (C) 2016 Automattic/g, 'Copyright (C) 2017 ' + _this.author);
							result = result.replace(/Project-Id-Version: _s/g, 'Project-Id-Version: ' + _this.themeName);
							result = result.replace(/Report-Msgid-Bugs-To: https:\/\/wordpress.org\/tags\/_s/g, 'Report-Msgid-Bugs-To: ' + _this.bugreport);
							result = result.replace(/Language-Team: LANGUAGE <LL@li\.org>/g, 'Language-Team: ' + _this.author + '<' + _this.authorEmail + '>');
							result = result.replace(/@ _s/g, '@ ' + _this.themeSlug);

							fs.writeFile(filePath, result, 'utf8', function (err) {
								if (err) {
									done(error);
								}
							});

							fs.rename(filePath, './languages/' + _this.themeSlug + '.pot');

							next();
						});
					} else {
						next();
					}
				});

				walker.on("errors", function (root, nodeStatsArray, next) {
					done(error);
					next();
				});

				walker.on("end", function () {
					done();
				});

				this.log(chalk.blue('Parsing done!'));
			});

		// Copying configuration files
		this.log(chalk.yellow('\nCopying configuration files...'));
		if (this.gitignore) {
			this.fs.copy(
				this.templatePath('_gitignore'),
				this.destinationPath('.gitignore')
			);
		}
		if (this.editorconfig) {
			this.fs.copy(
				this.templatePath('_editorconfig'),
				this.destinationPath('.editorconfig')
			);
		}

		if (this.stylelintrc) {
			this.fs.copy(
				this.templatePath('_stylelintrc'),
				this.destinationPath('.stylelintrc')
			);
		}
		if (this.npmrc) {
			this.fs.copy(
				this.templatePath('_npmrc'),
				this.destinationPath('.npmrc')
			);
		}
		if (this.npmsetup) {
			this.fs.copyTpl(
				this.templatePath('_package.json'),
				this.destinationPath('package.json'), {
					package_name: this.themeSlug,
					package_description: this.description,
					package_author: this.author,
					proxy_address: this.proxy,
					proxy_domain: this.domain,
					theme_name: this.themeName,
					theme_domain: this.themeSlug,
					theme_bugreport: this.bugreport,
					author_uri: this.authorURI,
					author_email: this.authorEmail
				}
			);
		}
		this.log(chalk.blue('Done!'));
	}

	install() {
		if (this.npmsetup) {
			this.log(chalk.yellow('\nInstalling required packages...'));

			this.npmInstall(['autoprefixer'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('autoprefixer'));

			this.npmInstall(['browser-sync'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('browser-sync'));

			this.npmInstall(['imagemin-cli'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('imagemin-cli'));

			this.npmInstall(['jscs'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('jscs'));

			this.npmInstall(['mkdirp'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('mkdirp'));

			this.npmInstall(['node-sass'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('node-sass'));

			this.npmInstall(['npm-run-all'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('npm-run-all'));

			this.npmInstall(['onchange'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('onchange'));

			this.npmInstall(['postcss-cli'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('postcss-cli'));

			this.npmInstall(['rimraf'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('rimraf'));

			this.npmInstall(['copyfiles'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('copyfiles'));

			this.npmInstall(['uglify-js'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('uglify-js'));

			this.npmInstall(['wiredep-cli'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('wiredep-cli'));

			this.npmInstall(['cross-zip-cli'], {
				'saveDev': true,
				'global': true
			});
			this.log(chalk.blue('cross-zip-cli'));
		};
	}
	end() {
		if (this.npmsetup) {

//			var exec = require('child_process').exec;
//			exec('npm link gulp', function(err, stdout) { console.log('link gulp', stdout); });

			this.log('\nRun ' + chalk.green('npm run watch ') + ' to start the development and ' + chalk.green('npm run build') + ' to create a files in /dist/' + chalk.white('' + this.themeSlug) + ' ready for production.');

		}
		this.log(chalk.green('\nAll Done!!\n------------------------\n'));
	}
};
<|endoftext|>