<commit_before>/*
 Copyright (C) 2015-2017 GEM Foundation

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/agpl.html>.
 */

(function($, Backbone, _) {
    var calculation_table;

    var progressHandlingFunction = function(progress) {
        var percent = progress.loaded / progress.total * 100;
        $('.bar').css('width', percent + '%');
        if (percent == 100) {
            dialog.hide();
        }
    };

    var htmlEscape = function (record) {
        // record[3] is the log message
        record[3] = record[3].replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
        return record
    };

    var dialog = (function ()
                  {
                      var pleaseWaitDiv = $('

Processing...

');
                      return {
                          show: function(msg, progress) {
                              $('h1', pleaseWaitDiv).text(msg);
                              if (progress) {
                                  progressHandlingFunction({loaded: 0, total: 1});
                              } else {
                                  progressHandlingFunction({loaded: 1, total: 1});
                              }
                              pleaseWaitDiv.modal('show');
                          },
                          hide: function () {
                              pleaseWaitDiv.modal('hide');
                          }
                      };
                  })();

    var diaerror = (function ()
                  {
                      var errorDiv = $('
\

\

\

\

Calculation not accepted: traceback
\

\

\

\

\
                      <input type="checkbox" id="diaerror_scroll_enabled" checked>\
                      Auto Scroll   \
                      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\

\

\

\

');
                      errorDiv.bind('hide', function() { calculation_table.hide_log(); });
                      return {
                          getdiv: function() {
                              return errorDiv;
                          },

                          show: function(is_large, title, msg) {
                              if (title != null) {
                                  $('.modal-title', errorDiv).html(title);
                              }
                              if (msg != null) {
                                  $('.modal-body-pre', errorDiv).html(msg);
                              }
                              if (is_large) {
                                  errorDiv.addClass("errorDialogLarge");
                              }
                              else {
                                  errorDiv.removeClass("errorDialogLarge");
                              }
                              errorDiv.modal('show');
                          },

                          append: function(title, msg) {
                              if (title != null) {
                                  $('.modal-title', errorDiv).html(title);
                              }
                              $( msg ).appendTo( $('.modal-body-pre', errorDiv) );
                          },

                          scroll_to_bottom: function(ctx) {
                              ctx.scrollTop(ctx[0].scrollHeight);
                          },

                          hide: function () {
                              errorDiv.modal('hide');
                          }
                      };
                  })();

    var CalculationTable = Backbone.View.extend(
        {
            /* the html element where the table is rendered */
            el: $('#my-calculations'),

            logXhr: null,
            logId: -1,
            logIsNew: false,
            logLinesAll: 0,
            logLines: 0,
            logTimeout: null,

            initialize: function(options) {

                /* whatever happens to any calculation, re-render the table */
                _.bindAll(this, 'render');
                this.calculations = options.calculations;
                this.calculations.bind('reset', this.render);
                this.calculations.bind('add', this.render);
                this.calculations.bind('remove', this.render);

                /* if false, it prevents the table to be refreshed */
                this.can_be_rendered = true;

                this.render();
            },

            events: {
                "click .btn-show-remove": "remove_calculation",
                "click .btn-danger": "show_modal_confirm_remove_calculation",
                "click .btn-hide-remove": "hide_modal_confirm_remove_calculation",
                "click .btn-traceback": "show_traceback",
                "click .btn-log": "show_log",
                "click .btn-file": "on_run_risk_clicked",
                "change .btn-file input": "on_run_risk_queued"
            },

            /* When an input dialog is opened, it is very important to not re-render the table */
            on_run_risk_clicked: function(e) {
                /* if a file input dialog has been opened do not refresh the calc table */
                this.can_be_rendered = false;
            },

            on_run_risk_queued: function(e) {
                this.can_be_rendered = true;
            },

            show_modal_confirm_remove_calculation: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');

                var show_or_back = (function(e) {
                    this.conf_show = $('#confirmDialog' + calc_id).show();
                    this.back_conf_show = $('.back_confirmDialog' + calc_id).show();
                    closeTimer();
                })();
            },

            hide_modal_confirm_remove_calculation: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');

                var hide_or_back = (function(e) {
                    this.conf_hide = $('#confirmDialog' + calc_id).hide();
                    this.back_conf_hide = $('.back_confirmDialog' + calc_id).hide();
                    setTimer();
                })();
            },

            remove_calculation: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');
                var calc_desc = $(e.target).attr('data-calc-desc');
                var view = this;
                diaerror.show(false, "Removing calculation " + calc_id, "...");

                var hide_or_back = (function(e) {
                    this.conf_hide = $('#confirmDialog' + calc_id).hide();
                    this.back_conf_hide = $('.back_confirmDialog' + calc_id).hide();
                    setTimer();
                })();

                var myXhr = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/remove",
                                    type: "POST",
                                    error: function (jqXHR, textStatus, errorThrown) {
                                        if (jqXHR.status == 403) {
                                            diaerror.show(false, "Error", "" + JSON.parse(jqXHR.responseText).error);
                                        }
                                    },
                                    success: function(data, textStatus, jqXHR) {
                                        err = data.error;
                                        if(!err) {
                                            err = "removed.";
                                        }
                                        diaerror.show(false, "Calculation removed", "The calculation:
(" + calc_id + ") " + calc_desc + " " + err );
                                        view.calculations.remove([view.calculations.get(calc_id)]);
                                    }});
            },

            show_traceback: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');
                var myXhr = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/traceback",
                                    error: function (jqXHR, textStatus, errorThrown) {
                                        if (jqXHR.status == 404) {
                                            diaerror.show(false, "Calculation " + calc_id + " not found.");
                                        }
                                        else {
                                            diaerror.show(false, "Error retrieving traceback for calculation " + calc_id, textStatus);
                                        }
                                        // alert("Error: " + textStatus);
                                    },
                                    success: function (data, textStatus, jqXHR) {
                                        if (data.length == 0) {
                                            diaerror.show(true, "Traceback not found for calculation " + calc_id, []);
                                        }
                                        else {
                                            var out = "";
                                            var ct = 0;
                                            for (s in data) {
                                                if (data[s] == "")
                                                    continue;
                                                out += '
' + data[s] + '
';
                                                ct++;
                                            }
                                            diaerror.show(true, "Traceback of calculation " + calc_id, out);
                                        }
                                        // alert("Success: " + textStatus);
                                    }});
            },

            _show_log_priv: function(is_new, calc_id, is_running, from) {
                var was_running = is_running;

                // TO CHECK hide_log method enable console.log and take a look
                // console.log("_show_log_priv: begin");
                if (this.logXhr != null) {
                    this.logXhr.abort();
                    this.logXhr = null;
                }
                if (is_new) {
                    if (this.logTimeout != null) {
                        window.clearTimeout(this.logTimeout);
                        this.logTimeout = null;
                    }
                }
                var obj = this;

                this.logXhr = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/log/" + from + ":",
                                      error: function (jqXHR, textStatus, errorThrown) {
                                          if (jqXHR.status == 404) {
                                              diaerror.show(true, "Log of calculation " + calc_id + " not found.");
                                          }
                                          else {
                                              diaerror.show(true, "Error retrieving log for calculation " + calc_id, textStatus);
                                          }
                                          obj.logIsNew = false;
                                      },
                                      success: function (data, textStatus, jqXHR) {
                                          var delay = 250;

                                          if (is_new) {
                                              obj.logLines = 0;
                                              obj.logLinesAll = 0;
                                          }
                                          else {
                                              // if data is empty check if job is still running
                                              if (is_running) {
                                                  if (data.length == 0) {
                                                      var ajax, status;

                                                      delay = 1000;

                                                      ajax = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/status",
                                                                     async: false}).done(function (data) { status = data.is_running; });
                                                      if (status !== true) {
                                                          is_running = false;
                                                      }
                                                  }
                                              }
                                          }
                                          var out = "";

                                          for (s in data) {
                                              if (data[s] == "") {
                                                  obj.logLinesAll++;
                                                  continue;
                                              }
                                              out += '
' + htmlEscape(data[s]) + '
';
                                              obj.logLines++;
                                              obj.logLinesAll++;
                                          }

                                          var title;
                                          if (is_running) {
                                              var dt;
                                              dt = new Date();
                                              title = "Log of calculation " + calc_id + " - " + dt.toString();
                                          }
                                          else if (was_running != is_running) {
                                              title = "Log of calculation " + calc_id + " - finished";
                                          }
                                          else {
                                              title = "Log of calculation " + calc_id;
                                          }

                                          if (obj.logIsNew) {
                                              diaerror.show(true, title, out);
                                          }
                                          else {
                                              diaerror.append(title, out);
                                          }
                                          if ($("#diaerror_scroll_enabled").prop( "checked" ) || was_running == false) {
                                              diaerror.scroll_to_bottom($('.modal-body', diaerror.getdiv()));
                                          }

                                          if (is_running) {
                                              function log_update(obj)
                                              {
                                                  obj._show_log_priv(false, obj.logId, true, obj.logLinesAll);
                                              }

                                              obj.logTimeout = window.setTimeout(log_update, delay, obj);
                                          }
                                          else {
                                              $('#diaerror_scroll_enabled_box').hide();
                                          }

                                          obj.logIsNew = false;
                                      }});
            },

            show_log: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');
                var is_running = ($(e.target).attr('is-running') == "true");

                this.logId = calc_id;
                this.logIsNew = true;

                if (is_running)
                    $('#diaerror_scroll_enabled_box', diaerror.getdiv()).show();
                else
                    $('#diaerror_scroll_enabled_box', diaerror.getdiv()).hide();

                this._show_log_priv(true, calc_id, is_running, "0");
            },

            hide_log: function(e) {
                if (this.logTimeout != null) {
                    window.clearTimeout(this.logTimeout);
                    this.logTimeout = null;
                }
                if (this.logXhr != null) {
                    this.logXhr.abort();
                    this.logXhr = null;
                }
                $('#diaerror_scroll_enabled_box').hide();
            },

            render: function() {
                if (!this.can_be_rendered) {
                    return;
                };
                this.$el.html(_.template($('#calculation-table-template').html(),
                                         { calculations: this.calculations.models }));
            }
        });

    var Calculation = Backbone.Model.extend({
        defaults: {
            map: null,
            layers: []
        }
    });

    var Calculations = Backbone.Collection.extend(
        {
            model: Calculation,
            url: gem_oq_server_url + "/v1/calc/list?relevant=true"
        });
    var calculations = new Calculations();

    var refresh_calcs;

    function setTimer() {
        refresh_calcs = setInterval(function() { calculations.fetch({reset: true}) }, 3000);
    }

    function closeTimer() {
        refresh_calcs = clearInterval(refresh_calcs);
    }

    /* classic event management */
    $(document).ready(
        function() {
            calculation_table = new CalculationTable({ calculations: calculations });
            calculations.fetch({reset: true});
            setTimer();

            /* XXX. Reset the input file value to ensure the change event
               will be always triggered */
            $(document).on("click", 'input[name=archive]',
                           function(e) { this.value = null; });
            $(document).on("change", 'input[name=archive]',
                           function(e) {
                               dialog.show('Uploading calculation', true);
                               var input = $(e.target);
                               var form = input.parents('form')[0];

                               $(form).ajaxSubmit(
                                   {
                                    xhr: function() {  // custom xhr to add progress bar management
                                        var myXhr = $.ajaxSettings.xhr();
                                        if(myXhr.upload){ // if upload property exists
                                            myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
                                        }
                                        return myXhr;
                                    },
                                    success: function(data) {
                                        calculations.add(new Calculation(data), {at: 0});
                                    },
                                    error: function(xhr) {
                                        dialog.hide();
                                        var s, out, data = $.parseJSON(xhr.responseText);
                                        var out = "";
                                        var ct = 0;
                                        for (s in data) {
                                            if (data[s] == "")
                                                continue;
                                            out += '
' + data[s] + '
';
                                            ct++;
                                        }
                                        diaerror.show(false, "Calculation not accepted: traceback", out);
                                    }});
                           });

            $(document).on('hidden.bs.modal', 'div[id^=traceback-]',
                           function(e) {
                               setTimer();
                           });

        });
})($, Backbone, _, gem_oq_server_url);
<commit_msg>fixed some error [skip CI]<commit_after>/*
 Copyright (C) 2015-2017 GEM Foundation

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/agpl.html>.
 */

(function($, Backbone, _) {
    var calculation_table;

    var progressHandlingFunction = function(progress) {
        var percent = progress.loaded / progress.total * 100;
        $('.bar').css('width', percent + '%');
        if (percent == 100) {
            dialog.hide();
        }
    };

    var htmlEscape = function (record) {
        // record[3] is the log message
        record[3] = record[3].replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
        return record
    };

    var dialog = (function ()
                  {
                      var pleaseWaitDiv = $('

Processing...

');
                      return {
                          show: function(msg, progress) {
                              $('h1', pleaseWaitDiv).text(msg);
                              if (progress) {
                                  progressHandlingFunction({loaded: 0, total: 1});
                              } else {
                                  progressHandlingFunction({loaded: 1, total: 1});
                              }
                              pleaseWaitDiv.modal('show');
                          },
                          hide: function () {
                              pleaseWaitDiv.modal('hide');
                          }
                      };
                  })();

    var diaerror = (function ()
                  {
                      var errorDiv = $('
\

\

\

\

Calculation not accepted: traceback
\

\

\

\

\
                      <input type="checkbox" id="diaerror_scroll_enabled" checked>\
                      Auto Scroll   \
                      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\

\

\

\

');
                      errorDiv.bind('hide', function() { calculation_table.hide_log(); });
                      return {
                          getdiv: function() {
                              return errorDiv;
                          },

                          show: function(is_large, title, msg) {
                              if (title != null) {
                                  $('.modal-title', errorDiv).html(title);
                              }
                              if (msg != null) {
                                  $('.modal-body-pre', errorDiv).html(msg);
                              }
                              if (is_large) {
                                  errorDiv.addClass("errorDialogLarge");
                              }
                              else {
                                  errorDiv.removeClass("errorDialogLarge");
                              }
                              errorDiv.modal('show');
                          },

                          append: function(title, msg) {
                              if (title != null) {
                                  $('.modal-title', errorDiv).html(title);
                              }
                              $( msg ).appendTo( $('.modal-body-pre', errorDiv) );
                          },

                          scroll_to_bottom: function(ctx) {
                              ctx.scrollTop(ctx[0].scrollHeight);
                          },

                          hide: function () {
                              errorDiv.modal('hide');
                          }
                      };
                  })();

    var CalculationTable = Backbone.View.extend(
        {
            /* the html element where the table is rendered */
            el: $('#my-calculations'),

            logXhr: null,
            logId: -1,
            logIsNew: false,
            logLinesAll: 0,
            logLines: 0,
            logTimeout: null,

            initialize: function(options) {

                /* whatever happens to any calculation, re-render the table */
                _.bindAll(this, 'render');
                this.calculations = options.calculations;
                this.calculations.bind('reset', this.render);
                this.calculations.bind('add', this.render);
                this.calculations.bind('remove', this.render);

                /* if false, it prevents the table to be refreshed */
                this.can_be_rendered = true;

                this.render();
            },

            events: {
                "click .btn-show-remove": "remove_calculation",
                "click .btn-danger": "show_modal_confirm_remove_calculation",
                "click .btn-hide-remove": "hide_modal_confirm_remove_calculation",
                "click .btn-traceback": "show_traceback",
                "click .btn-log": "show_log",
                "click .btn-file": "on_run_risk_clicked",
                "change .btn-file input": "on_run_risk_queued"
            },

            /* When an input dialog is opened, it is very important to not re-render the table */
            on_run_risk_clicked: function(e) {
                /* if a file input dialog has been opened do not refresh the calc table */
                this.can_be_rendered = false;
            },

            on_run_risk_queued: function(e) {
                this.can_be_rendered = true;
            },

            show_modal_confirm_remove_calculation: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');

                var show_or_back = (function(e) {
                    this.conf_show = $('#confirmDialog' + calc_id).show();
                    this.back_conf_show = $('.back_confirmDialog' + calc_id).show();
                    closeTimer();
                })();
            },

            hide_modal_confirm_remove_calculation: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');

                var hide_or_back = (function(e) {
                    this.conf_hide = $('#confirmDialog' + calc_id).hide();
                    this.back_conf_hide = $('.back_confirmDialog' + calc_id).hide();
                    setTimer();
                })();
            },

            remove_calculation: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');
                var calc_desc = $(e.target).attr('data-calc-desc');
                var view = this;
                diaerror.show(false, "Removing calculation " + calc_id, "...");

                var hide_or_back = (function(e) {
                    this.conf_hide = $('#confirmDialog' + calc_id).hide();
                    this.back_conf_hide = $('.back_confirmDialog' + calc_id).hide();
                    setTimer();
                })();

                var myXhr = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/remove",
                                    type: "POST",
                                    error: function (jqXHR, textStatus, errorThrown) {
                                        if (jqXHR.status == 403) {
                                            diaerror.show(false, "Error", JSON.parse(jqXHR.responseText).error);
                                        }
                                    },
                                    success: function(data, textStatus, jqXHR) {
                                        err = data.error;
                                        if(!err) {
                                            err = "has been removed.";
                                        }
                                        diaerror.show(false, "Calculation removed", "The calculation:
(" + calc_id + ") " + calc_desc + " " + err );
                                        view.calculations.remove([view.calculations.get(calc_id)]);
                                    }});
            },

            show_traceback: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');
                var myXhr = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/traceback",
                                    error: function (jqXHR, textStatus, errorThrown) {
                                        if (jqXHR.status == 404) {
                                            diaerror.show(false, "Calculation " + calc_id + " not found.");
                                        }
                                        else {
                                            diaerror.show(false, "Error retrieving traceback for calculation " + calc_id, textStatus);
                                        }
                                        // alert("Error: " + textStatus);
                                    },
                                    success: function (data, textStatus, jqXHR) {
                                        if (data.length == 0) {
                                            diaerror.show(true, "Traceback not found for calculation " + calc_id, []);
                                        }
                                        else {
                                            var out = "";
                                            var ct = 0;
                                            for (s in data) {
                                                if (data[s] == "")
                                                    continue;
                                                out += '
' + data[s] + '
';
                                                ct++;
                                            }
                                            diaerror.show(true, "Traceback of calculation " + calc_id, out);
                                        }
                                        // alert("Success: " + textStatus);
                                    }});
            },

            _show_log_priv: function(is_new, calc_id, is_running, from) {
                var was_running = is_running;

                // TO CHECK hide_log method enable console.log and take a look
                // console.log("_show_log_priv: begin");
                if (this.logXhr != null) {
                    this.logXhr.abort();
                    this.logXhr = null;
                }
                if (is_new) {
                    if (this.logTimeout != null) {
                        window.clearTimeout(this.logTimeout);
                        this.logTimeout = null;
                    }
                }
                var obj = this;

                this.logXhr = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/log/" + from + ":",
                                      error: function (jqXHR, textStatus, errorThrown) {
                                          if (jqXHR.status == 404) {
                                              diaerror.show(true, "Log of calculation " + calc_id + " not found.");
                                          }
                                          else {
                                              diaerror.show(true, "Error retrieving log for calculation " + calc_id, textStatus);
                                          }
                                          obj.logIsNew = false;
                                      },
                                      success: function (data, textStatus, jqXHR) {
                                          var delay = 250;

                                          if (is_new) {
                                              obj.logLines = 0;
                                              obj.logLinesAll = 0;
                                          }
                                          else {
                                              // if data is empty check if job is still running
                                              if (is_running) {
                                                  if (data.length == 0) {
                                                      var ajax, status;

                                                      delay = 1000;

                                                      ajax = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/status",
                                                                     async: false}).done(function (data) { status = data.is_running; });
                                                      if (status !== true) {
                                                          is_running = false;
                                                      }
                                                  }
                                              }
                                          }
                                          var out = "";

                                          for (s in data) {
                                              if (data[s] == "") {
                                                  obj.logLinesAll++;
                                                  continue;
                                              }
                                              out += '
' + htmlEscape(data[s]) + '
';
                                              obj.logLines++;
                                              obj.logLinesAll++;
                                          }

                                          var title;
                                          if (is_running) {
                                              var dt;
                                              dt = new Date();
                                              title = "Log of calculation " + calc_id + " - " + dt.toString();
                                          }
                                          else if (was_running != is_running) {
                                              title = "Log of calculation " + calc_id + " - finished";
                                          }
                                          else {
                                              title = "Log of calculation " + calc_id;
                                          }

                                          if (obj.logIsNew) {
                                              diaerror.show(true, title, out);
                                          }
                                          else {
                                              diaerror.append(title, out);
                                          }
                                          if ($("#diaerror_scroll_enabled").prop( "checked" ) || was_running == false) {
                                              diaerror.scroll_to_bottom($('.modal-body', diaerror.getdiv()));
                                          }

                                          if (is_running) {
                                              function log_update(obj)
                                              {
                                                  obj._show_log_priv(false, obj.logId, true, obj.logLinesAll);
                                              }

                                              obj.logTimeout = window.setTimeout(log_update, delay, obj);
                                          }
                                          else {
                                              $('#diaerror_scroll_enabled_box').hide();
                                          }

                                          obj.logIsNew = false;
                                      }});
            },

            show_log: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');
                var is_running = ($(e.target).attr('is-running') == "true");

                this.logId = calc_id;
                this.logIsNew = true;

                if (is_running)
                    $('#diaerror_scroll_enabled_box', diaerror.getdiv()).show();
                else
                    $('#diaerror_scroll_enabled_box', diaerror.getdiv()).hide();

                this._show_log_priv(true, calc_id, is_running, "0");
            },

            hide_log: function(e) {
                if (this.logTimeout != null) {
                    window.clearTimeout(this.logTimeout);
                    this.logTimeout = null;
                }
                if (this.logXhr != null) {
                    this.logXhr.abort();
                    this.logXhr = null;
                }
                $('#diaerror_scroll_enabled_box').hide();
            },

            render: function() {
                if (!this.can_be_rendered) {
                    return;
                };
                this.$el.html(_.template($('#calculation-table-template').html(),
                                         { calculations: this.calculations.models }));
            }
        });

    var Calculation = Backbone.Model.extend({
        defaults: {
            map: null,
            layers: []
        }
    });

    var Calculations = Backbone.Collection.extend(
        {
            model: Calculation,
            url: gem_oq_server_url + "/v1/calc/list?relevant=true"
        });
    var calculations = new Calculations();

    var refresh_calcs;

    function setTimer() {
        refresh_calcs = setInterval(function() { calculations.fetch({reset: true}) }, 3000);
    }

    function closeTimer() {
        refresh_calcs = clearInterval(refresh_calcs);
    }

    /* classic event management */
    $(document).ready(
        function() {
            calculation_table = new CalculationTable({ calculations: calculations });
            calculations.fetch({reset: true});
            setTimer();

            /* XXX. Reset the input file value to ensure the change event
               will be always triggered */
            $(document).on("click", 'input[name=archive]',
                           function(e) { this.value = null; });
            $(document).on("change", 'input[name=archive]',
                           function(e) {
                               dialog.show('Uploading calculation', true);
                               var input = $(e.target);
                               var form = input.parents('form')[0];

                               $(form).ajaxSubmit(
                                   {
                                    xhr: function() {  // custom xhr to add progress bar management
                                        var myXhr = $.ajaxSettings.xhr();
                                        if(myXhr.upload){ // if upload property exists
                                            myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
                                        }
                                        return myXhr;
                                    },
                                    success: function(data) {
                                        calculations.add(new Calculation(data), {at: 0});
                                    },
                                    error: function(xhr) {
                                        dialog.hide();
                                        var s, out, data = $.parseJSON(xhr.responseText);
                                        var out = "";
                                        var ct = 0;
                                        for (s in data) {
                                            if (data[s] == "")
                                                continue;
                                            out += '
' + data[s] + '
';
                                            ct++;
                                        }
                                        diaerror.show(false, "Calculation not accepted: traceback", out);
                                    }});
                           });

            $(document).on('hidden.bs.modal', 'div[id^=traceback-]',
                           function(e) {
                               setTimer();
                           });

        });
})($, Backbone, _, gem_oq_server_url);
<|endoftext|>


<commit_before>;(function( $ ){
	$.fn.extend({
		inViewport: function(){
			return inViewport(this.get(0)) > 0;
		},
		mostVisible: function(){
			var visibleElements = [];
			var mostVisible = null;
			var highestVisibility = 0;
			this.each(function(){
				if(inViewport(this)){
					visibleElements.push(this);
				}
				$.each(visibleElements, function(index, element){
					if($(element).data().vpVisibility > highestVisibility){
						highestVisibility = $(element).data().vpVisibility;
						mostVisible = $(element);
					}
				});

			});

			return mostVisible;
		}
	});

	var inViewport = function(element){
		var self = $(element),
			scrollTop = $(window).scrollTop(),
			windowHeight = $(window).height(),
			offset = self.offset(),
			elementBottom = offset.top + self.height() - scrollTop,
			elementTop = offset.top - scrollTop,
			position = 0;

			var a = elementTop - (windowHeight - self.height()) > self.height() ? self.height() : elementTop - (windowHeight - self.height());
			a = a > 0 ? a : 0;
			var b = elementBottom > self.height() ? self.height() : elementBottom;
			b = b > 0 ? b : 0;
			var vpVisibility = (b-a) / self.height();

			$(element).data('vpVisibility', vpVisibility);

		return vpVisibility;

	};
})( jQuery );<commit_msg>Optimized methods<commit_after>;(function( $ ){
	$.fn.extend({
		inViewport: function(){
			var self = $(this),
				scrollTop = $(window).scrollTop(),
				windowHeight = $(window).height(),
				offset = self.offset(),
				elementBottom = offset.top + self.height() - scrollTop,
				elementTop = offset.top - scrollTop,
				position = 0;

				var a = elementTop - (windowHeight - self.height()) > self.height() ? self.height() : elementTop - (windowHeight - self.height());
					a = a > 0 ? a : 0;
				var b = elementBottom > self.height() ? self.height() : elementBottom;
					b = b > 0 ? b : 0;
				var vpVisibility = (b-a) / self.height();
				self.data('vpVisibility', vpVisibility);
			return vpVisibility;
		},
		mostVisible: function(){
			var visibleElements = [];
			var mostVisible = null;
			var highestVisibility = 0;
			this.each(function(){
				if($(this).inViewport(true)){
					visibleElements.push(this);
				}
			});
			$.each(visibleElements, function(index, element){
				if(elementVisibility = $(element).data('vpVisibility')){
					if(elementVisibility > highestVisibility){
						highestVisibility = elementVisibility;
						mostVisible = $(element);
					}
				}
			});

			return mostVisible;
		}
	});
})( jQuery );<|endoftext|>


<commit_before>// Copyright 2019, University of Colorado Boulder

/**
 * Enumeration for the various states that can occur during an "update check." See updateCheck.js for main usage.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 * @author Michael Kauzmann (PhET Interactive Simulations)
 */
define( require => {
  'use strict';

  // modules
  const Enumeration = require( 'PHET_CORE/Enumeration' );
  const joist = require( 'JOIST/joist' );

  return joist.register( 'UpdateState', new Enumeration( [
    'UP_TO_DATE',  // Simulation version is equal to or greater than the currently published version.
    'OUT_OF_DATE', // Simulation version is less than currently published version (or equal but has a suffix)
    'CHECKING',    // Request to server sent out, has not processed reply yet.
    'OFFLINE',     // Last attempt to check failed, most likely offline
    'UNCHECKED'    // No attempt as been made to check the version against the latest online.
  ] ) );
} );
<commit_msg>Add support for rich enumerations, see https://github.com/phetsims/phet-core/issues/50<commit_after>// Copyright 2019, University of Colorado Boulder

/**
 * Enumeration for the various states that can occur during an "update check." See updateCheck.js for main usage.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 * @author Michael Kauzmann (PhET Interactive Simulations)
 */
define( require => {
  'use strict';

  // modules
  const Enumeration = require( 'PHET_CORE/Enumeration' );
  const joist = require( 'JOIST/joist' );

  return joist.register( 'UpdateState', Enumeration.byKeys( [
    'UP_TO_DATE',  // Simulation version is equal to or greater than the currently published version.
    'OUT_OF_DATE', // Simulation version is less than currently published version (or equal but has a suffix)
    'CHECKING',    // Request to server sent out, has not processed reply yet.
    'OFFLINE',     // Last attempt to check failed, most likely offline
    'UNCHECKED'    // No attempt as been made to check the version against the latest online.
  ] ) );
} );
<|endoftext|>


<commit_before>/**
 * Created by timfulmer on 10/25/14.
 */
var Promise = require("bluebird"),
    mongoose= require("mongoose"),
    options={},
    GeoData={},
    connection;

function distance(endPoints) {
    var R = 6371,
        lon1=endPoints[0][0],
        lat1=endPoints[0][1],
        lon2=endPoints[1][0],
        lat2=endPoints[1][1];
    var a =
        0.5 - Math.cos((lat2 - lat1) * Math.PI / 180)/2 +
        Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
        (1 - Math.cos((lon2 - lon1) * Math.PI / 180))/2;

    return R * 2 * Math.asin(Math.sqrt(a));
}

function initialize(opts){
    "use strict";

    options.driverType=opts.driverType || 'driver';
    options.routeType=opts.routeType || 'route';

    function initializePromise(resolve,reject){
        mongoose.connect('mongodb://localhost/test');
        connection=mongoose.connection;
        connection.on('error', reject);
        function connectionOpen() {
            var schema = mongoose.Schema({
                created:{type:Date,default:Date.now},
                updated:{type:Date,default:Date.now},
                type:String,
                maxDistance:Number,
                previousDrivers:[mongoose.Schema.Types.ObjectId],
                distance:Number,
                driverId:mongoose.Schema.Types.ObjectId,
                geoJson:{
                    type:{type:String},
                    coordinates:{type:[]}
                },
                datetime:{type:Date,default:Date.now}
            });
            schema.index({'geoJson':'2dsphere'});
            GeoData=mongoose.model('GeoData',schema);
            resolve();
        }
        connection.once('open', connectionOpen);
    }
    return new Promise(initializePromise);
}

function save(properties){
    "use strict";
    function savePromise(resolve,reject){
        if(properties.geoJson && properties.geoJson.type==='LineString'){
            properties.distance=distance(properties.geoJson.coordinates);
        }
        var geoData=new GeoData(properties);
        geoData.save(function geoDataSaved(err,geoData){
            if(err) return reject(err);
            resolve(geoData);
        });
    }
    return new Promise(savePromise);
}

function findDrivers(rider){
    "use strict";
    var previousDriverStrings=[];
    rider.previousDrivers.forEach(function(previousDriver){
        previousDriverStrings.push(previousDriver.toString());
    });
    function findDriversPromise(resolve,reject){
        var query={
            geoJson:{$near:{$geometry:rider.geoJson,$maxDistance:2500}},
            type:{$in:[options.driverType,options.routeType]},
            $or:[{maxDistance:{$gte:rider.distance}},{maxDistance:{$exists:false}}]
        };
        GeoData.find(query,function queryResults(err,docs){
            if(err) reject(err);
            docs.sort(function(a,b){
                return previousDriverStrings.indexOf(b.driverId.toString())>-1 ? 1 : 0;
            });
            resolve(docs);
        })
    }
    return new Promise(findDriversPromise);
}

function removeType(type){
    "use strict";
    function removeTypePromise(resolve,reject){
        GeoData.remove({type:type},function(err){
            if(err) return reject(err);
            resolve();
        })
    }
    return new Promise(removeTypePromise);
}

function close(){
    "use strict";
    connection.close();
}

module.exports=exports={
    initialize:initialize,
    save:save,
    findDrivers:findDrivers,
    removeType:removeType,
    close:close,
    distance:distance
};<commit_msg>Tweaks a couple items.<commit_after>/**
 * Created by timfulmer on 10/25/14.
 */
var Promise = require("bluebird"),
    mongoose= require("mongoose"),
    options={},
    GeoData={},
    connection;

function distance(endPoints) {
    var R = 6371,
        lon1=endPoints[0][0],
        lat1=endPoints[0][1],
        lon2=endPoints[1][0],
        lat2=endPoints[1][1];
    var a =
        0.5 - Math.cos((lat2 - lat1) * Math.PI / 180)/2 +
        Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
        (1 - Math.cos((lon2 - lon1) * Math.PI / 180))/2;

    return R * 2 * Math.asin(Math.sqrt(a));
}

function initialize(opts){
    "use strict";

    options.driverType=opts.driverType || 'driver';
    options.routeType=opts.routeType || 'route';

    function initializePromise(resolve,reject){
        mongoose.connect('mongodb://localhost/test');
        connection=mongoose.connection;
        connection.on('error', reject);
        function connectionOpen() {
            var schema = mongoose.Schema({
                created:{type:Date,default:Date.now},
                updated:{type:Date,default:Date.now},
                type:String,
                maxDistance:Number,
                previousDrivers:[mongoose.Schema.Types.ObjectId],
                distance:Number,
                driverId:mongoose.Schema.Types.ObjectId,
                geoJson:{
                    type:{type:String},
                    coordinates:{type:[]}
                },
                datetime:{type:Date,default:Date.now}
            });
            schema.index({'geoJson':'2dsphere'});
            GeoData=mongoose.model('GeoData',schema);
            resolve();
        }
        connection.once('open', connectionOpen);
    }
    return new Promise(initializePromise);
}

function save(properties){
    "use strict";
    function savePromise(resolve,reject){
        if(properties.geoJson && properties.geoJson.type==='LineString'){
            properties.distance=distance(properties.geoJson.coordinates);
        }
        var geoData=new GeoData(properties);
        geoData.save(function geoDataSaved(err,geoData){
            if(err) return reject(err);
            resolve(geoData);
        });
    }
    return new Promise(savePromise);
}

function findDrivers(rider){
    "use strict";
    var previousDriverStrings=[];
    rider.previousDrivers.forEach(function(previousDriver){
        previousDriverStrings.push(previousDriver.toString());
    });
    function findDriversPromise(resolve,reject){
        var query={
            geoJson:{$near:{$geometry:rider.geoJson,$maxDistance:750}},
            type:{$in:[options.driverType,options.routeType]},
            $or:[{maxDistance:{$gte:rider.distance}},{maxDistance:{$exists:false}}]
        };
        GeoData.find(query,function queryResults(err,docs){
            if(err) reject(err);
            docs.sort(function(a,b){
                return previousDriverStrings.indexOf(b.driverId.toString())>-1 ? 1 : 0;
            });
            resolve(docs);
        })
    }
    return new Promise(findDriversPromise);
}

function removeType(type){
    "use strict";
    function removeTypePromise(resolve,reject){
        GeoData.remove({type:type},function(err){
            if(err) return reject(err);
            resolve();
        })
    }
    return new Promise(removeTypePromise);
}

function close(){
    "use strict";
    connection.close();
}

module.exports=exports={
    initialize:initialize,
    save:save,
    findDrivers:findDrivers,
    removeType:removeType,
    close:close,
    distance:distance
};<|endoftext|>


<commit_before>var isMobile = {
    Android   : function () {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function () {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS       : function () {
        return navigator.userAgent.match(/iPhone|iPod|iPad/i);
    },
    Opera     : function () {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows   : function () {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any       : function () {
        return (
            isMobile.Android() ||
                isMobile.BlackBerry() ||
                isMobile.iOS() ||
                isMobile.Opera() ||
                isMobile.Windows() );
    }
};
var popupCenter = function(url, title, w, h) {
	// Fixes dual-screen position                         Most browsers      Firefox
	var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
	var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;

	var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
	var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

	var left = ((width / 2) - (w / 2)) + dualScreenLeft;
	var top = ((height / 3) - (h / 3)) + dualScreenTop;

	var newWindow = window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);

	// Puts focus on the newWindow
	if (window.focus) {
		newWindow.focus();
	}
};

/** For mobile friendliness, use touchstart for mobile devices, and click events for desktops**/
var handleClick = (isMobile.any() !== null) ? "touchstart" : "click";
//var functions = '';
$ = jQuery;
var functions = {
	offsetHeader: 0,
	debug: true,
	log: function(){
		var _args = Array.prototype.slice.call(arguments);
		if(this.debug){
			if (typeof console !== "undefined" || typeof console.log !== "undefined") {
				console.log(_args);
			}
		}
	},
	pushUpdate: function(){
		var _footer = $('.main-footer'),
			_bottomPush = $('.bottom-push'),
			_site = $('body > .site'),
			_offset = _footer.outerHeight();

		_bottomPush.css('height', _offset);
		_site.attr('style','margin-bottom:-'+_offset+'px');
	},
	getWindowWidth  : function () {
		return window.outerWidth;
	},
	pageScroll: function(_tag){
		var totalScroll = $(_tag).offset().top-functions.offsetHeader;
		setTimeout(function(){
			$('html,body').scrollTo(totalScroll, 500 );
		}, 100)
	},
	emailReplace: function(){
		/** Use JavaScript to replace <a> with a mail link, to reduce potential spam**/
		var _varPre = "mailto:",
			_varMid = '',
			_varEnd = '',
			_varText = '',
			_selector = ".js-replacer-text";

		if ($(_selector).length > 0) {
			$(_selector).each(function(){
				var _modifyText = $(this).data('modify');
				_varEnd = $(this).data('domain');
				_varMid = $(this).data('extra');
				_varText = $(this).data('text');
				$(this).attr('href', _varPre + _varMid + '@' + _varEnd);
				if(typeof _modifyText == 'boolean' && _modifyText != true){

				}else{
					if(typeof _varText !== 'undefined'){
						$(this).text(_varText);
					}else{
						$(this).text(_varMid + '@' + _varEnd);
					}
				}
			});
		}
	},
	windowResize: function(name, callback, vars){
		clearTimeout($.data(this, name));
		$.data(this, name, setTimeout(function() {
			if(typeof vars === 'string' || typeof vars == 'object'){
				callback(vars);
			}else{
				callback();
			}
		}, 100));
	},
	matchHeight :function(_tag){
		var _arrHeight = [],
			_elHeight = 0;

		$(_tag).each(function () {
			_arrHeight.push($(this).outerHeight());
		});
		_elHeight = Math.max.apply(Math,_arrHeight);

		if(functions.getWindowWidth() > 767){
			$(_tag).each(function () {
				$(this).stop(false,false).animate({
						'min-height': _elHeight+"px"
					}, 200, false
				);
			});
		}else{
			$(_tag).each(function () {
				$(this).stop(false,false).animate({
						'min-height': '0px'
					}, 200, false
				);
			});
		}
	},
	videoResize: function(){
		if ($(".js-video-resize:visible").length > 0) {
			$(".js-video-resize:visible").each(function () {

				var _this = $(this);
				var iFrameID = _this.find('iframe').attr('id');
				var $video = '';
				var ratioHeight = 0;
				var ratioWidth = 0;
				var vidWidth = 0;
				var vidHeight = 0;

				$video = $("#"+iFrameID);
				vidWidth = _this.outerWidth();
				ratioWidth = $video.attr('data-vidWidth');
				ratioHeight = $video.attr('data-vidHeight');
				vidHeight = ((vidWidth*ratioHeight) / ratioWidth);
				$video.css('display', 'block');
				$video.animate({height: vidHeight}, 100);
				//webLog.log({vid: _this, vidID: iFrameID, vW: vidWidth, vH: vidHeight, rW: ratioWidth, rH: ratioHeight});
			});
		}

	}

};

(function ( $ ) {
	$.this = 'undefined';
	$(window).resize(function() {
		functions.windowResize('video', functions.videoResize);
		functions.windowResize('pushUpdate', functions.pushUpdate);
		//functions.windowResize('headerScroll', functions.headerScroll);
	});

	$(document).ready(function () {
		functions.videoResize();
		functions.emailReplace();
		functions.pushUpdate();
		//functions.headerScroll();

	});

	$(document).on(handleClick, '.js-scroll-find', function (e) {
		e.preventDefault();
		//functions.scrollFind($(this), e);
	});

	/** Page Logic **/
	var successStories = $(".js-success-stories");
	successStories.owlCarousel({
		items : 1,
		singleItem : true,
		navigation: false,
		pagination: false,
		//navigationText : ["Previous", "Next"],
		responsiveRefreshRate : 100,
		mouseDrag: false,
		afterAction: function(){
			setTimeout(functions.videoResize(), 300);
		}

	});

	$(".navigation .right").click(function(e){
		e.preventDefault();
		successStories.trigger('owl.next');
	});
	$(".navigation .left").click(function(e){
		e.preventDefault();
		successStories.trigger('owl.prev');
	});
}( jQuery ));<commit_msg>footers dont always exist, eh?<commit_after>var isMobile = {
    Android   : function () {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function () {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS       : function () {
        return navigator.userAgent.match(/iPhone|iPod|iPad/i);
    },
    Opera     : function () {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows   : function () {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any       : function () {
        return (
            isMobile.Android() ||
                isMobile.BlackBerry() ||
                isMobile.iOS() ||
                isMobile.Opera() ||
                isMobile.Windows() );
    }
};
var popupCenter = function(url, title, w, h) {
	// Fixes dual-screen position                         Most browsers      Firefox
	var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
	var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;

	var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
	var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

	var left = ((width / 2) - (w / 2)) + dualScreenLeft;
	var top = ((height / 3) - (h / 3)) + dualScreenTop;

	var newWindow = window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);

	// Puts focus on the newWindow
	if (window.focus) {
		newWindow.focus();
	}
};

/** For mobile friendliness, use touchstart for mobile devices, and click events for desktops**/
var handleClick = (isMobile.any() !== null) ? "touchstart" : "click";
//var functions = '';
$ = jQuery;
var functions = {
	offsetHeader: 0,
	debug: true,
	log: function(){
		var _args = Array.prototype.slice.call(arguments);
		if(this.debug){
			if (typeof console !== "undefined" || typeof console.log !== "undefined") {
				console.log(_args);
			}
		}
	},
	pushUpdate: function(){
		var _footer = $('.main-footer'),
			_bottomPush = $('.bottom-push'),
			_site = $('body > .site'),
			_offset = _footer.outerHeight();
		if(_offset !== null){
			_bottomPush.css('height', _offset);
			_site.attr('style','margin-bottom:-'+_offset+'px');
		}
	},
	getWindowWidth  : function () {
		return window.outerWidth;
	},
	pageScroll: function(_tag){
		var totalScroll = $(_tag).offset().top-functions.offsetHeader;
		setTimeout(function(){
			$('html,body').scrollTo(totalScroll, 500 );
		}, 100)
	},
	emailReplace: function(){
		/** Use JavaScript to replace <a> with a mail link, to reduce potential spam**/
		var _varPre = "mailto:",
			_varMid = '',
			_varEnd = '',
			_varText = '',
			_selector = ".js-replacer-text";

		if ($(_selector).length > 0) {
			$(_selector).each(function(){
				var _modifyText = $(this).data('modify');
				_varEnd = $(this).data('domain');
				_varMid = $(this).data('extra');
				_varText = $(this).data('text');
				$(this).attr('href', _varPre + _varMid + '@' + _varEnd);
				if(typeof _modifyText == 'boolean' && _modifyText != true){

				}else{
					if(typeof _varText !== 'undefined'){
						$(this).text(_varText);
					}else{
						$(this).text(_varMid + '@' + _varEnd);
					}
				}
			});
		}
	},
	windowResize: function(name, callback, vars){
		clearTimeout($.data(this, name));
		$.data(this, name, setTimeout(function() {
			if(typeof vars === 'string' || typeof vars == 'object'){
				callback(vars);
			}else{
				callback();
			}
		}, 100));
	},
	matchHeight :function(_tag){
		var _arrHeight = [],
			_elHeight = 0;

		$(_tag).each(function () {
			_arrHeight.push($(this).outerHeight());
		});
		_elHeight = Math.max.apply(Math,_arrHeight);

		if(functions.getWindowWidth() > 767){
			$(_tag).each(function () {
				$(this).stop(false,false).animate({
						'min-height': _elHeight+"px"
					}, 200, false
				);
			});
		}else{
			$(_tag).each(function () {
				$(this).stop(false,false).animate({
						'min-height': '0px'
					}, 200, false
				);
			});
		}
	},
	videoResize: function(){
		if ($(".js-video-resize:visible").length > 0) {
			$(".js-video-resize:visible").each(function () {

				var _this = $(this);
				var iFrameID = _this.find('iframe').attr('id');
				var $video = '';
				var ratioHeight = 0;
				var ratioWidth = 0;
				var vidWidth = 0;
				var vidHeight = 0;

				$video = $("#"+iFrameID);
				vidWidth = _this.outerWidth();
				ratioWidth = $video.attr('data-vidWidth');
				ratioHeight = $video.attr('data-vidHeight');
				vidHeight = ((vidWidth*ratioHeight) / ratioWidth);
				$video.css('display', 'block');
				$video.animate({height: vidHeight}, 100);
				//webLog.log({vid: _this, vidID: iFrameID, vW: vidWidth, vH: vidHeight, rW: ratioWidth, rH: ratioHeight});
			});
		}

	}

};

(function ( $ ) {
	$.this = 'undefined';
	$(window).resize(function() {
		functions.windowResize('video', functions.videoResize);
		functions.windowResize('pushUpdate', functions.pushUpdate);
		//functions.windowResize('headerScroll', functions.headerScroll);
	});

	$(document).ready(function () {
		functions.videoResize();
		functions.emailReplace();
		functions.pushUpdate();
		//functions.headerScroll();

	});

	$(document).on(handleClick, '.js-scroll-find', function (e) {
		e.preventDefault();
		//functions.scrollFind($(this), e);
	});

	/** Page Logic **/
	var successStories = $(".js-success-stories");
	successStories.owlCarousel({
		items : 1,
		singleItem : true,
		navigation: false,
		pagination: false,
		//navigationText : ["Previous", "Next"],
		responsiveRefreshRate : 100,
		mouseDrag: false,
		afterAction: function(){
			setTimeout(functions.videoResize(), 300);
		}

	});

	$(".navigation .right").click(function(e){
		e.preventDefault();
		successStories.trigger('owl.next');
	});
	$(".navigation .left").click(function(e){
		e.preventDefault();
		successStories.trigger('owl.prev');
	});
}( jQuery ));<|endoftext|>


<commit_before>/*!
  jQuery Wookmark plugin 0.5
  @name jquery.wookmark.js
  @author Christoph Ono (chri@sto.ph or @gbks)
  @version 0.5
  @date 3/19/2012
  @category jQuery plugin
  @copyright (c) 2009-2012 Christoph Ono (www.wookmark.com)
  @license Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*/
$.fn.wookmark = function(options) {

  if(!this.wookmarkOptions) {
    this.wookmarkOptions = $.extend( {
        container: $('body'),
        offset: 2,
        autoResize: false,
        itemWidth: $(this[0]).outerWidth(),
        resizeDelay: 50
      }, options);
  } else if(options) {
    this.wookmarkOptions = $.extend(this.wookmarkOptions, options);
  }

  // Layout variables.
  if(!this.wookmarkColumns) {
    this.wookmarkColumns = null;
    this.wookmarkContainerWidth = null;
  }

  // Main layout function.
  this.wookmarkLayout = function() {
    // Calculate basic layout parameters.
    var columnWidth = this.wookmarkOptions.itemWidth + this.wookmarkOptions.offset;
    var containerWidth = this.wookmarkOptions.container.width();
    var columns = Math.floor((containerWidth+this.wookmarkOptions.offset)/columnWidth);
    var offset = Math.round((containerWidth - (columns*columnWidth-this.wookmarkOptions.offset))/2);

    // If container and column count hasn't changed, we can only update the columns.
    var bottom = 0;
    if(this.wookmarkColumns != null && this.wookmarkColumns.length == columns) {
      bottom = this.wookmarkLayoutColumns(columnWidth, offset);
    } else {
      bottom = this.wookmarkLayoutFull(columnWidth, columns, offset);
    }

    // Set container height to height of the grid.
    this.wookmarkOptions.container.css('height', bottom+'px');
  };

  /**
   * Perform a full layout update.
   */
  this.wookmarkLayoutFull = function(columnWidth, columns, offset) {
    // Prepare Array to store height of columns.
    var heights = [];
    while(heights.length < columns) {
      heights.push(0);
    }

    // Store column data.
    this.wookmarkColumns = [];
    while(this.wookmarkColumns.length < columns) {
      this.wookmarkColumns.push([]);
    }

    // Loop over items.
    var item, top, left, i=0, k=0, length=this.length, shortest=null, shortestIndex=null, bottom = 0;
    for(; i<length; i++ ) {
      item = $(this[i]);

      // Find the shortest column.
      shortest = null;
      shortestIndex = 0;
      for(k=0; k<columns; k++) {
        if(shortest == null || heights[k] < shortest) {
          shortest = heights[k];
          shortestIndex = k;
        }
      }

      // Postion the item.
      item.css({
        position: 'absolute',
        top: shortest+'px',
        left: (shortestIndex*columnWidth + offset)+'px'
      });

      // Update column height.
      heights[shortestIndex] = shortest + item.outerHeight() + this.wookmarkOptions.offset;
      bottom = Math.max(bottom, heights[shortestIndex]);

      this.wookmarkColumns[shortestIndex].push(item);
    }

    return bottom;
  };

  /**
   * This layout function only updates the vertical position of the
   * existing column assignments.
   */
  this.wookmarkLayoutColumns = function(columnWidth, offset) {
    var heights = [];
    while(heights.length < this.wookmarkColumns.length) {
      heights.push(0);
    }

    var i=0, length = this.wookmarkColumns.length, column;
    var k=0, kLength, item;
    var bottom = 0;
    for(; i<length; i++) {
      column = this.wookmarkColumns[i];
      kLength = column.length;
      for(k=0; k<kLength; k++) {
        item = column[k];
        item.css({
          left: (i*columnWidth + offset)+'px',
          top: heights[i]+'px'
        });
        heights[i] += item.outerHeight() + this.wookmarkOptions.offset;

        bottom = Math.max(bottom, heights[i]);
      }
    }

    return bottom;
  };

  // Listen to resize event if requested.
  this.wookmarkResizeTimer = null;
  if(!this.wookmarkResizeMethod) {
    this.wookmarkResizeMethod = null;
  }
  if(this.wookmarkOptions.autoResize) {
    // This timer ensures that layout is not continuously called as window is being dragged.
    this.wookmarkOnResize = function(event) {
      if(this.wookmarkResizeTimer) {
        clearTimeout(this.wookmarkResizeTimer);
      }
      this.wookmarkResizeTimer = setTimeout($.proxy(this.wookmarkLayout, this), this.wookmarkOptions.resizeDelay)
    };

    // Bind event listener.
    if(!this.wookmarkResizeMethod) {
      this.wookmarkResizeMethod = $.proxy(this.wookmarkOnResize, this);
    }
    $(window).resize(this.wookmarkResizeMethod);
  };

  /**
   * Clear event listeners and time outs.
   */
  this.wookmarkClear = function() {
    if(this.wookmarkResizeTimer) {
      clearTimeout(this.wookmarkResizeTimer);
      this.wookmarkResizeTimer = null;
    }
    if(this.wookmarkResizeMethod) {
      $(window).unbind('resize', this.wookmarkResizeMethod);
    }
  };

  // Apply layout
  this.wookmarkLayout();

  // Display items (if hidden).
  this.show();
};
<commit_msg>Layout responds to change in first tile width.<commit_after>/*!
  jQuery Wookmark plugin 0.5
  @name jquery.wookmark.js
  @author Christoph Ono (chri@sto.ph or @gbks)
  @version 0.5
  @date 3/19/2012
  @category jQuery plugin
  @copyright (c) 2009-2012 Christoph Ono (www.wookmark.com)
  @license Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*/
$.fn.wookmark = function(options) {

  var widthSetter = $(this[0]);
  var getItemWidth = function(fixedWidth) {
    if(fixedWidth===undefined) {
      return widthSetter.outerWidth();
    } else {
      return fixedWidth;
    }
  }

  if(!this.wookmarkOptions) {
    this.wookmarkOptions = $.extend( {
        container: $('body'),
        offset: 2,
        autoResize: false,
        resizeDelay: 50
      }, options);
  } else if(options) {
    this.wookmarkOptions = $.extend(this.wookmarkOptions, options);
  }

  // Layout variables.
  if(!this.wookmarkColumns) {
    this.wookmarkColumns = null;
    this.wookmarkContainerWidth = null;
  }

  // Main layout function.
  this.wookmarkLayout = function() {
    // Calculate basic layout parameters.
    var columnWidth = getItemWidth(this.wookmarkOptions.itemWidth) + this.wookmarkOptions.offset;
    var containerWidth = this.wookmarkOptions.container.width();
    var columns = Math.floor((containerWidth+this.wookmarkOptions.offset)/columnWidth);
    var offset = Math.round((containerWidth - (columns*columnWidth-this.wookmarkOptions.offset))/2);

    // If container and column count hasn't changed, we can only update the columns.
    var bottom = 0;
    if(this.wookmarkColumns != null && this.wookmarkColumns.length == columns) {
      bottom = this.wookmarkLayoutColumns(columnWidth, offset);
    } else {
      bottom = this.wookmarkLayoutFull(columnWidth, columns, offset);
    }

    // Set container height to height of the grid.
    this.wookmarkOptions.container.css('height', bottom+'px');
  };

  /**
   * Perform a full layout update.
   */
  this.wookmarkLayoutFull = function(columnWidth, columns, offset) {
    // Prepare Array to store height of columns.
    var heights = [];
    while(heights.length < columns) {
      heights.push(0);
    }

    // Store column data.
    this.wookmarkColumns = [];
    while(this.wookmarkColumns.length < columns) {
      this.wookmarkColumns.push([]);
    }

    // Loop over items.
    var item, top, left, i=0, k=0, length=this.length, shortest=null, shortestIndex=null, bottom = 0;
    for(; i<length; i++ ) {
      item = $(this[i]);

      // Find the shortest column.
      shortest = null;
      shortestIndex = 0;
      for(k=0; k<columns; k++) {
        if(shortest == null || heights[k] < shortest) {
          shortest = heights[k];
          shortestIndex = k;
        }
      }

      // Postion the item.
      item.css({
        position: 'absolute',
        top: shortest+'px',
        left: (shortestIndex*columnWidth + offset)+'px'
      });

      // Update column height.
      heights[shortestIndex] = shortest + item.outerHeight() + this.wookmarkOptions.offset;
      bottom = Math.max(bottom, heights[shortestIndex]);

      this.wookmarkColumns[shortestIndex].push(item);
    }

    return bottom;
  };

  /**
   * This layout function only updates the vertical position of the
   * existing column assignments.
   */
  this.wookmarkLayoutColumns = function(columnWidth, offset) {
    var heights = [];
    while(heights.length < this.wookmarkColumns.length) {
      heights.push(0);
    }

    var i=0, length = this.wookmarkColumns.length, column;
    var k=0, kLength, item;
    var bottom = 0;
    for(; i<length; i++) {
      column = this.wookmarkColumns[i];
      kLength = column.length;
      for(k=0; k<kLength; k++) {
        item = column[k];
        item.css({
          left: (i*columnWidth + offset)+'px',
          top: heights[i]+'px'
        });
        heights[i] += item.outerHeight() + this.wookmarkOptions.offset;

        bottom = Math.max(bottom, heights[i]);
      }
    }

    return bottom;
  };

  // Listen to resize event if requested.
  this.wookmarkResizeTimer = null;
  if(!this.wookmarkResizeMethod) {
    this.wookmarkResizeMethod = null;
  }
  if(this.wookmarkOptions.autoResize) {
    // This timer ensures that layout is not continuously called as window is being dragged.
    this.wookmarkOnResize = function(event) {
      if(this.wookmarkResizeTimer) {
        clearTimeout(this.wookmarkResizeTimer);
      }
      this.wookmarkResizeTimer = setTimeout($.proxy(this.wookmarkLayout, this), this.wookmarkOptions.resizeDelay)
    };

    // Bind event listener.
    if(!this.wookmarkResizeMethod) {
      this.wookmarkResizeMethod = $.proxy(this.wookmarkOnResize, this);
    }
    $(window).resize(this.wookmarkResizeMethod);
  };

  /**
   * Clear event listeners and time outs.
   */
  this.wookmarkClear = function() {
    if(this.wookmarkResizeTimer) {
      clearTimeout(this.wookmarkResizeTimer);
      this.wookmarkResizeTimer = null;
    }
    if(this.wookmarkResizeMethod) {
      $(window).unbind('resize', this.wookmarkResizeMethod);
    }
  };

  // Apply layout
  this.wookmarkLayout();

  // Display items (if hidden).
  this.show();
};
<|endoftext|>


<commit_before>/*
 * This is a generalised search for torrent links.
 */

function showDownloadIcon() {
    var links = [];

    // Find any anchor links that mention torrents.
    $('a[href*=torrent], a:contains(torrent)').each(function(i) {
        if(this === undefined) {
            return false;
        }

        // Now check that the link contains either .torrent or download, get, etc...
        if(this.href.search(/\/(download|get)\//) > 0 || this.href.search(/\.torrent$/) > 0) {
            links.push(this);
        }
        return false;
    });

    // For all the found links, add the little download icon.
    var icon = chrome.extension.getURL('images/icons/16.png');
    var iconAdded = chrome.extension.getURL('images/icons/16_green.png');

    for(var i = 0; i < links.length; i++) {
        // Check we don't already have the icon.
        if($(links[i]).next('.deluge-icon').length > 0) {
          continue;
        }
        $(links[i]).after('');
    }

    // For all the new Deluge download links we need to send a message to the main
    // extension to perform the adding action (see background.html).
    $('.deluge-icon').live('click', function() {
        var link = this;

        chrome.extension.sendRequest({ msg: 'add_torrent_from_url', url: this.href},
        function(response) {
          if(response.msg == 'success') {
            $('img', link).attr('src', iconAdded);
          }
        });
        return false;
    });
}

chrome.extension.sendRequest({msg: 'enable_download_icon'}, function(response) {
    if(response == 'true') {
        showDownloadIcon();
    }
});<commit_msg>Fixed adding icons to torrent links<commit_after>/*
 * This is a generalised search for torrent links.
 */

function showDownloadIcon() {
    var links = [];

    // Find any anchor links that mention torrents.
    $('a[href*=torrent], a:contains(torrent)').each(function(i) {
        if(this === undefined) {
            return false;
        }

        // Now check that the link contains either .torrent or download, get, etc...
        if(this.href.search(/\/(download|get)\//) > 0 || this.href.search(/\.torrent$/) > 0) {
            links.push(this);
        }
    });

    // For all the found links, add the little download icon.
    var icon = chrome.extension.getURL('images/icons/16.png');
    var iconAdded = chrome.extension.getURL('images/icons/16_green.png');

    for(var i = 0; i < links.length; i++) {
        // Check we don't already have the icon.
        if($(links[i]).next('.deluge-icon').length > 0) {
            continue;
        }
        $(links[i]).after('');
    }

    // For all the new Deluge download links we need to send a message to the main
    // extension to perform the adding action (see background.html).
    $('.deluge-icon').live('click', function() {
        var link = this;

        chrome.extension.sendRequest({ msg: 'add_torrent_from_url', url: this.href},
        function(response) {
            if(response.msg == 'success') {
              $('img', link).attr('src', iconAdded);
            }
        });
        return false;
    });
}

chrome.extension.sendRequest({msg: 'enable_download_icon'}, function(response) {
    if(response == 'true') {
        showDownloadIcon();
    }
});<|endoftext|>


<commit_before>var forEachAsync = require('forEachAsync').forEachAsync;
var Show = require('./Show');
var Schedule = {};

Schedule.getSchedule = function(client, cb) {

  var schedule = new Array(168);
  forEachAsync(schedule, function(next, e, i, arr) {
    Schedule.getShowAtTime(client, i, function(err, show) {
      if (err) return cb(err);

      schedule[i] = {timeslot: i};
      if (show !== null) {
        schedule[i]['show'] = show;
      } else {
        schedule[i]['show'] = 'automator';
      }

      next();
    });
  }).then(function() {
    cb(null, schedule);
  })
}

Schedule.deleteSchedule = function(client, cb) {
  var query = client.query("DELETE FROM schedule");
  query.on('error', function(err) {
    cb(err);
    })
    .on('row', function(row, result) {
    result.addRow(row);
    })
    .on('end', function(result) {
      cb(null, result.rowCount);
  });
}

Schedule.getShowAtTime = function(client, timeslot, cb) {
  var values = [timeslot];
  var query = "SELECT * FROM schedule WHERE timeslot = $1";
  client.query(query, values, function(err, result) {
    if (err) {
      cb(err);
    } else {

      if (result.rows[0]) {
        Show.getShowById(client, result.rows[0].show_id, function(err, show) {
          if (err) return cb(err);
          cb(null, show[0]);
        });
      } else {
        cb(null, null);
      }

    }
  });
}

Schedule.getUpcoming = function(client, current_timeslot, numShows, cb) {
  Schedule.getSchedule(client, function(err, sched) {
    if (err) return cb(err);

    var shows = [];
    var next_slot = current_timeslot + 7;
    var count = 0;

    while (shows.length < numShows) {
      if (count >= 167) return cb(null, shows);

      if (sched[next_slot].show !== 'automator') shows.push(sched[next_slot]);

      //  loop back to the next day if the counter gets within 7 of max
      if (next_slot >= 160) {
        next_slot = (current_timeslot % 7) + 1
      } else {
        next_slot += 7;
      }

      count++;
    }
    return cb(null, shows);
  });
}

Schedule.scheduleShow = function(client, show, cb) {
  var values = [show.timeslot, show.show_id];
  var query = "INSERT INTO schedule(timeslot, show_id) \
                VALUES($1, $2 ) RETURNING *";
  client.query(query, values, function(err, result) {
    if (err) {
      cb(err);
    } else {
      cb(null, result.rows);
    }
  });
}

Schedule.deleteShowAtTime = function(client, timeslot, cb) {
  var qStr = "DELETE FROM schedule WHERE timeslot = $1";
  client.query(qStr, [timeslot], function(err, result) {
    if (err) {
      return cb(err);
    } else {
      cb(null, result.rowCount);
    }
  });
}

module.exports = Schedule;
<commit_msg>fix getUpcoming looping logic<commit_after>var forEachAsync = require('forEachAsync').forEachAsync;
var Show = require('./Show');
var Schedule = {};

Schedule.getSchedule = function(client, cb) {

  var schedule = new Array(168);
  forEachAsync(schedule, function(next, e, i, arr) {
    Schedule.getShowAtTime(client, i, function(err, show) {
      if (err) return cb(err);

      schedule[i] = {timeslot: i};
      if (show !== null) {
        schedule[i]['show'] = show;
      } else {
        schedule[i]['show'] = 'automator';
      }

      next();
    });
  }).then(function() {
    cb(null, schedule);
  })
}

Schedule.deleteSchedule = function(client, cb) {
  var query = client.query("DELETE FROM schedule");
  query.on('error', function(err) {
    cb(err);
    })
    .on('row', function(row, result) {
    result.addRow(row);
    })
    .on('end', function(result) {
      cb(null, result.rowCount);
  });
}

Schedule.getShowAtTime = function(client, timeslot, cb) {
  var values = [timeslot];
  var query = "SELECT * FROM schedule WHERE timeslot = $1";
  client.query(query, values, function(err, result) {
    if (err) {
      cb(err);
    } else {

      if (result.rows[0]) {
        Show.getShowById(client, result.rows[0].show_id, function(err, show) {
          if (err) return cb(err);
          cb(null, show[0]);
        });
      } else {
        cb(null, null);
      }

    }
  });
}

Schedule.getUpcoming = function(client, current_timeslot, numShows, cb) {
  Schedule.getSchedule(client, function(err, sched) {
    if (err) return cb(err);

    var shows = [];
    var next_slot = current_timeslot + 7;
    var count = 0;

    while (shows.length < numShows) {
      if (count >= 167) return cb(null, shows);

      //  loop back to the next day if the counter gets within 7 of max
      if (next_slot >= 160) {
        next_slot = (current_timeslot % 7) + 1
      } else {
        next_slot += 7;
      }

      if (sched[next_slot].show !== 'automator') shows.push(sched[next_slot]);

      count++;
    }
    return cb(null, shows);
  });
}

Schedule.scheduleShow = function(client, show, cb) {
  var values = [show.timeslot, show.show_id];
  var query = "INSERT INTO schedule(timeslot, show_id) \
                VALUES($1, $2 ) RETURNING *";
  client.query(query, values, function(err, result) {
    if (err) {
      cb(err);
    } else {
      cb(null, result.rows);
    }
  });
}

Schedule.deleteShowAtTime = function(client, timeslot, cb) {
  var qStr = "DELETE FROM schedule WHERE timeslot = $1";
  client.query(qStr, [timeslot], function(err, result) {
    if (err) {
      return cb(err);
    } else {
      cb(null, result.rowCount);
    }
  });
}

module.exports = Schedule;
<|endoftext|>


<commit_before>var should   = require('should'),
    assert   = require('assert'),
    request  = require('supertest'),
    mongoose = require('mongoose'),
    app      = require('./../app.js'),
    apimodel = require('./../model');

describe('API routing', function() {

  before(function(done) {
    mongoose.connect('mongodb://localhost/boycott_db');
    done();
  });

  after(function(done) {
    mongoose.disconnect();
    done();
  });

  describe('GET /api/venues', function() {
    beforeEach(function (done) {
      apimodel.venue.create({
        name: "Starbucks",
        foursquare_id: "16172612681726",
        latitude: 12.123124,
        longitude: 24.2312312,
        agree_count: 0,
        disagree_count: 1
      }, function (res) {
        done();
      });
    });

    afterEach(function (done) {
      apimodel.venue.remove({}, function () {
        done();
      });
    });

    it('should respond with JSON', function (done) {
      request(app)
        .get('/api/venues')
        .set('Accept', 'application/json')
        .expect('Content-Type', /json/)
        .expect(200, done);
    });

    it('should return one venue', function(done) {
      request(app)
        .get('/api/venues')
        .end(function(err, res) {
          if (err) {
            throw err;
          }

          res.body.should.have.lengthOf(1);
          done();
        });
    });

    it('should not return two venues', function(done) {
      request(app)
        .get('/api/venues')
        .end(function(err, res) {
          if (err) {
            throw err;
          }

          res.body.should.not.have.lengthOf(2);
          done();
        });
    });
  });

  describe('POST /api/venues/add', function() {
    beforeEach(function (done) {
      apimodel.venue.create({
        name: "Starbucks",
        foursquare_id: "16172612681726",
        latitude: 12.123124,
        longitude: 24.2312312,
        agree_count: 0,
        disagree_count: 1
      }, function (res) {
        done();
      });
    });

    afterEach(function (done) {
      apimodel.venue.remove({}, function () {
        done();
      });
    });

    it('should respond with JSON', function (done) {
      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send({
          name: "Starbucks",
          foursquare_id: "16172612681721",
          latitude: 12.123124,
          longitude: 24.2312312,
          agree_count: 0,
          disagree_count: 1
        })
        .expect('Content-Type', /json/)
        .expect(200, done);
    });

    it('should respond with venue keys', function (done) {
      var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681720",
        latitude: 12.123124,
        longitude: 24.2312312
      };

      var keys = ['name', 'foursquare_id', 'latitude', 'longitude', 'approve_count', 'veto_count', 'id'];

      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send(testVenue)
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.should.have.keys(keys);
          done();
        });
    });

    it('should respond with the same values', function (done) {
      var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681720",
        latitude: 12.123124,
        longitude: 24.2312312
      };

      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send(testVenue)
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.name.should.eql(testVenue.name);
          res.body.foursquare_id.should.eql(testVenue.foursquare_id);
          res.body.latitude.should.eql(testVenue.latitude);
          res.body.longitude.should.eql(testVenue.longitude);

          done();
        });
    });

    it('should respond with approve and veto counts set to zero', function (done) {
      var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681720",
        latitude: 12.123124,
        longitude: 24.2312312
      };

      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send(testVenue)
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.approve_count.should.eql(0);
          res.body.veto_count.should.eql(0);

          done();
        });
    });

    it('should not allow duplicate foursquare ids', function (done) {
      var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681726",
        latitude: 12.123124,
        longitude: 24.2312312
      };

      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send(testVenue)
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.should.have.keys(['code', 'msg']);
          done();
        });
    });
  });
});<commit_msg>added test cases for /api/venue/:id<commit_after>var should   = require('should'),
    assert   = require('assert'),
    request  = require('supertest'),
    mongoose = require('mongoose'),
    app      = require('./../app.js'),
    apimodel = require('./../model');

describe('API routing', function() {

  before(function(done) {
    mongoose.connect('mongodb://localhost/boycott_db');
    done();
  });

  after(function(done) {
    mongoose.disconnect();
    done();
  });

  describe('GET /api/venues', function() {
    beforeEach(function (done) {
      apimodel.venue.create({
        name: "Starbucks",
        foursquare_id: "16172612681726",
        latitude: 12.123124,
        longitude: 24.2312312,
        agree_count: 0,
        disagree_count: 1
      }, function (err) {
        done();
      });
    });

    afterEach(function (done) {
      apimodel.venue.remove({}, function () {
        done();
      });
    });

    it('should respond with JSON', function (done) {
      request(app)
        .get('/api/venues')
        .set('Accept', 'application/json')
        .expect('Content-Type', /json/)
        .expect(200, done);
    });

    it('should return one venue', function(done) {
      request(app)
        .get('/api/venues')
        .end(function(err, res) {
          if (err) {
            throw err;
          }

          res.body.should.have.lengthOf(1);
          done();
        });
    });

    it('should not return two venues', function(done) {
      request(app)
        .get('/api/venues')
        .end(function(err, res) {
          if (err) {
            throw err;
          }

          res.body.should.not.have.lengthOf(2);
          done();
        });
    });
  });

  describe('POST /api/venues/add', function() {
    beforeEach(function (done) {
      apimodel.venue.create({
        name: "Starbucks",
        foursquare_id: "16172612681726",
        latitude: 12.123124,
        longitude: 24.2312312,
        agree_count: 0,
        disagree_count: 1
      }, function (err) {
        done();
      });
    });

    afterEach(function (done) {
      apimodel.venue.remove({}, function () {
        done();
      });
    });

    it('should respond with JSON', function (done) {
      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send({
          name: "Starbucks",
          foursquare_id: "16172612681721",
          latitude: 12.123124,
          longitude: 24.2312312,
          agree_count: 0,
          disagree_count: 1
        })
        .expect('Content-Type', /json/)
        .expect(200, done);
    });

    it('should respond with venue keys', function (done) {
      var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681720",
        latitude: 12.123124,
        longitude: 24.2312312
      };

      var keys = ['name', 'foursquare_id', 'latitude', 'longitude', 'approve_count', 'veto_count', 'id'];

      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send(testVenue)
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.should.have.keys(keys);
          done();
        });
    });

    it('should respond with the same values', function (done) {
      var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681720",
        latitude: 12.123124,
        longitude: 24.2312312
      };

      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send(testVenue)
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.name.should.eql(testVenue.name);
          res.body.foursquare_id.should.eql(testVenue.foursquare_id);
          res.body.latitude.should.eql(testVenue.latitude);
          res.body.longitude.should.eql(testVenue.longitude);

          done();
        });
    });

    it('should respond with approve and veto counts set to zero', function (done) {
      var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681720",
        latitude: 12.123124,
        longitude: 24.2312312
      };

      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send(testVenue)
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.approve_count.should.eql(0);
          res.body.veto_count.should.eql(0);

          done();
        });
    });

    it('should not allow duplicate foursquare ids', function (done) {
      var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681726",
        latitude: 12.123124,
        longitude: 24.2312312
      };

      request(app)
        .post('/api/venues/add')
        .set('Accept', 'application/json').
        send(testVenue)
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.should.have.keys(['code', 'msg']);
          done();
        });
    });
  });

  describe("GET /api/venues/:id", function () {
    var venue_id;
    var testVenue = {
        name: "Starbucks",
        foursquare_id: "16172612681726",
        latitude: 12.123124,
        longitude: 24.2312312,
        agree_count: 0,
        disagree_count: 1
    };

    beforeEach(function (done) {
      apimodel.venue.create(testVenue, function (err, res) {
        venue_id = res.id;
        done();
      });
    });

    afterEach(function (done) {
      apimodel.venue.remove({}, function () {
        done();
      });
    });

    it('should return object with requested id', function (done) {
       request(app)
        .get('/api/venues/' + venue_id)
        .set('Accept', 'application/json')
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.id.should.eql(venue_id);
          done();
        });
    });

    it('should return the correct venue', function (done) {
       request(app)
        .get('/api/venues/' + venue_id)
        .set('Accept', 'application/json')
        .end(function (err, res) {
           if (err) {
            throw err;
          }

          res.body.name.should.eql(testVenue.name);
          res.body.foursquare_id.should.eql(testVenue.foursquare_id);
          res.body.latitude.should.eql(testVenue.latitude);
          res.body.longitude.should.eql(testVenue.longitude);

          done();
        });
    });

    it('should return 404 for nonexistent venue', function (done) {
       request(app)
        .get('/api/venues/51eb16bd4412f6680a000009')
        .set('Accept', 'application/json')
        .expect(404, done);
    });

    it('should return 404 for improper id for venue', function (done) {
       request(app)
        .get('/api/venues/2312312312')
        .set('Accept', 'application/json')
        .expect(404, done);
    });
  });
});<|endoftext|>