<commit_before>document.addEventListener("DOMContentLoaded", function (event) {

    $('#submit-acceptance').click(function () {
        var t_id = $('#request-id').attr('request-id');
        var data = {
            id: t_id,
            _csrf: $('#csrf_token').val(),
            message: $('#text-input').val(),
        };
        $.ajax({
            url: '/acceptRequest',
            method: 'POST',
            data: data,
        }).done(function (data) {
            var request_info = $('[data-id="' + t_id + '"]');
            $('[data-id="' + t_id + '"]').hide('slide', {direction: 'right'}, 1000, function () {
                // 'Move' the request info box from the proposed column to the upcoming
                // column and change CSS classes so the right divs get hidden/shown
                $(request_info).removeClass($(request_info).attr('data-status'));
                $(request_info).addClass(data.status);
                $(request_info).attr('data-status', data.status);
                $($('.transaction-table')[1]).append(request_info);
                $($('.transaction-table')[1]).find('.request-info').show();
                // Force a click to go to the 'Upcoming' tab
                ($('.exchange-type')[1]).click();
                load_scheduling_section(request_info);
                maps_loaded[t_id] = true;
            });
        });
        $('#acceptModal').modal('hide');

        return false;
    });

    $('.chat').click( function () {
        var request_info = $(this).closest('.request-info');
        $(request_info).addClass('message-mode');
    });

    $('.back-button').click( function () {
        var request_info = $(this).closest('.request-info');
        $(request_info).removeClass('message-mode');
    });

    $('.reject').click( function () {
        $(this).closest('.request-info').hide('slide',{direction:'right'},1000);
        $.ajax({
            url: '/rejectRequest/' + $(this).closest('.request-info').data('id'),
            method: 'GET',
        }).done(function (data) {
            console.log(data);
        });
    });

    $('.cancel').click( function () {
        $(this).closest('.request-info').hide('slide',{direction:'right'},1000);
        $.ajax({
            url: '/cancelRequest/' + $(this).closest('.request-info').data('id'),
            method: 'GET',
        }).done(function (data) {
            console.log(data);
        });
    });

    function newChatBubble (message) {
        var klass = message.author.isMe ? 'myself' : 'other-person';
        var chat = '
'.replace('{who}', klass) +
                        '
{comment}
'.replace('{comment}', message.message) +
                        '
{author}
'.replace('{author}', message.author.name) +
                    '
';
        return chat;
    }

    function serializeDate (date) {
        return date.getHours() + ':' + ('0'+ date.getMinutes()).slice(-2);
    }

    var socket = io();
    $('.message-form').submit(function () {
        var message_text = $(this).find('.text-input').val();
        if (!message_text) {
            return false;
        }
        var packet = {
            message: message_text,
            t_id: $(this).closest('.request-info').data('id'),
        };

        socket.emit('send message', packet);
        $('.text-input').val('');

        return false;
    });

    socket.on('new message', function (data) {
        var match = $('.transaction-table').find('[data-id="' + data.transaction._id + '"]');
        // If its a message for an existing transaction, and that transaction has conversation
        // div already set up, then append it.
        if (match.length > 0 && $(match[0]).find('.conversation').length > 0) {
            var request = match[0];

            // If its a message for the current thread, make a new chat bubble and append it
            // otherwise just set that thread to be 'pending'
            var new_element = newChatBubble(data);
            $(request).find('.conversation').append(new_element);
            $(request).find('.conversation').scrollTop($(request).find('.conversation')[0].scrollHeight);

            return;
        } else {
            console.log("Couldn't find transaction with id " + data.transaction._id);
        }
    });

    function createReview (data) {
        var rating = '';
        for (var i = 0; i < data.rating; i++) {
            rating += '★';
        }
        var review = '
' +
                        '
' +
                            rating +
                        '
' +
                        '<time class="review-timestamp">' +
                            data.timestamp +
                        '</time>' +
                        '<quote>' +
                            data.text +
                        '</quote>' +
                     '
';
        return review;
    }

    var maps_loaded = {};
    var chosen_places = {};

    function load_map (request_info) {
        var map = new google.maps.Map($(request_info).find('.map-canvas')[0], {
            mapTypeControl: false,
            panControl: true,
            zoomControl: true,
            streetViewControl: false,
        });

        var center = {lat: 52.5200, lng: 13.4050}; // Berlin
        var zoom = 10;
        var lat = Number($(request_info).attr('data-lat'));
        var lng = Number($(request_info).attr('data-lng'));

        if (lat && lng) {
            center = {lat: lat, lng: lng};
            zoom = 15;
            let pin = new google.maps.Marker({
                position: center,
                map: map,
            });
        }
        map.setCenter(center);
        map.setZoom(zoom);

        var input = $(request_info).find('.pac-input')[0];
        var autocomplete = new google.maps.places.Autocomplete(input, {
            componentRestrictions: {'country': 'de'},
        });
        autocomplete.addListener('place_changed', function () {
            var place = autocomplete.getPlace();
            if (place.geometry) {
                chosen_places[request_id] = {
                    latitude: place.geometry.location.lat(),
                    longitude: place.geometry.location.lng(),
                    name: place.name,
                }
                map.panTo(place.geometry.location);
                map.setZoom(15);
                let marker = new google.maps.Marker({
                    position: place.geometry.location,
                    animation: google.maps.Animation.DROP,
                });
                marker.setMap(map);
            }
        });
        var center = map.getCenter();
        google.maps.event.trigger(map, "resize");
        map.setCenter(center);
    }

    function load_scheduling_section (request_info) {
        var request_id = $(request_info).attr('data-id');
        $(request_info).find('.datetimepicker').datetimepicker();

        var moment_date = moment($(request_info).find('.datetimepicker').attr('data-value'), 'x');
        $(request_info).find('.datetimepicker').data("DateTimePicker").date(moment_date);

        if (maps_loaded[request_id]) {
            return;
        }

        load_map(request_info);
        maps_loaded[request_id] = true;
    }

    $('.action-section').on('shown.bs.collapse', function () {
        var request_info = $(this).closest('.request-info');
        if ($(request_info).attr('data-status').indexOf('accepted') >= 0) {
            load_scheduling_section(request_info);
            // FIgure out how to know if curr user hasn't confirmed it
        } else if ($(request_info).attr('data-status').indexOf('complete') >= 0) {
            $.ajax({
                url: '/_transactionReviews/' + $(request_info).data('id'),
            }).done(function (response) {
                var notice = '';
                if (response.curr_user_has_review == false) {
                    var review_button = '<button class="btn btn-success" data-toggle="modal" data-target="#reviewModal">' +
                                            'Write Review' +
                                        '</button>';
                    notice = '
' +
                                    'Please write a review for this exchange. ' +
                                    'You won\'t be able to see your partner\'s review until you write one' +
                                 '
';
                    $(request_info).find('.notice').html(notice + review_button);
                } else if (response.partner_has_review == false) {
                    notice = '
' +
                                'Thank you for submitting a review. ' +
                                'As soon as your partner submits one, you\'ll be able to see it!' +
                             '
';
                    $(request_info).find('.notice').html(notice);
                } else {
                    $(request_info).find('.reviews').html(createReview(response.review));
                }
            });
        }
    });

    $('#acceptModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget); // Button that triggered the modal
        var id = button.closest('.request-info').data('id');
        var skill_label = button.closest('.request-info').find('.content .skill-label').html();
        var modal = $(this);
        modal.find('.modal-body #request-id').attr('request-id', id);
        modal.find('.modal-body .statement').html('Get ready for ' + skill_label);
    });

    $('#submit-review').click(function () {
        var rating = 1;
        $('.rating span').each(function (i, obj) {
            if ($(obj).hasClass('selected')) {
                rating = 5 - i;
            }
        });
        var data = {
            t_id: $('#transaction-id').attr('transaction-id'),
            _csrf: $('#review-csrf_token').val(),
            message: $('#review-text-input').val(),
            rating: rating
        };
        $.ajax({
            url: '/submitReview',
            method: 'POST',
            data: data,
        }).done(function (response) {
            console.log(response);
        });
        $('#reviewModal').modal('hide');
        return false;
    });

    $('.rating span').click(function () {
        $('.rating span').removeClass('selected');
        $(this).addClass('selected');
    });

    function confirmExchange (t_id) {
        $.ajax({
            url: '/confirmExchange/' + t_id,
            method: 'GET',
        }).done(function (data) {
            var request_info = $('[data-id="' + t_id + '"]');
            var old_status = $(request_info).attr('data-status');

            // If it's accepted, that means it was in the upcoming column, so we
            // should slide it out of view. Maybe change this to instead check the
            // actual column that it is in instead of using status proxy
            if (old_status == 'accepted') {
                $('[data-id="' + t_id + '"]').hide('slide', {direction: 'right'}, 1000, function () {
                    $(request_info).removeClass(old_status);
                    $(request_info).addClass(data.status);
                    $(request_info).attr('data-status', data.status);
                    $($('.transaction-table')[2]).append(request_info);
                    $($('.transaction-table')[2]).find('.request-info').show();
                });
            } else {
                $(request_info).removeClass(old_status);
                $(request_info).addClass(data.status);
                $(request_info).attr('data-status', data.status);
            }
        });
    }

    $('#reviewModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget) // Button that triggered the modal
        var request = button.closest('.request-info');
        var id = request.data('id');
        var status = request.attr('data-status');

        if (status != 'complete') {
            confirmExchange(id);
        }

        var skill_label = button.closest('.request-info').find('.content .skill-label').html();
        var modal = $(this);
        modal.find('.modal-body #transaction-id').attr('transaction-id', id);
        modal.find('.modal-body #review-activity').val(skill_label);
    });

    $('.exchange-type').click(function () {
        $('.exchange-type').removeClass('selected');
        $(this).addClass('selected');
        var index = $('.exchange-type').index($(this));
        $('.transaction-table').hide();
        $('.transaction-table').eq(index).fadeIn();
    });

    $('.suggest').click(function () {
        var request = $(this).closest('.request-info');
        var request_id = $(request).attr('data-id');

        var location = chosen_places[request_id];
        var picker = $(request).find('.datetimepicker');
        var date = $(picker).data("DateTimePicker").date();

        var data = {
            id: request_id,
            _csrf: $('#csrf_token').val(),
            location: location,
            date: date.valueOf(),
        };
        $.ajax({
            url: '/schedule',
            method: 'POST',
            data: data,
        }).done(function (data) {
            console.log(data)
        });
    });
});
<commit_msg>Declare missing id variable<commit_after>document.addEventListener("DOMContentLoaded", function (event) {

    $('#submit-acceptance').click(function () {
        var t_id = $('#request-id').attr('request-id');
        var data = {
            id: t_id,
            _csrf: $('#csrf_token').val(),
            message: $('#text-input').val(),
        };
        $.ajax({
            url: '/acceptRequest',
            method: 'POST',
            data: data,
        }).done(function (data) {
            var request_info = $('[data-id="' + t_id + '"]');
            $('[data-id="' + t_id + '"]').hide('slide', {direction: 'right'}, 1000, function () {
                // 'Move' the request info box from the proposed column to the upcoming
                // column and change CSS classes so the right divs get hidden/shown
                $(request_info).removeClass($(request_info).attr('data-status'));
                $(request_info).addClass(data.status);
                $(request_info).attr('data-status', data.status);
                $($('.transaction-table')[1]).append(request_info);
                $($('.transaction-table')[1]).find('.request-info').show();
                // Force a click to go to the 'Upcoming' tab
                ($('.exchange-type')[1]).click();
                load_scheduling_section(request_info);
                maps_loaded[t_id] = true;
            });
        });
        $('#acceptModal').modal('hide');

        return false;
    });

    $('.chat').click( function () {
        var request_info = $(this).closest('.request-info');
        $(request_info).addClass('message-mode');
    });

    $('.back-button').click( function () {
        var request_info = $(this).closest('.request-info');
        $(request_info).removeClass('message-mode');
    });

    $('.reject').click( function () {
        $(this).closest('.request-info').hide('slide',{direction:'right'},1000);
        $.ajax({
            url: '/rejectRequest/' + $(this).closest('.request-info').data('id'),
            method: 'GET',
        }).done(function (data) {
            console.log(data);
        });
    });

    $('.cancel').click( function () {
        $(this).closest('.request-info').hide('slide',{direction:'right'},1000);
        $.ajax({
            url: '/cancelRequest/' + $(this).closest('.request-info').data('id'),
            method: 'GET',
        }).done(function (data) {
            console.log(data);
        });
    });

    function newChatBubble (message) {
        var klass = message.author.isMe ? 'myself' : 'other-person';
        var chat = '
'.replace('{who}', klass) +
                        '
{comment}
'.replace('{comment}', message.message) +
                        '
{author}
'.replace('{author}', message.author.name) +
                    '
';
        return chat;
    }

    function serializeDate (date) {
        return date.getHours() + ':' + ('0'+ date.getMinutes()).slice(-2);
    }

    var socket = io();
    $('.message-form').submit(function () {
        var message_text = $(this).find('.text-input').val();
        if (!message_text) {
            return false;
        }
        var packet = {
            message: message_text,
            t_id: $(this).closest('.request-info').data('id'),
        };

        socket.emit('send message', packet);
        $('.text-input').val('');

        return false;
    });

    socket.on('new message', function (data) {
        var match = $('.transaction-table').find('[data-id="' + data.transaction._id + '"]');
        // If its a message for an existing transaction, and that transaction has conversation
        // div already set up, then append it.
        if (match.length > 0 && $(match[0]).find('.conversation').length > 0) {
            var request = match[0];

            // If its a message for the current thread, make a new chat bubble and append it
            // otherwise just set that thread to be 'pending'
            var new_element = newChatBubble(data);
            $(request).find('.conversation').append(new_element);
            $(request).find('.conversation').scrollTop($(request).find('.conversation')[0].scrollHeight);

            return;
        } else {
            console.log("Couldn't find transaction with id " + data.transaction._id);
        }
    });

    function createReview (data) {
        var rating = '';
        for (var i = 0; i < data.rating; i++) {
            rating += '★';
        }
        var review = '
' +
                        '
' +
                            rating +
                        '
' +
                        '<time class="review-timestamp">' +
                            data.timestamp +
                        '</time>' +
                        '<quote>' +
                            data.text +
                        '</quote>' +
                     '
';
        return review;
    }

    var maps_loaded = {};
    var chosen_places = {};

    function load_map (request_info) {
        var request_id = $(request_info).attr('data-id');

        var map = new google.maps.Map($(request_info).find('.map-canvas')[0], {
            mapTypeControl: false,
            panControl: true,
            zoomControl: true,
            streetViewControl: false,
        });

        var center = {lat: 52.5200, lng: 13.4050}; // Berlin
        var zoom = 10;
        var lat = Number($(request_info).attr('data-lat'));
        var lng = Number($(request_info).attr('data-lng'));

        if (lat && lng) {
            center = {lat: lat, lng: lng};
            zoom = 15;
            let pin = new google.maps.Marker({
                position: center,
                map: map,
            });
        }
        map.setCenter(center);
        map.setZoom(zoom);

        var input = $(request_info).find('.pac-input')[0];
        var autocomplete = new google.maps.places.Autocomplete(input, {
            componentRestrictions: {'country': 'de'},
        });
        autocomplete.addListener('place_changed', function () {
            var place = autocomplete.getPlace();
            if (place.geometry) {
                chosen_places[request_id] = {
                    latitude: place.geometry.location.lat(),
                    longitude: place.geometry.location.lng(),
                    name: place.name,
                }
                map.panTo(place.geometry.location);
                map.setZoom(15);
                let marker = new google.maps.Marker({
                    position: place.geometry.location,
                    animation: google.maps.Animation.DROP,
                });
                marker.setMap(map);
            }
        });
        var center = map.getCenter();
        google.maps.event.trigger(map, "resize");
        map.setCenter(center);
    }

    function load_scheduling_section (request_info) {
        var request_id = $(request_info).attr('data-id');
        $(request_info).find('.datetimepicker').datetimepicker();

        var moment_date = moment($(request_info).find('.datetimepicker').attr('data-value'), 'x');
        $(request_info).find('.datetimepicker').data("DateTimePicker").date(moment_date);

        if (maps_loaded[request_id]) {
            return;
        }

        load_map(request_info);
        maps_loaded[request_id] = true;
    }

    $('.action-section').on('shown.bs.collapse', function () {
        var request_info = $(this).closest('.request-info');
        if ($(request_info).attr('data-status').indexOf('accepted') >= 0) {
            load_scheduling_section(request_info);
            // FIgure out how to know if curr user hasn't confirmed it
        } else if ($(request_info).attr('data-status').indexOf('complete') >= 0) {
            $.ajax({
                url: '/_transactionReviews/' + $(request_info).data('id'),
            }).done(function (response) {
                var notice = '';
                if (response.curr_user_has_review == false) {
                    var review_button = '<button class="btn btn-success" data-toggle="modal" data-target="#reviewModal">' +
                                            'Write Review' +
                                        '</button>';
                    notice = '
' +
                                    'Please write a review for this exchange. ' +
                                    'You won\'t be able to see your partner\'s review until you write one' +
                                 '
';
                    $(request_info).find('.notice').html(notice + review_button);
                } else if (response.partner_has_review == false) {
                    notice = '
' +
                                'Thank you for submitting a review. ' +
                                'As soon as your partner submits one, you\'ll be able to see it!' +
                             '
';
                    $(request_info).find('.notice').html(notice);
                } else {
                    $(request_info).find('.reviews').html(createReview(response.review));
                }
            });
        }
    });

    $('#acceptModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget); // Button that triggered the modal
        var id = button.closest('.request-info').data('id');
        var skill_label = button.closest('.request-info').find('.content .skill-label').html();
        var modal = $(this);
        modal.find('.modal-body #request-id').attr('request-id', id);
        modal.find('.modal-body .statement').html('Get ready for ' + skill_label);
    });

    $('#submit-review').click(function () {
        var rating = 1;
        $('.rating span').each(function (i, obj) {
            if ($(obj).hasClass('selected')) {
                rating = 5 - i;
            }
        });
        var data = {
            t_id: $('#transaction-id').attr('transaction-id'),
            _csrf: $('#review-csrf_token').val(),
            message: $('#review-text-input').val(),
            rating: rating
        };
        $.ajax({
            url: '/submitReview',
            method: 'POST',
            data: data,
        }).done(function (response) {
            console.log(response);
        });
        $('#reviewModal').modal('hide');
        return false;
    });

    $('.rating span').click(function () {
        $('.rating span').removeClass('selected');
        $(this).addClass('selected');
    });

    function confirmExchange (t_id) {
        $.ajax({
            url: '/confirmExchange/' + t_id,
            method: 'GET',
        }).done(function (data) {
            var request_info = $('[data-id="' + t_id + '"]');
            var old_status = $(request_info).attr('data-status');

            // If it's accepted, that means it was in the upcoming column, so we
            // should slide it out of view. Maybe change this to instead check the
            // actual column that it is in instead of using status proxy
            if (old_status == 'accepted') {
                $('[data-id="' + t_id + '"]').hide('slide', {direction: 'right'}, 1000, function () {
                    $(request_info).removeClass(old_status);
                    $(request_info).addClass(data.status);
                    $(request_info).attr('data-status', data.status);
                    $($('.transaction-table')[2]).append(request_info);
                    $($('.transaction-table')[2]).find('.request-info').show();
                });
            } else {
                $(request_info).removeClass(old_status);
                $(request_info).addClass(data.status);
                $(request_info).attr('data-status', data.status);
            }
        });
    }

    $('#reviewModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget) // Button that triggered the modal
        var request = button.closest('.request-info');
        var id = request.data('id');
        var status = request.attr('data-status');

        if (status != 'complete') {
            confirmExchange(id);
        }

        var skill_label = button.closest('.request-info').find('.content .skill-label').html();
        var modal = $(this);
        modal.find('.modal-body #transaction-id').attr('transaction-id', id);
        modal.find('.modal-body #review-activity').val(skill_label);
    });

    $('.exchange-type').click(function () {
        $('.exchange-type').removeClass('selected');
        $(this).addClass('selected');
        var index = $('.exchange-type').index($(this));
        $('.transaction-table').hide();
        $('.transaction-table').eq(index).fadeIn();
    });

    $('.suggest').click(function () {
        var request = $(this).closest('.request-info');
        var request_id = $(request).attr('data-id');

        var location = chosen_places[request_id];
        var picker = $(request).find('.datetimepicker');
        var date = $(picker).data("DateTimePicker").date();

        var data = {
            id: request_id,
            _csrf: $('#csrf_token').val(),
            location: location,
            date: date.valueOf(),
        };
        $.ajax({
            url: '/schedule',
            method: 'POST',
            data: data,
        }).done(function (data) {
            console.log(data)
        });
    });
});
<|endoftext|>


<commit_before>import { InsertInlineNodeCommand as SubstanceInsertInlineNodeCommand, documentHelpers } from 'substance'

export default class InsertInlineFormulaCommand extends SubstanceInsertInlineNodeCommand {
  getType () {
    return 'inline-formula'
  }

  createNode (tx) {
    const inlineFormula = tx.createElement('inline-formula')
      .attr('content-type', 'math/tex')
      .appendChild(
        tx.createElement('tex-math')
      )
    return inlineFormula
  }

  /**
    Insert new inline node at the current selection
  */
  execute (params) {
    const state = this.getCommandState(params)
    if (state.disabled) return
    const editorSession = this._getEditorSession(params)
    const sel = params.selection
    editorSession.transaction((tx) => {
      const doc = tx.getDocument()
      const text = documentHelpers.getTextForSelection(doc, sel)
      const node = tx.createElement('inline-formula')
        .attr('content-type', 'math/tex')
      const inlineFormula = tx.insertInlineNode(node)
      inlineFormula.appendChild(
        tx.createElement('tex-math').text(text)
      )
      this.setSelection(tx, node)
    })
  }

  setSelection (tx, node) {
    if (node.isPropertyAnnotation()) {
      tx.selection = {
        type: 'property',
        path: node.getPath(),
        startOffset: node.start.offset,
        endOffset: node.end.offset
      }
    }
  }

  isDisabled (params) {
    const sel = params.selection
    const selectionState = params.editorSession.getSelectionState()
    if (!sel.isPropertySelection()) {
      return true
    }
    // We don't allow inserting an inline node on top of an existing inline node.
    if (selectionState.isInlineNodeSelection) {
      return true
    }
    return false
  }
}
<commit_msg>Fix regression in InsertInlineFormulaCommand.<commit_after>import { InsertInlineNodeCommand as SubstanceInsertInlineNodeCommand, documentHelpers } from 'substance'

export default class InsertInlineFormulaCommand extends SubstanceInsertInlineNodeCommand {
  getType () {
    return 'inline-formula'
  }

  createNode (tx) {
    const inlineFormula = tx.createElement('inline-formula')
      .attr('content-type', 'math/tex')
      .appendChild(
        tx.createElement('tex-math')
      )
    return inlineFormula
  }

  /**
    Insert new inline node at the current selection
  */
  execute (params, context) {
    const state = this.getCommandState(params)
    if (state.disabled) return
    const editorSession = context.editorSession
    const sel = params.selection
    editorSession.transaction((tx) => {
      const doc = tx.getDocument()
      const text = documentHelpers.getTextForSelection(doc, sel)
      const node = tx.createElement('inline-formula')
        .attr('content-type', 'math/tex')
      const inlineFormula = tx.insertInlineNode(node)
      inlineFormula.appendChild(
        tx.createElement('tex-math').text(text)
      )
      this.setSelection(tx, node)
    })
  }

  setSelection (tx, node) {
    if (node.isPropertyAnnotation()) {
      tx.selection = {
        type: 'property',
        path: node.getPath(),
        startOffset: node.start.offset,
        endOffset: node.end.offset
      }
    }
  }

  isDisabled (params) {
    const sel = params.selection
    const selectionState = params.editorSession.getSelectionState()
    if (!sel.isPropertySelection()) {
      return true
    }
    // We don't allow inserting an inline node on top of an existing inline node.
    if (selectionState.isInlineNodeSelection) {
      return true
    }
    return false
  }
}
<|endoftext|>


<commit_before>import loadZips from '../shared/load-zips'
import importData from '../shared/import-data'

exports.seed = async function(knex, Promise) {
  let zipCodes = loadZips('./seeds/shared/zip-codes.csv')
  await knex('zip_codes').del()
  await importData('zip_codes', zipCodes)
};
<commit_msg>Fix another thing that is bad<commit_after>import loadZips from '../shared/load-zips'
import importData from '../shared/import-data'

exports.seed = async function(knex, Promise) {
  let zipCodes = loadZips('./seeds/shared/zip-codes.csv')
  await knex('zip_codes').del()
  await importData(knex, 'zip_codes', zipCodes)
};
<|endoftext|>


<commit_before>var n = 3, // The number of series.
    m = 24; // The number of values per series.

// The xz array has m elements, representing the x-values shared by all series.
// The yz array has n elements, representing the y-values of each of the n series.
// Each yz[i] is an array of m non-negative numbers representing a y-value for xz[i].
// The y01z array has the same structure as yz, but with stacked [y₀, y₁] instead of y.
var xz = d3.range(m),
    yz = [[1,2],[3,4]]//d3.range(n).map(function() { return bumps(m); }),
    y01z = d3.stack().keys(d3.range(n))(d3.transpose(yz)),
    yMax = d3.max(yz, function(y) { return d3.max(y); }),
    y1Max = d3.max(y01z, function(y) { return d3.max(y, function(d) { return d[1]; }); });

var svg = d3.select("#chart"),
    margin = {top: 40, right: 10, bottom: 20, left: 10},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var x = d3.scaleBand()
    .domain(xz)
    .rangeRound([0, width])
    .padding(0.08);

var y = d3.scaleLinear()
    .domain([0, y1Max])
    .range([height, 0]);

var color = d3.scaleOrdinal()
    .domain(d3.range(n))
    .range(d3.schemeCategory20c);

var series = g.selectAll(".series")
  .data(y01z)
  .enter().append("g")
    .attr("fill", function(d, i) { return color(i); });

var rect = series.selectAll("rect")
  .data(function(d) { return d; })
  .enter().append("rect")
    .attr("x", function(d, i) { return x(i); })
    .attr("y", height)
    .attr("width", x.bandwidth())
    .attr("height", 0);

rect.transition()
    .delay(function(d, i) { return i * 10; })
    .attr("y", function(d) { return y(d[1]); })
    .attr("height", function(d) { return y(d[0]) - y(d[1]); });

g.append("g")
    .attr("class", "axis axis--x")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x)
        .tickSize(0)
        .tickPadding(6));

d3.selectAll("input")
    .on("change", changed);

var timeout = d3.timeout(function() {
  d3.select("input[value=\"grouped\"]")
      .property("checked", true)
      .dispatch("change");
}, 2000);

function changed() {
  timeout.stop();
  if (this.value === "grouped") transitionGrouped();
  else transitionStacked();
}

function transitionGrouped() {
  y.domain([0, yMax]);

  rect.transition()
      .duration(500)
      .delay(function(d, i) { return i * 10; })
      .attr("x", function(d, i) { return x(i) + x.bandwidth() / n * this.parentNode.__data__.key; })
      .attr("width", x.bandwidth() / n)
    .transition()
      .attr("y", function(d) { return y(d[1] - d[0]); })
      .attr("height", function(d) { return y(0) - y(d[1] - d[0]); });
}

function transitionStacked() {
  y.domain([0, y1Max]);

  rect.transition()
      .duration(500)
      .delay(function(d, i) { return i * 10; })
      .attr("y", function(d) { return y(d[1]); })
      .attr("height", function(d) { return y(d[0]) - y(d[1]); })
    .transition()
      .attr("x", function(d, i) { return x(i); })
      .attr("width", x.bandwidth());
}

// Returns an array of m psuedorandom, smoothly-varying non-negative numbers.
// Inspired by Lee Byron’s test data generator.
// http://leebyron.com/streamgraph/
function bumps(m) {
  var values = [], i, j, w, x, y, z;

  // Initialize with uniform random values in [0.1, 0.2).
  for (i = 0; i < m; ++i) {
    values[i] = 0.1 + 0.1 * Math.random();
  }

  // Add five random bumps.
  for (j = 0; j < 5; ++j) {
    x = 1 / (0.1 + Math.random());
    y = 2 * Math.random() - 0.5;
    z = 10 / (0.1 + Math.random());
    for (i = 0; i < m; i++) {
      w = (i / m - y) * z;
      values[i] += x * Math.exp(-w * w);
    }
  }

  // Ensure all values are positive.
  for (i = 0; i < m; ++i) {
    values[i] = Math.max(0, values[i]);
  }

  return values;
}

<commit_msg>Added jquery GET<commit_after>var fetched_data = 0;
$.get(
    "/fetchDB",
    function(data) {
       //alert('page content: ' + data);
       console.log(data)
       fetched_data = data;
    }
);

var n = 3, // The number of series.
    m = 24; // The number of values per series.

// The xz array has m elements, representing the x-values shared by all series.
// The yz array has n elements, representing the y-values of each of the n series.
// Each yz[i] is an array of m non-negative numbers representing a y-value for xz[i].
// The y01z array has the same structure as yz, but with stacked [y₀, y₁] instead of y.
var xz = d3.range(m),
    yz=[fetched_data[0],fetched_data[1]]
    //yz = [[1,2],[3,4]]//d3.range(n).map(function() { return bumps(m); }),
    y01z = d3.stack().keys(d3.range(n))(d3.transpose(yz)),
    yMax = d3.max(yz, function(y) { return d3.max(y); }),
    y1Max = d3.max(y01z, function(y) { return d3.max(y, function(d) { return d[1]; }); });

var svg = d3.select("#chart"),
    margin = {top: 40, right: 10, bottom: 20, left: 10},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var x = d3.scaleBand()
    .domain(xz)
    .rangeRound([0, width])
    .padding(0.08);

var y = d3.scaleLinear()
    .domain([0, y1Max])
    .range([height, 0]);

var color = d3.scaleOrdinal()
    .domain(d3.range(n))
    .range(d3.schemeCategory20c);

var series = g.selectAll(".series")
  .data(y01z)
  .enter().append("g")
    .attr("fill", function(d, i) { return color(i); });

var rect = series.selectAll("rect")
  .data(function(d) { return d; })
  .enter().append("rect")
    .attr("x", function(d, i) { return x(i); })
    .attr("y", height)
    .attr("width", x.bandwidth())
    .attr("height", 0);

rect.transition()
    .delay(function(d, i) { return i * 10; })
    .attr("y", function(d) { return y(d[1]); })
    .attr("height", function(d) { return y(d[0]) - y(d[1]); });

g.append("g")
    .attr("class", "axis axis--x")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x)
        .tickSize(0)
        .tickPadding(6));

d3.selectAll("input")
    .on("change", changed);

var timeout = d3.timeout(function() {
  d3.select("input[value=\"grouped\"]")
      .property("checked", true)
      .dispatch("change");
}, 2000);

function changed() {
  timeout.stop();
  if (this.value === "grouped") transitionGrouped();
  else transitionStacked();
}

function transitionGrouped() {
  y.domain([0, yMax]);

  rect.transition()
      .duration(500)
      .delay(function(d, i) { return i * 10; })
      .attr("x", function(d, i) { return x(i) + x.bandwidth() / n * this.parentNode.__data__.key; })
      .attr("width", x.bandwidth() / n)
    .transition()
      .attr("y", function(d) { return y(d[1] - d[0]); })
      .attr("height", function(d) { return y(0) - y(d[1] - d[0]); });
}

function transitionStacked() {
  y.domain([0, y1Max]);

  rect.transition()
      .duration(500)
      .delay(function(d, i) { return i * 10; })
      .attr("y", function(d) { return y(d[1]); })
      .attr("height", function(d) { return y(d[0]) - y(d[1]); })
    .transition()
      .attr("x", function(d, i) { return x(i); })
      .attr("width", x.bandwidth());
}

// Returns an array of m psuedorandom, smoothly-varying non-negative numbers.
// Inspired by Lee Byron’s test data generator.
// http://leebyron.com/streamgraph/
function bumps(m) {
  var values = [], i, j, w, x, y, z;

  // Initialize with uniform random values in [0.1, 0.2).
  for (i = 0; i < m; ++i) {
    values[i] = 0.1 + 0.1 * Math.random();
  }

  // Add five random bumps.
  for (j = 0; j < 5; ++j) {
    x = 1 / (0.1 + Math.random());
    y = 2 * Math.random() - 0.5;
    z = 10 / (0.1 + Math.random());
    for (i = 0; i < m; i++) {
      w = (i / m - y) * z;
      values[i] += x * Math.exp(-w * w);
    }
  }

  // Ensure all values are positive.
  for (i = 0; i < m; ++i) {
    values[i] = Math.max(0, values[i]);
  }

  return values;
}

<|endoftext|>


<commit_before>var recipesTables = $('#recipes-table').DataTable({
	'order': [[1, 'asc']],
	'columnDefs': [
		{ 'orderable': false, 'targets': 0 },
		{ 'searchable': false, "targets": 0 },
		{ "type": "html-num-fmt", "targets": 2 },
	].concat($.fn.dataTable.defaults.columnDefs),
	select: {
		style: 'single',
		selector: 'tr td:not(:first-child)'
	},
	'initComplete': function()
	{
		this.api().row({ order: 'current' }, 0).select();
	}
});
$('#recipes-table tbody').removeClass("d-none");
recipesTables.columns.adjust().draw();

if ((typeof GetUriParam("tab") !== "undefined" && GetUriParam("tab") === "gallery") || window.localStorage.getItem("recipes_last_tab_id") == "gallery-tab")
{
	$(".nav-tabs a[href='#gallery']").tab("show");
}

var recipe = GetUriParam("recipe");
if (typeof recipe !== "undefined")
{
	$("#recipes-table tr").removeClass("selected");
	var rowId = "#recipe-row-" + recipe;
	$(rowId).addClass("selected")

	var cardId = "#RecipeGalleryCard-" + recipe;
	$(cardId).addClass("border-primary");

	if ($(window).width() < 768)
	{
		// Scroll to recipe card on mobile
		$("#selectedRecipeCard")[0].scrollIntoView();
	}
}

if (GetUriParam("search") !== undefined)
{
	$("#search").val(GetUriParam("search"));
	setTimeout(function()
	{
		$("#search").keyup();
	}, 50);
}

if (GetUriParam("status") !== undefined)
{
	$("#status-filter").val(GetUriParam("status"));
	setTimeout(function()
	{
		$("#status-filter").trigger("change");
	}, 50);
}

$("a[data-toggle='tab']").on("shown.bs.tab", function(e)
{
	var tabId = $(e.target).attr("id");
	window.localStorage.setItem("recipes_last_tab_id", tabId);
});

$("#search").on("keyup", Delay(function()
{
	var value = $(this).val();

	recipesTables.search(value).draw();

	if (value.isEmpty())
	{
		RemoveUriParam("search");
	}
	else
	{
		UpdateUriParam("search", value);
	}

	$(".recipe-gallery-item").removeClass("d-none");
	$(".recipe-gallery-item .card-title:not(:contains_case_insensitive(" + value + "))").parent().parent().parent().addClass("d-none");
}, 200));

$("#clear-filter-button").on("click", function()
{
	$("#search").val("");
	$("#status-filter").val("all");
	$("#search").trigger("keyup");
	$("#status-filter").trigger("change");
});

$("#status-filter").on("change", function()
{
	var value = $(this).val();
	if (value === "all")
	{
		value = "";
	}

	recipesTables.column(5).search(value).draw();

	$('.recipe-gallery-item').removeClass('d-none');
	if (value !== "")
	{
		if (value === 'Xenoughinstock')
		{
			$('.recipe-gallery-item').not('.recipe-enoughinstock').addClass('d-none');
		}
		else if (value === 'enoughinstockwithshoppinglist')
		{
			$('.recipe-gallery-item').not('.recipe-enoughinstockwithshoppinglist').addClass('d-none');
		}
		if (value === 'notenoughinstock')
		{
			$('.recipe-gallery-item').not('.recipe-notenoughinstock').addClass('d-none');
		}
	}

	if (value.isEmpty())
	{
		RemoveUriParam("status");
	}
	else
	{
		UpdateUriParam("status", value);
	}
});

$(".recipe-delete").on('click', function(e)
{
	e.preventDefault();

	var objectName = $(e.currentTarget).attr('data-recipe-name');
	var objectId = $(e.currentTarget).attr('data-recipe-id');

	bootbox.confirm({
		message: __t('Are you sure to delete recipe "%s"?', objectName),
		closeButton: false,
		buttons: {
			confirm: {
				label: __t('Yes'),
				className: 'btn-success'
			},
			cancel: {
				label: __t('No'),
				className: 'btn-danger'
			}
		},
		callback: function(result)
		{
			if (result === true)
			{
				Grocy.Api.Delete('objects/recipes/' + objectId, {},
					function(result)
					{
						window.location.href = U('/recipes');
					},
					function(xhr)
					{
						console.error(xhr);
					}
				);
			}
		}
	});
});

$(document).on('click', '.recipe-shopping-list', function(e)
{
	var objectName = $(e.currentTarget).attr('data-recipe-name');
	var objectId = $(e.currentTarget).attr('data-recipe-id');

	bootbox.confirm({
		message: __t('Are you sure to put all missing ingredients for recipe "%s" on the shopping list?', objectName) + "

" + __t("Uncheck ingredients to not put them on the shopping list") + ":" + $("#missing-recipe-pos-list")[0].outerHTML.replace("d-none", ""),
		closeButton: false,
		buttons: {
			confirm: {
				label: __t('Yes'),
				className: 'btn-success'
			},
			cancel: {
				label: __t('No'),
				className: 'btn-danger'
			}
		},
		callback: function(result)
		{
			if (result === true)
			{
				Grocy.FrontendHelpers.BeginUiBusy();

				var excludedProductIds = new Array();
				$(".missing-recipe-pos-product-checkbox:checkbox:not(:checked)").each(function()
				{
					excludedProductIds.push($(this).data("product-id"));
				});

				Grocy.Api.Post('recipes/' + objectId + '/add-not-fulfilled-products-to-shoppinglist', { "excludedProductIds": excludedProductIds },
					function(result)
					{
						window.location.href = U('/recipes');
					},
					function(xhr)
					{
						Grocy.FrontendHelpers.EndUiBusy();
						console.error(xhr);
					}
				);
			}
		}
	});
});

$(".recipe-consume").on('click', function(e)
{
	var objectName = $(e.currentTarget).attr('data-recipe-name');
	var objectId = $(e.currentTarget).attr('data-recipe-id');

	bootbox.confirm({
		message: __t('Are you sure to consume all ingredients needed by recipe "%s" (ingredients marked with "only check if any amount is in stock" will be ignored)?', objectName),
		closeButton: false,
		buttons: {
			confirm: {
				label: __t('Yes'),
				className: 'btn-success'
			},
			cancel: {
				label: __t('No'),
				className: 'btn-danger'
			}
		},
		callback: function(result)
		{
			if (result === true)
			{
				Grocy.FrontendHelpers.BeginUiBusy();

				Grocy.Api.Post('recipes/' + objectId + '/consume', {},
					function(result)
					{
						Grocy.FrontendHelpers.EndUiBusy();
						toastr.success(__t('Removed all ingredients of recipe "%s" from stock', objectName));
					},
					function(xhr)
					{
						Grocy.FrontendHelpers.EndUiBusy();
						toastr.warning(__t('Not all ingredients of recipe "%s" are in stock, nothing removed', objectName));
						console.error(xhr);
					}
				);
			}
		}
	});
});

recipesTables.on('select', function(e, dt, type, indexes)
{
	if (type === 'row')
	{
		var selectedRecipeId = $(recipesTables.row(indexes[0]).node()).data("recipe-id");
		var currentRecipeId = location.search.split('recipe=')[1];
		if (selectedRecipeId.toString() !== currentRecipeId)
		{
			UpdateUriParam("recipe", selectedRecipeId.toString());
			window.location.reload();
		}
	}
});

$(".recipe-gallery-item").on("click", function(e)
{
	e.preventDefault();

	window.location.href = U('/recipes?tab=gallery&recipe=' + $(this).data("recipe-id"));
});

$(".recipe-fullscreen").on('click', function(e)
{
	e.preventDefault();

	$("#selectedRecipeCard").toggleClass("fullscreen");
	$("body").toggleClass("fullscreen-card");
	$("#selectedRecipeCard .card-header").toggleClass("fixed-top");
	$("#selectedRecipeCard .card-body").toggleClass("mt-5");

	if ($("body").hasClass("fullscreen-card"))
	{
		window.location.hash = "#fullscreen";
	}
	else
	{
		window.history.replaceState(null, null, " ");
	}
});

$(".recipe-print").on('click', function(e)
{
	e.preventDefault();

	$("#selectedRecipeCard").removeClass("fullscreen");
	$("body").removeClass("fullscreen-card");
	$("#selectedRecipeCard .card-header").removeClass("fixed-top");
	$("#selectedRecipeCard .card-body").removeClass("mt-5");

	window.history.replaceState(null, null, " ");
	window.print();
});

$('#servings-scale').keyup(function(event)
{
	var data = {};
	data.desired_servings = $(this).val();

	Grocy.Api.Put('objects/recipes/' + $(this).data("recipe-id"), data,
		function(result)
		{
			window.location.reload();
		},
		function(xhr)
		{
			console.error(xhr);
		}
	);
});

$(document).on("click", ".missing-recipe-pos-select-button", function(e)
{
	e.preventDefault();

	var checkbox = $(this).find(".form-check-input");
	checkbox.prop("checked", !checkbox.prop("checked"));

	$(this).toggleClass("list-group-item-primary");
});

if (window.location.hash === "#fullscreen")
{
	$("#selectedRecipeToggleFullscreenButton").click();
}
<commit_msg>Fixed mssing-recipe-ingredients-to-shopping-list checkbox inner-click (fixes #1383)<commit_after>var recipesTables = $('#recipes-table').DataTable({
	'order': [[1, 'asc']],
	'columnDefs': [
		{ 'orderable': false, 'targets': 0 },
		{ 'searchable': false, "targets": 0 },
		{ "type": "html-num-fmt", "targets": 2 },
	].concat($.fn.dataTable.defaults.columnDefs),
	select: {
		style: 'single',
		selector: 'tr td:not(:first-child)'
	},
	'initComplete': function()
	{
		this.api().row({ order: 'current' }, 0).select();
	}
});
$('#recipes-table tbody').removeClass("d-none");
recipesTables.columns.adjust().draw();

if ((typeof GetUriParam("tab") !== "undefined" && GetUriParam("tab") === "gallery") || window.localStorage.getItem("recipes_last_tab_id") == "gallery-tab")
{
	$(".nav-tabs a[href='#gallery']").tab("show");
}

var recipe = GetUriParam("recipe");
if (typeof recipe !== "undefined")
{
	$("#recipes-table tr").removeClass("selected");
	var rowId = "#recipe-row-" + recipe;
	$(rowId).addClass("selected")

	var cardId = "#RecipeGalleryCard-" + recipe;
	$(cardId).addClass("border-primary");

	if ($(window).width() < 768)
	{
		// Scroll to recipe card on mobile
		$("#selectedRecipeCard")[0].scrollIntoView();
	}
}

if (GetUriParam("search") !== undefined)
{
	$("#search").val(GetUriParam("search"));
	setTimeout(function()
	{
		$("#search").keyup();
	}, 50);
}

if (GetUriParam("status") !== undefined)
{
	$("#status-filter").val(GetUriParam("status"));
	setTimeout(function()
	{
		$("#status-filter").trigger("change");
	}, 50);
}

$("a[data-toggle='tab']").on("shown.bs.tab", function(e)
{
	var tabId = $(e.target).attr("id");
	window.localStorage.setItem("recipes_last_tab_id", tabId);
});

$("#search").on("keyup", Delay(function()
{
	var value = $(this).val();

	recipesTables.search(value).draw();

	if (value.isEmpty())
	{
		RemoveUriParam("search");
	}
	else
	{
		UpdateUriParam("search", value);
	}

	$(".recipe-gallery-item").removeClass("d-none");
	$(".recipe-gallery-item .card-title:not(:contains_case_insensitive(" + value + "))").parent().parent().parent().addClass("d-none");
}, 200));

$("#clear-filter-button").on("click", function()
{
	$("#search").val("");
	$("#status-filter").val("all");
	$("#search").trigger("keyup");
	$("#status-filter").trigger("change");
});

$("#status-filter").on("change", function()
{
	var value = $(this).val();
	if (value === "all")
	{
		value = "";
	}

	recipesTables.column(5).search(value).draw();

	$('.recipe-gallery-item').removeClass('d-none');
	if (value !== "")
	{
		if (value === 'Xenoughinstock')
		{
			$('.recipe-gallery-item').not('.recipe-enoughinstock').addClass('d-none');
		}
		else if (value === 'enoughinstockwithshoppinglist')
		{
			$('.recipe-gallery-item').not('.recipe-enoughinstockwithshoppinglist').addClass('d-none');
		}
		if (value === 'notenoughinstock')
		{
			$('.recipe-gallery-item').not('.recipe-notenoughinstock').addClass('d-none');
		}
	}

	if (value.isEmpty())
	{
		RemoveUriParam("status");
	}
	else
	{
		UpdateUriParam("status", value);
	}
});

$(".recipe-delete").on('click', function(e)
{
	e.preventDefault();

	var objectName = $(e.currentTarget).attr('data-recipe-name');
	var objectId = $(e.currentTarget).attr('data-recipe-id');

	bootbox.confirm({
		message: __t('Are you sure to delete recipe "%s"?', objectName),
		closeButton: false,
		buttons: {
			confirm: {
				label: __t('Yes'),
				className: 'btn-success'
			},
			cancel: {
				label: __t('No'),
				className: 'btn-danger'
			}
		},
		callback: function(result)
		{
			if (result === true)
			{
				Grocy.Api.Delete('objects/recipes/' + objectId, {},
					function(result)
					{
						window.location.href = U('/recipes');
					},
					function(xhr)
					{
						console.error(xhr);
					}
				);
			}
		}
	});
});

$(document).on('click', '.recipe-shopping-list', function(e)
{
	var objectName = $(e.currentTarget).attr('data-recipe-name');
	var objectId = $(e.currentTarget).attr('data-recipe-id');

	bootbox.confirm({
		message: __t('Are you sure to put all missing ingredients for recipe "%s" on the shopping list?', objectName) + "

" + __t("Uncheck ingredients to not put them on the shopping list") + ":" + $("#missing-recipe-pos-list")[0].outerHTML.replace("d-none", ""),
		closeButton: false,
		buttons: {
			confirm: {
				label: __t('Yes'),
				className: 'btn-success'
			},
			cancel: {
				label: __t('No'),
				className: 'btn-danger'
			}
		},
		callback: function(result)
		{
			if (result === true)
			{
				Grocy.FrontendHelpers.BeginUiBusy();

				var excludedProductIds = new Array();
				$(".missing-recipe-pos-product-checkbox:checkbox:not(:checked)").each(function()
				{
					excludedProductIds.push($(this).data("product-id"));
				});

				Grocy.Api.Post('recipes/' + objectId + '/add-not-fulfilled-products-to-shoppinglist', { "excludedProductIds": excludedProductIds },
					function(result)
					{
						window.location.href = U('/recipes');
					},
					function(xhr)
					{
						Grocy.FrontendHelpers.EndUiBusy();
						console.error(xhr);
					}
				);
			}
		}
	});
});

$(".recipe-consume").on('click', function(e)
{
	var objectName = $(e.currentTarget).attr('data-recipe-name');
	var objectId = $(e.currentTarget).attr('data-recipe-id');

	bootbox.confirm({
		message: __t('Are you sure to consume all ingredients needed by recipe "%s" (ingredients marked with "only check if any amount is in stock" will be ignored)?', objectName),
		closeButton: false,
		buttons: {
			confirm: {
				label: __t('Yes'),
				className: 'btn-success'
			},
			cancel: {
				label: __t('No'),
				className: 'btn-danger'
			}
		},
		callback: function(result)
		{
			if (result === true)
			{
				Grocy.FrontendHelpers.BeginUiBusy();

				Grocy.Api.Post('recipes/' + objectId + '/consume', {},
					function(result)
					{
						Grocy.FrontendHelpers.EndUiBusy();
						toastr.success(__t('Removed all ingredients of recipe "%s" from stock', objectName));
					},
					function(xhr)
					{
						Grocy.FrontendHelpers.EndUiBusy();
						toastr.warning(__t('Not all ingredients of recipe "%s" are in stock, nothing removed', objectName));
						console.error(xhr);
					}
				);
			}
		}
	});
});

recipesTables.on('select', function(e, dt, type, indexes)
{
	if (type === 'row')
	{
		var selectedRecipeId = $(recipesTables.row(indexes[0]).node()).data("recipe-id");
		var currentRecipeId = location.search.split('recipe=')[1];
		if (selectedRecipeId.toString() !== currentRecipeId)
		{
			UpdateUriParam("recipe", selectedRecipeId.toString());
			window.location.reload();
		}
	}
});

$(".recipe-gallery-item").on("click", function(e)
{
	e.preventDefault();

	window.location.href = U('/recipes?tab=gallery&recipe=' + $(this).data("recipe-id"));
});

$(".recipe-fullscreen").on('click', function(e)
{
	e.preventDefault();

	$("#selectedRecipeCard").toggleClass("fullscreen");
	$("body").toggleClass("fullscreen-card");
	$("#selectedRecipeCard .card-header").toggleClass("fixed-top");
	$("#selectedRecipeCard .card-body").toggleClass("mt-5");

	if ($("body").hasClass("fullscreen-card"))
	{
		window.location.hash = "#fullscreen";
	}
	else
	{
		window.history.replaceState(null, null, " ");
	}
});

$(".recipe-print").on('click', function(e)
{
	e.preventDefault();

	$("#selectedRecipeCard").removeClass("fullscreen");
	$("body").removeClass("fullscreen-card");
	$("#selectedRecipeCard .card-header").removeClass("fixed-top");
	$("#selectedRecipeCard .card-body").removeClass("mt-5");

	window.history.replaceState(null, null, " ");
	window.print();
});

$('#servings-scale').keyup(function(event)
{
	var data = {};
	data.desired_servings = $(this).val();

	Grocy.Api.Put('objects/recipes/' + $(this).data("recipe-id"), data,
		function(result)
		{
			window.location.reload();
		},
		function(xhr)
		{
			console.error(xhr);
		}
	);
});

$(document).on("click", ".missing-recipe-pos-select-button", function(e)
{
	e.preventDefault();

	var checkbox = $(this).find(".form-check-input");
	checkbox.prop("checked", !checkbox.prop("checked"));

	$(this).toggleClass("list-group-item-primary");
});

$(document).on("click", ".missing-recipe-pos-product-checkbox", function(e)
{
	e.stopPropagation();

	$(this).prop("checked", !$(this).prop("checked"));
	$(this).parent().parent().click();
});

if (window.location.hash === "#fullscreen")
{
	$("#selectedRecipeToggleFullscreenButton").click();
}
<|endoftext|>


<commit_before>'use strict'

const ApiClient = require('./ApiClient')

const assertOption = (options, name) => {
  if (!options[name]) {
    throw new Error(`Missing required option '${name}'`)
  }
}

const encode = (value = '') => {
  return encodeURIComponent(value)
}

module.exports = function (options) {
  assertOption(options, 'applicationId')
  assertOption(options, 'clientSecretKey')

  const client = new ApiClient(options)

  return {
    /*
    *  List vouchers. Sample query: { limit: 100, skip: 200, category: 'Loyalty' }
    */
    list: (query, callback) => {
      return client.get('/vouchers/', query, callback)
    },

    get: (code, callback) => {
      return client.get(`/vouchers/${encode(code)}`, null, callback)
    },

    create: (voucher, callback) => {
      return client.post(`/vouchers/${encode(voucher.code)}`, voucher, callback)
    },

    delete: (voucherCode, params = {}, callback = null) => {
      if (typeof (params) === 'function') {
        callback = params
        params = {}
      }

      let path = `/vouchers/${encode(voucherCode)}`
      if (params.force) {
        path += '?force=true'
      }

      return client.delete(path, callback)
    },

    update: (voucher, callback) => {
      return client.put(`/vouchers/${encode(voucher.code)}`, voucher, callback)
    },

    enable: (code, callback) => {
      return client.post(`/vouchers/${encode(code)}/enable`, null, callback)
    },

    disable: (code, callback) => {
      return client.post(`/vouchers/${encode(code)}/disable`, null, callback)
    },

    validate: (code, context = {}, callback = null) => {
      if (typeof (context) === 'function') {
        callback = context
        context = {}
      }

      return client.post(`/vouchers/${encode(code)}/validate`, context, callback)
    },

    redemption: (code, callback) => {
      return client.get(`/vouchers/${encode(code)}/redemption`, null, callback)
    },

    /*
    *  List redemptions. Sample query (1000 successful redemptions from April 2016):
    *  {
    *      limit: 1000,
    *      page: 0,
    *      start_date: '2016-04-01T00:00:00',
    *      end_date: '2016-04-30T23:59:59',
    *      result: 'Success'
    *  }
    */
    redemptions: (query, callback) => {
      return client.get('/redemptions/', query, callback)
    },

    redeem: (code, trackingId, callback) => {
      let context = {}
      if (typeof (code) === 'object') {
        context = code
        code = context.voucher
        delete context.voucher
      }
      // No `tracking_id` passed here,
      // use callback from 2n argument.
      if (typeof (trackingId) === 'function') {
        callback = trackingId
        trackingId = undefined
      }

      let url = `/vouchers/${encode(code)}/redemption`
      // If `tracking_id` passed, use it in query string.
      if (typeof (trackingId) === 'string' && trackingId) {
        url += `?tracking_id=${encode(trackingId)}`
      }

      return client.post(url, context, callback)
    },

    rollback: (redemptionId, data, callback) => {
      if (typeof (data) === 'function') {
        callback = data
        data = undefined
      }

      const qs = {}
      const payload = {}

      // If `reason` passed, use it in query string.
      if (typeof (data) === 'string') {
        qs['reason'] = encode(data)
      }

      if (typeof (data) === 'object') {
        qs['reason'] = data['reason'] || undefined
        qs['tracking_id'] = data['tracking_id'] || undefined
        payload['customer'] = data['customer'] || undefined
      }

      return client.post(
        `/redemptions/${encode(redemptionId)}/rollback`,
        payload, callback, {qs}
      )
    },

    publish: function (campaignName, callback) {
      let path = '/vouchers/publish'
      let payload = {}
      if (typeof (campaignName) === 'string') {
        path += '?campaign=' + encode(campaignName)
      }
      if (typeof (campaignName) === 'object') {
        payload = campaignName
      }

      return client.post(path, payload, callback)
    },

    campaign: {
      voucher: {
        create: (campaignName, voucher, callback) => {
          return client.post(
            `/campaigns/${encode(campaignName)}/vouchers`,
            // TODO if voucher is optional, secure against callback version
            voucher || {},
            callback
          )
        }
      }
    },

    customer: {
      create: (customer, callback) => {
        return client.post('/customers', customer, callback)
      },

      get: (customerId, callback) => {
        // TODO why fallback to empty string ?! shall we rather throw an error? print warning?
        return client.get(`/customers/${encode(customerId)}`, null, callback)
      },

      update: (customer, callback) => {
        return client.put(`/customers/${encode(customer.id)}`, customer, callback)
      },

      delete: (customerId, callback) => {
        return client.delete(`/customers/${encode(customerId)}`, callback)
      }
    },

    product: {
      create: (product, callback) => {
        return client.post('/products', product, callback)
      },

      get: (productId, callback) => {
        return client.get(`/products/${encode(productId)}`, null, callback)
      },

      update: (product, callback) => {
        return client.put(`/products/${encode(product.id)}`, product, callback)
      },

      delete: (productId, callback) => {
        return client.delete(`/products/${encode(productId)}`, callback)
      },

      sku: {
        create: (productId, sku, callback) => {
          return client.post(`/products/${encode(productId)}/skus`, sku, callback)
        },

        get: (productId, skuId, callback) => {
          return client.get(
            `/products/${encode(productId)}/skus/${encode(skuId)}`,
            null, callback
          )
        },

        update: (productId, sku, callback) => {
          return client.put(
            `/products/${encode(productId)}/skus/${encode(sku.id)}`,
            sku, callback
          )
        },

        delete: (productId, skuId, callback) => {
          return client.delete(
            `/products/${encode(productId)}/skus/${encode(skuId)}`,
            callback
          )
        }
      }
    }
  }
}
<commit_msg>make one line func<commit_after>'use strict'

const ApiClient = require('./ApiClient')

const assertOption = (options, name) => {
  if (!options[name]) {
    throw new Error(`Missing required option '${name}'`)
  }
}

const encode = (value = '') => encodeURIComponent(value)

module.exports = function (options) {
  assertOption(options, 'applicationId')
  assertOption(options, 'clientSecretKey')

  const client = new ApiClient(options)

  return {
    /*
    *  List vouchers. Sample query: { limit: 100, skip: 200, category: 'Loyalty' }
    */
    list: (query, callback) => {
      return client.get('/vouchers/', query, callback)
    },

    get: (code, callback) => {
      return client.get(`/vouchers/${encode(code)}`, null, callback)
    },

    create: (voucher, callback) => {
      return client.post(`/vouchers/${encode(voucher.code)}`, voucher, callback)
    },

    delete: (voucherCode, params = {}, callback = null) => {
      if (typeof (params) === 'function') {
        callback = params
        params = {}
      }

      let path = `/vouchers/${encode(voucherCode)}`
      if (params.force) {
        path += '?force=true'
      }

      return client.delete(path, callback)
    },

    update: (voucher, callback) => {
      return client.put(`/vouchers/${encode(voucher.code)}`, voucher, callback)
    },

    enable: (code, callback) => {
      return client.post(`/vouchers/${encode(code)}/enable`, null, callback)
    },

    disable: (code, callback) => {
      return client.post(`/vouchers/${encode(code)}/disable`, null, callback)
    },

    validate: (code, context = {}, callback = null) => {
      if (typeof (context) === 'function') {
        callback = context
        context = {}
      }

      return client.post(`/vouchers/${encode(code)}/validate`, context, callback)
    },

    redemption: (code, callback) => {
      return client.get(`/vouchers/${encode(code)}/redemption`, null, callback)
    },

    /*
    *  List redemptions. Sample query (1000 successful redemptions from April 2016):
    *  {
    *      limit: 1000,
    *      page: 0,
    *      start_date: '2016-04-01T00:00:00',
    *      end_date: '2016-04-30T23:59:59',
    *      result: 'Success'
    *  }
    */
    redemptions: (query, callback) => {
      return client.get('/redemptions/', query, callback)
    },

    redeem: (code, trackingId, callback) => {
      let context = {}
      if (typeof (code) === 'object') {
        context = code
        code = context.voucher
        delete context.voucher
      }
      // No `tracking_id` passed here,
      // use callback from 2n argument.
      if (typeof (trackingId) === 'function') {
        callback = trackingId
        trackingId = undefined
      }

      let url = `/vouchers/${encode(code)}/redemption`
      // If `tracking_id` passed, use it in query string.
      if (typeof (trackingId) === 'string' && trackingId) {
        url += `?tracking_id=${encode(trackingId)}`
      }

      return client.post(url, context, callback)
    },

    rollback: (redemptionId, data, callback) => {
      if (typeof (data) === 'function') {
        callback = data
        data = undefined
      }

      const qs = {}
      const payload = {}

      // If `reason` passed, use it in query string.
      if (typeof (data) === 'string') {
        qs['reason'] = encode(data)
      }

      if (typeof (data) === 'object') {
        qs['reason'] = data['reason'] || undefined
        qs['tracking_id'] = data['tracking_id'] || undefined
        payload['customer'] = data['customer'] || undefined
      }

      return client.post(
        `/redemptions/${encode(redemptionId)}/rollback`,
        payload, callback, {qs}
      )
    },

    publish: function (campaignName, callback) {
      let path = '/vouchers/publish'
      let payload = {}
      if (typeof (campaignName) === 'string') {
        path += '?campaign=' + encode(campaignName)
      }
      if (typeof (campaignName) === 'object') {
        payload = campaignName
      }

      return client.post(path, payload, callback)
    },

    campaign: {
      voucher: {
        create: (campaignName, voucher, callback) => {
          return client.post(
            `/campaigns/${encode(campaignName)}/vouchers`,
            // TODO if voucher is optional, secure against callback version
            voucher || {},
            callback
          )
        }
      }
    },

    customer: {
      create: (customer, callback) => {
        return client.post('/customers', customer, callback)
      },

      get: (customerId, callback) => {
        // TODO why fallback to empty string ?! shall we rather throw an error? print warning?
        return client.get(`/customers/${encode(customerId)}`, null, callback)
      },

      update: (customer, callback) => {
        return client.put(`/customers/${encode(customer.id)}`, customer, callback)
      },

      delete: (customerId, callback) => {
        return client.delete(`/customers/${encode(customerId)}`, callback)
      }
    },

    product: {
      create: (product, callback) => {
        return client.post('/products', product, callback)
      },

      get: (productId, callback) => {
        return client.get(`/products/${encode(productId)}`, null, callback)
      },

      update: (product, callback) => {
        return client.put(`/products/${encode(product.id)}`, product, callback)
      },

      delete: (productId, callback) => {
        return client.delete(`/products/${encode(productId)}`, callback)
      },

      sku: {
        create: (productId, sku, callback) => {
          return client.post(`/products/${encode(productId)}/skus`, sku, callback)
        },

        get: (productId, skuId, callback) => {
          return client.get(
            `/products/${encode(productId)}/skus/${encode(skuId)}`,
            null, callback
          )
        },

        update: (productId, sku, callback) => {
          return client.put(
            `/products/${encode(productId)}/skus/${encode(sku.id)}`,
            sku, callback
          )
        },

        delete: (productId, skuId, callback) => {
          return client.delete(
            `/products/${encode(productId)}/skus/${encode(skuId)}`,
            callback
          )
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

// Load chai
const chai = require('chai');
const expect = chai.expect;

// Load our module
const format = require('../../../../app/lib/queue/format');

// Describe the module
describe('Function "regex"', () => {

  it('should export a function', () => {
    expect(format.regex).to.be.a('function');
  });

});
<commit_msg>Add regex format spec<commit_after>'use strict';

// Load chai
const chai = require('chai');
const expect = chai.expect;

// Load our module
const format = require('../../../../app/lib/queue/format');

// Describe the module
describe('Function "regex"', () => {

  beforeEach(() => { format.reset(); });

  afterEach(() => { format.reset(); });

  it('should export a function', () => {
    expect(format.regex).to.be.a('function');
  });

  it('should update the pattern property', () => {

    let addResult = format.add('foo');

    expect(addResult).to.be.true;

    let matchResult = 'test file.foo'.match(format.pattern);

    expect(matchResult).to.not.be.null;
  });

  it('should handle regex unsafe characters', () => {

    let addResult = format.add('fo*o');

    expect(addResult).to.be.true;

    let matchResult = 'test file.fo*o'.match(format.pattern);

    expect(matchResult).to.not.be.null;
  });

});
<|endoftext|>


<commit_before>(function (root, factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD
		define(['on'], factory);
	}
	else if (typeof module === 'object' && module.exports) {
		// Node / CommonJS
		module.exports = factory(require('on'));
	}
	else {
		// Browser globals (root is window)
		root['mouse'] = factory(root.on);
	}
}(this, function (on) {
	'use strict';

	function mouse (parent, options) {
		options = options || {};
		var
			upHandle,
			moveHandle,
			downHandle,
			box,
			cBox,
			org,
			last,
			lastx,
			lasty,
			handles,
			mouseTarget,
			downNodes;

		if(options.downNodes){
			downNodes = options.downNodes;
		} else {
			downNodes = [options.downNode || parent];
		}

		function findInList (target, targets) {
			var i, node;
			for(i = 0; i < targets.length; i++){
				if(targets[i] === target){
					return targets[i];
				}
			}
			return null;
		}

		function findTarget (child, targets) {
			var target;
			while (!target && child !== document.body) {
				target = findInList(child, targets);
				if(target){
					return target;
				}
				child = child.parentNode;
			}
			return null;
		}

		function onMove (e) {
			e.preventDefault();
			var
				x = e.clientX - box.x,
				y = e.clientY - box.y;

			if(x > 0 && x < box.w) {
				last.x = x - lastx;
				lastx = x;
			}
			if(y > 0 && y < box.h) {
				last.y = y - lasty;
				lasty = y;
			}

			emit('move', x, y);
			return false;
		}

		function onDown (e) {
			e.preventDefault();
			box = getBox(parent);
			mouseTarget = findTarget(e.target, downNodes);
			cBox = getBox(mouseTarget);

			var
				x = e.clientX - box.x,
				y = e.clientY - box.y;

			lastx = x;
			lasty = y;

			org = cBox;
			org.x -= box.x;
			org.y -= box.y;

			last = {
				x: 0,
				y: 0
			};
			moveHandle.resume();
			emit('down', x, y);
			return false;
		}

		function onUp (e) {
			moveHandle.pause();
		}

		moveHandle = on(window, 'mousemove', onMove);
		moveHandle.pause();
		upHandle = on(window, 'mouseup', onUp);

		handles = [moveHandle, upHandle];

		downNodes.forEach(function (node) {
			handles.push(
				on(node, 'mousedown', onDown)
			);
		});

		if(options.constrain || options.horizontal || options.vertical){
			handles.push(
				on(parent, 'mouse', mouse.constrain(options))
			)
		}

		return on.makeMultiHandle([moveHandle, downHandle, upHandle]);

		function emit (type, x, y) {
			on.emit(parent, 'mouse', {
				x: x,
				y: y,
				px: range(x/box.w, 0, 1),
				py: range(y/box.h, 0, 1),
				org: org,
				parent: box,
				last: last,
				dist:{
					x: x - org.x,
					y: y - org.y
				},
				up: type === 'up',
				down: type === 'down',
				move: type === 'move',
				mouseType: type,
				mouseTarget: mouseTarget
			});
		}
	}

	mouse.constrain = function (options) {
		var dx, dy, dw, dh;
		return function (e) {
			if (e.down) {
				dx = e.org.x;
				dy = e.org.y;
				if(options.centerEdge){
					dw = e.parent.w;
					dh = e.parent.h;
				} else {
					dw = e.parent.w - e.org.w;
					dh = e.parent.h - e.org.h;
				}
			}

			dx += e.last.x;
			dy += e.last.y;

			dx = Math.max(0, Math.min(dx, dw));
			dy = Math.max(0, Math.min(dy, dh));
			pos(e.mouseTarget, dx, dy);
		}
	};

	return mouse;

}));

function range (value, min, max) {
	return Math.min(max, Math.max(min, value));
}

function pos (node, x, y) {
	node.style.left = x + 'px';
	node.style.top = y + 'px';
}

function getBox (node){
	if(node === window){
		node = document.documentElement;
	}

	var
		dimensions = node.getBoundingClientRect();
	return {
		top: dimensions.top,
		right: dimensions.right,
		bottom: dimensions.bottom,
		left: dimensions.left,
		height: dimensions.height,
		h: dimensions.height,
		width: dimensions.width,
		w: dimensions.width,
		scrollY: window.scrollY,
		scrollX: window.scrollX,
		x: dimensions.left + window.pageXOffset,
		y: dimensions.top + window.pageYOffset
	};
}<commit_msg>losing real target<commit_after>(function (root, factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD
		define(['on'], factory);
	}
	else if (typeof module === 'object' && module.exports) {
		// Node / CommonJS
		module.exports = factory(require('on'));
	}
	else {
		// Browser globals (root is window)
		root['mouse'] = factory(root.on);
	}
}(this, function (on) {
	'use strict';

	function mouse (parent, options) {
		options = options || {};
		var
			upHandle,
			moveHandle,
			downHandle,
			box,
			cBox,
			org,
			last,
			lastx,
			lasty,
			handles,
			mouseTarget,
			realTarget,
			downNodes;

		if(options.downNodes){
			downNodes = options.downNodes;
		} else {
			downNodes = [options.downNode || parent];
		}

		function findInList (target, targets) {
			var i, node;
			for(i = 0; i < targets.length; i++){
				if(targets[i] === target){
					return targets[i];
				}
			}
			return null;
		}

		function findTarget (child, targets) {
			var target;
			while (!target && child !== document.body) {
				target = findInList(child, targets);
				if(target){
					return target;
				}
				child = child.parentNode;
			}
			return null;
		}

		function onMove (e) {
			e.preventDefault();
			var
				x = e.clientX - box.x,
				y = e.clientY - box.y;

			if(x > 0 && x < box.w) {
				last.x = x - lastx;
				lastx = x;
			}
			if(y > 0 && y < box.h) {
				last.y = y - lasty;
				lasty = y;
			}

			emit('move', x, y);
			return false;
		}

		function onDown (e) {
			e.preventDefault();
			box = getBox(parent);
			realTarget = e.target;
			mouseTarget = findTarget(e.target, downNodes);
			cBox = getBox(mouseTarget);

			var
				x = e.clientX - box.x,
				y = e.clientY - box.y;

			lastx = x;
			lasty = y;

			org = cBox;
			org.x -= box.x;
			org.y -= box.y;

			last = {
				x: 0,
				y: 0
			};
			moveHandle.resume();
			emit('down', x, y);
			return false;
		}

		function onUp (e) {
			moveHandle.pause();
		}

		moveHandle = on(window, 'mousemove', onMove);
		moveHandle.pause();
		upHandle = on(window, 'mouseup', onUp);

		handles = [moveHandle, upHandle];

		downNodes.forEach(function (node) {
			handles.push(
				on(node, 'mousedown', onDown)
			);
		});

		if(options.constrain || options.horizontal || options.vertical){
			handles.push(
				on(parent, 'mouse', mouse.constrain(options))
			)
		}

		return on.makeMultiHandle([moveHandle, downHandle, upHandle]);

		function emit (type, x, y) {
			on.emit(parent, 'mouse', {
				x: x,
				y: y,
				px: range(x/box.w, 0, 1),
				py: range(y/box.h, 0, 1),
				org: org,
				parent: box,
				last: last,
				dist:{
					x: x - org.x,
					y: y - org.y
				},
				up: type === 'up',
				down: type === 'down',
				move: type === 'move',
				mouseType: type,
				mouseTarget: mouseTarget,
				realTarget: realTarget
			});
		}
	}

	mouse.constrain = function (options) {
		var dx, dy, dw, dh;
		return function (e) {
			if (e.down) {
				dx = e.org.x;
				dy = e.org.y;
				if(options.centerEdge){
					dw = e.parent.w;
					dh = e.parent.h;
				} else {
					dw = e.parent.w - e.org.w;
					dh = e.parent.h - e.org.h;
				}
			}

			dx += e.last.x;
			dy += e.last.y;

			dx = Math.max(0, Math.min(dx, dw));
			dy = Math.max(0, Math.min(dy, dh));
			pos(e.mouseTarget, dx, dy);
		}
	};

	return mouse;

}));

function range (value, min, max) {
	return Math.min(max, Math.max(min, value));
}

function pos (node, x, y) {
	node.style.left = x + 'px';
	node.style.top = y + 'px';
}

function getBox (node){
	if(node === window){
		node = document.documentElement;
	}

	var
		dimensions = node.getBoundingClientRect();
	return {
		top: dimensions.top,
		right: dimensions.right,
		bottom: dimensions.bottom,
		left: dimensions.left,
		height: dimensions.height,
		h: dimensions.height,
		width: dimensions.width,
		w: dimensions.width,
		scrollY: window.scrollY,
		scrollX: window.scrollX,
		x: dimensions.left + window.pageXOffset,
		y: dimensions.top + window.pageYOffset
	};
}<|endoftext|>


<commit_before>'use strict';

var test = require('tape');
var fauxJax = require('faux-jax');
var bind = require('lodash-compat/function/bind');

var createFixture = require('../../../utils/create-fixture');
var fixture = createFixture();

var hits = [
  {company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
  {company: 'Algolia', name: 'Nicolas Dessaigne', objectID: 'nicolas-dessaigne'},
  {company: 'Amazon', name: 'Jeff Bezos'},
  {company: 'Arista Networks', name: 'Jayshree Ullal'},
  {company: 'Google', name: 'Larry Page'},
  {company: 'Google', name: 'Rob Pike'},
  {company: 'Google', name: 'Serguey Brin'},
  {company: 'Apple', name: 'Steve Jobs'},
  {company: 'Apple', name: 'Steve Wozniak'},
  {company: 'Microsoft', name: 'Bill Gates'},
  {company: 'SpaceX', name: 'Elon Musk'},
  {company: 'Tesla', name: 'Elon Musk'},
  {company: 'Yahoo', name: 'Marissa Mayer'}
];

fauxJax.install();

test('findObject: no object was found when callback always return false', function(t) {
  var index = fixture.index;
  t.plan(1);

  fauxJax.once('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits,
        nbPages: 1
      })
    );
  });

  index
    .findObject(function() {
      return false;
    })
    .then(bind(t.fail, t))
    .catch(function(error) {
      t.same(error, {
        name: 'AlgoliaSearchObjectNotFoundError',
        message: 'Object not found'
      });
    });
});

test('findObject: the first object is returned with a `position=0` and `page=0`', function(t) {
  var index = fixture.index;
  t.plan(1);

  fauxJax.once('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits,
        nbPages: 1
      })
    );
  });

  index
    .findObject(function() {
      return true;
    })
    .then(function(result) {
      t.same(result, {
        object: {company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
        position: 0,
        page: 0
      });
    })
    .catch(bind(t.fail, t));
});

test('findObject: object not found with non matching query', function(t) {
  var index = fixture.index;
  t.plan(1);

  fauxJax.once('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits.filter(function(hit) {
          return hit.company === 'Algolia';
        }),
        nbPages: 1
      })
    );
  });

  index
    .findObject(function(hit) {
      return hit.company === 'Apple';
    }, {
      query: 'Algolia'
    })
    .then(bind(t.fail, t))
    .catch(function(error) {
      t.same(error, {
        name: 'AlgoliaSearchObjectNotFoundError',
        message: 'Object not found'
      });
    });
});

test('findObject: object not found without pagination', function(t) {
  var index = fixture.index;
  t.plan(1);

  var page = 0;
  fauxJax.once('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits.slice(0, page * 5),
        nbPages: 3
      })
    );

    page++;
  });

  index
    .findObject(function(hit) {
      return hit.company === 'Apple';
    }, {
      query: '',
      paginate: false
    })
    .then(bind(t.fail, t))
    .catch(function(error) {
      t.same(error, {
        name: 'AlgoliaSearchObjectNotFoundError',
        message: 'Object not found'
      });
    });
});

test('findObject: object found with pagination', function(t) {
  var index = fixture.index;
  t.plan(1);

  var page = 0;
  fauxJax.on('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits.slice(0, page * 5),
        nbPages: 3
      })
    );

    page++;
  });

  index
    .findObject(function(hit) {
      return hit.company === 'Apple';
    }, {
      query: '',
      paginate: true
    })
    .then(function(result) {
      t.same(result, {
        object: {company: 'Apple', name: 'Steve Jobs'},
        position: 7,
        page: 2
      });
    })
    .catch(t.fail, t);
});
<commit_msg>chore(fix-test-usage-of-fauxjax): updates wrong usage of fauxjax (#788)<commit_after>'use strict';

var test = require('tape');
var bind = require('lodash-compat/function/bind');

var createFixture = require('../../../utils/create-fixture');
var fixture = createFixture();

var hits = [
  {company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
  {company: 'Algolia', name: 'Nicolas Dessaigne', objectID: 'nicolas-dessaigne'},
  {company: 'Amazon', name: 'Jeff Bezos'},
  {company: 'Arista Networks', name: 'Jayshree Ullal'},
  {company: 'Google', name: 'Larry Page'},
  {company: 'Google', name: 'Rob Pike'},
  {company: 'Google', name: 'Serguey Brin'},
  {company: 'Apple', name: 'Steve Jobs'},
  {company: 'Apple', name: 'Steve Wozniak'},
  {company: 'Microsoft', name: 'Bill Gates'},
  {company: 'SpaceX', name: 'Elon Musk'},
  {company: 'Tesla', name: 'Elon Musk'},
  {company: 'Yahoo', name: 'Marissa Mayer'}
];

test('findObject: no object was found when callback always return false', function(t) {
  var fauxJax = require('faux-jax');
  fauxJax.install();

  var index = fixture.index;
  t.plan(1);

  fauxJax.once('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits,
        nbPages: 1
      })
    );

    fauxJax.restore();
  });

  index
    .findObject(function() {
      return false;
    })
    .then(bind(t.fail, t))
    .catch(function(error) {
      t.same(error, {
        name: 'AlgoliaSearchObjectNotFoundError',
        message: 'Object not found'
      });
    });
});

test('findObject: the first object is returned with a `position=0` and `page=0`', function(t) {
  var fauxJax = require('faux-jax');
  fauxJax.install();

  var index = fixture.index;
  t.plan(1);

  fauxJax.once('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits,
        nbPages: 1
      })
    );

    fauxJax.restore();
  });

  index
    .findObject(function() {
      return true;
    })
    .then(function(result) {
      t.same(result, {
        object: {company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
        position: 0,
        page: 0
      });
    })
    .catch(bind(t.fail, t));
});

test('findObject: object not found with non matching query', function(t) {
  var fauxJax = require('faux-jax');
  fauxJax.install();

  var index = fixture.index;
  t.plan(1);

  fauxJax.once('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits.filter(function(hit) {
          return hit.company === 'Algolia';
        }),
        nbPages: 1
      })
    );

    fauxJax.restore();
  });

  index
    .findObject(function(hit) {
      return hit.company === 'Apple';
    }, {
      query: 'Algolia'
    })
    .then(bind(t.fail, t))
    .catch(function(error) {
      t.same(error, {
        name: 'AlgoliaSearchObjectNotFoundError',
        message: 'Object not found'
      });
    });
});

test('findObject: object not found without pagination', function(t) {
  var fauxJax = require('faux-jax');
  fauxJax.install();

  var index = fixture.index;
  t.plan(1);

  var page = 0;
  fauxJax.once('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits.slice(0, page * 5),
        nbPages: 3
      })
    );

    page++;
  });

  index
    .findObject(function(hit) {
      return hit.company === 'Apple';
    }, {
      query: '',
      paginate: false
    })
    .then(bind(t.fail, t))
    .catch(function(error) {
      t.same(error, {
        name: 'AlgoliaSearchObjectNotFoundError',
        message: 'Object not found'
      });

      fauxJax.restore();
    });
});

test('findObject: object found with pagination', function(t) {
  var fauxJax = require('faux-jax');
  fauxJax.install();

  var index = fixture.index;
  t.plan(1);

  var page = 0;
  fauxJax.on('request', function(req) {
    req.respond(
      200,
      {},
      JSON.stringify({
        hits: hits.slice(0, page * 5),
        nbPages: 3
      })
    );

    page++;
  });

  index
    .findObject(function(hit) {
      return hit.company === 'Apple';
    }, {
      query: '',
      paginate: true
    })
    .then(function(result) {
      t.same(result, {
        object: {company: 'Apple', name: 'Steve Jobs'},
        position: 7,
        page: 2
      });

      fauxJax.restore();
    })
    .catch(t.fail, t);
});
<|endoftext|>