<commit_before>/**
 * validationFunctions.css
 *
 * Custom functions handling client-side validation (validation also performed on backend).
 */

/**
 * This function tests/loops through the metadata array and validates the
 * user input data (String) stored in the session against the array values.
 *
 * @param metadataArray  The array of metadata objects we are going to evaluate.
 * @param metadataType  The type of metadata to validate (platform, etc.).
 * @param currentStep  The current step in the jWizard.
 */
function validateMetadataEntries(metadataArray, metadataType, currentStep) {
    var boolean = true;
    for (var i = 0; i < metadataArray.length; i++) {
        var obj = metadataArray[i];
        var errorLabel = $(".jw-step:eq(" + currentStep + ")")
            .find("label[for=\"" + obj["tagName"] + "\"]");
        var userEnteredValue = getItemEntered(metadataType, obj["tagName"]);

        if (userEnteredValue == null) {
            if (obj["isRequired"]) {
                $(errorLabel).text("You need to provide input for " + obj["displayName"]);
                $(errorLabel).attr("style", "");
                boolean = false;
            }
        } else {
            var errorMessage = lookForBadChars(userEnteredValue, obj["displayName"]);
            if (errorMessage != null) {
                $(errorLabel).text(errorMessage);
                $(errorLabel).attr("style", "");
                boolean = false;
            } else {
                if (obj["units"]) {
                    var units = $(".jw-step:eq(" + currentStep + ")")
                        .find("select[name=\"" + obj["tagName"] + "Units\"]").attr("value");
                    var metadataString = buildStringForSession("platformMetadata",
                                                               obj["tagName"] + "Units", units);
                    addToSession(metadataType, metadataString);
                }
            }
        }
    }
    return boolean;
}

/**
 * This function verifies the needed data exists in the session.
 *
 * @param currentStep  The current step in the jWizard.
 * @param dataToExamine  The data to look for in the session.
 * @param errorMessage  The corresponding error message if the data is missing.
 */
function validateItemExistsInSession(currentStep, dataToExamine, errorMessage) {
    var boolean = true;
    var errorLabel = $(".jw-step:eq(" + currentStep + ")").find("label.error");
    if (!getFromSession(dataToExamine)) {
        $(errorLabel).text(errorMessage);
        boolean = false;
    }
    return boolean;
}

/**
 * This function validates the file size and type uploaded by the user.
 *
 * @param file  The file uploaded by the user.
 * @param currentStep  The current step in the jWizard.
 */
function validateUploadedFile(file, currentStep) {
    var boolean = true;
    var errorLabel = $(".jw-step:eq(" + currentStep + ")").find("label.error");
    // RegEx patters for valid files (extensions, "type" from input variable `file`)
    var excelPattern = /^\.(xls|xlsx)$/i;
    var ncmlPattern = /^\.ncml$/i;
    var zipPattern = /^\.zip$/i;
    var filePattern = /(text)/i;
    var eolCompositeSountingPattern = /^\.cls$/i;

    // get file extension
    var fileExt = file.name.match(/\.[a-zA-Z]{3,4}$/);

    // test valid regex patterns
    var isExcel = excelPattern.test(fileExt[0]);
    var isNcml = ncmlPattern.test(fileExt[0]);
    var isZip = zipPattern.test(fileExt[0]);
    var isFile = filePattern.test(file.type);
    var isEcs = eolCompositeSountingPattern.test(fileExt[0]);
    if (file.size > maxUploadSize) {
        $(errorLabel).text(
            "Error! File size should be less then " + (maxUploadSize / 1024 / 1000).toFixed(2)
            + " MB");
        $("#upload").addClass("hideMe");
        boolean = false;
    } else if (($("#file")[0].files[0].size / 1024) <= 0) {
        $(errorLabel).text("Error! You are attempting to upload an empty file");
        $("#upload").addClass("hideMe");
        boolean = false;
    } else {
        // handle special cases first, then as last check see if it of type "file:
        if (isExcel) {
            $(".jw-step:eq(" + currentStep + ")").find("#notice").empty().append(
                "Notice: Any date formatted cells in your spreadsheet will be reformatted in 'seconds since 1970-01-01'!");
        } else if ((!isFile) && (!isNcml) && (!isZip) && (!isEcs)) {
            $(errorLabel).text("Error! Incorrect file type selected for upload");
            $("#upload").addClass("hideMe");
            boolean = false;
        }
    }
    return boolean;
}

/**
 * This function validates the file size and type uploaded by the user.
 *     Specific to template files
 * @param file  The file uploaded by the user.
 * @param currentStep  The current step in the jWizard.
 */
function validateUploadedTemplateFile(file, currentStep) {
    var boolean = true;
    var errorLabel = $(".jw-step:eq(" + currentStep + ")").find("label.error");
    // RegEx patters for valid files (extensions, "type" from input variable `file`)
    var zipPattern = /^\.zip$/i;

    // get file extension
    var fileExt = file.name.match(/\.[a-zA-Z]{3,4}$/);

    // test valid regex patterns
    var isZip = zipPattern.test(fileExt[0]);

    if (file.size > maxUploadSize) {
        $(errorLabel).text(
            "Error! File size should be less then " + (maxUploadSize / 1024 / 1000).toFixed(2)
            + " MB");
        $("#uploadTemplate").addClass("hideMe");
        boolean = false;
    } else if (($("#templateFile")[0].files[0].size / 1024) <= 0) {
        $(errorLabel).text("Error! You are attempting to upload an empty file");
        $("#uploadTemplate").addClass("hideMe");
        boolean = false;
    } else {
        // handle special cases first, then as last check see if it of type "file:
        if (!isZip) {
            $(errorLabel).text("Error! Incorrect file type selected for upload");
            $("#uploadTemplate").addClass("hideMe");
            boolean = false;
        }
    }
    return boolean;
}

/**
 * This function verifies a value for other delimiter exists if users has "Other" among the
 * delimiters listed in the session.
 *
 * @param currentStep  The current step in the jWizard.
 */
function validateOtherDelimiter(currentStep) {
    var boolean = true;
    var errorLabel = $(".jw-step:eq(" + currentStep + ")").find("label.error");

    if (getFromSession("delimiters").search("Other") >= 0) {
        if (!getFromSession("otherDelimiter")) {
            $(errorLabel).text(
                "You Specified 'Other' as a delimiter.  Please input that delimiter to continue.");
            boolean = false;
        }
    }
    return boolean;
}

/**
 * This function tests user input data (String) against a know set of acceptable
 * characters.  If any bad characters are detected in the input data, the function
 * returns a message and the calling code handles the error display accordingly.
 *
 * @param userInput  The user input data to test.
 * @param tagName  The name value of the input tag that collected the data.
 */
function lookForBadChars(userInput, tagName) {
    if (tagName != "Units") {
        if (/[^a-zA-Z0-9_\s\-\.]/g.test(userInput.trim())) { // garbage characters entered
            return "Please enter a legitimate value for " + tagName + " (allowed: a-zA-Z0-9 _-.):";
        } else {
            return null;
        }
    }
}

/**
 * This function tests user input data (String) to see if the user provided
 * only whitespace characters or if the entry was submitted with a blank value.
 * If the entry is perceived as being blank, the function returns a message
 * and the calling code handles the error display accordingly.
 *
 * @param userInput  The user input data to test.
 * @param tagName  The name value of the input tag that collected the data.
 */
function lookForBlankEntries(userInput, tagName) {
    if (userInput.trim() === "") {  // only whitespace entered
        return "Please enter a legitimate value for " + getMetadataDisplayName(tagName) + ":";
    } else {
        return null;
    }
}

/**
 * Similar to lookForBlankEnteries, but for a blank
 * option for a select element
 *
 * @param userInput  The user input data to test.
 * @param tagName  The name value of the input tag that collected the data.
 */
function lookForBlankSelection(userInput, tagName) {
    if (userInput === "") {  // empty selection
        return "Please select a value for " + getMetadataDisplayName(tagName);
    } else {
        return null;
    }
}

/**
 * This function checks to see that all the required metadata values for the specified
 * variable type (coordinate versus non-coordinate) were provided by the user and stored in
 * the session.  If something is missing, an error for that metadata item is added to the DOM.
 *
 * @param variableType  The variable "type" (coordinate variable or not).
 * @param metadataInSession  The metadata values entered by the user and stored in the session
 */
function checkRequiredMetadataCompletion(variableType, metadataInSession) {
    var requiredMetadata = getKnownRequiredMetadataList(variableType);
    for (var i = 0; i < requiredMetadata.length; i++) {
        if (metadataInSession.indexOf(requiredMetadata[i]) < 0) {
            $("#dialog #requiredMetadataAssignment label[for=\"" + requiredMetadata[i]
              + "\"].error").text("This metadata item is a required.  Please provide a value: ");
        }
    }
}

/**
 * This function looks at the data stored in the session and does a validation.
 *
 * @param sessionKey  The key used to store the data in the session.
 * @param finalCheck  If the final validation being performed (when done button is clicked).
 *     Optional.
 */
function validateVariableData(sessionKey, finalCheck) {
    // get the name of the variable supplied by the user
    var variableValue = getFromSession(sessionKey);

    if (variableValue) {  // the user has provided something for the variable name or opted not to use the column of data

        if (variableValue != "Do Not Use") {
            var errorMessage = lookForBlankEntries(variableValue, "Variable Name");
            if (errorMessage != null) {
                $("#dialog #variableNameTypeAssignment").find("label.error").text(errorMessage);
                removeFromSession(sessionKey);
            } else {
                errorMessage = lookForBadChars(variableValue, "Variable Name");
                if (errorMessage != null) {
                    $("#dialog #variableNameTypeAssignment").find("label.error").text(errorMessage);
                    removeFromSession(sessionKey);
                } else {

                    // now validate the metadata if it exists in the session
                    var variableMetadataInSession = getFromSession(sessionKey + "Metadata");

                    if (variableMetadataInSession) { // if we have metadata in the session, grab it and populate the input tags
                        // coordinate variable
                        var coordinateVariableSelected = getItemEntered(sessionKey + "Metadata",
                                                                        "_coordinateVariable");
                        if (coordinateVariableSelected != null) {
                            var coordinateVariableType = getItemEntered(sessionKey + "Metadata",
                                                                        "_coordinateVariableType");
                            if (((coordinateVariableType != "") & (coordinateVariableType != null))
                                | ((coordinateVariableType == null) & (coordinateVariableSelected
                                                                       != "coordinate"))) {
                                // data type
                                var dataTypeSelected = getItemEntered(sessionKey + "Metadata",
                                                                      "dataType");
                                if (dataTypeSelected != null) {

                                    // metadata
                                    // get the metadata from the session string, minus the
                                    // coordinateVariable and dataType entries
                                    var metadataProvided = getAllButTheseFromSessionString(
                                        sessionKey + "Metadata",
                                        ["_coordinateVariable", "dataType"]);
                                    if (metadataProvided.length > 0) {
                                        // make sure chars are correct and no blank entries
                                        for (var i = 0; i < metadataProvided.length; i++) {
                                            var metadataKeyValuePair = metadataProvided[i].match(/(\\.|[^:])+/g);

                                            // all entries have to pass this test if it has a value
                                            if (metadataKeyValuePair.length > 1){
                                                errorMessage =
                                                    lookForBadChars(metadataKeyValuePair[1],
                                                                    getMetadataDisplayName(
                                                                        metadataKeyValuePair[0]));
                                            }
                                            if (errorMessage != null) {
                                                $("#dialog #variableAttributes label[for=\""
                                                  + metadataKeyValuePair[0] + "\"].error")
                                                    .text(errorMessage);
                                                removeItemFromSessionString(sessionKey + "Metadata",
                                                                            metadataKeyValuePair[0]);
                                            } else {
                                                var value = "";
                                                if (metadataKeyValuePair.length > 1){
                                                    value = metadataKeyValuePair[1];
                                                }
                                                errorMessage =
                                                    lookForBlankEntries(value,
                                                                        metadataKeyValuePair[0]);
                                                if (errorMessage != null) {
                                                    // only required metadata must pass this
                                                    if (isRequiredMetadata(
                                                            coordinateVariableSelected,
                                                            metadataKeyValuePair[0])) {
                                                        $("#dialog #variableAttributes label[for=\""
                                                          + metadataKeyValuePair[0] + "\"].error")
                                                            .text(errorMessage);
                                                    }
                                                    removeItemFromSessionString(
                                                        sessionKey + "Metadata",
                                                        metadataKeyValuePair[0]);
                                                } else {
                                                    // has all the required metadata been provided?
                                                    if (finalCheck) { // has the "done" button been clicked?
                                                        checkRequiredMetadataCompletion(
                                                            coordinateVariableSelected,
                                                            getKeysFromSessionData(
                                                                metadataProvided));
                                                    }
                                                }
                                            }
                                        }
                                    } else {
                                        if (finalCheck) { // has the "done" button been clicked?
                                            $("#dialog #requiredMetadataAssignment")
                                                .find("label.error")
                                                .text("Please provide an entry for this field: ");
                                        }
                                    }

                                } else {
                                    if (finalCheck) { // has the "done" button been clicked?
                                        $("#dialog #dataTypeAssignment").find("label.error")
                                            .text("Please select the data type for this variable.");
                                    }
                                }
                            } else { // no coordinate variable type specified
                                if (finalCheck) { // has the "done" button been clicked?
                                    $("#dialog #coordinateVarTypeAssignment").find("label.error")
                                        .text("Please specify the coordinate variable type.");
                                }
                            }

                        } else { // no coordinate variable specified
                            if (finalCheck) { // has the "done" button been clicked?
                                $("#dialog #coordinateVariableAssignment").find("label.error")
                                    .text("Please specify if this a coordinate variable or not.");
                            }
                        }

                    } else {  // no variable metadata in session yet
                        if (finalCheck) { // has the "done" button been clicked?
                            // give the error because the coordinateVariable is the first thing we
                            // collect
                            $("#dialog #coordinateVariableAssignment").find("label.error")
                                .text("Please specify if this a coordinate variable or not.");
                            removeFromSession(sessionKey + "Metadata");
                        }
                    }
                }
            }
        }
    } else { // no input given: error
        if (finalCheck) { // has the "done" button been clicked?
            $("#dialog #variableNameTypeAssignment").find("label.error")
                .text("You must assign a variable name or select not to use this column of data.");
            removeFromSession(sessionKey);
        }
    }
}
<commit_msg>Fixed a probable bug where user didn't recieve an error message<commit_after>/**
 * validationFunctions.css
 *
 * Custom functions handling client-side validation (validation also performed on backend).
 */

/**
 * This function tests/loops through the metadata array and validates the
 * user input data (String) stored in the session against the array values.
 *
 * @param metadataArray  The array of metadata objects we are going to evaluate.
 * @param metadataType  The type of metadata to validate (platform, etc.).
 * @param currentStep  The current step in the jWizard.
 */
function validateMetadataEntries(metadataArray, metadataType, currentStep) {
    var boolean = true;
    for (var i = 0; i < metadataArray.length; i++) {
        var obj = metadataArray[i];
        var errorLabel = $(".jw-step:eq(" + currentStep + ")")
            .find("label[for=\"" + obj["tagName"] + "\"]");
        var userEnteredValue = getItemEntered(metadataType, obj["tagName"]);

        if (userEnteredValue == null) {
            if (obj["isRequired"]) {
                $(errorLabel).text("You need to provide input for " + obj["displayName"]);
                $(errorLabel).attr("style", "");
                boolean = false;
            }
        } else {
            var errorMessage = lookForBadChars(userEnteredValue, obj["displayName"]);
            if (errorMessage != null) {
                $(errorLabel).text(errorMessage);
                $(errorLabel).attr("style", "");
                boolean = false;
            } else {
                if (obj["units"]) {
                    var units = $(".jw-step:eq(" + currentStep + ")")
                        .find("select[name=\"" + obj["tagName"] + "Units\"]").attr("value");
                    var metadataString = buildStringForSession("platformMetadata",
                                                               obj["tagName"] + "Units", units);
                    addToSession(metadataType, metadataString);
                }
            }
        }
    }
    return boolean;
}

/**
 * This function verifies the needed data exists in the session.
 *
 * @param currentStep  The current step in the jWizard.
 * @param dataToExamine  The data to look for in the session.
 * @param errorMessage  The corresponding error message if the data is missing.
 */
function validateItemExistsInSession(currentStep, dataToExamine, errorMessage) {
    var boolean = true;
    var errorLabel = $(".jw-step:eq(" + currentStep + ")").find("label.error");
    if (!getFromSession(dataToExamine)) {
        $(errorLabel).text(errorMessage);
        boolean = false;
    }
    return boolean;
}

/**
 * This function validates the file size and type uploaded by the user.
 *
 * @param file  The file uploaded by the user.
 * @param currentStep  The current step in the jWizard.
 */
function validateUploadedFile(file, currentStep) {
    var boolean = true;
    var errorLabel = $(".jw-step:eq(" + currentStep + ")").find("label.error");
    // RegEx patters for valid files (extensions, "type" from input variable `file`)
    var excelPattern = /^\.(xls|xlsx)$/i;
    var ncmlPattern = /^\.ncml$/i;
    var zipPattern = /^\.zip$/i;
    var filePattern = /(text)/i;
    var eolCompositeSountingPattern = /^\.cls$/i;

    // get file extension
    var fileExt = file.name.match(/\.[a-zA-Z]{3,4}$/);

    if (fileExt){
        // test valid regex patterns
        var isExcel = excelPattern.test(fileExt[0]);
        var isNcml = ncmlPattern.test(fileExt[0]);
        var isZip = zipPattern.test(fileExt[0]);
        var isFile = filePattern.test(file.type);
        var isEcs = eolCompositeSountingPattern.test(fileExt[0]);
        if (file.size > maxUploadSize) {
            $(errorLabel).text(
                "Error! File size should be less then " + (maxUploadSize / 1024 / 1000).toFixed(2)
                + " MB");
            $("#upload").addClass("hideMe");
            boolean = false;
        } else if (($("#file")[0].files[0].size / 1024) <= 0) {
            $(errorLabel).text("Error! You are attempting to upload an empty file");
            $("#upload").addClass("hideMe");
            boolean = false;
        } else {
            // handle special cases first, then as last check see if it of type "file:
            if (isExcel) {
                $(".jw-step:eq(" + currentStep + ")").find("#notice").empty().append(
                    "Notice: Any date formatted cells in your spreadsheet will be reformatted in 'seconds since 1970-01-01'!");
            } else if ((!isFile) && (!isNcml) && (!isZip) && (!isEcs)) {
                $(errorLabel).text("Error! Incorrect file type selected for upload");
                $("#upload").addClass("hideMe");
                boolean = false;
            }
        }
    } else {
        $(errorLabel).text("Error! The filename does not match the pattern \\.[a-zA-Z]{3,4}$");
        $("#upload").addClass("hideMe");
        boolean = false;
    }
    return boolean;
}

/**
 * This function validates the file size and type uploaded by the user.
 *     Specific to template files
 * @param file  The file uploaded by the user.
 * @param currentStep  The current step in the jWizard.
 */
function validateUploadedTemplateFile(file, currentStep) {
    var boolean = true;
    var errorLabel = $(".jw-step:eq(" + currentStep + ")").find("label.error");
    // RegEx patters for valid files (extensions, "type" from input variable `file`)
    var templatePattern = /^\.template$/i;

    // get file extension
    var fileExt = file.name.match(/\.[a-zA-Z]{3,8}$/);

    if (fileExt){
        // test valid regex patterns
        var isTemplate = templatePattern.test(fileExt[0]);

        if (file.size > maxUploadSize) {
            $(errorLabel).text(
                "Error! File size should be less then " + (maxUploadSize / 1024 / 1000).toFixed(2)
                + " MB");
            $("#uploadTemplate").addClass("hideMe");
            boolean = false;
        } else if (($("#templateFile")[0].files[0].size / 1024) <= 0) {
            $(errorLabel).text("Error! You are attempting to upload an empty file");
            $("#uploadTemplate").addClass("hideMe");
            boolean = false;
        } else {
            // handle special cases first, then as last check see if it of type "file:
            if (!isTemplate) {
                $(errorLabel).text("Error! Incorrect file type selected for upload");
                $("#uploadTemplate").addClass("hideMe");
                boolean = false;
            }
        }
    } else {
        $(errorLabel).text("Error! The filename does not match the pattern \\.[a-zA-Z]{3,8}$");
        $("#upload").addClass("hideMe");
        boolean = false;
    }
    return boolean;
    return boolean;
}

/**
 * This function verifies a value for other delimiter exists if users has "Other" among the
 * delimiters listed in the session.
 *
 * @param currentStep  The current step in the jWizard.
 */
function validateOtherDelimiter(currentStep) {
    var boolean = true;
    var errorLabel = $(".jw-step:eq(" + currentStep + ")").find("label.error");

    if (getFromSession("delimiters").search("Other") >= 0) {
        if (!getFromSession("otherDelimiter")) {
            $(errorLabel).text(
                "You Specified 'Other' as a delimiter.  Please input that delimiter to continue.");
            boolean = false;
        }
    }
    return boolean;
}

/**
 * This function tests user input data (String) against a know set of acceptable
 * characters.  If any bad characters are detected in the input data, the function
 * returns a message and the calling code handles the error display accordingly.
 *
 * @param userInput  The user input data to test.
 * @param tagName  The name value of the input tag that collected the data.
 */
function lookForBadChars(userInput, tagName) {
    if (tagName != "Units") {
        if (/[^a-zA-Z0-9_\s\-\.]/g.test(userInput.trim())) { // garbage characters entered
            return "Please enter a legitimate value for " + tagName + " (allowed: a-zA-Z0-9 _-.):";
        } else {
            return null;
        }
    }
}

/**
 * This function tests user input data (String) to see if the user provided
 * only whitespace characters or if the entry was submitted with a blank value.
 * If the entry is perceived as being blank, the function returns a message
 * and the calling code handles the error display accordingly.
 *
 * @param userInput  The user input data to test.
 * @param tagName  The name value of the input tag that collected the data.
 */
function lookForBlankEntries(userInput, tagName) {
    if (userInput.trim() === "") {  // only whitespace entered
        return "Please enter a legitimate value for " + getMetadataDisplayName(tagName) + ":";
    } else {
        return null;
    }
}

/**
 * Similar to lookForBlankEnteries, but for a blank
 * option for a select element
 *
 * @param userInput  The user input data to test.
 * @param tagName  The name value of the input tag that collected the data.
 */
function lookForBlankSelection(userInput, tagName) {
    if (userInput === "") {  // empty selection
        return "Please select a value for " + getMetadataDisplayName(tagName);
    } else {
        return null;
    }
}

/**
 * This function checks to see that all the required metadata values for the specified
 * variable type (coordinate versus non-coordinate) were provided by the user and stored in
 * the session.  If something is missing, an error for that metadata item is added to the DOM.
 *
 * @param variableType  The variable "type" (coordinate variable or not).
 * @param metadataInSession  The metadata values entered by the user and stored in the session
 */
function checkRequiredMetadataCompletion(variableType, metadataInSession) {
    var requiredMetadata = getKnownRequiredMetadataList(variableType);
    for (var i = 0; i < requiredMetadata.length; i++) {
        if (metadataInSession.indexOf(requiredMetadata[i]) < 0) {
            $("#dialog #requiredMetadataAssignment label[for=\"" + requiredMetadata[i]
              + "\"].error").text("This metadata item is a required.  Please provide a value: ");
        }
    }
}

/**
 * This function looks at the data stored in the session and does a validation.
 *
 * @param sessionKey  The key used to store the data in the session.
 * @param finalCheck  If the final validation being performed (when done button is clicked).
 *     Optional.
 */
function validateVariableData(sessionKey, finalCheck) {
    // get the name of the variable supplied by the user
    var variableValue = getFromSession(sessionKey);

    if (variableValue) {  // the user has provided something for the variable name or opted not to use the column of data

        if (variableValue != "Do Not Use") {
            var errorMessage = lookForBlankEntries(variableValue, "Variable Name");
            if (errorMessage != null) {
                $("#dialog #variableNameTypeAssignment").find("label.error").text(errorMessage);
                removeFromSession(sessionKey);
            } else {
                errorMessage = lookForBadChars(variableValue, "Variable Name");
                if (errorMessage != null) {
                    $("#dialog #variableNameTypeAssignment").find("label.error").text(errorMessage);
                    removeFromSession(sessionKey);
                } else {

                    // now validate the metadata if it exists in the session
                    var variableMetadataInSession = getFromSession(sessionKey + "Metadata");

                    if (variableMetadataInSession) { // if we have metadata in the session, grab it and populate the input tags
                        // coordinate variable
                        var coordinateVariableSelected = getItemEntered(sessionKey + "Metadata",
                                                                        "_coordinateVariable");
                        if (coordinateVariableSelected != null) {
                            var coordinateVariableType = getItemEntered(sessionKey + "Metadata",
                                                                        "_coordinateVariableType");
                            if (((coordinateVariableType != "") & (coordinateVariableType != null))
                                | ((coordinateVariableType == null) & (coordinateVariableSelected
                                                                       != "coordinate"))) {
                                // data type
                                var dataTypeSelected = getItemEntered(sessionKey + "Metadata",
                                                                      "dataType");
                                if (dataTypeSelected != null) {

                                    // metadata
                                    // get the metadata from the session string, minus the
                                    // coordinateVariable and dataType entries
                                    var metadataProvided = getAllButTheseFromSessionString(
                                        sessionKey + "Metadata",
                                        ["_coordinateVariable", "dataType"]);
                                    if (metadataProvided.length > 0) {
                                        // make sure chars are correct and no blank entries
                                        for (var i = 0; i < metadataProvided.length; i++) {
                                            var metadataKeyValuePair = metadataProvided[i].match(/(\\.|[^:])+/g);

                                            // all entries have to pass this test if it has a value
                                            if (metadataKeyValuePair.length > 1){
                                                errorMessage =
                                                    lookForBadChars(metadataKeyValuePair[1],
                                                                    getMetadataDisplayName(
                                                                        metadataKeyValuePair[0]));
                                            }
                                            if (errorMessage != null) {
                                                $("#dialog #variableAttributes label[for=\""
                                                  + metadataKeyValuePair[0] + "\"].error")
                                                    .text(errorMessage);
                                                removeItemFromSessionString(sessionKey + "Metadata",
                                                                            metadataKeyValuePair[0]);
                                            } else {
                                                var value = "";
                                                if (metadataKeyValuePair.length > 1){
                                                    value = metadataKeyValuePair[1];
                                                }
                                                errorMessage =
                                                    lookForBlankEntries(value,
                                                                        metadataKeyValuePair[0]);
                                                if (errorMessage != null) {
                                                    // only required metadata must pass this
                                                    if (isRequiredMetadata(
                                                            coordinateVariableSelected,
                                                            metadataKeyValuePair[0])) {
                                                        $("#dialog #variableAttributes label[for=\""
                                                          + metadataKeyValuePair[0] + "\"].error")
                                                            .text(errorMessage);
                                                    }
                                                    removeItemFromSessionString(
                                                        sessionKey + "Metadata",
                                                        metadataKeyValuePair[0]);
                                                } else {
                                                    // has all the required metadata been provided?
                                                    if (finalCheck) { // has the "done" button been clicked?
                                                        checkRequiredMetadataCompletion(
                                                            coordinateVariableSelected,
                                                            getKeysFromSessionData(
                                                                metadataProvided));
                                                    }
                                                }
                                            }
                                        }
                                    } else {
                                        if (finalCheck) { // has the "done" button been clicked?
                                            $("#dialog #requiredMetadataAssignment")
                                                .find("label.error")
                                                .text("Please provide an entry for this field: ");
                                        }
                                    }

                                } else {
                                    if (finalCheck) { // has the "done" button been clicked?
                                        $("#dialog #dataTypeAssignment").find("label.error")
                                            .text("Please select the data type for this variable.");
                                    }
                                }
                            } else { // no coordinate variable type specified
                                if (finalCheck) { // has the "done" button been clicked?
                                    $("#dialog #coordinateVarTypeAssignment").find("label.error")
                                        .text("Please specify the coordinate variable type.");
                                }
                            }

                        } else { // no coordinate variable specified
                            if (finalCheck) { // has the "done" button been clicked?
                                $("#dialog #coordinateVariableAssignment").find("label.error")
                                    .text("Please specify if this a coordinate variable or not.");
                            }
                        }

                    } else {  // no variable metadata in session yet
                        if (finalCheck) { // has the "done" button been clicked?
                            // give the error because the coordinateVariable is the first thing we
                            // collect
                            $("#dialog #coordinateVariableAssignment").find("label.error")
                                .text("Please specify if this a coordinate variable or not.");
                            removeFromSession(sessionKey + "Metadata");
                        }
                    }
                }
            }
        }
    } else { // no input given: error
        if (finalCheck) { // has the "done" button been clicked?
            $("#dialog #variableNameTypeAssignment").find("label.error")
                .text("You must assign a variable name or select not to use this column of data.");
            removeFromSession(sessionKey);
        }
    }
}
<|endoftext|>


<commit_before>import { connect } from 'react-redux';

import {
    deleteOAuthServer,
    fetchOAuthServers,
    refreshOAuthServers,
    setOAuthServersAscendingFilter,
    setOAuthServersListCurrentPageIndex,
    setOAuthServersSortingFilter,
} from '../../../store/actions';
import { filteredOAuthServersList } from '../../../store/selectors';

import OAuthServersList from './OAuthServersList';

const mapStateToProps = state => ({
    oAuthServers: filteredOAuthServersList(state),
    currentPageIndex: state.oAuthServersListReducer.currentPageIndex,
    searchQuery: state.searchReducer.searchQuery,
});

export default connect(
    mapStateToProps,
    {
        deleteOAuthServer,
        fetchOAuthServers,
        refreshOAuthServers,
        setAscendingFilter: setOAuthServersAscendingFilter,
        setCurrentPageIndex: setOAuthServersListCurrentPageIndex,
        setSortingFilter: setOAuthServersSortingFilter,
    },
)(OAuthServersList);
<commit_msg>remove redundant and unused stuff<commit_after>import { connect } from 'react-redux';

import {
    deleteOAuthServer,
    fetchOAuthServers,
    setOAuthServersAscendingFilter,
    setOAuthServersListCurrentPageIndex,
    setOAuthServersSortingFilter,
} from '../../../store/actions';
import { filteredOAuthServersList } from '../../../store/selectors';

import OAuthServersList from './OAuthServersList';

const mapStateToProps = state => ({
    oAuthServers: filteredOAuthServersList(state),
    currentPageIndex: state.oAuthServersListReducer.currentPageIndex,
    searchQuery: state.searchReducer.searchQuery,
});

export default connect(
    mapStateToProps,
    {
        deleteOAuthServer,
        fetchOAuthServers,
        setAscendingFilter: setOAuthServersAscendingFilter,
        setCurrentPageIndex: setOAuthServersListCurrentPageIndex,
        setSortingFilter: setOAuthServersSortingFilter,
    },
)(OAuthServersList);
<|endoftext|>


<commit_before>odoo.define('sale.tour', function(require) {
"use strict";

var core = require('web.core');
var tour = require('web_tour.tour');

var _t = core._t;

tour.register('sale_tour', {
    url: "/web",
}, [tour.STEPS.MENU_MORE, {
    trigger: '.o_app[data-menu-xmlid="sale.sale_menu_root"], .oe_menu_toggler[data-menu-xmlid="sale.sale_menu_root"]',
    content: _t('Organize your sales activities with the Sales Management app.'),
    position: 'bottom',
},  {
    trigger: ".o_list_button_add",
    extra_trigger: ".o_sale_order",
    content: _t("Let's create a new quotation.
Note that colored buttons usually point to the next logical actions."),
    position: "right",
}, {
    trigger: ".o_required_modifier input",
    extra_trigger: ".o_sale_order",
    content: _t("Write the name of your customer to create one on the fly, or select an existing one."),
    position: "top",
    run: "text Agrolait",
}, {
    trigger: ".ui-menu-item > a",
    auto: true,
    in_modal: false,
}, {
    trigger: ".o_field_x2many_list_row_add > a",
    extra_trigger: ".o_sale_order",
    content: _t("Click here to add some lines to your quotations."),
    position: "bottom",
}, {
    trigger: ".modal-body .o_required_modifier input, .o_list_view .o_required_modifier input",
    extra_trigger: ".o_sale_order",
    content: _t("Select a product, or create a new one on the fly. The product will define the default sales price (that you can change), taxes and description automatically."),
    position: "right",
    run: "text Ipad",
}, {
    trigger: ".ui-menu-item > a",
    auto: true,
    in_modal: false,
    run: function (actions) {
        actions.auto();
        if ($(".modal-footer .btn-primary").length) {
            actions.auto(".modal-footer .btn-primary");
        }
    },
    id: "quotation_product_selected",
}, {
    trigger: ".o_form_button_save",
    extra_trigger: ".o_sale_order",
    content: _t("Once your quotation is ready, you can save, print or send it by email."),
    position: "right",
}, {
    trigger: ".o_sale_print",
    extra_trigger: ".o_sale_order.o_form_readonly",
    content: _t("
Print this quotation. If not yet done, you will be requested to set your company data and to select a document layout.
"),
    position: "bottom"
}, {
    trigger: ".breadcrumb li:not(.active):last",
    extra_trigger: ".o_sale_order [data-value='sent'].btn-primary",
    content: _t("Use the breadcrumbs to go back to preceeding screens."),
    position: "bottom"
}, {
    trigger: 'li a[data-menu-xmlid="sale.sale_order_menu"], .oe_secondary_menu_section[data-menu-xmlid="sale.sale_order_menu"]',
    content: _t("Use this menu to access quotations, sales orders and customers."),
    edition: "enterprise",
    position: "bottom"
}, tour.STEPS.TOGGLE_HOME_MENU,
tour.STEPS.MENU_MORE, {
    trigger: '.o_app[data-menu-xmlid="base.menu_administration"], .oe_menu_toggler[data-menu-xmlid="base.menu_administration"]',
    content: _t("Configuration options are available in the Settings app."),
    position: "bottom"
}, {
    trigger: ".o_web_settings_dashboard textarea#user_emails",
    content: _t("Invite salespeople or managers via email.
Enter one email per line."),
    position: "right"
}]);

});
<commit_msg>[IMP] sale_management: Improve tour<commit_after>odoo.define('sale.tour', function(require) {
"use strict";

var core = require('web.core');
var tour = require('web_tour.tour');

var _t = core._t;

tour.register('sale_tour', {
    url: "/web",
}, [tour.STEPS.MENU_MORE, {
    trigger: '.o_app[data-menu-xmlid="sale.sale_menu_root"], .oe_menu_toggler[data-menu-xmlid="sale.sale_menu_root"]',
    content: _t('Organize your sales activities with the Sales Management app.'),
    position: 'bottom',
},  {
    trigger: ".o_list_button_add",
    extra_trigger: ".o_sale_order",
    content: _t("Let's create a new quotation.
Note that colored buttons usually point to the next logical actions."),
    position: "bottom",
}, {
    trigger: ".o_form_editable .o_field_many2one[name='partner_id']",
    extra_trigger: ".o_sale_order",
    content: _t("Write the name of your customer to create one on the fly, or select an existing one."),
    position: "bottom",
    run: function (actions) {
        actions.text("Agrolait", this.$anchor.find("input"));
    },
}, {
    trigger: ".ui-menu-item > a",
    auto: true,
    in_modal: false,
}, {
    trigger: ".o_field_x2many_list_row_add > a",
    extra_trigger: ".o_sale_order",
    content: _t("Click here to add some products or services to your quotation."),
    position: "bottom",
}, {
    trigger: ".o_form_editable .o_field_many2one[name='product_id']",
    extra_trigger: ".o_sale_order",
    content: _t("Select a product, or create a new one on the fly."),
    position: "right",
    run: function (actions) {
        actions.text("Ipad", this.$anchor.find("input"));
    },
}, {
    trigger: ".ui-menu-item > a",
    auto: true,
    in_modal: false,
    run: function (actions) {
        actions.auto();
        if ($(".modal-footer .btn-primary").length) {
            actions.auto(".modal-footer .btn-primary");
        }
    },
    id: "quotation_product_selected",
}, {
    trigger: ".o_form_button_save",
    extra_trigger: ".o_sale_order",
    content: _t("Once your quotation is ready, you can save, print or send it by email."),
    position: "right",
}, {
    trigger: ".o_sale_print",
    extra_trigger: ".o_sale_order.o_form_readonly",
    content: _t("
Print this quotation. If not yet done, you will be requested to set your company data and to select a document layout.
"),
    position: "bottom"
}, {
    trigger: ".breadcrumb li:not(.active):last",
    extra_trigger: ".o_sale_order [data-value='sent'].btn-primary",
    content: _t("Use the breadcrumbs to go back to preceeding screens."),
    position: "bottom"
}, {
    trigger: 'li a[data-menu-xmlid="sale.sale_order_menu"], .oe_secondary_menu_section[data-menu-xmlid="sale.sale_order_menu"]',
    content: _t("Use this menu to access quotations, sales orders and customers."),
    edition: "enterprise",
    position: "bottom"
}]);

});
<|endoftext|>


<commit_before>const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const EosKnowledge = imports.gi.EosKnowledge;

const SearchIFace = '\
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> \
  <interface name="org.gnome.Shell.SearchProvider2"> \
    <method name="GetInitialResultSet"> \
      <arg type="as" name="Terms" direction="in" /> \
      <arg type="as" name="Results" direction="out" /> \
    </method> \
    <method name = "GetSubsearchResultSet"> \
      <arg type="as" name="PreviousResults" direction="in" /> \
      <arg type="as" name="Terms" direction="in" /> \
      <arg type="as" name="Results" direction="out" /> \
    </method> \
    <method name = "GetResultMetas"> \
      <arg type="as" name="Results" direction="in" /> \
      <arg type="aa{sv}" name="Metas" direction="out" /> \
    </method> \
    <method name = "ActivateResult"> \
      <arg type="s" name="Result" direction="in" /> \
      <arg type="as" name="Terms" direction="in" /> \
      <arg type="u" name="Timestamp" direction="in" /> \
    </method> \
    <method name = "LaunchSearch"> \
      <arg type="as" name="Terms" direction="in" /> \
      <arg type="u" name="Timestamp" direction="in" /> \
    </method> \
  </interface> \
</node> \
'

// Enum for error codes
const SearchProviderErrors = {
    RetrievalError: 0
};

const SearchProvider = Lang.Class({
    Name: 'EknSearchProvider',
    Extends: GObject.Object,

    Signals: {
        'load-page': { param_types: [
            GObject.TYPE_OBJECT,
            GObject.TYPE_STRING,
            GObject.TYPE_UINT
        ] },
        'load-query': { param_types: [
            GObject.TYPE_STRING,
            GObject.TYPE_UINT
        ] },
    },

    NUM_RESULTS: 5,

    _init: function(args) {
        this.parent(args);

        this._impl = Gio.DBusExportedObject.wrapJSObject(SearchIFace, this);
        this._search_provider_domain = GLib.quark_from_string('Knowledge App Search Provider Error');

        this._search_domain = Gio.Application.get_default().application_id.split('.').pop();

        this._engine = new EosKnowledge.Engine();
        this._object_cache = {};
    },

    export: function (connection, path) {
        return this._impl.export(connection, path);
    },

    unexport: function (connection) {
        return this._impl.unexport_from_connection(connection);
    },

    _add_results_to_cache: function (results) {
        results.forEach(function (result) {
            this._object_cache[result.ekn_id] = result;
        }.bind(this));
    },

    _get_from_cache: function (id) {
        return this._object_cache[id];
    },

    _run_query: function (terms, limit, cb) {
        let search_phrase = terms.join(' ');
        this._engine.get_objects_by_query(this._search_domain, {
            q: search_phrase,
            limit: limit,
        }, function (err, results) {
            cb(err, results);
        }.bind(this));
    },

    GetInitialResultSetAsync: function (params, invocation) {
        let app = Gio.Application.get_default();
        app.hold();

        let terms = params[0];
        this._run_query(terms, this.NUM_RESULTS, function (err, results) {
            if (!err) {
                this._add_results_to_cache(results);
                let ids = results.map(function (result) { return result.ekn_id });
                invocation.return_value(new GLib.Variant('(as)', [ids]));
            } else {
                invocation.return_error_literal(this._search_provider_domain, SearchProviderErrors.RetrievalError, 'Error retrieving results: ' + err);
            }
            app.release();
        }.bind(this));
    },

    GetSubsearchResultSetAsync: function (params, invocation) {
        let app = Gio.Application.get_default();
        app.hold();

        let previous = params[0];
        let terms = params[1];
        this._run_query(terms, this.NUM_RESULTS, function (err, results) {
            if (!err) {
                this._add_results_to_cache(results);
                let ids = results.map(function (result) { return result.ekn_id });
                invocation.return_value(new GLib.Variant('(as)', [ids]));
            } else {
                invocation.return_error_literal(this._search_provider_domain, SearchProviderErrors.RetrievalError, 'Error retrieving results: ' + err);
            }
            app.release();
        }.bind(this));
    },

    GetResultMetas: function (params) {
        let identifiers = params;

        let result_gvariants = [];
        let result_ekn_objects = identifiers.map(this._get_from_cache.bind(this));
        for (let obj of result_ekn_objects) {
            if (typeof obj !== 'undefined') {
                let displayTitle;
                if (typeof obj.originalTitle !== 'undefined') {
                    displayTitle = obj.originalTitle;
                } else {
                    displayTitle = obj.title;
                }

                let result = {
                    name: new GLib.Variant('s', displayTitle),
                    id: new GLib.Variant('s', obj.ekn_id),
                };

                if (typeof obj.synopsis !== 'undefined') {
                    result.description = new GLib.Variant('s', obj.synopsis);
                }
                result_gvariants.push(result);
            }
        }

        return result_gvariants;
    },

    ActivateResult: function (id, terms, timestamp) {
        let query = terms.join(' ');
        let model = this._get_from_cache(id);
        model.fetch_all(this._engine);
        this.emit('load-page', model, query, timestamp);
    },

    LaunchSearch: function (terms, timestamp) {
        let query = terms.join(' ');
        this.emit('load-query', query, timestamp);
    },
});
<commit_msg>On search provider cache misses, re-fetch results<commit_after>const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const EosKnowledge = imports.gi.EosKnowledge;

const SearchIFace = '\
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> \
  <interface name="org.gnome.Shell.SearchProvider2"> \
    <method name="GetInitialResultSet"> \
      <arg type="as" name="Terms" direction="in" /> \
      <arg type="as" name="Results" direction="out" /> \
    </method> \
    <method name = "GetSubsearchResultSet"> \
      <arg type="as" name="PreviousResults" direction="in" /> \
      <arg type="as" name="Terms" direction="in" /> \
      <arg type="as" name="Results" direction="out" /> \
    </method> \
    <method name = "GetResultMetas"> \
      <arg type="as" name="Results" direction="in" /> \
      <arg type="aa{sv}" name="Metas" direction="out" /> \
    </method> \
    <method name = "ActivateResult"> \
      <arg type="s" name="Result" direction="in" /> \
      <arg type="as" name="Terms" direction="in" /> \
      <arg type="u" name="Timestamp" direction="in" /> \
    </method> \
    <method name = "LaunchSearch"> \
      <arg type="as" name="Terms" direction="in" /> \
      <arg type="u" name="Timestamp" direction="in" /> \
    </method> \
  </interface> \
</node> \
'

// Enum for error codes
const SearchProviderErrors = {
    RetrievalError: 0
};

const SearchProvider = Lang.Class({
    Name: 'EknSearchProvider',
    Extends: GObject.Object,

    Signals: {
        'load-page': { param_types: [
            GObject.TYPE_OBJECT,
            GObject.TYPE_STRING,
            GObject.TYPE_UINT
        ] },
        'load-query': { param_types: [
            GObject.TYPE_STRING,
            GObject.TYPE_UINT
        ] },
    },

    NUM_RESULTS: 5,

    _init: function(args) {
        this.parent(args);

        this._impl = Gio.DBusExportedObject.wrapJSObject(SearchIFace, this);
        this._search_provider_domain = GLib.quark_from_string('Knowledge App Search Provider Error');

        this._search_domain = Gio.Application.get_default().application_id.split('.').pop();

        this._engine = new EosKnowledge.Engine();
        this._object_cache = {};
    },

    export: function (connection, path) {
        return this._impl.export(connection, path);
    },

    unexport: function (connection) {
        return this._impl.unexport_from_connection(connection);
    },

    _add_results_to_cache: function (results) {
        results.forEach(function (result) {
            this._object_cache[result.ekn_id] = result;
        }.bind(this));
    },

    _get_from_cache: function (id) {
        return this._object_cache[id];
    },

    _run_query: function (terms, limit, cb) {
        let search_phrase = terms.join(' ');
        this._engine.get_objects_by_query(this._search_domain, {
            q: search_phrase,
            limit: limit,
        }, function (err, results) {
            cb(err, results);
        }.bind(this));
    },

    GetInitialResultSetAsync: function (params, invocation) {
        let app = Gio.Application.get_default();
        app.hold();

        let terms = params[0];
        this._run_query(terms, this.NUM_RESULTS, function (err, results) {
            if (!err) {
                this._add_results_to_cache(results);
                let ids = results.map(function (result) { return result.ekn_id });
                invocation.return_value(new GLib.Variant('(as)', [ids]));
            } else {
                invocation.return_error_literal(this._search_provider_domain, SearchProviderErrors.RetrievalError, 'Error retrieving results: ' + err);
            }
            app.release();
        }.bind(this));
    },

    GetSubsearchResultSetAsync: function (params, invocation) {
        let app = Gio.Application.get_default();
        app.hold();

        let previous = params[0];
        let terms = params[1];
        this._run_query(terms, this.NUM_RESULTS, function (err, results) {
            if (!err) {
                this._add_results_to_cache(results);
                let ids = results.map(function (result) { return result.ekn_id });
                invocation.return_value(new GLib.Variant('(as)', [ids]));
            } else {
                invocation.return_error_literal(this._search_provider_domain, SearchProviderErrors.RetrievalError, 'Error retrieving results: ' + err);
            }
            app.release();
        }.bind(this));
    },

    GetResultMetas: function (params) {
        let identifiers = params;

        let result_gvariants = [];
        let result_ekn_objects = identifiers.map(this._get_from_cache.bind(this));
        for (let obj of result_ekn_objects) {
            if (typeof obj !== 'undefined') {
                let displayTitle;
                if (typeof obj.originalTitle !== 'undefined') {
                    displayTitle = obj.originalTitle;
                } else {
                    displayTitle = obj.title;
                }

                let result = {
                    name: new GLib.Variant('s', displayTitle),
                    id: new GLib.Variant('s', obj.ekn_id),
                };

                if (typeof obj.synopsis !== 'undefined') {
                    result.description = new GLib.Variant('s', obj.synopsis);
                }
                result_gvariants.push(result);
            }
        }

        return result_gvariants;
    },

    ActivateResult: function (id, terms, timestamp) {
        let query = terms.join(' ');
        let model = this._get_from_cache(id);

        // if there's a cache miss (because the app auto-quit after a timeout
        // before the user activated a result), re-fetch it. otherwise just
        // emit the load-page signal with the cache result
        if (typeof model === 'undefined') {
            // id is a full EKN URI, but the engine operates in domains and
            // SHA ids (the last two components of the EKN URI path)
            let uri_parts = id.split('/');
            let obj_id = uri_parts.pop();
            let domain = uri_parts.pop();

            this._engine.get_object_by_id(domain, obj_id, function (err, new_model) {
                if (err) {
                    throw err;
                } else {
                    new_model.fetch_all(this._engine);
                    this.emit('load-page', new_model, query, timestamp);
                }
            }.bind(this));
        } else {
            model.fetch_all(this._engine);
            this.emit('load-page', model, query, timestamp);
        }
    },

    LaunchSearch: function (terms, timestamp) {
        let query = terms.join(' ');
        this.emit('load-query', query, timestamp);
    },
});
<|endoftext|>


<commit_before>(function() {
    var Agora = this.Agora,
        app = this.app;

    Agora.QuestionListView = Backbone.View.extend({
        tagName: "div",
        initialize: function() {
            _.bindAll(this);
            this.template = _.template($("#template-question_list_view").html());
            this.render();
            return this.$el;
        },

        render: function() {
            // render template
            this.$el.html(this.template(ajax_data));
            $("#question-list").append(this.$el);
            $("#question-list table tbody").each(function (index) {
                var randomize = $(this).data('randomize');
                if (randomize) {
                    $(this).shuffle();
                }
            });
        }
    });

    Agora.ElectionResultsView = Backbone.View.extend({
        tagName: "div",
        initialize: function() {
            _.bindAll(this);
            this.template = _.template($("#template-election_results_view").html());
            this.render();
            return this.$el;
        },

        render: function() {
            // render template
            this.$el.html(this.template(ajax_data));
            $("#election-results").append(this.$el);
            for (var i = 0; i < ajax_data.election.result.counts.length; i++) {
                var view = null;
                if (ajax_data.election.result.counts[i].tally_type == 'MEEK-STV') {
                    view = new Agora.MeekStvTallyView({
                        question: ajax_data.election.result.counts[i],
                        tally:ajax_data.extra_data.tally_log[i],
                        question_num: i,
                    });
                } else if (ajax_data.election.result.counts[i].tally_type == 'ONE_CHOICE') {
                    view = new Agora.OneChoiceTallyView({
                        question: ajax_data.election.result.counts[i],
                        tally: ajax_data.extra_data.tally_log[i],
                        question_num: i,
                    });
                }
                $("#election-results").append(view.render().el);
            }
        }
    });

    Agora.MeekStvTallyView = Backbone.View.extend({
        tagName: "div",

        id: function() {
            return "tally_question" + this.options.question_num;
        },

        initialize: function() {
            _.bindAll(this);
            this.template = _.template($("#template-question_meek_stv_tally").html());
            this.render();
            return this.$el;
        },

        render: function() {
            // render template
            this.$el.html(this.template(this.options));
            this.$el.find('tbody tr').sortElements(function (a, b) {
                var rate = function (i) {
                    return ($(i).find('.already_won').length
                        + $(i).find('.won').length
                        - $(i).find('.lost').length
                        - $(i).find('.already_lost').length);
                }
                return rate(a) < rate(b);
            });
            return this;
        },
    });

    Agora.OneChoiceTallyView = Backbone.View.extend({
        tagName: "div",

        id: function() {
            return "tally_question" + this.options.question_num;
        },

        className: "election-results",

        initialize: function() {
            _.bindAll(this);
            this.color = d3.scale.category10();
            this.template = _.template($("#template-question_one_choice_tally").html());
            this.render();
            return this.$el;
        },

        render: function() {
            // render template
            for (var i=0; i<this.options.question.answers.length; i++) {
                this.options.question.answers[i]['color'] = this.color(i);
            }
            this.$el.html(this.template(this.options));
            this.$el.find('li').sortElements(function (a, b) {
                var rate = function (i) {
                    return parseFloat($(i).data('value'));
                }
                return rate(a) < rate(b);
            });
            this.pieChart();
            return this;
        },

        pieChart: function() {
            var pienode = this.$el.find('.piechart')[0];
            Charts.arc(this.options.question.answers,
                       pienode,
                       function (d) { return d.total_count; },
                       function (d) { return d.value; },
                       this.color,
                       500, 250);
        }
    });

    Agora.ElectionView = Backbone.View.extend({
        el: "div.election",

        initialize: function() {
            _.bindAll(this);
            // Only initialize on correct section of page exists.
            if ($("#activity-list").length > 0) {
                this.activityListView = new Agora.ActivityListView();
            }

            this.questionListView = new Agora.QuestionListView();

            if (ajax_data.election.tally_released_at_date) {
                this.electionResultsView = new Agora.ElectionResultsView();
            }
        }
    });

    Agora.ElectionDelegatesView = Agora.GenericListView.extend({
        el: "#user-list",
        templateEl: "#template-vote_list_item",
        templateVoteInfoEl: "#template-vote_info",
        templateVoteInfo: null,
        sendingData: false,

        events: {
            'hover .user-result .row': 'hoverUser'
        },

        initialize: function() {
            Agora.GenericListView.prototype.initialize.apply(this);

            this.delegateView = null;
            this.init_filter();
        },

        init_filter: function() {
            this.filter = '';
            var obj = this;

            var delay = (function(){
              var timer = 0;
              return function(callback, ms){
                clearTimeout (timer);
                timer = setTimeout(callback, ms);
              };
            })();
            $("#filter-input").keyup(function(e) {
                delay(function() {
                    obj.filterList();
                }, 500);
            });
            $("#filter-input").keypress(function(e) {
                if(e.which == 13) {
                    obj.filterList();
                }
            });
            $("#filter-button").click(function() {
                obj.filterList();
            });
        },

        filterList: function() {
            newf = $("#filter-input").val();
            if (this.filter != newf) {
                this.filter = newf;
                this.filterf(this.filter);
            }
        },

        filterf: function(param) {
            if (!param) {
                this.url = this.$el.data('url');
            } else {
                this.url = this.$el.data('url') + "?username=" + param;
            }
            this.collection.reset();

            this.firstLoadSuccess = false;
            this.finished = false;
            this.offset = 0;
            this.requestObjects();
        },

        renderItem: function(model) {
            return this.template(model.toJSON());
        },

        hoverUser: function(e) {
            if (!this.templateVoteInfo) {
                this.templateVoteInfo = _.template($(this.templateVoteInfoEl).html());
            }
            var id = $(e.target).closest('.row').data('id');
            var self = this;
            var agora = ajax_data.election.agora;
            self.delegate = (ajax_data.election.agora.delegation_policy == "ALLOW_DELEGATION");
            var model = {
                vote: this.collection.get(id).toJSON(),
                election: ajax_data.election,
                delegation: self.delegate,
                extra_data: ajax_data.extra_data
            };
            if (model.election.tally_released_at_date) {
                model.num_delegated_votes = 0;
                model.rank_in_delegates = "-";
                if (model.vote.delegate_election_count) {
                    model.num_delegated_votes = model.vote.delegate_election_count.count;
                    var rank = model.vote.delegate_election_count.rank;
                    if (rank) {
                        model.rank_in_delegates = rank + "º";
                    }
                }
            }
            $("#vote_info").html(this.templateVoteInfo(model));
            if(self.delegate == true)
            {
                $("#vote_info .delegate_vote").click(this.delegateVote);
            }
        },

        delegateVote: function (e) {
            e.preventDefault();
            Agora.delegateVoteHandler(e, this);
        }
    });

    Agora.FeaturedElectionView = Backbone.View.extend({
        el: "#content-wrapper",

        initialize: function() {
            _.bindAll(this);
            app.modalDialog = new Agora.ModalDialogView();
            this.bw_template = _.template($("#template_background-wrapper-featured-election").html());
            this.question_template = _.template($("#template_featured-election-question").html());
            this.question_primary_template = _.template($("#template_featured-election-primary-question").html());
            this.oc_question_template = _.template($("#template_featured-election-tallied-one-choice-question").html());
            this.stv_question_template = _.template($("#template_featured-election-tallied-stv-question").html());

            var data = ajax_data;
            data.is_demo = (window.location.href.lastIndexOf("/demo") >= window.location.href.length - 6);

            $("#background-wrapper-fe").html(this.bw_template(ajax_data));
            if (ajax_data.election.tally_released_at_date) {
                for (var i = 0; i < ajax_data.election.questions.length; i++) {
                    var data = {
                        i: i,
                        q: ajax_data.election.result.counts[i],
                        q_tally: ajax_data.extra_data.tally_log[i]
                    };
                    if (data.q.layout == "PRIMARY") {
                        $("#bloques").append(this.question_primary_template(data));
                        $('#q' + i + ' table.question-stv tbody tr').sortElements(function (a, b) {
                            var rate = function (i) {
                                return ($(i).find('.already_won').length
                                    + $(i).find('.won').length
                                    - $(i).find('.lost').length
                                    - $(i).find('.already_lost').length);
                            }
                            return rate(a) < rate(b);
                        });
                    } else if (data.q.a == "question/result/ONE_CHOICE") {
                        $("#bloques").append(this.oc_question_template(data));
                    } else {
                        var el = this.stv_question_template(data);
                        $("#bloques").append(el);
                        $('#q' + i + ' table.question-stv tbody tr').sortElements(function (a, b) {
                            var rate = function (i) {
                                return ($(i).find('.already_won').length
                                    + $(i).find('.won').length
                                    - $(i).find('.lost').length
                                    - $(i).find('.already_lost').length);
                            }
                            return rate(a) < rate(b);
                        });
                    }
                }
            } else {
                for (var i = 0; i < ajax_data.election.questions.length; i++) {
                    var data = {
                        i: i,
                        q: ajax_data.election.questions[i]
                    };
                    if (data.q.layout == "PRIMARY") {
                        $("#bloques").append(this.question_primary_template(data));

                        // shuffle options
                        if (data.q.randomize_answer_order) {
                            $('.candidates-list.list-' + i).shuffle();
                        }

                    } else {
                        $("#bloques").append(this.question_template(data));
                    }
                }
            }

            // in case there's only on question, uncollapse it
            if (ajax_data.election.questions.length == 1) {
                $("#q0").addClass("in");
            }

            $("a.cand-details").click(this.showDetails);
        },

        showDetails: function(e) {
            e.preventDefault();
            var i = $(e.target).data('question-index');
            var j = $(e.target).data('option-index');
            var answer = ajax_data.election.questions[i].answers[j];

            var title = answer.value;
            var bodyTmpl = _.template($("#template-show_option_details_body").html());
            var body = bodyTmpl(answer);
            var footer = '<button type="button" class="btn btn-warning" data-dismiss="modal" aria-hidden="true">' + gettext("Close") + '</button>';

            app.modalDialog.populate(title, body, footer);
            app.modalDialog.show();
        }
    });

    Agora.ElectionSecurityCenterView = Backbone.View.extend({
        el: "#election-security-center",

        initialize: function() {
            this.template = _.template($("#template-election-security-center").html());
            this.$el.html(this.template(ajax_data));
        }
    });
}).call(this)
<commit_msg>shuffle primary results<commit_after>(function() {
    var Agora = this.Agora,
        app = this.app;

    Agora.QuestionListView = Backbone.View.extend({
        tagName: "div",
        initialize: function() {
            _.bindAll(this);
            this.template = _.template($("#template-question_list_view").html());
            this.render();
            return this.$el;
        },

        render: function() {
            // render template
            this.$el.html(this.template(ajax_data));
            $("#question-list").append(this.$el);
            $("#question-list table tbody").each(function (index) {
                var randomize = $(this).data('randomize');
                if (randomize) {
                    $(this).shuffle();
                }
            });
        }
    });

    Agora.ElectionResultsView = Backbone.View.extend({
        tagName: "div",
        initialize: function() {
            _.bindAll(this);
            this.template = _.template($("#template-election_results_view").html());
            this.render();
            return this.$el;
        },

        render: function() {
            // render template
            this.$el.html(this.template(ajax_data));
            $("#election-results").append(this.$el);
            for (var i = 0; i < ajax_data.election.result.counts.length; i++) {
                var view = null;
                if (ajax_data.election.result.counts[i].tally_type == 'MEEK-STV') {
                    view = new Agora.MeekStvTallyView({
                        question: ajax_data.election.result.counts[i],
                        tally:ajax_data.extra_data.tally_log[i],
                        question_num: i,
                    });
                } else if (ajax_data.election.result.counts[i].tally_type == 'ONE_CHOICE') {
                    view = new Agora.OneChoiceTallyView({
                        question: ajax_data.election.result.counts[i],
                        tally: ajax_data.extra_data.tally_log[i],
                        question_num: i,
                    });
                }
                $("#election-results").append(view.render().el);
            }
        }
    });

    Agora.MeekStvTallyView = Backbone.View.extend({
        tagName: "div",

        id: function() {
            return "tally_question" + this.options.question_num;
        },

        initialize: function() {
            _.bindAll(this);
            this.template = _.template($("#template-question_meek_stv_tally").html());
            this.render();
            return this.$el;
        },

        render: function() {
            // render template
            this.$el.html(this.template(this.options));
            this.$el.find('tbody tr').sortElements(function (a, b) {
                var rate = function (i) {
                    return ($(i).find('.already_won').length
                        + $(i).find('.won').length
                        - $(i).find('.lost').length
                        - $(i).find('.already_lost').length);
                }
                return rate(a) < rate(b);
            });
            return this;
        },
    });

    Agora.OneChoiceTallyView = Backbone.View.extend({
        tagName: "div",

        id: function() {
            return "tally_question" + this.options.question_num;
        },

        className: "election-results",

        initialize: function() {
            _.bindAll(this);
            this.color = d3.scale.category10();
            this.template = _.template($("#template-question_one_choice_tally").html());
            this.render();
            return this.$el;
        },

        render: function() {
            // render template
            for (var i=0; i<this.options.question.answers.length; i++) {
                this.options.question.answers[i]['color'] = this.color(i);
            }
            this.$el.html(this.template(this.options));
            this.$el.find('li').sortElements(function (a, b) {
                var rate = function (i) {
                    return parseFloat($(i).data('value'));
                }
                return rate(a) < rate(b);
            });
            this.pieChart();
            return this;
        },

        pieChart: function() {
            var pienode = this.$el.find('.piechart')[0];
            Charts.arc(this.options.question.answers,
                       pienode,
                       function (d) { return d.total_count; },
                       function (d) { return d.value; },
                       this.color,
                       500, 250);
        }
    });

    Agora.ElectionView = Backbone.View.extend({
        el: "div.election",

        initialize: function() {
            _.bindAll(this);
            // Only initialize on correct section of page exists.
            if ($("#activity-list").length > 0) {
                this.activityListView = new Agora.ActivityListView();
            }

            this.questionListView = new Agora.QuestionListView();

            if (ajax_data.election.tally_released_at_date) {
                this.electionResultsView = new Agora.ElectionResultsView();
            }
        }
    });

    Agora.ElectionDelegatesView = Agora.GenericListView.extend({
        el: "#user-list",
        templateEl: "#template-vote_list_item",
        templateVoteInfoEl: "#template-vote_info",
        templateVoteInfo: null,
        sendingData: false,

        events: {
            'hover .user-result .row': 'hoverUser'
        },

        initialize: function() {
            Agora.GenericListView.prototype.initialize.apply(this);

            this.delegateView = null;
            this.init_filter();
        },

        init_filter: function() {
            this.filter = '';
            var obj = this;

            var delay = (function(){
              var timer = 0;
              return function(callback, ms){
                clearTimeout (timer);
                timer = setTimeout(callback, ms);
              };
            })();
            $("#filter-input").keyup(function(e) {
                delay(function() {
                    obj.filterList();
                }, 500);
            });
            $("#filter-input").keypress(function(e) {
                if(e.which == 13) {
                    obj.filterList();
                }
            });
            $("#filter-button").click(function() {
                obj.filterList();
            });
        },

        filterList: function() {
            newf = $("#filter-input").val();
            if (this.filter != newf) {
                this.filter = newf;
                this.filterf(this.filter);
            }
        },

        filterf: function(param) {
            if (!param) {
                this.url = this.$el.data('url');
            } else {
                this.url = this.$el.data('url') + "?username=" + param;
            }
            this.collection.reset();

            this.firstLoadSuccess = false;
            this.finished = false;
            this.offset = 0;
            this.requestObjects();
        },

        renderItem: function(model) {
            return this.template(model.toJSON());
        },

        hoverUser: function(e) {
            if (!this.templateVoteInfo) {
                this.templateVoteInfo = _.template($(this.templateVoteInfoEl).html());
            }
            var id = $(e.target).closest('.row').data('id');
            var self = this;
            var agora = ajax_data.election.agora;
            self.delegate = (ajax_data.election.agora.delegation_policy == "ALLOW_DELEGATION");
            var model = {
                vote: this.collection.get(id).toJSON(),
                election: ajax_data.election,
                delegation: self.delegate,
                extra_data: ajax_data.extra_data
            };
            if (model.election.tally_released_at_date) {
                model.num_delegated_votes = 0;
                model.rank_in_delegates = "-";
                if (model.vote.delegate_election_count) {
                    model.num_delegated_votes = model.vote.delegate_election_count.count;
                    var rank = model.vote.delegate_election_count.rank;
                    if (rank) {
                        model.rank_in_delegates = rank + "º";
                    }
                }
            }
            $("#vote_info").html(this.templateVoteInfo(model));
            if(self.delegate == true)
            {
                $("#vote_info .delegate_vote").click(this.delegateVote);
            }
        },

        delegateVote: function (e) {
            e.preventDefault();
            Agora.delegateVoteHandler(e, this);
        }
    });

    Agora.FeaturedElectionView = Backbone.View.extend({
        el: "#content-wrapper",

        initialize: function() {
            _.bindAll(this);
            app.modalDialog = new Agora.ModalDialogView();
            this.bw_template = _.template($("#template_background-wrapper-featured-election").html());
            this.question_template = _.template($("#template_featured-election-question").html());
            this.question_primary_template = _.template($("#template_featured-election-primary-question").html());
            this.oc_question_template = _.template($("#template_featured-election-tallied-one-choice-question").html());
            this.stv_question_template = _.template($("#template_featured-election-tallied-stv-question").html());

            var data = ajax_data;
            data.is_demo = (window.location.href.lastIndexOf("/demo") >= window.location.href.length - 6);

            $("#background-wrapper-fe").html(this.bw_template(ajax_data));
            if (ajax_data.election.tally_released_at_date) {
                for (var i = 0; i < ajax_data.election.questions.length; i++) {
                    var data = {
                        i: i,
                        q: ajax_data.election.result.counts[i],
                        q_tally: ajax_data.extra_data.tally_log[i]
                    };
                    if (data.q.layout == "PRIMARY") {
                        $("#bloques").append(this.question_primary_template(data));
                        $('#q' + i + ' table.question-stv tbody tr').sortElements(function (a, b) {
                            var rate = function (i) {
                                return ($(i).find('.already_won').length
                                    + $(i).find('.won').length
                                    - $(i).find('.lost').length
                                    - $(i).find('.already_lost').length);
                            }
                            return rate(a) < rate(b);
                        });
                        // shuffle options
                        if (data.q.randomize_answer_order) {
                            $('.candidates-list.list-' + i).shuffle();
                        }
                    } else if (data.q.a == "question/result/ONE_CHOICE") {
                        $("#bloques").append(this.oc_question_template(data));
                    } else {
                        var el = this.stv_question_template(data);
                        $("#bloques").append(el);
                        $('#q' + i + ' table.question-stv tbody tr').sortElements(function (a, b) {
                            var rate = function (i) {
                                return ($(i).find('.already_won').length
                                    + $(i).find('.won').length
                                    - $(i).find('.lost').length
                                    - $(i).find('.already_lost').length);
                            }
                            return rate(a) < rate(b);
                        });
                    }
                }
            } else {
                for (var i = 0; i < ajax_data.election.questions.length; i++) {
                    var data = {
                        i: i,
                        q: ajax_data.election.questions[i]
                    };
                    if (data.q.layout == "PRIMARY") {
                        $("#bloques").append(this.question_primary_template(data));

                        // shuffle options
                        if (data.q.randomize_answer_order) {
                            $('.candidates-list.list-' + i).shuffle();
                        }

                    } else {
                        $("#bloques").append(this.question_template(data));
                    }
                }
            }

            // in case there's only on question, uncollapse it
            if (ajax_data.election.questions.length == 1) {
                $("#q0").addClass("in");
            }

            $("a.cand-details").click(this.showDetails);
        },

        showDetails: function(e) {
            e.preventDefault();
            var i = $(e.target).data('question-index');
            var j = $(e.target).data('option-index');
            var answer = ajax_data.election.questions[i].answers[j];

            var title = answer.value;
            var bodyTmpl = _.template($("#template-show_option_details_body").html());
            var body = bodyTmpl(answer);
            var footer = '<button type="button" class="btn btn-warning" data-dismiss="modal" aria-hidden="true">' + gettext("Close") + '</button>';

            app.modalDialog.populate(title, body, footer);
            app.modalDialog.show();
        }
    });

    Agora.ElectionSecurityCenterView = Backbone.View.extend({
        el: "#election-security-center",

        initialize: function() {
            this.template = _.template($("#template-election-security-center").html());
            this.$el.html(this.template(ajax_data));
        }
    });
}).call(this)
<|endoftext|>


<commit_before>import { change, date } from 'common/changelog';
import SPELLS from 'common/SPELLS';
import { Adoraci, Juko8, Skeletor, Zeboot, Hordehobbs } from 'CONTRIBUTORS';
import { SpellLink } from 'interface';
import React from 'react';

export default [
  change(date(2021, 4, 3), 'Verified patch changes and bumped support to 9.0.5', Adoraci),
  change(date(2020, 12, 1), <>Added <SpellLink id={SPELLS.SANCTIFIED_WRATH_TALENT_RETRIBUTION.id} icon /> module and minor housekeeping.</>, Skeletor),
  change(date(2020, 11, 8), <>Added <SpellLink id={SPELLS.EMPYREAN_POWER_TALENT.id} icon /> module.</>, Skeletor),
  change(date(2020, 11, 7), <>Added <SpellLink id={SPELLS.HOLY_AVENGER_TALENT.id} icon /> module from new Shared module.</>, Skeletor),
  change(date(2020, 11, 7), <>Updated <SpellLink id={SPELLS.DIVINE_PURPOSE_TALENT.id} icon /> module to new Shared module.</>, Skeletor),
  change(date(2020, 11, 7), 'Core and Talent modules converted to TypeScript', Skeletor),
  change(date(2020, 11, 6), 'General housekeeping and ability updates.', Skeletor),
  change(date(2020, 10, 23), <>Aggregate Prot and Ret <SpellLink id={SPELLS.JUDGMENT_CAST.id} /> analyzers into single analyzer.</>, Hordehobbs),
  change(date(2020, 10, 18), 'Converted legacy listeners to new event filters', Zeboot),
  change(date(2020, 10, 17), <>Updated <SpellLink id={SPELLS.HAMMER_OF_WRATH.id} icon /> max casts calculation to account for execute restrictions and added cast efficiency tracking</>, Juko8),
  change(date(2020, 9, 18), 'Removed BFA stuff and updated most things for 9.0', Juko8),
];
<commit_msg>Changelog<commit_after>import { change, date } from 'common/changelog';
import SPELLS from 'common/SPELLS';
import { Adoraci, Juko8, Skeletor, Zeboot, Hordehobbs } from 'CONTRIBUTORS';
import { SpellLink } from 'interface';
import React from 'react';

export default [
  change(date(2021, 4, 10), <>Added <SpellLink id={SPELLS.FINAL_VERDICT.id} icon />.</>, Juko8),
  change(date(2021, 4, 3), 'Verified patch changes and bumped support to 9.0.5', Adoraci),
  change(date(2020, 12, 1), <>Added <SpellLink id={SPELLS.SANCTIFIED_WRATH_TALENT_RETRIBUTION.id} icon /> module and minor housekeeping.</>, Skeletor),
  change(date(2020, 11, 8), <>Added <SpellLink id={SPELLS.EMPYREAN_POWER_TALENT.id} icon /> module.</>, Skeletor),
  change(date(2020, 11, 7), <>Added <SpellLink id={SPELLS.HOLY_AVENGER_TALENT.id} icon /> module from new Shared module.</>, Skeletor),
  change(date(2020, 11, 7), <>Updated <SpellLink id={SPELLS.DIVINE_PURPOSE_TALENT.id} icon /> module to new Shared module.</>, Skeletor),
  change(date(2020, 11, 7), 'Core and Talent modules converted to TypeScript', Skeletor),
  change(date(2020, 11, 6), 'General housekeeping and ability updates.', Skeletor),
  change(date(2020, 10, 23), <>Aggregate Prot and Ret <SpellLink id={SPELLS.JUDGMENT_CAST.id} /> analyzers into single analyzer.</>, Hordehobbs),
  change(date(2020, 10, 18), 'Converted legacy listeners to new event filters', Zeboot),
  change(date(2020, 10, 17), <>Updated <SpellLink id={SPELLS.HAMMER_OF_WRATH.id} icon /> max casts calculation to account for execute restrictions and added cast efficiency tracking</>, Juko8),
  change(date(2020, 9, 18), 'Removed BFA stuff and updated most things for 9.0', Juko8),
];
<|endoftext|>


<commit_before>import { createView, config } from './utils/domvm.js';

import * as styles from './app.css';
import { GalleryView } from './interface/gallery.js';
import { router } from './services/router.js';
import { streamConfig } from './utils/event.js';
import { log } from './services/console.js';

config({ stream: streamConfig });

function go() {
	// Attach our root view to the DOM
	createView(GalleryView, {}).mount(document.body);

	// Start the router
	router.start('home');
}

if ('serviceWorker' in navigator && window.top === window) {
	navigator.serviceWorker.register('/assets/sw.bundle.js', { scope: '/' }).then(go).catch(go);
} else {
	go();
}
<commit_msg>Try to be less dumb about insecure hosting<commit_after>import { createView, config } from './utils/domvm.js';

import * as styles from './app.css';
import { GalleryView } from './interface/gallery.js';
import { router } from './services/router.js';
import { streamConfig } from './utils/event.js';
import { log } from './services/console.js';

config({ stream: streamConfig });

function go() {
	// Attach our root view to the DOM
	createView(GalleryView, {}).mount(document.body);

	// Start the router
	router.start('home');
}

const url = `https://${location.host}${location.pathname}${location.hash}`;
const msg = `This photo gallery will not work properly unless accessed securely.  Connect to ${url} instead?`;

// We use subtleCrypto which is only available from secure domains and localhost.
if (location.protocol !== 'https:' && (!crypto.subtle || !crypto.subtle.digest) && confirm(msg)) {
	location.assign(url);
} else if ('serviceWorker' in navigator && window.top === window) {
	navigator.serviceWorker.register('/assets/sw.bundle.js', { scope: '/' }).then(go).catch(go);
} else {
	go();
}
<|endoftext|>