<commit_before>var favoriteTeamsCookieName = "tba-favorite-teams";

function updateFavoriteTeams() {
  updateFavoriteTeams(null, null);
}

function updateFavoriteTeams(teamKey, action) {
  /*
  Updates Favorites locally and on the server and
  updates the page to reflect these changes
  teamKey: like "frc254" or null
  action: "add" or "delete" or null (doesn't do anything if teamKey is null)
  */
  var storedFavoriteTeams = getLocalFavoriteTeams();

  if (teamKey != null) {
    if (action == 'add') {
      console.log("REMOTE ADD");
      $.ajax({
        type: 'POST',
        url: '/_/account/favorites/add',
        data: {'model_key': teamKey, 'model_type': 1},
        success: function(data, textStatus, xhr) {
          addLocalFavoriteTeam(teamKey);
          updateFavoriteTeams();
        },
        error: function(xhr, textStatus, errorThrown) {
          if (xhr.status == 401) {
            $('#login-modal').modal('show');
          } else {
            $('#fixed-alert-container').append('
<button type="button" class="close" data-dismiss="alert" aria-label="Close">×</button>Oops! Failed to add favorite.
Something went wrong on our end. Please try again later.
');
          }
          updateFavoriteTeams();
        }
      });
    } else if (action == 'delete') {
      console.log("REMOTE DELETE");
      $.ajax({
        type: 'POST',
        url: '/_/account/favorites/delete',
        data: {'model_key': teamKey, 'model_type': 1},
        success: function(data, textStatus, xhr) {
          deleteLocalFavoriteTeam(teamKey);
          updateFavoriteTeams();
        },
        error: function(xhr, textStatus, errorThrown) {
          if (xhr.status == 401) {
            $('#login-modal').modal('show');
          } else {
            $('#fixed-alert-container').append('
<button type="button" class="close" data-dismiss="alert" aria-label="Close">×</button>Oops! Failed to delete favorite.
Something went wrong on our end. Please try again later.
');
          }
          updateFavoriteTeams();
        }
      });
    }
  } else {
    if (storedFavoriteTeams == null) {
      $.ajax({
        type: 'GET',
        dataType: 'json',
        url: '/_/account/favorites/1',
        success: function(favorites, textStatus, xhr) {
          var favoriteTeams = {};
          for (var key in favorites) {
            favoriteTeams[favorites[key]['model_key']] = true;
          }
          setLocalFavoriteTeams(favoriteTeams);
          updatePageFavoriteTeams(favoriteTeams);
        },
        error: function(xhr, textStatus, errorThrown) {
          setLocalFavoriteTeams(null);
          updatePageFavoriteTeams({});
        }
      });
    } else {
      updatePageFavoriteTeams(storedFavoriteTeams);
    }
  }
}

function getLocalFavoriteTeams() {
  return JSON.parse($.cookie(favoriteTeamsCookieName));
}

function setLocalFavoriteTeams(favoriteTeams) {
  var date = new Date();
  date.setTime(date.getTime() + (1 * 60 * 1000));  // Set 5 minutes cookie expiration
  $.cookie(favoriteTeamsCookieName, JSON.stringify(favoriteTeams), { expires: date });
}

function addLocalFavoriteTeam(teamKey) {
  var storedFavoriteTeams = getLocalFavoriteTeams();
  if (storedFavoriteTeams != null) {
    console.log("Adding: " + teamKey);
    storedFavoriteTeams[teamKey] = true;
    setLocalFavoriteTeams(storedFavoriteTeams);
    console.log(storedFavoriteTeams);
  }
}

function deleteLocalFavoriteTeam(teamKey) {
  var storedFavoriteTeams = getLocalFavoriteTeams();
  if (storedFavoriteTeams != null && teamKey in storedFavoriteTeams) {
    console.log("Deleting: " + teamKey);
    delete storedFavoriteTeams[teamKey];
    setLocalFavoriteTeams(storedFavoriteTeams);
    console.log(storedFavoriteTeams);
  }
}

function updatePageFavoriteTeams(favoriteTeams) {
  updateMatchFavoriteTeams(favoriteTeams);
  updateTeamlistFavoriteTeams(favoriteTeams);
  setTimeout(function() {updateTeamFABFavoriteTeams(favoriteTeams)}, 3000);
}

function updateMatchFavoriteTeams(favoriteTeams) {
  // Reset all stars
  $(".favorite-match-icon").each(function() {
    $(this).hide();
  });

  $(".favorite-team-dot").each(function() {
    if ($(this).attr("data-team") in favoriteTeams) {
      $(this).show();  // Dot
      var match_key = $(this).attr("data-match");
      $('.favorite-match-icon-' + match_key).show();  // Star
    } else {
      $(this).hide();  // Dot
    }
  });
}

function updateTeamlistFavoriteTeams(favoriteTeams) {
  $(".favorite-team-icon").each(function() {
    if ($(this).attr("data-team") in favoriteTeams) {
      $(this).show();
    } else {
      $(this).hide();
    }
  });
}

function updateTeamFABFavoriteTeams(favoriteTeams) {
  $(".tba-fab-team").each(function() {
    $(this).find(".fa-spin").remove();
    $(this).prop("disabled", false);
    if ($(this).attr("data-team") in favoriteTeams) {
      $(this).find(".not-favorite").hide();
      $(this).find(".favorite").show();
      setupFavDeleteClick();
    } else {
      $(this).find(".favorite").hide();
      $(this).find(".not-favorite").show();
      setupFavAddClick();
    }
  });
}

function setupFavAddClick() {
  $(".tba-fab-team").off("click");  // make sure only one click handler is attached at a time
  $(".tba-fab-team").click(function() {
    $(".tba-fab-team").off("click");
    $(this).find(".not-favorite").hide();
    addSpinner($(this));

    console.log("CLICK ADD");
    console.log($(this).attr("data-team"));
    updateFavoriteTeams($(this).attr("data-team"), 'add')
  });
}

function setupFavDeleteClick() {
  $(".tba-fab-team").off("click");  // make sure only one click handler is attached at a time
  $(".tba-fab-team").click(function() {
    $(".tba-fab-team").off("click");
    $(this).find(".favorite").hide();
    addSpinner($(this));

    console.log("CLICK DELETE");
    console.log($(this).attr("data-team"));
    updateFavoriteTeams($(this).attr("data-team"), 'delete')
  });
}

function addSpinner(el) {
  el.append("");
  el.prop("disabled", true);
}

$(document).ready(function(){
  // Setup redirect after login
  $('#mytba-login').click(function() {
    window.location.href = '/account?redirect=' + escape(document.URL.replace(document.location.origin, ""));
  });

  console.log(getLocalFavoriteTeams());
  setupFavAddClick();
  updateFavoriteTeams();
});
<commit_msg>Temp disable saving favorites in cookie<commit_after>var favoriteTeamsCookieName = "tba-favorite-teams";

function updateFavoriteTeams() {
  updateFavoriteTeams(null, null);
}

function updateFavoriteTeams(teamKey, action) {
  /*
  Updates Favorites locally and on the server and
  updates the page to reflect these changes
  teamKey: like "frc254" or null
  action: "add" or "delete" or null (doesn't do anything if teamKey is null)
  */
  var storedFavoriteTeams = getLocalFavoriteTeams();

  if (teamKey != null) {
    if (action == 'add') {
      console.log("REMOTE ADD");
      $.ajax({
        type: 'POST',
        url: '/_/account/favorites/add',
        data: {'model_key': teamKey, 'model_type': 1},
        success: function(data, textStatus, xhr) {
          addLocalFavoriteTeam(teamKey);
          updateFavoriteTeams();
        },
        error: function(xhr, textStatus, errorThrown) {
          if (xhr.status == 401) {
            $('#login-modal').modal('show');
          } else {
            $('#fixed-alert-container').append('
<button type="button" class="close" data-dismiss="alert" aria-label="Close">×</button>Oops! Failed to add favorite.
Something went wrong on our end. Please try again later.
');
          }
          updateFavoriteTeams();
        }
      });
    } else if (action == 'delete') {
      console.log("REMOTE DELETE");
      $.ajax({
        type: 'POST',
        url: '/_/account/favorites/delete',
        data: {'model_key': teamKey, 'model_type': 1},
        success: function(data, textStatus, xhr) {
          deleteLocalFavoriteTeam(teamKey);
          updateFavoriteTeams();
        },
        error: function(xhr, textStatus, errorThrown) {
          if (xhr.status == 401) {
            $('#login-modal').modal('show');
          } else {
            $('#fixed-alert-container').append('
<button type="button" class="close" data-dismiss="alert" aria-label="Close">×</button>Oops! Failed to delete favorite.
Something went wrong on our end. Please try again later.
');
          }
          updateFavoriteTeams();
        }
      });
    }
  } else {
    if (storedFavoriteTeams == null) {
      $.ajax({
        type: 'GET',
        dataType: 'json',
        url: '/_/account/favorites/1',
        success: function(favorites, textStatus, xhr) {
          var favoriteTeams = {};
          for (var key in favorites) {
            favoriteTeams[favorites[key]['model_key']] = true;
          }
          setLocalFavoriteTeams(favoriteTeams);
          updatePageFavoriteTeams(favoriteTeams);
        },
        error: function(xhr, textStatus, errorThrown) {
          setLocalFavoriteTeams(null);
          updatePageFavoriteTeams({});
        }
      });
    } else {
      updatePageFavoriteTeams(storedFavoriteTeams);
    }
  }
}

function getLocalFavoriteTeams() {
  return JSON.parse($.cookie(favoriteTeamsCookieName));
}

function setLocalFavoriteTeams(favoriteTeams) {
  var date = new Date();
  date.setTime(date.getTime() + (1 * 60 * 1000));  // Set 5 minutes cookie expiration
  // $.cookie(favoriteTeamsCookieName, JSON.stringify(favoriteTeams), {expires: date, path: '/'});
}

function addLocalFavoriteTeam(teamKey) {
  var storedFavoriteTeams = getLocalFavoriteTeams();
  if (storedFavoriteTeams != null) {
    console.log("Adding: " + teamKey);
    storedFavoriteTeams[teamKey] = true;
    setLocalFavoriteTeams(storedFavoriteTeams);
    console.log(storedFavoriteTeams);
  }
}

function deleteLocalFavoriteTeam(teamKey) {
  var storedFavoriteTeams = getLocalFavoriteTeams();
  if (storedFavoriteTeams != null && teamKey in storedFavoriteTeams) {
    console.log("Deleting: " + teamKey);
    delete storedFavoriteTeams[teamKey];
    setLocalFavoriteTeams(storedFavoriteTeams);
    console.log(storedFavoriteTeams);
  }
}

function updatePageFavoriteTeams(favoriteTeams) {
  updateMatchFavoriteTeams(favoriteTeams);
  updateTeamlistFavoriteTeams(favoriteTeams);
  setTimeout(function() {updateTeamFABFavoriteTeams(favoriteTeams)}, 3000);
}

function updateMatchFavoriteTeams(favoriteTeams) {
  // Reset all stars
  $(".favorite-match-icon").each(function() {
    $(this).hide();
  });

  $(".favorite-team-dot").each(function() {
    if ($(this).attr("data-team") in favoriteTeams) {
      $(this).show();  // Dot
      var match_key = $(this).attr("data-match");
      $('.favorite-match-icon-' + match_key).show();  // Star
    } else {
      $(this).hide();  // Dot
    }
  });
}

function updateTeamlistFavoriteTeams(favoriteTeams) {
  $(".favorite-team-icon").each(function() {
    if ($(this).attr("data-team") in favoriteTeams) {
      $(this).show();
    } else {
      $(this).hide();
    }
  });
}

function updateTeamFABFavoriteTeams(favoriteTeams) {
  $(".tba-fab-team").each(function() {
    $(this).find(".fa-spin").remove();
    $(this).prop("disabled", false);
    if ($(this).attr("data-team") in favoriteTeams) {
      $(this).find(".not-favorite").hide();
      $(this).find(".favorite").show();
      setupFavDeleteClick();
    } else {
      $(this).find(".favorite").hide();
      $(this).find(".not-favorite").show();
      setupFavAddClick();
    }
  });
}

function setupFavAddClick() {
  $(".tba-fab-team").off("click");  // make sure only one click handler is attached at a time
  $(".tba-fab-team").click(function() {
    $(".tba-fab-team").off("click");
    $(this).find(".not-favorite").hide();
    addSpinner($(this));

    console.log("CLICK ADD");
    console.log($(this).attr("data-team"));
    updateFavoriteTeams($(this).attr("data-team"), 'add')
  });
}

function setupFavDeleteClick() {
  $(".tba-fab-team").off("click");  // make sure only one click handler is attached at a time
  $(".tba-fab-team").click(function() {
    $(".tba-fab-team").off("click");
    $(this).find(".favorite").hide();
    addSpinner($(this));

    console.log("CLICK DELETE");
    console.log($(this).attr("data-team"));
    updateFavoriteTeams($(this).attr("data-team"), 'delete')
  });
}

function addSpinner(el) {
  el.append("");
  el.prop("disabled", true);
}

$(document).ready(function(){
  // Setup redirect after login
  $('#mytba-login').click(function() {
    window.location.href = '/account?redirect=' + escape(document.URL.replace(document.location.origin, ""));
  });

  console.log(getLocalFavoriteTeams());
  setupFavAddClick();
  updateFavoriteTeams();
});
<|endoftext|>


<commit_before>/*global define */
/*jshint indent:4 */

define(['AppParams', 'jquery', 'underscore', 'text!templates/search/results.html', 'text!templates/search/facets.html', 'jquery.maskMoney'],
    function (AppParams, $, underscore, resultsTemplate, facetsTemplate) {
        "use strict";

        var $body = $("body");
        var $postsViewStyle = $("#posts-view-style");
        var $postsViewStyleThumbnail = $("#posts-view-style-thumbnail");
        var $postsViewStyleTable = $("#posts-view-style-table");
        var $searchPostsForm = $("#search-posts-form");
        var $searchText = $("#search-text");
        var $searchTextAutocomplete = $("#search-text-autocomplete");
        var $searchTypes = $("#search-types");
        var $searchTypesNames = $('input[name="type"]', $searchPostsForm);
        var $searchResults = $("#search-results");
        var $searchPrices = $("#search-prices");
        var $searchPriceMin = $("#search-price-min");
        var $searchPriceMax = $("#search-price-max");
        var $searchButton = $("#search-button");

        var currentPage;
        var currentSort;
        var pages;
        var lastSuggestions = [];
        var allPastSuggestions = [];

        var maskMoney = function ($element) {
            $element.maskMoney(
                {
                    symbol: 'R$ ',
                    showSymbol: true,
                    symbolStay: true,
                    thousands: '.',
                    decimal: ',',
                    defaultZero: false
                }
            );
        };

        maskMoney($searchPriceMin);
        maskMoney($searchPriceMax);

        var openSearch = function () {
            $searchPrices.removeClass("hidden");
            $searchTypes.removeClass("hidden");
            $searchButton.removeClass("hidden");
        };

        var urlParts = (function () {
            var vars = {};
            window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
                if (vars[key] !== undefined) {
                    if (typeof vars[key] === "string") {
                        vars[key] = [vars[key]];
                        vars[key].push(value);
                    } else {
                        vars[key].push(value);
                    }
                } else {
                    vars[key] = value;
                }
            });

            if (vars.type !== undefined && typeof vars.type === "string") {
                vars.type = [vars.type];
            }

            return vars;
        } ());

        var pageLink = function (formSerialized, page, pageSort) {
            if (formSerialized === "") {
                if (page === 1) {
                    if (pageSort) {
                        return "?sort=" + pageSort;
                    } else {
                        return "";
                    }
                } else {
                    if (pageSort) {
                        return "?page=" + page + "&sort=" + pageSort;
                    } else {
                        return "?page=" + page;
                    }
                }
            } else {
                if (page === 1) {
                    if (pageSort) {
                        return "?" + formSerialized + "&sort=" + pageSort;
                    } else {
                        return "?" + formSerialized;
                    }
                } else {
                    if (pageSort) {
                        return "?" + formSerialized + "&page=" + page + "&sort=" + pageSort;
                    } else {
                        return "?" + formSerialized + "&page=" + page;
                    }
                }
            }
        };

        var formatMoney = function (money) {
            var $foo = $('<input type="text">');
            maskMoney($foo);
            $foo.val(money);
            $foo.trigger("mask");
            return $foo.val();
        };

        $(document.documentElement).on("keyup", function (e) {
            if (e.target.nodeName.toLowerCase() !== "body") {
                return;
            }

            if (e.keyCode === 191) {
                // focus on search by pressing slash (/)
                $searchText.focus();
            } else if (e.keyCode === 37 && typeof currentPage === "number" && currentPage > 1) {
                //pagination with left key
                search({page: currentPage - 1, sort: currentSort, scroll: true});
            } else if (e.keyCode === 39 && typeof currentPage === "number" && typeof pages === "number" && pages > currentPage) {
                //pagination with right key
                search({page: currentPage + 1, sort: currentSort, scroll: true});
            }
        });

        $searchResults.on("click", ".sortable a", function (e) {
            var target = e.currentTarget;
            e.preventDefault();

            var sortBy = target.getAttribute("data-sort");
            search({sort: sortBy});
        });

        $searchResults.on("click", ".pagination a", function (e) {
            var target = e.currentTarget;
            e.preventDefault();
            var page = target.getAttribute("data-page");
            var sort = target.getAttribute("data-sort");
            search({page: page, sort: sort, scroll: true});
        });

        var changeViewStyle = function (style) {
            if (style === "table") {
                $($(".results-thumbnail", $searchResults)[0]).addClass("hidden");
            } else {
                $($(".results-table", $searchResults)[0]).addClass("hidden");
            }

            $($(".results-" + style, $searchResults)[0]).removeClass("hidden");

            $.ajax({
                url: AppParams.webroot + "/search?posts_view_style=" + style,
                type: "HEAD"
            });
        };

        $postsViewStyleTable.on("click", function (e) {
            changeViewStyle("table");
            e.preventDefault();
        });

        $postsViewStyleThumbnail.on("click", function (e) {
            changeViewStyle("thumbnail");
            e.preventDefault();
        });

        var search = function (data) {
            if (data === undefined) {
                data = {};
            }

            var sort = data.sort || "";
            var page = data.page || 1;
            var scroll = data.scroll || false;

            if (scroll) {
                $body.animate({
                    scrollTop: ($searchResults.offset().top) - 50
                }, 500);
            }

            var formSerialized = $(':input[value!=""]', $searchPostsForm).serialize();

            var size = 20;
            var from = 1;
            var to;
            var total;

            if (page !== undefined) {

                page = parseInt(page, 10);

                if (isNaN(page)) {
                    page = 1;
                }

                from = ((page - 1) * size) + 1;
            } else {
                page = 1;
            }

            $.ajax({
                data: formSerialized,
                url: AppParams.webroot + "search-engine?size=" + encodeURIComponent(size) + "&from=" + encodeURIComponent(from) + "&sort=" + encodeURIComponent(sort),
                type: "GET",
                success: function (result) {
                    total = result.hits.total;
                    to = from + size - 1;

                    pages = Math.ceil(total / size);

                    if (to > total) {
                        to = total;
                    }

                    var compiled = underscore.template(resultsTemplate);

                    var viewStyle = $(".active", $postsViewStyle).data("view-style");

                    currentPage = page;
                    currentSort = sort;

                    if (window.history && window.history.pushState) {
                        var address = AppParams.webroot + "/search";

                        var q = $searchText.val();

                        if (! q) {
                            if (formSerialized) {
                                formSerialized = "q=&" + formSerialized;
                            } else {
                                formSerialized = "q=";
                            }
                        }

                        address = address + "?" + formSerialized;

                        if (currentPage !== 1) {
                            address = address + "&page=" + currentPage;
                        }

                        if (sort) {
                            address = address + "&sort=" + encodeURIComponent(sort);
                        }

                        window.history.pushState(null, null, address);
                    }

                    $searchResults.html(compiled(
                        {
                            pageLink : pageLink,
                            formatMoney : formatMoney,
                            AppParams : AppParams,
                            result : result,
                            size : size,
                            from : from,
                            to : to,
                            total : total,
                            sort : sort,
                            viewStyle : viewStyle,
                            formSerialized : formSerialized,
                            currentPage : currentPage,
                            pages : pages
                        }
                    ));
                }
            });
        };

        $searchText.typeahead({
            source : function (query, process) {
                var formSerialized = $(':input[value!=""]', $searchPostsForm).serialize();
                $.ajax({
                    data: formSerialized,
                    url: AppParams.webroot + "search-engine?suggestion=true",
                    type: "GET",
                    success: function (result) {
                        lastSuggestions = result;
                        process(result);

                        //add all the suggestions to a array to cache them
                        for (var eachSuggestionPosition in lastSuggestions) {
                            if (allPastSuggestions.indexOf(lastSuggestions[eachSuggestionPosition]) === -1) {
                                allPastSuggestions.push(lastSuggestions[eachSuggestionPosition]);
                            }
                        }

                        if (result[0] !== undefined) {
                            var q = $searchText.val();
                            var qAutocomplete = "";

                            if (result[0].indexOf(q.toLowerCase()) !== -1) {
                                qAutocomplete = q.substr(0, result[0].length) + (result[0]).substr(q.length);
                            }

                            $searchTextAutocomplete.val(qAutocomplete);
                        }
                    }
                });
            },
            items : 3
        });

        if (urlParts["price-min"] !== undefined) {
            $searchPriceMin.val(decodeURIComponent(urlParts["price-min"].replace(/\+/gi, " ")));
        }

        if (urlParts["price-max"] !== undefined) {
            $searchPriceMax.val(decodeURIComponent(urlParts["price-max"].replace(/\+/gi, " ")));
        }

        $searchTypesNames.each(function (pos, element) {
            if ($.inArray(element.value, urlParts["type"]) !== -1) {
                element.checked = true;
            }
        });

        if (urlParts.q !== undefined) {
            $searchText.val(decodeURIComponent(urlParts.q.replace(/\+/gi, " ")));
            search({page: urlParts.page || 1, sort: urlParts.sort});
            openSearch();
        } else {
            $searchText.focus();
            $searchText.one("keyup", function (e) {
                openSearch();
            });
        }

        $searchTypesNames.on("change", function (e) {
            search();
        });

        $searchText.on("change", function (e) {
            $searchTextAutocomplete.val("");
            search();
        });

        $searchText.on("keyup", function (e) {
            var q = $searchText.val();
            var qAutocomplete = $searchTextAutocomplete.val();

            if (q === "" || qAutocomplete.indexOf(q) < 0) {
                $searchTextAutocomplete.val("");
            }

            //only go ahead if the keyCode is a "printable character" or erase / delete
            var key = e.keyCode;
            if ((key >= 48 && key <= 90) || (key >= 188 && key <= 222) || key === 8 || key === 46) {
                if (allPastSuggestions.indexOf(q.toLowerCase()) !== -1) {
                    search();
                }
            }
        });

        $searchPostsForm.on("submit", function (e) {
            e.preventDefault();
        });
    }
);
<commit_msg>add the parseQueryString method<commit_after>/*global define */
/*jshint indent:4 */

define(['AppParams', 'jquery', 'underscore', 'text!templates/search/results.html', 'text!templates/search/facets.html', 'jquery.maskMoney'],
    function (AppParams, $, underscore, resultsTemplate, facetsTemplate) {
        "use strict";

        var parseQueryString = function (queryString) {
            //from http://www.joezimjs.com/javascript/3-ways-to-parse-a-query-string-in-a-url/
            var params = {};
            var queries;
            var temp;
            var i;
            var l;

            // Split into key/value pairs
            queries = queryString.split("&");

            // Convert the array of strings into an object
            for (i = 0, l = queries.length; i < l; i++) {
                temp = queries[i].split('=');
                params[temp[0]] = temp[1];
            }

            return params;
        };

        var $body = $("body");
        var $postsViewStyle = $("#posts-view-style");
        var $postsViewStyleThumbnail = $("#posts-view-style-thumbnail");
        var $postsViewStyleTable = $("#posts-view-style-table");
        var $searchPostsForm = $("#search-posts-form");
        var $searchText = $("#search-text");
        var $searchTextAutocomplete = $("#search-text-autocomplete");
        var $searchTypes = $("#search-types");
        var $searchTypesNames = $('input[name="type"]', $searchPostsForm);
        var $searchResults = $("#search-results");
        var $searchPrices = $("#search-prices");
        var $searchPriceMin = $("#search-price-min");
        var $searchPriceMax = $("#search-price-max");
        var $searchButton = $("#search-button");

        var currentPage;
        var currentSort;
        var pages;
        var lastSuggestions = [];
        var allPastSuggestions = [];

        var maskMoney = function ($element) {
            $element.maskMoney(
                {
                    symbol: 'R$ ',
                    showSymbol: true,
                    symbolStay: true,
                    thousands: '.',
                    decimal: ',',
                    defaultZero: false
                }
            );
        };

        maskMoney($searchPriceMin);
        maskMoney($searchPriceMax);

        var openSearch = function () {
            $searchPrices.removeClass("hidden");
            $searchTypes.removeClass("hidden");
            $searchButton.removeClass("hidden");
        };

        var urlParts = (function () {
            var vars = {};
            window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
                if (vars[key] !== undefined) {
                    if (typeof vars[key] === "string") {
                        vars[key] = [vars[key]];
                        vars[key].push(value);
                    } else {
                        vars[key].push(value);
                    }
                } else {
                    vars[key] = value;
                }
            });

            if (vars.type !== undefined && typeof vars.type === "string") {
                vars.type = [vars.type];
            }

            return vars;
        } ());

        var pageLink = function (formSerialized, page, pageSort) {
            if (formSerialized === "") {
                if (page === 1) {
                    if (pageSort) {
                        return "?sort=" + pageSort;
                    } else {
                        return "";
                    }
                } else {
                    if (pageSort) {
                        return "?page=" + page + "&sort=" + pageSort;
                    } else {
                        return "?page=" + page;
                    }
                }
            } else {
                if (page === 1) {
                    if (pageSort) {
                        return "?" + formSerialized + "&sort=" + pageSort;
                    } else {
                        return "?" + formSerialized;
                    }
                } else {
                    if (pageSort) {
                        return "?" + formSerialized + "&page=" + page + "&sort=" + pageSort;
                    } else {
                        return "?" + formSerialized + "&page=" + page;
                    }
                }
            }
        };

        var formatMoney = function (money) {
            var $foo = $('<input type="text">');
            maskMoney($foo);
            $foo.val(money);
            $foo.trigger("mask");
            return $foo.val();
        };

        $(document.documentElement).on("keyup", function (e) {
            if (e.target.nodeName.toLowerCase() !== "body") {
                return;
            }

            if (e.keyCode === 191) {
                // focus on search by pressing slash (/)
                $searchText.focus();
            } else if (e.keyCode === 37 && typeof currentPage === "number" && currentPage > 1) {
                //pagination with left key
                search({page: currentPage - 1, sort: currentSort, scroll: true});
            } else if (e.keyCode === 39 && typeof currentPage === "number" && typeof pages === "number" && pages > currentPage) {
                //pagination with right key
                search({page: currentPage + 1, sort: currentSort, scroll: true});
            }
        });

        $searchResults.on("click", ".sortable a", function (e) {
            var target = e.currentTarget;
            e.preventDefault();

            var sortBy = target.getAttribute("data-sort");
            search({sort: sortBy});
        });

        $searchResults.on("click", ".pagination a", function (e) {
            var target = e.currentTarget;
            e.preventDefault();
            var page = target.getAttribute("data-page");
            var sort = target.getAttribute("data-sort");
            search({page: page, sort: sort, scroll: true});
        });

        var changeViewStyle = function (style) {
            if (style === "table") {
                $($(".results-thumbnail", $searchResults)[0]).addClass("hidden");
            } else {
                $($(".results-table", $searchResults)[0]).addClass("hidden");
            }

            $($(".results-" + style, $searchResults)[0]).removeClass("hidden");

            $.ajax({
                url: AppParams.webroot + "/search?posts_view_style=" + style,
                type: "HEAD"
            });
        };

        $postsViewStyleTable.on("click", function (e) {
            changeViewStyle("table");
            e.preventDefault();
        });

        $postsViewStyleThumbnail.on("click", function (e) {
            changeViewStyle("thumbnail");
            e.preventDefault();
        });

        var search = function (data) {
            if (data === undefined) {
                data = {};
            }

            var sort = data.sort || "";
            var page = data.page || 1;
            var scroll = data.scroll || false;

            if (scroll) {
                $body.animate({
                    scrollTop: ($searchResults.offset().top) - 50
                }, 500);
            }

            var formSerialized = $(':input[value!=""]', $searchPostsForm).serialize();

            var size = 20;
            var from = 1;
            var to;
            var total;

            if (page !== undefined) {

                page = parseInt(page, 10);

                if (isNaN(page)) {
                    page = 1;
                }

                from = ((page - 1) * size) + 1;
            } else {
                page = 1;
            }

            $.ajax({
                data: formSerialized,
                url: AppParams.webroot + "search-engine?size=" + encodeURIComponent(size) + "&from=" + encodeURIComponent(from) + "&sort=" + encodeURIComponent(sort),
                type: "GET",
                success: function (result) {
                    total = result.hits.total;
                    to = from + size - 1;

                    pages = Math.ceil(total / size);

                    if (to > total) {
                        to = total;
                    }

                    var compiled = underscore.template(resultsTemplate);

                    var viewStyle = $(".active", $postsViewStyle).data("view-style");

                    currentPage = page;
                    currentSort = sort;

                    if (window.history && window.history.pushState) {
                        var address = AppParams.webroot + "/search";

                        var q = $searchText.val();

                        if (! q) {
                            if (formSerialized) {
                                formSerialized = "q=&" + formSerialized;
                            } else {
                                formSerialized = "q=";
                            }
                        }

                        address = address + "?" + formSerialized;

                        if (currentPage !== 1) {
                            address = address + "&page=" + currentPage;
                        }

                        if (sort) {
                            address = address + "&sort=" + encodeURIComponent(sort);
                        }

                        window.history.pushState(null, null, address);
                    }

                    $searchResults.html(compiled(
                        {
                            pageLink : pageLink,
                            formatMoney : formatMoney,
                            AppParams : AppParams,
                            result : result,
                            size : size,
                            from : from,
                            to : to,
                            total : total,
                            sort : sort,
                            viewStyle : viewStyle,
                            formSerialized : formSerialized,
                            currentPage : currentPage,
                            pages : pages
                        }
                    ));
                }
            });
        };

        $searchText.typeahead({
            source : function (query, process) {
                var formSerialized = $(':input[value!=""]', $searchPostsForm).serialize();
                $.ajax({
                    data: formSerialized,
                    url: AppParams.webroot + "search-engine?suggestion=true",
                    type: "GET",
                    success: function (result) {
                        lastSuggestions = result;
                        process(result);

                        //add all the suggestions to a array to cache them
                        for (var eachSuggestionPosition in lastSuggestions) {
                            if (allPastSuggestions.indexOf(lastSuggestions[eachSuggestionPosition]) === -1) {
                                allPastSuggestions.push(lastSuggestions[eachSuggestionPosition]);
                            }
                        }

                        if (result[0] !== undefined) {
                            var q = $searchText.val();
                            var qAutocomplete = "";

                            if (result[0].indexOf(q.toLowerCase()) !== -1) {
                                qAutocomplete = q.substr(0, result[0].length) + (result[0]).substr(q.length);
                            }

                            $searchTextAutocomplete.val(qAutocomplete);
                        }
                    }
                });
            },
            items : 3
        });

        if (urlParts["price-min"] !== undefined) {
            $searchPriceMin.val(decodeURIComponent(urlParts["price-min"].replace(/\+/gi, " ")));
        }

        if (urlParts["price-max"] !== undefined) {
            $searchPriceMax.val(decodeURIComponent(urlParts["price-max"].replace(/\+/gi, " ")));
        }

        $searchTypesNames.each(function (pos, element) {
            if ($.inArray(element.value, urlParts["type"]) !== -1) {
                element.checked = true;
            }
        });

        if (urlParts.q !== undefined) {
            $searchText.val(decodeURIComponent(urlParts.q.replace(/\+/gi, " ")));
            search({page: urlParts.page || 1, sort: urlParts.sort});
            openSearch();
        } else {
            $searchText.focus();
            $searchText.one("keyup", function (e) {
                openSearch();
            });
        }

        $searchTypesNames.on("change", function (e) {
            search();
        });

        $searchText.on("change", function (e) {
            $searchTextAutocomplete.val("");
            search();
        });

        $searchText.on("keyup", function (e) {
            var q = $searchText.val();
            var qAutocomplete = $searchTextAutocomplete.val();

            if (q === "" || qAutocomplete.indexOf(q) < 0) {
                $searchTextAutocomplete.val("");
            }

            //only go ahead if the keyCode is a "printable character" or erase / delete
            var key = e.keyCode;
            if ((key >= 48 && key <= 90) || (key >= 188 && key <= 222) || key === 8 || key === 46) {
                if (allPastSuggestions.indexOf(q.toLowerCase()) !== -1) {
                    search();
                }
            }
        });

        $searchPostsForm.on("submit", function (e) {
            e.preventDefault();
        });
    }
);
<|endoftext|>


<commit_before>var socket = io.connect('http://localhost:8089');

var client = {
    guid: null,
    searches: [],
    counter: 0
};

var ospnc = {};

ospnc.generateUUID = function() {
    var d = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
    });
    return uuid;
};

ospnc.registerUser = function() {
    if(client.guid == null){
        client.guid = ospnc.generateUUID();
        console.log("generated new client:" + client.guid)
    }
    // Register Client
    socket.emit('register', {
        'guid': client.guid
    });
};
ospnc.setupSocketEvents = function() {
    socket.on('welcome', function(data) {
        client.guid = escape(data.guid);
        console.log("User " + client.guid + " is registered!");
    });

    socket.on('console_output', function(data) {
        var resJson = data.data;

        var resHuman = {
            icon: null,
            title: null,
            favicon: 'template/images/favicons/' + resJson.namesafe + "_16x16.png"
        }

        if(resJson.status === 'available'){
            resHuman.icon = 'fa-smile-o';
            resHuman.title = 'Name is available!';
        }else if(resJson.status === 'unavailable'){
            resHuman.icon = 'fa-meh-o';
            resHuman.title = 'Name is unavailable!';
        }else{
            resHuman.icon = 'fa-warning';
            resHuman.title = 'Check failed!';
        }
        if(!$('.res-title').length){
            var resContainer = $("section.container div.results_body");
            resContainer.append('

Results for:

'+ escape(data.clientSearch) +'

');
        }
        ospnc.addResult(resJson, resHuman);

    });
};
ospnc.resetSearchInput = function() {
    $('#search').val(function() {
        return this.defaultValue;
    });
};
ospnc.resetSearchDisplay = function() {
    $("div.res-item").remove();
};
ospnc.showAlertWindow = function() {
    swal({
            title: "Hmm...",
            text: "Please enter project name larger than two characters!",
            type: "warning",
            showCancelButton: false,
            confirmButtonColor: '#DD6B55',
            confirmButtonText: 'Okay, i will...'
        },
        function() {
            ospnc.resetSearchInput();
        });
};
ospnc.addResult = function(data, resHuman) {
    var resContainer = $("section .results_body");
    var resId = 'item-' + data.namesafe;

    var resTemplate = '
' +
                      '
' + data.name + '
' +
                      '
^
' +
                      '
';
    resContainer.append(resTemplate);
};

ospnc.queryServer = function() {
    // Ask server to process query
    socket.emit('process', {
        'guid': client.guid,
        'clientSearch': client.searches[client.counter - 1].searchValue
    });
};

$(document).ready(function() {
    /* Bin mousetrap to input field */
    var inputSearch = $('#search');
    Mousetrap.bind('enter', function(e) {
        if (e.target === inputSearch[0]) {

            var searchObj = {
                searchValue: inputSearch.val().replace(/\s+/g, '-').toLowerCase()
            };
            if (searchObj.searchValue.length < 3) {
                ospnc.showAlertWindow();
            } else {
                ospnc.resetSearchDisplay();

                searchObj.searchID = client.counter;
                client.searches.push(searchObj);
                client.counter++;

                ospnc.queryServer();
            }

        }
    });
    ospnc.registerUser();
    ospnc.setupSocketEvents();

    // Slide out left menu
    $("#legend").css('left', '-248px');
});

// (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
// (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
// m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
// })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

// ga('create', 'UA-38013109-1', 'auto');
// ga('require', 'displayfeatures');
// ga('require', 'linkid', 'linkid.js');
// ga('send', 'pageview');<commit_msg>added comment for Google Analytics<commit_after>var socket = io.connect('http://localhost:8089');

var client = {
    guid: null,
    searches: [],
    counter: 0
};

var ospnc = {};

ospnc.generateUUID = function() {
    var d = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
    });
    return uuid;
};

ospnc.registerUser = function() {
    if(client.guid == null){
        client.guid = ospnc.generateUUID();
        console.log("generated new client:" + client.guid)
    }
    // Register Client
    socket.emit('register', {
        'guid': client.guid
    });
};
ospnc.setupSocketEvents = function() {
    socket.on('welcome', function(data) {
        client.guid = escape(data.guid);
        console.log("User " + client.guid + " is registered!");
    });

    socket.on('console_output', function(data) {
        var resJson = data.data;

        var resHuman = {
            icon: null,
            title: null,
            favicon: 'template/images/favicons/' + resJson.namesafe + "_16x16.png"
        }

        if(resJson.status === 'available'){
            resHuman.icon = 'fa-smile-o';
            resHuman.title = 'Name is available!';
        }else if(resJson.status === 'unavailable'){
            resHuman.icon = 'fa-meh-o';
            resHuman.title = 'Name is unavailable!';
        }else{
            resHuman.icon = 'fa-warning';
            resHuman.title = 'Check failed!';
        }
        if(!$('.res-title').length){
            var resContainer = $("section.container div.results_body");
            resContainer.append('

Results for:

'+ escape(data.clientSearch) +'

');
        }
        ospnc.addResult(resJson, resHuman);

    });
};
ospnc.resetSearchInput = function() {
    $('#search').val(function() {
        return this.defaultValue;
    });
};
ospnc.resetSearchDisplay = function() {
    $("div.res-item").remove();
};
ospnc.showAlertWindow = function() {
    swal({
            title: "Hmm...",
            text: "Please enter project name larger than two characters!",
            type: "warning",
            showCancelButton: false,
            confirmButtonColor: '#DD6B55',
            confirmButtonText: 'Okay, i will...'
        },
        function() {
            ospnc.resetSearchInput();
        });
};
ospnc.addResult = function(data, resHuman) {
    var resContainer = $("section .results_body");
    var resId = 'item-' + data.namesafe;

    var resTemplate = '
' +
                      '
' + data.name + '
' +
                      '
^
' +
                      '
';
    resContainer.append(resTemplate);
};

ospnc.queryServer = function() {
    // Ask server to process query
    socket.emit('process', {
        'guid': client.guid,
        'clientSearch': client.searches[client.counter - 1].searchValue
    });
};

$(document).ready(function() {
    /* Bin mousetrap to input field */
    var inputSearch = $('#search');
    Mousetrap.bind('enter', function(e) {
        if (e.target === inputSearch[0]) {

            var searchObj = {
                searchValue: inputSearch.val().replace(/\s+/g, '-').toLowerCase()
            };
            if (searchObj.searchValue.length < 3) {
                ospnc.showAlertWindow();
            } else {
                ospnc.resetSearchDisplay();

                searchObj.searchID = client.counter;
                client.searches.push(searchObj);
                client.counter++;

                ospnc.queryServer();
            }

        }
    });
    ospnc.registerUser();
    ospnc.setupSocketEvents();

    // Slide out left menu
    $("#legend").css('left', '-248px');
});

/* Only for production
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-38013109-1', 'auto');
ga('require', 'displayfeatures');
ga('require', 'linkid', 'linkid.js');
ga('send', 'pageview');
*/<|endoftext|>


<commit_before>(function() {
  'use strict';

  var module = angular.module(
    'communityshare.controllers.user',
    [
      'communityshare.services.user',
      'communityshare.directives.user'
    ]);

  // User Views

  module.controller(
    'UserController',
    function($scope, $routeParams, User, Session) {
      $scope.Session = Session;
      var userId = $routeParams.userId;
      var userPromise = User.get(userId);
      $scope.message = 'Loading user...'
      userPromise.then(
        function(user) {
          $scope.message = '';
          $scope.user = user;
          if ($scope.communityPartnerViewMethods.onUserUpdate) {
            $scope.communityPartnerViewMethods.onUserUpdate(user);
          }
          if ($scope.educatorViewMethods.onUserUpdate) {
            $scope.educatorViewMethods.onUserUpdate(user);
          }
        },
        function(response) {
          $scope.message = 'Could not find user with id=' + userId;
        });
      $scope.communityPartnerViewMethods = {};
      $scope.educatorViewMethods = {};
    });

  // User Signups

  module.controller(
    'SignupCommunityPartnerController',
    function($scope, Session, Messages, User, signUp, $location, $q) {
      // This controller relies on a CommunityPartnerSettings directive.
      $scope.Session = Session;
      $scope.newUser = new User();
      $scope.communityPartnerSettingsMethods = {}
      $scope.properties = {};
      $scope.saveSettings = function() {
        var userPromise = signUp($scope.newUser.name, $scope.newUser.email,
                                 $scope.newUser.password);
        userPromise.then(
          function(user) {
            var methods = $scope.communityPartnerSettingsMethods;
            if ((methods.setUser) && (methods.saveSettings)) {
              methods.setUser(user);
              var settingsPromise = methods.saveSettings();
              settingsPromise.then(
                function(search) {
                  $location.path('/search/' + search.id + '/results');
                },
                function(message) {
                  Messages.error(message);
                });
            }
          },
          function(message) {
            Messages.error(message);
          });
      };
    });

  module.controller(
    'SignupEducatorController',
    function($scope, Session, Messages, User, signUp, $location, $q, Search) {
      // This controller relies on a CommunityPartnerSettings directive.
      $scope.Session = Session;
      $scope.newUser = new User();
      $scope.properties = {};
      $scope.educatorSearchSettingsMethods = {}
      $scope.search = new Search({
        searcher_user_id: undefined,
        searcher_role: 'educator',
        searching_for_role: 'partner',
        active: true,
        labels: [],
        latitude: undefined,
        longitude: undefined,
        distance: undefined
      });

      $scope.saveSettings = function() {
        var userPromise = signUp($scope.newUser.name, $scope.newUser.email,
                                 $scope.newUser.password);
        userPromise.then(
          function(user) {
            $scope.search.searcher_user_id = user.id;
            var methods = $scope.educatorSearchSettingsMethods;
            if (methods.saveSettings) {
              var settingsPromise = methods.saveSettings();
              settingsPromise.then(
                function(search) {
                  $location.path('/search/' + search.id + '/results');
                },
                function(message) {
                  Messages.error(message);
                });
            }
          },
          function(message) {
            Messages.error(message);
          });
      };
    });

  // Settings Controller

  module.controller(
    'SettingsController',
    function($scope, $location, Session, Messages) {
      $scope.Session = Session;
      $scope.user = Session.activeUser;
      $scope.properties = {};
      // Methods of 'setUser' and 'saveSettings' will be created by
      // the directive.
      $scope.communityPartnerSettingsMethods = {};
      if (Session.activeUser) {
        $scope.editedUser = Session.activeUser.clone();
      }
      $scope.saveSettings = function() {
        var saveUserPromise = $scope.editedUser.save();
        saveUserPromise.then(
          function(user) {
            Session.activeUser.updateFromData(user.toData());
            $location.path('/home');
          },
          function(message) {
            var msg = ''
            if (message) {
              msg = ': ' + message;
            }
            var msg = 'Failed to update settings' + msg;
            $scope.errorMessage = msg;
            $scope.successMessage = '';
          });
        var methods = $scope.communityPartnerSettingsMethods;
        if (methods.saveSettings) {
          var saveCPSettingsPromise = methods.saveSettings();
        }
      };
    });

})();
<commit_msg>Don't fail silently when CP settings save fails.<commit_after>(function() {
  'use strict';

  var module = angular.module(
    'communityshare.controllers.user',
    [
      'communityshare.services.user',
      'communityshare.directives.user'
    ]);

  // User Views

  module.controller(
    'UserController',
    function($scope, $routeParams, User, Session) {
      $scope.Session = Session;
      var userId = $routeParams.userId;
      var userPromise = User.get(userId);
      $scope.message = 'Loading user...'
      userPromise.then(
        function(user) {
          $scope.message = '';
          $scope.user = user;
          if ($scope.communityPartnerViewMethods.onUserUpdate) {
            $scope.communityPartnerViewMethods.onUserUpdate(user);
          }
          if ($scope.educatorViewMethods.onUserUpdate) {
            $scope.educatorViewMethods.onUserUpdate(user);
          }
        },
        function(response) {
          $scope.message = 'Could not find user with id=' + userId;
        });
      $scope.communityPartnerViewMethods = {};
      $scope.educatorViewMethods = {};
    });

  // User Signups

  module.controller(
    'SignupCommunityPartnerController',
    function($scope, Session, Messages, User, signUp, $location, $q) {
      // This controller relies on a CommunityPartnerSettings directive.
      $scope.Session = Session;
      $scope.newUser = new User();
      $scope.communityPartnerSettingsMethods = {}
      $scope.properties = {};
      $scope.saveSettings = function() {
        var userPromise = signUp($scope.newUser.name, $scope.newUser.email,
                                 $scope.newUser.password);
        userPromise.then(
          function(user) {
            var methods = $scope.communityPartnerSettingsMethods;
            if ((methods.setUser) && (methods.saveSettings)) {
              methods.setUser(user);
              var settingsPromise = methods.saveSettings();
              settingsPromise.then(
                function(search) {
                  $location.path('/search/' + search.id + '/results');
                },
                function(message) {
                  Messages.error(message);
                });
            }
          },
          function(message) {
            Messages.error(message);
          });
      };
    });

  module.controller(
    'SignupEducatorController',
    function($scope, Session, Messages, User, signUp, $location, $q, Search) {
      // This controller relies on a CommunityPartnerSettings directive.
      $scope.Session = Session;
      $scope.newUser = new User();
      $scope.properties = {};
      $scope.educatorSearchSettingsMethods = {}
      $scope.search = new Search({
        searcher_user_id: undefined,
        searcher_role: 'educator',
        searching_for_role: 'partner',
        active: true,
        labels: [],
        latitude: undefined,
        longitude: undefined,
        distance: undefined
      });

      $scope.saveSettings = function() {
        var userPromise = signUp($scope.newUser.name, $scope.newUser.email,
                                 $scope.newUser.password);
        userPromise.then(
          function(user) {
            $scope.search.searcher_user_id = user.id;
            var methods = $scope.educatorSearchSettingsMethods;
            if (methods.saveSettings) {
              var settingsPromise = methods.saveSettings();
              settingsPromise.then(
                function(search) {
                  $location.path('/search/' + search.id + '/results');
                },
                function(message) {
                  Messages.error(message);
                });
            }
          },
          function(message) {
            Messages.error(message);
          });
      };
    });

  // Settings Controller

  module.controller(
    'SettingsController',
    function($scope, $location, Session, Messages, $q) {
      $scope.Session = Session;
      $scope.user = Session.activeUser;
      $scope.properties = {};
      // Methods of 'setUser' and 'saveSettings' will be created by
      // the directive.
      $scope.communityPartnerSettingsMethods = {};
      if (Session.activeUser) {
        $scope.editedUser = Session.activeUser.clone();
      }

      var onError = function(message) {
        var msg = '';
        if (message) {
          msg = ': ' + message;
        }
        var msg = 'Failed to update settings' + msg;
        $scope.errorMessage = msg;
        $scope.successMessage = '';
      };

      $scope.saveSettings = function() {
        var saveUserPromise = $scope.editedUser.save();
        var combinedPromise;
        var saveCPSettingsPromise;
        var methods = $scope.communityPartnerSettingsMethods;
        if (methods.saveSettings) {
          saveCPSettingsPromise = methods.saveSettings();
          combinedPromise = $q.all([saveUserPromise, saveCPSettingsPromise]);
        } else {
          combinedPromise = $q.all([saveUserPromise]);
        }
        saveUserPromise.then(
          function(user) {
            Session.activeUser.updateFromData(user.toData());
          },
          onError);
        if (saveCPSettingsPromise) {
          saveCPSettingsPromise.then(
            function() {},
            onError);
        }
        combinedPromise.then(
          function() {
            $location.path('/home');
          });
      };
    });

})();
<|endoftext|>


<commit_before>// ==UserScript==
// @name         CargoShorts
// @namespace    http://github.com/Fryguy/cargo_shorts
// @updateURL    http://localhost/userscripts/cargo_shorts.js
// @version      0.4.0
// @description  Auto-click through BlueJeans screens
// @author       Jason Frey
// @match        https://*.bluejeans.com/*
// @run-at       document-end
// @noframes
// @grant        GM_xmlhttpRequest
// @grant        GM_getValue
// @grant        GM_setValue
// @connect      localhost
// ==/UserScript==

(function() {
    'use strict';

    /****************************/
    /* Element selector methods */
    /****************************/

    function guestLoginInput() {
        return document.querySelector(".guestView.panel > div:nth-child(2) > input");
    }

    function guestLoginButton() {
        return document.querySelector(".guestView.panel > button");
    }

    function computerAudioButton() {
        return document.querySelector(".primaryConnectionsDialog[style*=\"visible\"] .joinComputer");
    }

    function phoneAudioButton() {
        return document.querySelector(".primaryConnectionsDialog[style*=\"visible\"] .joinPhone");
    }

    function callMeTab() {
        return document.querySelector(".primaryPhoneDialog[style*=\"visible\"] .callMeOption");
    }

    function phoneNumberInput() {
        return document.querySelector(".primaryPhoneDialog[style*=\"visible\"] .callMeContainer input");
    }

    function callMeNowButton() {
        return document.querySelector(".primaryPhoneDialog[style*=\"visible\"] .callMeContainer button");
    }

    function joinMeetingButton() {
        return document.querySelector(".primaryComputerDialog[style*=\"visible\"] .decisionsHolder button");
    }

    /********************/
    /* Workflow methods */
    /********************/

    function doEntrypoint() {
        waitFor(guestLoginInput, doLogin);
    }

    function doLogin() {
        guestLoginInput().value = configuration().name;
        guestLoginButton().click();
        waitFor(computerAudioButton, doAudioOptions);
    }

    function doAudioOptions() {
        if (configuration().phone) {
            phoneAudioButton().click();
            waitFor(callMeTab, doEnterPhoneNumber);
        } else {
            computerAudioButton().click();
            waitFor(joinMeetingButton, doJoinMeeting);
        }
    }

    function doEnterPhoneNumber() {
        callMeTab().click();
        phoneNumberInput().value = configuration().phone;
        // Delay the click of the callMeNowButton to prevent a race with
        // BlueJeans trying to set up the session
        console.log("CargoShorts is delaying click of callMeNowButton");
        setTimeout(doCallMeNow, 1000);
    }

    function doCallMeNow() {
        callMeNowButton().click();
        waitFor(joinMeetingButton, doJoinMeeting);
    }

    function doJoinMeeting() {
        joinMeetingButton().click(); // FIN
    }

    /*********************/
    /* Framework Methods */
    /*********************/

    function waitFor(waitingFor, callback) {
        console.log("CargoShorts is waiting for " + waitingFor.name);
        if (waitingFor()) {
            callback();
        } else {
            setTimeout(waitFor, 1000, waitingFor, callback);
        }
    }

    function configuration() {
        return JSON.parse(GM_getValue("configuration"));
    }

    /*******************/
    /* Main entrypoint */
    /*******************/

    GM_xmlhttpRequest({
        method: "GET",
        headers: { Accept: "application/json" },
        url: "http://localhost/configuration.json",
        onload: function(response) {
            GM_setValue("configuration", response.responseText);
            doEntrypoint();
        },
        onerror: function(response) {
            GM_setValue("configuration", JSON.stringify({"name": "CargoShorts"}));
            doEntrypoint();
        }
    });
})();
<commit_msg>Make cargo_shorts work again<commit_after>// ==UserScript==
// @name         CargoShorts
// @namespace    http://github.com/Fryguy/cargo_shorts
// @updateURL    http://localhost/userscripts/cargo_shorts.js
// @version      0.4.0
// @description  Auto-click through BlueJeans screens
// @author       Jason Frey
// @match        https://*.bluejeans.com/*
// @run-at       document-end
// @noframes
// @grant        GM_xmlhttpRequest
// @grant        GM_getValue
// @grant        GM_setValue
// @connect      localhost
// ==/UserScript==

// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js

(function() {
    'use strict';

    /****************************/
    /* Element selector methods */
    /****************************/

    function guestLoginInput() {
        return document.querySelector(".guestView.panel > div:nth-child(2) > input");
    }

    function guestLoginButton() {
        return document.querySelector(".guestView.panel > button");
    }

    function computerAudioButton() {
        if ($(".computerAudio.audioOption").is(":visible")) {
            return $(".computerAudio.audioOption");
        }
    }

    function phoneAudioButton() {
        if ($(".phoneAudio.audioOption").is(":visible")) {
            return $(".phoneAudio.audioOption");
        }
    }

    function callMeTab() {
        return document.querySelector(".primaryPhoneDialog[style*=\"visible\"] .callMeOption");
    }

    function phoneNumberInput() {
        return document.querySelector(".primaryPhoneDialog[style*=\"visible\"] .callMeContainer input");
    }

    function callMeNowButton() {
        return document.querySelector(".primaryPhoneDialog[style*=\"visible\"] .callMeContainer button");
    }

    function joinMeetingButton() {
        return document.querySelector(".primaryComputerDialog[style*=\"visible\"] .decisionsHolder button");
    }

    /********************/
    /* Workflow methods */
    /********************/

    function doEntrypoint() {
        waitFor(guestLoginInput, doLogin);
    }

    function doLogin() {
        guestLoginInput().value = configuration().name;
        guestLoginButton().click();
        waitFor(computerAudioButton, doAudioOptions);
    }

    function doAudioOptions() {
        if (configuration().phone) {
            phoneAudioButton().click();
            waitFor(callMeTab, doEnterPhoneNumber);
        } else {
            computerAudioButton().click();
            waitFor(joinMeetingButton, doJoinMeeting);
        }
    }

    function doEnterPhoneNumber() {
        callMeTab().click();
        phoneNumberInput().value = configuration().phone;
        // Delay the click of the callMeNowButton to prevent a race with
        // BlueJeans trying to set up the session
        console.log("CargoShorts is delaying click of callMeNowButton");
        setTimeout(doCallMeNow, 1000);
    }

    function doCallMeNow() {
        callMeNowButton().click();
        waitFor(joinMeetingButton, doJoinMeeting);
    }

    function doJoinMeeting() {
        joinMeetingButton().click(); // FIN
    }

    /*********************/
    /* Framework Methods */
    /*********************/

    function waitFor(waitingFor, callback) {
        console.log("CargoShorts is waiting for " + waitingFor.name);
        if (waitingFor()) {
            callback();
        } else {
            setTimeout(waitFor, 1000, waitingFor, callback);
        }
    }

    function configuration() {
        return JSON.parse(GM_getValue("configuration"));
    }

    /*******************/
    /* Main entrypoint */
    /*******************/

    var $ = unsafeWindow.jQuery;

    GM_xmlhttpRequest({
        method: "GET",
        headers: { Accept: "application/json" },
        url: "http://localhost/configuration.json",
        onload: function(response) {
            GM_setValue("configuration", response.responseText);
            doEntrypoint();
        },
        onerror: function(response) {
            GM_setValue("configuration", JSON.stringify({"name": "CargoShorts"}));
            doEntrypoint();
        }
    });
})();
<|endoftext|>


<commit_before>function initializeDetector(name, headline){
    var headWrapper = document.createElement('div')
    ,   title = document.createElement('h1')
    ,   drawTarget = document.createElement('div')
    ,   plotControlWrap = document.createElement('form')
    ,   plotControlTitle = document.createElement('h3')
    ,   plotControlMinLabel = document.createElement('label')
    ,   plotControlMaxLabel = document.createElement('label')
    ,   plotControlMin = document.createElement('input')
    ,   plotControlMax = document.createElement('input')
    ,   plotScale = document.createElement('select')
    ,   plotScaleLin = document.createElement('option')
    ,   plotScaleLog = document.createElement('option')
    ,   deckWrap = document.createElement('div')
    ,   sidebarWrap = document.createElement('div')
    ,   plotDeck
    ,   plotCard
    ,   xString
    ,   deckNavigator, deckOption
    ,   width = 0.70*this.offsetWidth
    ,   height = 2*width/3
    ,   i, subdetectorNav, subdetectorNavLabel

    this.name = name;
    //declare default views and units if none pre-defined
    if(!this.views){
        this.views = ['HV', 'Threshold', 'reqRate', 'acptRate'];
        this.viewLabels = ['HV', 'Threshold', 'Trigger Request Rate', 'Trigger Accept Rate'];
    }
    if(!this.units)
        this.units = ['V', 'ADC Units', 'Hz', 'Hz'];

    //set up data store for detectors
    if(!window.currentData)
        window.currentData = {};
    for(i=0; i<this.views.length; i++){
        window.currentData[this.views[i]] = {};
    }

    //////////////////////
    //Build DOM
    //////////////////////
    //the DOM layout for a detector view is roughly:

    //-----------------------------------
    // h1 Title
    //-----------------------------------
    // input[radio] HV / Thresh / Rate
    //-----------------------------------
    // x-deck for detector views; each
    // card contains a Kinetic drawing
    // context
    //
    //-----------------------------------
    // x-deck navigation if required
    //-----------------------------------
    // form plot control widget
    //-----------------------------------

    headWrapper.setAttribute('id', this.id+'titleWrapper');
    headWrapper.setAttribute('class', 'subdetectorHeadlineWrap')
    this.appendChild(headWrapper);
    //top nav title
    title.setAttribute('id', this.id+'title');
    title.setAttribute('class', 'subdetectorTitle');
    document.getElementById(this.id+'titleWrapper').appendChild(title);
    document.getElementById(this.id+'title').innerHTML = headline;
    //state nav radio
    for(i=0; i<this.views.length; i++){
        subdetectorNav = document.createElement('input')
        subdetectorNav.setAttribute('id', this.id+'goto'+this.views[i]);
        subdetectorNav.setAttribute('class', 'stdin');
        subdetectorNav.setAttribute('type', 'radio');
        subdetectorNav.setAttribute('name', this.id+'Nav');
        subdetectorNav.setAttribute('value', this.views[i]);
        subdetectorNav.onchange = this.trackView.bind(this);
        if(i==3) subdetectorNav.setAttribute('checked', true); //default to rate view
        document.getElementById(this.id+'titleWrapper').appendChild(subdetectorNav);
        subdetectorNavLabel = document.createElement('label');
        subdetectorNavLabel.setAttribute('id', this.id+'goto'+this.views[i]+'Label');
        subdetectorNavLabel.setAttribute('for', this.id+'goto'+this.views[i]);
        document.getElementById(this.id+'titleWrapper').appendChild(subdetectorNavLabel);
        document.getElementById(this.id+'goto'+this.views[i]+'Label').innerHTML = this.viewLabels[i];
    }

    //sidebar deck
    sidebarWrap.setAttribute('id', this.id+'sidebarWrap');
    sidebarWrap.setAttribute('class', 'sidebarWrap');
    this.appendChild(sidebarWrap);
    xString = '<x-deck id='+this.id+'SidebarDeck selected-index=1>'
    xString += '<x-card id='+this.id+'HVSideCard class="sidebarCard"><widget-HVcontrol id="HVcontrol" MIDAS='+this.MIDAS+' style="width:calc(100% - 2em)"></widget-HVcontrol></x-card>'
    xString += '<x-card id='+this.id+'RateSideCard class="sidebarCard"><widget-rateBar id="ratesAndThresholds" MIDAS='+this.MIDAS+'></widget-RateBar></x-card>'
    xString += '</x-deck>'
    sidebarWrap.innerHTML = xString;

    //plot deck wrapper:
    deckWrap.setAttribute('id', this.id+'DeckWrap');
    deckWrap.setAttribute('class', 'deckWrap')
    this.appendChild(deckWrap);

    //declaring x-tags from within other x-tags needs special treatment via innerHTML; must build HTML string and set it.
    xString = '<x-deck id="' + this.id + 'Deck" selected-index=0 style="height:'+height+'">';
    for(i=0; i<this.viewNames.length; i++){
        xString += '<x-card id="' + this.id+this.viewNames[i] + 'Card"></x-card>';
    }
    xString += '</x-deck>'
    deckWrap.innerHTML = xString;

    //plot buffers
    for(i=0; i<this.viewNames.length; i++){
        //divs to hold kinetic contexts
        drawTarget = document.createElement('div');
        drawTarget.setAttribute('id', this.id+this.viewNames[i]+'Draw');
        document.getElementById(this.id+this.viewNames[i] + 'Card').appendChild(drawTarget);
    }

    //plot control widget
    plotControlWrap.setAttribute('id', this.id+'PlotControl');
    plotControlWrap.setAttribute('class', 'plotControlWidget');
    this.appendChild(plotControlWrap);
    document.getElementById(this.id+'PlotControl').onchange = this.updatePlotParameters.bind(this);

    plotControlTitle.setAttribute('id', this.id+'PlotControlTitle');
    plotControlWrap.appendChild(plotControlTitle);
    document.getElementById(this.id + 'PlotControlTitle').innerHTML = 'Plot Control'

    //x-deck navigation
    if(this.viewNames.length > 1){
        deckNavigator = document.createElement('select');
        deckNavigator.setAttribute('class', 'stdin viewSelect');
        deckNavigator.id = this.id + 'viewSelect';
        for(i=0; i<this.viewNames.length; i++){
            deckOption = document.createElement('option');
            deckOption.innerHTML = this.viewNames[i];
            deckOption.value = i;
            deckNavigator.appendChild(deckOption);
        }
        deckNavigator.onchange = function(){
            var viewVal = selected(this.id+'viewSelect');

            document.getElementById(this.id+'Deck').shuffleTo(viewVal);
            this.displayIndex = viewVal;
            this.update();  //repaint right away
            this.updatePlotParameters(); //keep the scale up to date too
        }.bind(this)

        //plotControlWrap.appendChild(deckNavigator);
        document.getElementById(this.id+'titleWrapper').insertBefore(deckNavigator, document.getElementById(this.id+'title').nextSibling);
    }

    plotControlMinLabel.setAttribute('id', this.id+'PlotControlMinLabel');
    plotControlWrap.appendChild(plotControlMinLabel)
    document.getElementById(this.id+'PlotControlMinLabel').innerHTML = 'Min: ';
    plotControlMin.setAttribute('id', this.id + 'PlotControlMin');
    plotControlMin.setAttribute('type', 'number');
    plotControlMin.setAttribute('step', 'any');
    plotControlMin.setAttribute('class', 'stdin');
    plotControlWrap.appendChild(plotControlMin);

    plotControlMaxLabel.setAttribute('id', this.id+'PlotControlMaxLabel');
    plotControlWrap.appendChild(plotControlMaxLabel)
    document.getElementById(this.id+'PlotControlMaxLabel').innerHTML = 'Max: ';
    plotControlMax.setAttribute('id', this.id + 'PlotControlMax');
    plotControlMax.setAttribute('type', 'number');
    plotControlMax.setAttribute('step', 'any');
    plotControlMax.setAttribute('class', 'stdin');
    plotControlWrap.appendChild(plotControlMax);

    plotScale.setAttribute('id', this.id+'PlotControlScale');
    plotScale.setAttribute('class', 'stdin');
    plotControlWrap.appendChild(plotScale);

    plotScaleLin.setAttribute('id', this.id+'PlotScaleLin');
    plotScaleLin.setAttribute('value', 'lin');
    plotScale.appendChild(plotScaleLin);
    document.getElementById(this.id+'PlotScaleLin').innerHTML = 'Linear';

    plotScaleLog.setAttribute('id', this.id+'PlotScaleLog');
    plotScaleLog.setAttribute('value', 'log');
    plotScale.appendChild(plotScaleLog);
    document.getElementById(this.id+'PlotScaleLog').innerHTML = 'Log';

    //tooltip
    this.tooltip = document.createElement('div');
    this.tooltip.setAttribute('id', 'tooltip');
    this.appendChild(this.tooltip);

    ///////////////////////
    //State variables
    ///////////////////////
    this.currentView = this.views[this.views.length-1];
    this.currentUnit = this.units[this.units.length-1];
    this.displayIndex = 0;  //always start on the first card, guarnateed to exist.
    this.HVcrates = 0;
    detectHVcrates(this.MIDAS, this);
    //cells
    this.cells = {};
    this.summaryDepth = 0;

    ////////////////////////////
    //Drawing parameters
    ////////////////////////////
    this.frameLineWidth = 2;
    this.frameColor = '#000000';//'#999999';
    this.width = width;
    this.height = height;

    ///////////////////////////
    //Scale Parameters
    ///////////////////////////
    this.scale = 'ROOT Rainbow';
    this.min = {};
    this.max = {};
    this.scaleType = {};
    for(i=0; i<this.views.length; i++){
        this.min[this.views[i]] = canHas(localStorage.getItem(name+this.views[i]+'min'), 0);
        this.max[this.views[i]] = canHas(localStorage.getItem(name+this.views[i]+'max'), 3000);
        this.scaleType[this.views[i]] = canHas(localStorage.getItem(name+this.views[i]+'scaleType'), 'lin');
    }

    //if anything was in local storage, communicate this to the UI:
    plotControlMin.value = this.min[this.currentView];
    plotControlMax.value = this.max[this.currentView];
    plotScale.value = this.scaleType[this.currentView];

    ///////////////////////////
    //Tooltip state
    ///////////////////////////
    this.lastTTindex = -1;

    ////////////////////////////
    //MSC table construction
    ////////////////////////////
    this.buildHostmap();

    ////////////////////////////
    //Kinetic.js setup
    ////////////////////////////

    //indices for these arrays correspond to the x-card index on display
    this.stage = [];
    this.mainLayer = [];
    this.scaleLayer = [];

    for(i=0; i<this.viewNames.length; i++){

        //point kinetic at the div and set up the staging and layers:
        this.stage[i] = new Kinetic.Stage({
            container: this.id+this.viewNames[i]+'Draw',
            width: width,
            height: height
        });
        this.mainLayer[i] = new Kinetic.Layer();       //main rendering layer
        this.scaleLayer[i] = new Kinetic.Layer();      //layer for scales / legends
    }

    this.errorPattern = new Image();
    this.errorPattern.onload = function(){
        var key;

        for(key in this.cells){
            this.cells[key].setAttr('fillPatternImage', this.errorPattern);
        }

        this.mainLayer[this.displayIndex].draw();
    }.bind(this)
    this.errorPattern.src = 'static/img/static.gif'

    //let repopulate know that the detector would like to be updated every loop:
    if(!window.refreshTargets)
        window.refreshTargets = [];
    window.refreshTargets[window.refreshTargets.length] = this;

}

//stick the ODB equipment directory into its local slot:
function fetchODBEquipment(returnObj){
    if(!window.currentData.ODB)
        window.currentData.ODB = {};
    window.currentData.ODB.Equipment = returnObj;
}

//and again for HV:
function parseHV(data){
    var i, j, firstTimeFlag = false;

    if(!window.currentData.HV)
        window.currentData.HV = {};

    if(!window.ODBEquipment)
        window.ODBEquipment = {};

    for(i=0; i<data.length; i++){
        window.ODBEquipment['HV-'+i] = data[i]; //keep the whole blob around for the benefit of the HV sidebar
        for(j=0; j<data[i].Settings.Names.length; j++){
            window.currentData.HV[data[i].Settings.Names[j].toUpperCase().slice(0,10)] = data[i].Variables.Measured[j];
        }
    }
}

//determine how many HV frontends are in the ODB.  Frontends must be named HV-0, HV-1, HV-2....
function detectHVcrates(MIDAS, obj){
    XHR('http://' + MIDAS + '/?cmd=jcopy&odb=/Equipment&encoding=json-nokeys',
        function(target, response){
            var data, nCrates = 0;

            data = JSON.parse(response.slice(response.indexOf('{'), response.lastIndexOf('}')+1 ) )

            while(data['HV-'+nCrates])
                nCrates++

            target.HVcrates = nCrates;
            target.acquireHV()
        }.bind(null, obj) );
}<commit_msg>infrastructure for per channel daq plots<commit_after>function initializeDetector(name, headline){
    var headWrapper = document.createElement('div')
    ,   title = document.createElement('h1')
    ,   drawTarget = document.createElement('div')
    ,   plotControlWrap = document.createElement('form')
    ,   plotControlTitle = document.createElement('h3')
    ,   plotControlMinLabel = document.createElement('label')
    ,   plotControlMaxLabel = document.createElement('label')
    ,   plotControlMin = document.createElement('input')
    ,   plotControlMax = document.createElement('input')
    ,   plotScale = document.createElement('select')
    ,   plotScaleLin = document.createElement('option')
    ,   plotScaleLog = document.createElement('option')
    ,   deckWrap = document.createElement('div')
    ,   sidebarWrap = document.createElement('div')
    ,   plotDeck
    ,   plotCard
    ,   xString
    ,   deckNavigator, deckOption
    ,   width = 0.70*this.offsetWidth
    ,   height = 2*width/3
    ,   i, subdetectorNav, subdetectorNavLabel

    this.name = name;
    //declare default views and units if none pre-defined
    if(!this.views){
        this.views = ['HV', 'Threshold', 'reqRate', 'acptRate'];
        this.viewLabels = ['HV', 'Threshold', 'Trigger Request Rate', 'Trigger Accept Rate'];
    }
    if(!this.units)
        this.units = ['V', 'ADC Units', 'Hz', 'Hz'];

    //set up data store for detectors
    if(!window.currentData)
        window.currentData = {};
    for(i=0; i<this.views.length; i++){
        window.currentData[this.views[i]] = {};
    }

    //////////////////////
    //Build DOM
    //////////////////////
    //the DOM layout for a detector view is roughly:

    //-----------------------------------
    // h1 Title
    //-----------------------------------
    // input[radio] HV / Thresh / Rate
    //-----------------------------------
    // x-deck for detector views; each
    // card contains a Kinetic drawing
    // context
    //
    //-----------------------------------
    // x-deck navigation if required
    //-----------------------------------
    // form plot control widget
    //-----------------------------------

    headWrapper.setAttribute('id', this.id+'titleWrapper');
    headWrapper.setAttribute('class', 'subdetectorHeadlineWrap')
    this.appendChild(headWrapper);
    //top nav title
    title.setAttribute('id', this.id+'title');
    title.setAttribute('class', 'subdetectorTitle');
    document.getElementById(this.id+'titleWrapper').appendChild(title);
    document.getElementById(this.id+'title').innerHTML = headline;
    //state nav radio
    for(i=0; i<this.views.length; i++){
        subdetectorNav = document.createElement('input')
        subdetectorNav.setAttribute('id', this.id+'goto'+this.views[i]);
        subdetectorNav.setAttribute('class', 'stdin');
        subdetectorNav.setAttribute('type', 'radio');
        subdetectorNav.setAttribute('name', this.id+'Nav');
        subdetectorNav.setAttribute('value', this.views[i]);
        subdetectorNav.onchange = this.trackView.bind(this);
        if(i==3) subdetectorNav.setAttribute('checked', true); //default to rate view
        document.getElementById(this.id+'titleWrapper').appendChild(subdetectorNav);
        subdetectorNavLabel = document.createElement('label');
        subdetectorNavLabel.setAttribute('id', this.id+'goto'+this.views[i]+'Label');
        subdetectorNavLabel.setAttribute('for', this.id+'goto'+this.views[i]);
        document.getElementById(this.id+'titleWrapper').appendChild(subdetectorNavLabel);
        document.getElementById(this.id+'goto'+this.views[i]+'Label').innerHTML = this.viewLabels[i];
    }

    //sidebar deck
    sidebarWrap.setAttribute('id', this.id+'sidebarWrap');
    sidebarWrap.setAttribute('class', 'sidebarWrap');
    this.appendChild(sidebarWrap);
    xString = '<x-deck id='+this.id+'SidebarDeck selected-index=1>'
    xString += '<x-card id='+this.id+'HVSideCard class="sidebarCard"><widget-HVcontrol id="HVcontrol" MIDAS='+this.MIDAS+' style="width:calc(100% - 2em)"></widget-HVcontrol></x-card>'
    xString += '<x-card id='+this.id+'RateSideCard class="sidebarCard"><widget-rateBar id="ratesAndThresholds" MIDAS='+this.MIDAS+'></widget-RateBar></x-card>'
    xString += '</x-deck>'
    sidebarWrap.innerHTML = xString;

    //plot deck wrapper:
    deckWrap.setAttribute('id', this.id+'DeckWrap');
    deckWrap.setAttribute('class', 'deckWrap')
    this.appendChild(deckWrap);

    //declaring x-tags from within other x-tags needs special treatment via innerHTML; must build HTML string and set it.
    xString = '<x-deck id="' + this.id + 'Deck" selected-index=0 style="height:'+height+'">';
    for(i=0; i<this.viewNames.length; i++){
        xString += '<x-card id="' + this.id+this.viewNames[i] + 'Card"></x-card>';
    }
    xString += '<x-card id="DAQhistoCard">

</x-card>'
    xString += '</x-deck>'
    deckWrap.innerHTML = xString;
    this.viewNames.push('Plots')

    //plot buffers
    for(i=0; i<this.viewNames.length; i++){
        //divs to hold kinetic contexts
        drawTarget = document.createElement('div');
        drawTarget.setAttribute('id', this.id+this.viewNames[i]+'Draw');
        document.getElementById(this.id+this.viewNames[i] + 'Card').appendChild(drawTarget);
    }

    //plot control widget
    plotControlWrap.setAttribute('id', this.id+'PlotControl');
    plotControlWrap.setAttribute('class', 'plotControlWidget');
    this.appendChild(plotControlWrap);
    document.getElementById(this.id+'PlotControl').onchange = this.updatePlotParameters.bind(this);

    plotControlTitle.setAttribute('id', this.id+'PlotControlTitle');
    plotControlWrap.appendChild(plotControlTitle);
    document.getElementById(this.id + 'PlotControlTitle').innerHTML = 'Plot Control'

    //x-deck navigation
    if(this.viewNames.length > 1){
        deckNavigator = document.createElement('select');
        deckNavigator.setAttribute('class', 'stdin viewSelect');
        deckNavigator.id = this.id + 'viewSelect';
        for(i=0; i<this.viewNames.length; i++){
            deckOption = document.createElement('option');
            deckOption.innerHTML = this.viewNames[i];
            deckOption.value = i;
            deckNavigator.appendChild(deckOption);
        }
        deckNavigator.onchange = function(){
            var viewVal = selected(this.id+'viewSelect');

            document.getElementById(this.id+'Deck').shuffleTo(viewVal);
            this.displayIndex = viewVal;
            this.update();  //repaint right away
            this.updatePlotParameters(); //keep the scale up to date too
        }.bind(this)

        //plotControlWrap.appendChild(deckNavigator);
        document.getElementById(this.id+'titleWrapper').insertBefore(deckNavigator, document.getElementById(this.id+'title').nextSibling);
    }

    plotControlMinLabel.setAttribute('id', this.id+'PlotControlMinLabel');
    plotControlWrap.appendChild(plotControlMinLabel)
    document.getElementById(this.id+'PlotControlMinLabel').innerHTML = 'Min: ';
    plotControlMin.setAttribute('id', this.id + 'PlotControlMin');
    plotControlMin.setAttribute('type', 'number');
    plotControlMin.setAttribute('step', 'any');
    plotControlMin.setAttribute('class', 'stdin');
    plotControlWrap.appendChild(plotControlMin);

    plotControlMaxLabel.setAttribute('id', this.id+'PlotControlMaxLabel');
    plotControlWrap.appendChild(plotControlMaxLabel)
    document.getElementById(this.id+'PlotControlMaxLabel').innerHTML = 'Max: ';
    plotControlMax.setAttribute('id', this.id + 'PlotControlMax');
    plotControlMax.setAttribute('type', 'number');
    plotControlMax.setAttribute('step', 'any');
    plotControlMax.setAttribute('class', 'stdin');
    plotControlWrap.appendChild(plotControlMax);

    plotScale.setAttribute('id', this.id+'PlotControlScale');
    plotScale.setAttribute('class', 'stdin');
    plotControlWrap.appendChild(plotScale);

    plotScaleLin.setAttribute('id', this.id+'PlotScaleLin');
    plotScaleLin.setAttribute('value', 'lin');
    plotScale.appendChild(plotScaleLin);
    document.getElementById(this.id+'PlotScaleLin').innerHTML = 'Linear';

    plotScaleLog.setAttribute('id', this.id+'PlotScaleLog');
    plotScaleLog.setAttribute('value', 'log');
    plotScale.appendChild(plotScaleLog);
    document.getElementById(this.id+'PlotScaleLog').innerHTML = 'Log';

    //tooltip
    this.tooltip = document.createElement('div');
    this.tooltip.setAttribute('id', 'tooltip');
    this.appendChild(this.tooltip);

    ///////////////////////
    //State variables
    ///////////////////////
    this.currentView = this.views[this.views.length-1];
    this.currentUnit = this.units[this.units.length-1];
    this.displayIndex = 0;  //always start on the first card, guarnateed to exist.
    this.HVcrates = 0;
    detectHVcrates(this.MIDAS, this);
    //cells
    this.cells = {};
    this.summaryDepth = 0;

    ////////////////////////////
    //Drawing parameters
    ////////////////////////////
    this.frameLineWidth = 2;
    this.frameColor = '#000000';//'#999999';
    this.width = width;
    this.height = height;

    ///////////////////////////
    //Scale Parameters
    ///////////////////////////
    this.scale = 'ROOT Rainbow';
    this.min = {};
    this.max = {};
    this.scaleType = {};
    for(i=0; i<this.views.length; i++){
        this.min[this.views[i]] = canHas(localStorage.getItem(name+this.views[i]+'min'), 0);
        this.max[this.views[i]] = canHas(localStorage.getItem(name+this.views[i]+'max'), 3000);
        this.scaleType[this.views[i]] = canHas(localStorage.getItem(name+this.views[i]+'scaleType'), 'lin');
    }

    //if anything was in local storage, communicate this to the UI:
    plotControlMin.value = this.min[this.currentView];
    plotControlMax.value = this.max[this.currentView];
    plotScale.value = this.scaleType[this.currentView];

    ///////////////////////////
    //Tooltip state
    ///////////////////////////
    this.lastTTindex = -1;

    ////////////////////////////
    //MSC table construction
    ////////////////////////////
    this.buildHostmap();

    ////////////////////////////
    //Kinetic.js setup
    ////////////////////////////

    //indices for these arrays correspond to the x-card index on display
    this.stage = [];
    this.mainLayer = [];
    this.scaleLayer = [];

    for(i=0; i<this.viewNames.length; i++){

        //point kinetic at the div and set up the staging and layers:
        this.stage[i] = new Kinetic.Stage({
            container: this.id+this.viewNames[i]+'Draw',
            width: width,
            height: height
        });
        this.mainLayer[i] = new Kinetic.Layer();       //main rendering layer
        this.scaleLayer[i] = new Kinetic.Layer();      //layer for scales / legends
    }

    this.errorPattern = new Image();
    this.errorPattern.onload = function(){
        var key;

        for(key in this.cells){
            this.cells[key].setAttr('fillPatternImage', this.errorPattern);
        }

        this.mainLayer[this.displayIndex].draw();
    }.bind(this)
    this.errorPattern.src = 'static/img/static.gif'

    //let repopulate know that the detector would like to be updated every loop:
    if(!window.refreshTargets)
        window.refreshTargets = [];
    window.refreshTargets[window.refreshTargets.length] = this;

}

//stick the ODB equipment directory into its local slot:
function fetchODBEquipment(returnObj){
    if(!window.currentData.ODB)
        window.currentData.ODB = {};
    window.currentData.ODB.Equipment = returnObj;
}

//and again for HV:
function parseHV(data){
    var i, j, firstTimeFlag = false;

    if(!window.currentData.HV)
        window.currentData.HV = {};

    if(!window.ODBEquipment)
        window.ODBEquipment = {};

    for(i=0; i<data.length; i++){
        window.ODBEquipment['HV-'+i] = data[i]; //keep the whole blob around for the benefit of the HV sidebar
        for(j=0; j<data[i].Settings.Names.length; j++){
            window.currentData.HV[data[i].Settings.Names[j].toUpperCase().slice(0,10)] = data[i].Variables.Measured[j];
        }
    }
}

//determine how many HV frontends are in the ODB.  Frontends must be named HV-0, HV-1, HV-2....
function detectHVcrates(MIDAS, obj){
    XHR('http://' + MIDAS + '/?cmd=jcopy&odb=/Equipment&encoding=json-nokeys',
        function(target, response){
            var data, nCrates = 0;

            data = JSON.parse(response.slice(response.indexOf('{'), response.lastIndexOf('}')+1 ) )

            while(data['HV-'+nCrates])
                nCrates++

            target.HVcrates = nCrates;
            target.acquireHV()
        }.bind(null, obj) );
}<|endoftext|>