<commit_before>'use strict';

var log         = require('../log')(module);
var User        = require('../models').User;
var Message     = require('../models').Message;

module.exports = {
    getInbox : function (req, res, next) {
        // GET /api/messages/inbox
        var currentUser = req.user;
        Message.find({ 'to': currentUser._id })
            .populate('from to', 'username firstName lastName imageUrl')
            .exec(function (err, messages) {
                if (err) {
                    res.send(err);
                    return log('Messages could not be loaded: ' + err);
                }

                res.send(messages);
                // Mark as read after sent
                messages.forEach(function (m) {
                    m.isRead = true;
                    m.save();
                });
            });
    },
    getSent : function (req, res, next) {
        // GET /api/messages/inbox
        var currentUser = req.user;
        Message.find({ 'from': currentUser._id })
            .populate('from to', 'username firstName lastName imageUrl')
            .exec(function (err, messages) {
                if (err) {
                    res.send(err);
                    return log('Messages could not be loaded: ' + err);
                }
                // DO NOT MARK AS READ !!!
                res.send(messages);
            });
    },
    getAllWithUser : function (req, res, next) {
        // GET /api/messages/withUser/:username?unread=true
        var currentUser = req.user;
        User.findOne({ username: req.params.username }).exec(function (err, otherUser) {
            if (otherUser) {

                if (otherUser._id.equals(currentUser._id)) {
                    console.log('You cannot have messages from yourself!');
                    return res.status(404).send({error: 'You cannot have messages from yourself!'});
                }

                var messageQuery = Message.find({
                    $or:
                    [
                     { $and:[ {'from': currentUser._id}, {'to': otherUser._id} ] },
                     { $and:[ {'from': otherUser._id}, {'to': currentUser._id} ] }
                    ]
                });

                var unread = req.query.unread || false;
                if (unread) {
                    messageQuery.where('isRead').equals(false);
                    messageQuery.where('from').equals(otherUser._id);
                }

                messageQuery.populate('from to', 'username firstName lastName imageUrl')
                    .exec(function (err, messages) {
                        if (err) {
                            res.send(err);
                            return log('Messages could not be loaded: ' + err);
                        }

                        res.send({messages:messages});
                        // Mark as read after sent
                        messages.forEach(function (m) {
                            if (!m.isRead && m.to._id.equals(currentUser._id)) {
                                m.isRead = true;
                                m.save();
                            }
                        });
                    });

            } else {
                console.log('Other user not found!');
                res.status(404).send({error:'Other user not found!'});
            }
        });
    },
    getMessageById: function (req, res, next) {
        // GET /api/messages/:id
        var currentUser = req.user;
        Message.findOne(
            {
                $and:
                [
                 {_id: req.params.id},
                 { $or:[ {'from': currentUser._id}, {'to': currentUser._id} ] }
                ]
            })
            .populate('from to', 'username firstName lastName imageUrl')
            .exec(function (err, message) {
                if (err) {
                    res.send(err);
                    return log('Message could not be loaded: ' + err);
                }

                if (message) {
                    res.send(message);
                    // Mark as read
                    if (!message.isRead && message.to.username == currentUser.username) {
                        message.isRead = true;
                        message.save();
                    }
                } else {
                    res.status(404).send('Message not found!');
                }
            });
    },
    sendMessage: function (req, res, next) {
        // POST api/messages/send/:username
        var sender = req.user;
        User.findOne({ username: req.params.username }).exec(function (err, receiver) {
            if (receiver) {

                if (receiver._id.equals(sender._id)) {
                    return res.status(404).send({error: 'You cannot send message to your self!'});
                }

                var message = new Message({
                    title: req.body.title,
                    content: req.body.content,
                    date: new Date(),
                    from: sender,
                    to: receiver,
                    isRead: false
                });
                message.save(function (err) {
                    if (err) {
                        res.status(400).send(err);
                        return log('Error in saving message' + err);
                    }

                    // Send the user view models
                    var messageViewModel = {
                        title: message.title,
                        content: message.content,
                        date: message.date,
                        isRead: message.isRead
                    };
                    messageViewModel.from = {
                        userId: sender.userId,
                        username: sender.username,
                        firstName: sender.firstName,
                        lastName: sender.lastName,
                        imageUrl: sender.imageUrl
                    };
                    messageViewModel.to = {
                        userId: receiver.userId,
                        username: receiver.username,
                        firstName: receiver.firstName,
                        lastName: receiver.lastName,
                        imageUrl: receiver.imageUrl
                    };
                    res.send({message:messageViewModel});

                    // Send push notification for new message to the receiver
                });

                receiver.messages.push(message);
                receiver.save();
            } else {
                res.status(404).send('User not found!');
            }
        });
    }
}<commit_msg>last unread messages<commit_after>'use strict';

var log         = require('../log')(module);
var User        = require('../models').User;
var Message     = require('../models').Message;

module.exports = {
    getInbox : function (req, res, next) {
        // GET /api/messages/inbox
        var currentUser = req.user;
        Message.find({ 'to': currentUser._id })
            .populate('from to', 'username firstName lastName imageUrl')
            .exec(function (err, messages) {
                if (err) {
                    res.send(err);
                    return log('Messages could not be loaded: ' + err);
                }

                res.send(messages);
                // Mark as read after sent
                messages.forEach(function (m) {
                    m.isRead = true;
                    m.save();
                });
            });
    },
    getSent : function (req, res, next) {
        // GET /api/messages/inbox
        var currentUser = req.user;
        Message.find({ 'from': currentUser._id })
            .populate('from to', 'username firstName lastName imageUrl')
            .exec(function (err, messages) {
                if (err) {
                    res.send(err);
                    return log('Messages could not be loaded: ' + err);
                }
                // DO NOT MARK AS READ !!!
                res.send(messages);
            });
    },
    getAllWithUser : function (req, res, next) {
        // GET /api/messages/withUser/:username?unread=true
        var currentUser = req.user;
        User.findOne({ username: req.params.username }).exec(function (err, otherUser) {
            if (otherUser) {

                if (otherUser._id.equals(currentUser._id)) {
                    console.log('You cannot receive messages from yourself!');
                    return res.status(404).send({error: 'You cannot receive messages from yourself!'});
                }

                var messageQuery = Message.find({
                    $or:
                    [
                     { $and:[ {'from': currentUser._id}, {'to': otherUser._id} ] },
                     { $and:[ {'from': otherUser._id}, {'to': currentUser._id} ] }
                    ]
                });

                var unread = req.query.unread || false;
                if (unread) {
                    messageQuery.where('isRead').equals(false);
                    messageQuery.where('from').equals(otherUser._id);
                }

                messageQuery.populate('from to', 'username firstName lastName imageUrl')
                    .exec(function (err, messages) {
                        if (err) {
                            res.send(err);
                            return log('Messages could not be loaded: ' + err);
                        }

                        res.send({messages:messages});
                        // Mark as read after sent
                        messages.forEach(function (m) {
                            if (!m.isRead && m.to._id.equals(currentUser._id)) {
                                m.isRead = true;
                                m.save();
                            }
                        });
                    });

            } else {
                console.log('Other user not found!');
                res.status(404).send({error:'Other user not found!'});
            }
        });
    },
    getMessageById: function (req, res, next) {
        // GET /api/messages/:id
        var currentUser = req.user;
        Message.findOne(
            {
                $and:
                [
                 {_id: req.params.id},
                 { $or:[ {'from': currentUser._id}, {'to': currentUser._id} ] }
                ]
            })
            .populate('from to', 'username firstName lastName imageUrl')
            .exec(function (err, message) {
                if (err) {
                    res.send(err);
                    return log('Message could not be loaded: ' + err);
                }

                if (message) {
                    res.send(message);
                    // Mark as read
                    if (!message.isRead && message.to.username == currentUser.username) {
                        message.isRead = true;
                        message.save();
                    }
                } else {
                    res.status(404).send('Message not found!');
                }
            });
    },
    sendMessage: function (req, res, next) {
        // POST api/messages/send/:username
        var sender = req.user;
        User.findOne({ username: req.params.username }).exec(function (err, receiver) {
            if (receiver) {

                if (receiver._id.equals(sender._id)) {
                    return res.status(404).send({error: 'You cannot send message to your self!'});
                }

                var message = new Message({
                    title: req.body.title,
                    content: req.body.content,
                    date: new Date(),
                    from: sender,
                    to: receiver,
                    isRead: false
                });
                message.save(function (err) {
                    if (err) {
                        res.status(400).send(err);
                        return log('Error in saving message' + err);
                    }

                    // Send the user view models
                    var messageViewModel = {
                        title: message.title,
                        content: message.content,
                        date: message.date,
                        isRead: message.isRead
                    };
                    messageViewModel.from = {
                        userId: sender.userId,
                        username: sender.username,
                        firstName: sender.firstName,
                        lastName: sender.lastName,
                        imageUrl: sender.imageUrl
                    };
                    messageViewModel.to = {
                        userId: receiver.userId,
                        username: receiver.username,
                        firstName: receiver.firstName,
                        lastName: receiver.lastName,
                        imageUrl: receiver.imageUrl
                    };
                    res.send({message:messageViewModel});

                    // Send push notification for new message to the receiver
                });

                receiver.messages.push(message);
                receiver.save();
            } else {
                res.status(404).send({error:'User not found!'});
            }
        });
    }
}<|endoftext|>


<commit_before>import Models from '../models';
const Bill = Models.Bill;
const User = Models.User;

/**
 * List
 */
export function all(req, res) {
  return User.findOne({
    where: { id: req.user.id },
    include: [
      { model: Bill, as: 'Debts' },
      { model: Bill, as: 'Credits' }
    ]
  }).then((existingUser) => {
    const { Credits, Debts } = existingUser;
    return res.json({ Credits, Debts });
  }).catch((err) => {
    console.log(err);
    return res.status(500).send('Error in first query');
  });
}

/**
 * Add a Bill
 * will create a non-operative user if user does not exist
 */
function createBill(req, res, debtorId) {
  return Bill.create({
    description: req.body.description,
    amount: req.body.amount,
    creditorId: req.user.id,
    debtorId
  }).then(() => {
    return res.status(200).send('OK');
  }).catch((err) => {
    console.log(err);
    return res.status(400).send(err);
  });
}

export function add(req, res) {
  return User.findOne({ where: { email: req.body.email } }).then((existingUser) => {
    if (existingUser !== null) {
      return createBill(req, res, existingUser.id);
    }
    const newUser = User.build({
      email: req.body.email,
      operative: false
    });

    return newUser.save.then(() => {
      return createBill(req, res, newUser.id);
    }).catch((err) => {
      console.log(err);
      return res.status(500).send('We have failed to save your bill');
    });
  }).catch((err) => {
    console.log(err);
    return res.status(500).send('Error in first query');
  });
}

/**
 * Update a Bill
 */
export function update(req, res) {
  const query = { id: req.params.id };
  const params = {
    description: req.body.description,
    amount: req.body.amount
  };

  return Bill.update(params, { where: query }).then(() => {
    res.status(200).send('Updated successfully');
  }).catch((err) => {
    console.log(err);
    res.status(500).send('We failed to save for some reason');
  });
}

/**
 * Remove a Bill
 */
export function remove(req, res) {
  const query = { id: req.params.id };

  return Bill.destroy({ where: query }).then(() => {
    res.status(200).send('Removed Successfully');
  }).catch((err) => {
    console.log(err);
    res.status(500).send('We failed to delete for some reason');
  });
}

export default {
  all,
  add,
  update,
  remove
};
<commit_msg>refactor existingUser in bill controller<commit_after>import Models from '../models';
const Bill = Models.Bill;
const User = Models.User;

/**
 * List
 */
export function all(req, res) {
  return User.findOne({
    where: { id: req.user.id },
    include: [
      { model: Bill, as: 'Debts' },
      { model: Bill, as: 'Credits' }
    ]
  }).then(({ Credits, Debts }) => {
    return res.json({ Credits, Debts });
  }).catch((err) => {
    console.log(err);
    return res.status(500).send('Error in first query');
  });
}

/**
 * Add a Bill
 * will create a non-operative user if user does not exist
 */
function createBill(req, res, debtorId) {
  return Bill.create({
    description: req.body.description,
    amount: req.body.amount,
    creditorId: req.user.id,
    debtorId
  }).then(() => {
    return res.status(200).send('OK');
  }).catch((err) => {
    console.log(err);
    return res.status(400).send(err);
  });
}

export function add(req, res) {
  return User.findOne({ where: { email: req.body.email } }).then((existingUser) => {
    if (existingUser !== null) {
      return createBill(req, res, existingUser.id);
    }
    const newUser = User.build({
      email: req.body.email,
      operative: false
    });

    return newUser.save.then(() => {
      return createBill(req, res, newUser.id);
    }).catch((err) => {
      console.log(err);
      return res.status(500).send('We have failed to save your bill');
    });
  }).catch((err) => {
    console.log(err);
    return res.status(500).send('Error in first query');
  });
}

/**
 * Update a Bill
 */
export function update(req, res) {
  const query = { id: req.params.id };
  const params = {
    description: req.body.description,
    amount: req.body.amount
  };

  return Bill.update(params, { where: query }).then(() => {
    res.status(200).send('Updated successfully');
  }).catch((err) => {
    console.log(err);
    res.status(500).send('We failed to save for some reason');
  });
}

/**
 * Remove a Bill
 */
export function remove(req, res) {
  const query = { id: req.params.id };

  return Bill.destroy({ where: query }).then(() => {
    res.status(200).send('Removed Successfully');
  }).catch((err) => {
    console.log(err);
    res.status(500).send('We failed to delete for some reason');
  });
}

export default {
  all,
  add,
  update,
  remove
};
<|endoftext|>


<commit_before>'use strict';

export class LocaisService {

    constructor(db_profile = 'SCORE') {
        require('../config/db_config')(db_profile);

        // const Local = require('../model/Local'),
        //     _ = require('../util/util');
    }

}

<commit_msg>Só colocando umas variáveis<commit_after>'use strict';

const Local = require('../model/Local'),
    _ = require('../util/util');

export class LocaisService {

    constructor(db_profile = 'SCORE') {
        require('../config/db_config')(db_profile);
    }

}

<|endoftext|>


<commit_before>/**
 Flexitable jQuery plugin
 Copyright (c) 2015 Adam Messinger, http://zenscope.com/
 Released under the MIT license, see LICENSE file for details.

 This plugin owes its starting point to the work of Marco Pegoraro (movableapp.com):
   https://github.com/marcopeg/MediaTable
 ...and also borrows some ideas from Tablesaw by Filament Group:
   https://github.com/filamentgroup/tablesaw
 **/

;(function($, undefined) {
  'use strict';

  $.fn.flexitable = function(user_config) {
    return this.each(function(i) {
      var $table = $(this);
      var config = $.extend({
        column_toggle: true,
        has_column_menu: true,
        column_button_txt: 'Columns:',
        // NOTE: takes a CSS selector; 'this' means position relative to the enhanced table
        toolbar_position_target: 'this',
        toolbar_before_or_after: 'before',
        destroy: false
      }, (user_config || {}));

      if (config.destroy) {
        columnChooser($table, config, i).destroy();
      } else if (config.column_toggle) {
        columnChooser($table, config, i).init();
      }
    });
  };

  function columnChooser($table, config, i) {
    // view_model will contain all the data we need for future DOM manipulations.
    // Much faster than revisiting the DOM repeatedly.
    var view_model = {
      id: $table[0].id,
      // cfg: this table's Flexitable config
      cfg: config,
      $table: $table,
      $toolbar: $('
'),
      // $menu: will hold column toggle menu
      $menu: null,
      // cells_by_column: array of objects w/ each col's header txt & th,
      // contained cells, and visibility & persistence states
      cells_by_column: []
    };

    // public methods
    return {
      init: initFlexitable,
      destroy: destroyFlexitable
    };

    function initFlexitable() {
      var $headers;

      // Prevent re-initialization
      if (view_model.$table.data('Flexitable')) {
        return;
      }

      // Set table ID if not specified
      if (!view_model.id) {
        view_model.id = 'flexitable-' + i;
        view_model.$table[0].id = view_model.id;
      }

      $headers = view_model.$table.find('> thead th');
      if ($headers.length) {
        // NOTE: "deferredEach" plugin is tacked onto the very bottom of this file
        $.deferredEach($headers, _initCellsByHeader)
          .done(function() {
            // 'flexitable-active' class enables media queries, once above init gives
            // proper classes to cells
            view_model.$table.addClass('flexitable-active');

            // NOTE: MUST build menu after _initCellsByHeader, not before
            if (view_model.cfg.has_column_menu && view_model.cells_by_column.length) {
              _buildMenu();
              _initMenuInteractions();
              _insertMenu();
            }

            view_model.$table.data('Flexitable', view_model);

            view_model.$table.trigger('flexitable.initialized');
          });
      }
    }

    function destroyFlexitable() {
      var stored_view_model = $table.data('Flexitable');

      if (!stored_view_model) {
        return;
      }

      stored_view_model.$menu.remove();
      stored_view_model.$toolbar.remove();
      // remove active class to nix Flexitable media queries
      $table.removeClass('flexitable-active');
      // remove stored plugin data on the table
      $table.removeData('Flexitable');
    }

    function _initCellsByHeader(index, header) {
      var $header = $(header);
      var priority_class = $header.data('flexitablePriorityClass');
      // NOTE: cell_num is used for nth-child selectors, which aren't 0-indexed
      var cell_num = index + 1;
      var $col_cells = view_model.$table.find('> thead th:nth-child(' + cell_num + '), > tbody td:nth-child(' + cell_num + ')');
      // cell loop vars:
      var i, l;

      for (i = 0, l = $col_cells.length; i < l; i++) {
        if (priority_class) {
          $col_cells[i].className += (' ' + priority_class);
        }
      }

      view_model.cells_by_column[index] = {
        // NOTE: we're using the th's visibility as a proxy for the column's
        is_visible: ($header.css('display') === 'table-cell'),
        $th: $header,
        heading_text: $header.text(),
        is_persistent_col: $header.hasClass('persist'),
        $cells: $col_cells
      };
    }

    // debounce: from https://github.com/twitter/typeahead.js & http://davidwalsh.name/function-debounce
    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds. If 'immediate' is passed, trigger the function on the
    // leading edge instead of the trailing.
    function _debounce(func, wait, immediate) {
      var timeout;
      var result;

      return function() {
        var context = this;
        var args = arguments;
        var later = function() {
          timeout = null;
          if (!immediate) {
            result = func.apply(context, args);
          }
        };
        var callNow = immediate && !timeout;

        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) {
          result = func.apply(context, args);
        }
        return result;
      };
    }

    function _buildMenu() {
      var cells_by_column = view_model.cells_by_column;
      var checkbox_id_pfx = (view_model.id + '_toggle-col-');
      var li_cache = [];
      var i, l, $this_checkbox, $this_label;

      // Build menu containers
      view_model.$menu = $('
');
      view_model.$menu.$button = $('<button type="button" />').text(view_model.cfg.column_button_txt);
      view_model.$menu.$list = $('
');
      view_model.$menu
        .append(view_model.$menu.$button)
        .append(view_model.$menu.$list);

      // populate menu with checkboxes for each non-persistent column
      for (i = 0, l = cells_by_column.length; i < l; i++) {
        if (!cells_by_column[i].is_persistent_col) {
          $this_checkbox = $('<input />', {
            type: 'checkbox',
            name: 'toggle-cols',
            id: (checkbox_id_pfx + i),
            value: i,
            'data-flexitable-id': view_model.id
          });
          $this_checkbox.prop('checked', cells_by_column[i].is_visible);

          $this_label = $('', {
            for: (checkbox_id_pfx + i),
            text: cells_by_column[i].heading_text
          });

          li_cache.push($('
').append($this_checkbox).append($this_label))
        }
      }

      view_model.$menu.$list.append(li_cache);
    }

    function _insertMenu() {
      var placement_target = view_model.cfg.toolbar_position_target === 'this'
        ? view_model.$table
        : $(view_model.cfg.toolbar_position_target);
      var placement_method = view_model.cfg.toolbar_before_or_after.toLowerCase() === 'after'
        ? 'insertAfter'
        : 'insertBefore';

      view_model.$toolbar
        .append(view_model.$menu)
        // Add a class to the toolbar to inform about menu presence.
        .addClass('flexitable-toolbar-has-widgets')
        [placement_method](placement_target);
    }

    function _initMenuInteractions() {
      view_model.$menu
        .on('click', 'button', _toggleMenuVisibility)
        .on('change', 'input[name="toggle-cols"]', _toggleColumn)
        .on('updateCheck', 'input[name="toggle-cols"]', _updateMenuCheckbox);

      // Update checkbox status on viewport changes.
      $(window).on('orientationchange resize', _debounce(_updateCheckboxesOnViewportChange, 500));

      // Close menu when user clicks anywhere outside the menu.
      $(document).on('click', _closeMenuOnOutsideClick);
    }

    function _toggleMenuVisibility() {
      view_model.$menu.toggleClass('flexitable-menu-closed');
    }

    function _closeMenuOnOutsideClick(event) {
      if (!view_model.$menu.find(event.target).length) {
        view_model.$menu.addClass('flexitable-menu-closed');
      }
    }

    function _toggleColumn(event) {
      var checkbox = event.target;
      // NOTE: checkbox value is the same as column index from view_model.cells_by_column
      var i_col = parseInt(checkbox.value, 10);

      view_model.cells_by_column[i_col].$cells
        .toggleClass('flexitable-cell-shown', checkbox.checked)
        .toggleClass('flexitable-cell-hidden', !checkbox.checked);

      // update active state in view_model
      view_model.cells_by_column[i_col].is_visible = checkbox.checked;
    }

    function _updateMenuCheckbox(event) {
      var checkbox = event.target;
      // NOTE: checkbox value is the same as column index from view_model.cells_by_column
      var i_col = parseInt(checkbox.value, 10);

      checkbox.checked = view_model.cells_by_column[i_col].is_visible;
    }

    function _updateCheckboxesOnViewportChange() {
      var i, l, cells_by_column = view_model.cells_by_column;

      // update active state of columns
      for (i = 0, l = cells_by_column.length; i < l; i++) {
        cells_by_column[i].is_visible = (cells_by_column[i].$th.css('display') === 'table-cell');
      }
      // update all checkboxes
      view_model.$menu.$list.find('input').trigger('updateCheck');
    }
  }
})(jQuery);

/* jQuery.deferredEach docs and info:
 * https://github.com/adammessinger/jQuery.deferredEach */
(function($, undefined) {
  'use strict';

  $.deferredEach = function(collection, callback) {
    var i = 0;
    var length = collection.length;
    var is_array = _isArraylike(collection);
    var parent_deferred = new $.Deferred();
    var child_deferreds;
    var keys = [];
    var next, key;

    if (is_array) {
      child_deferreds = _makeChildDeferredsArray(length);

      next = function() {
        if (i < length && callback.call(collection[i], i, collection[i++]) !== false) {
          setTimeout(next, 1);
        }
        child_deferreds[i - 1].resolve();
        parent_deferred.notify(i / length);
      };
      next();
    } else {
      for (key in collection) {
        keys.push(key);
      }
      child_deferreds = _makeChildDeferredsArray(keys.length);

      next = function() {
        if (i < keys.length && callback.call(collection[keys[i]], keys[i], collection[keys[i++]]) !== false) {
          setTimeout(next, 1);
        }
        child_deferreds[i - 1].resolve();
        parent_deferred.notify(i / keys.length);
      };
      next();
    }

    $.when.apply(undefined, child_deferreds).then(function() {
      parent_deferred.notify(1);
      parent_deferred.resolve(collection);
    });
    return parent_deferred.promise();
  };

  function _makeChildDeferredsArray(length) {
    var i = 0;
    var array = [];

    for (; i < length; i++) {
      array.push(new $.Deferred());
    }
    return array;
  }

  function _isArraylike(obj) {
    var length = obj.length;
    var type = $.type(obj);

    if (type === "function" || $.isWindow(obj)) {
      return false;
    }
    if (obj.nodeType === 1 && length) {
      return true;
    }
    return type === "array" || length === 0 ||
           (typeof length === "number" && length > 0 && (length - 1) in obj);
  }
})(jQuery);<commit_msg>Changed an option name.<commit_after>/**
 Flexitable jQuery plugin
 Copyright (c) 2015 Adam Messinger, http://zenscope.com/
 Released under the MIT license, see LICENSE file for details.

 This plugin owes its starting point to the work of Marco Pegoraro (movableapp.com):
   https://github.com/marcopeg/MediaTable
 ...and also borrows some ideas from Tablesaw by Filament Group:
   https://github.com/filamentgroup/tablesaw
 **/

;(function($, undefined) {
  'use strict';

  $.fn.flexitable = function(user_config) {
    return this.each(function(i) {
      var $table = $(this);
      var config = $.extend({
        column_toggle: true,
        column_menu: true,
        column_button_txt: 'Columns:',
        // NOTE: takes a CSS selector; 'this' means position relative to the enhanced table
        toolbar_position_target: 'this',
        toolbar_before_or_after: 'before',
        destroy: false
      }, (user_config || {}));

      if (config.destroy) {
        columnChooser($table, config, i).destroy();
      } else if (config.column_toggle) {
        columnChooser($table, config, i).init();
      }
    });
  };

  function columnChooser($table, config, i) {
    // view_model will contain all the data we need for future DOM manipulations.
    // Much faster than revisiting the DOM repeatedly.
    var view_model = {
      id: $table[0].id,
      // cfg: this table's Flexitable config
      cfg: config,
      $table: $table,
      $toolbar: $('
'),
      // $menu: will hold column toggle menu
      $menu: null,
      // cells_by_column: array of objects w/ each col's header txt & th,
      // contained cells, and visibility & persistence states
      cells_by_column: []
    };

    // public methods
    return {
      init: initFlexitable,
      destroy: destroyFlexitable
    };

    function initFlexitable() {
      var $headers;

      // Prevent re-initialization
      if (view_model.$table.data('Flexitable')) {
        return;
      }

      // Set table ID if not specified
      if (!view_model.id) {
        view_model.id = 'flexitable-' + i;
        view_model.$table[0].id = view_model.id;
      }

      $headers = view_model.$table.find('> thead th');
      if ($headers.length) {
        // NOTE: "deferredEach" plugin is tacked onto the very bottom of this file
        $.deferredEach($headers, _initCellsByHeader)
          .done(function() {
            // 'flexitable-active' class enables media queries, once above init gives
            // proper classes to cells
            view_model.$table.addClass('flexitable-active');

            // NOTE: MUST build menu after _initCellsByHeader, not before
            if (view_model.cfg.column_menu && view_model.cells_by_column.length) {
              _buildMenu();
              _initMenuInteractions();
              _insertMenu();
            }

            view_model.$table.data('Flexitable', view_model);

            view_model.$table.trigger('flexitable.initialized');
          });
      }
    }

    function destroyFlexitable() {
      var stored_view_model = $table.data('Flexitable');

      if (!stored_view_model) {
        return;
      }

      stored_view_model.$menu.remove();
      stored_view_model.$toolbar.remove();
      // remove active class to nix Flexitable media queries
      $table.removeClass('flexitable-active');
      // remove stored plugin data on the table
      $table.removeData('Flexitable');
    }

    function _initCellsByHeader(index, header) {
      var $header = $(header);
      var priority_class = $header.data('flexitablePriorityClass');
      // NOTE: cell_num is used for nth-child selectors, which aren't 0-indexed
      var cell_num = index + 1;
      var $col_cells = view_model.$table.find('> thead th:nth-child(' + cell_num + '), > tbody td:nth-child(' + cell_num + ')');
      // cell loop vars:
      var i, l;

      for (i = 0, l = $col_cells.length; i < l; i++) {
        if (priority_class) {
          $col_cells[i].className += (' ' + priority_class);
        }
      }

      view_model.cells_by_column[index] = {
        // NOTE: we're using the th's visibility as a proxy for the column's
        is_visible: ($header.css('display') === 'table-cell'),
        $th: $header,
        heading_text: $header.text(),
        is_persistent_col: $header.hasClass('persist'),
        $cells: $col_cells
      };
    }

    // debounce: from https://github.com/twitter/typeahead.js & http://davidwalsh.name/function-debounce
    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds. If 'immediate' is passed, trigger the function on the
    // leading edge instead of the trailing.
    function _debounce(func, wait, immediate) {
      var timeout;
      var result;

      return function() {
        var context = this;
        var args = arguments;
        var later = function() {
          timeout = null;
          if (!immediate) {
            result = func.apply(context, args);
          }
        };
        var callNow = immediate && !timeout;

        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) {
          result = func.apply(context, args);
        }
        return result;
      };
    }

    function _buildMenu() {
      var cells_by_column = view_model.cells_by_column;
      var checkbox_id_pfx = (view_model.id + '_toggle-col-');
      var li_cache = [];
      var i, l, $this_checkbox, $this_label;

      // Build menu containers
      view_model.$menu = $('
');
      view_model.$menu.$button = $('<button type="button" />').text(view_model.cfg.column_button_txt);
      view_model.$menu.$list = $('
');
      view_model.$menu
        .append(view_model.$menu.$button)
        .append(view_model.$menu.$list);

      // populate menu with checkboxes for each non-persistent column
      for (i = 0, l = cells_by_column.length; i < l; i++) {
        if (!cells_by_column[i].is_persistent_col) {
          $this_checkbox = $('<input />', {
            type: 'checkbox',
            name: 'toggle-cols',
            id: (checkbox_id_pfx + i),
            value: i,
            'data-flexitable-id': view_model.id
          });
          $this_checkbox.prop('checked', cells_by_column[i].is_visible);

          $this_label = $('', {
            for: (checkbox_id_pfx + i),
            text: cells_by_column[i].heading_text
          });

          li_cache.push($('
').append($this_checkbox).append($this_label))
        }
      }

      view_model.$menu.$list.append(li_cache);
    }

    function _insertMenu() {
      var placement_target = view_model.cfg.toolbar_position_target === 'this'
        ? view_model.$table
        : $(view_model.cfg.toolbar_position_target);
      var placement_method = view_model.cfg.toolbar_before_or_after.toLowerCase() === 'after'
        ? 'insertAfter'
        : 'insertBefore';

      view_model.$toolbar
        .append(view_model.$menu)
        // Add a class to the toolbar to inform about menu presence.
        .addClass('flexitable-toolbar-has-widgets')
        [placement_method](placement_target);
    }

    function _initMenuInteractions() {
      view_model.$menu
        .on('click', 'button', _toggleMenuVisibility)
        .on('change', 'input[name="toggle-cols"]', _toggleColumn)
        .on('updateCheck', 'input[name="toggle-cols"]', _updateMenuCheckbox);

      // Update checkbox status on viewport changes.
      $(window).on('orientationchange resize', _debounce(_updateCheckboxesOnViewportChange, 500));

      // Close menu when user clicks anywhere outside the menu.
      $(document).on('click', _closeMenuOnOutsideClick);
    }

    function _toggleMenuVisibility() {
      view_model.$menu.toggleClass('flexitable-menu-closed');
    }

    function _closeMenuOnOutsideClick(event) {
      if (!view_model.$menu.find(event.target).length) {
        view_model.$menu.addClass('flexitable-menu-closed');
      }
    }

    function _toggleColumn(event) {
      var checkbox = event.target;
      // NOTE: checkbox value is the same as column index from view_model.cells_by_column
      var i_col = parseInt(checkbox.value, 10);

      view_model.cells_by_column[i_col].$cells
        .toggleClass('flexitable-cell-shown', checkbox.checked)
        .toggleClass('flexitable-cell-hidden', !checkbox.checked);

      // update active state in view_model
      view_model.cells_by_column[i_col].is_visible = checkbox.checked;
    }

    function _updateMenuCheckbox(event) {
      var checkbox = event.target;
      // NOTE: checkbox value is the same as column index from view_model.cells_by_column
      var i_col = parseInt(checkbox.value, 10);

      checkbox.checked = view_model.cells_by_column[i_col].is_visible;
    }

    function _updateCheckboxesOnViewportChange() {
      var i, l, cells_by_column = view_model.cells_by_column;

      // update active state of columns
      for (i = 0, l = cells_by_column.length; i < l; i++) {
        cells_by_column[i].is_visible = (cells_by_column[i].$th.css('display') === 'table-cell');
      }
      // update all checkboxes
      view_model.$menu.$list.find('input').trigger('updateCheck');
    }
  }
})(jQuery);

/* jQuery.deferredEach docs and info:
 * https://github.com/adammessinger/jQuery.deferredEach */
(function($, undefined) {
  'use strict';

  $.deferredEach = function(collection, callback) {
    var i = 0;
    var length = collection.length;
    var is_array = _isArraylike(collection);
    var parent_deferred = new $.Deferred();
    var child_deferreds;
    var keys = [];
    var next, key;

    if (is_array) {
      child_deferreds = _makeChildDeferredsArray(length);

      next = function() {
        if (i < length && callback.call(collection[i], i, collection[i++]) !== false) {
          setTimeout(next, 1);
        }
        child_deferreds[i - 1].resolve();
        parent_deferred.notify(i / length);
      };
      next();
    } else {
      for (key in collection) {
        keys.push(key);
      }
      child_deferreds = _makeChildDeferredsArray(keys.length);

      next = function() {
        if (i < keys.length && callback.call(collection[keys[i]], keys[i], collection[keys[i++]]) !== false) {
          setTimeout(next, 1);
        }
        child_deferreds[i - 1].resolve();
        parent_deferred.notify(i / keys.length);
      };
      next();
    }

    $.when.apply(undefined, child_deferreds).then(function() {
      parent_deferred.notify(1);
      parent_deferred.resolve(collection);
    });
    return parent_deferred.promise();
  };

  function _makeChildDeferredsArray(length) {
    var i = 0;
    var array = [];

    for (; i < length; i++) {
      array.push(new $.Deferred());
    }
    return array;
  }

  function _isArraylike(obj) {
    var length = obj.length;
    var type = $.type(obj);

    if (type === "function" || $.isWindow(obj)) {
      return false;
    }
    if (obj.nodeType === 1 && length) {
      return true;
    }
    return type === "array" || length === 0 ||
           (typeof length === "number" && length > 0 && (length - 1) in obj);
  }
})(jQuery);<|endoftext|>


<commit_before>/**
 * flexselect: a jQuery plugin, version: %RELEASE_VERSION% (%RELEASE_DATE%)
 * @requires jQuery v1.3 or later
 *
 * FlexSelect is a jQuery plugin that makes it easy to convert a select box into
 * a Quicksilver-style, autocompleting, flex matching selection tool.
 *
 * For usage and examples, visit:
 * http://rmm5t.github.com/jquery-flexselect/
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2009-2012, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
 */
(function($) {
  $.flexselect = function(select, options) { this.init(select, options); };

  $.extend($.flexselect.prototype, {
    settings: {
      allowMismatch: false,
      allowMismatchBlank: true, // If "true" a user can backspace such that the value is nothing (even if no blank value was provided in the original criteria)
      sortBy: 'score', // 'score' || 'name'
      preSelection: true,
      selectedClass: "flexselect_selected",
      dropdownClass: "flexselect_dropdown",
      inputIdTransform:    function(id)   { return id + "_flexselect"; },
      inputNameTransform:  function(name) { return; },
      dropdownIdTransform: function(id)   { return id + "_flexselect_dropdown"; }
    },
    select: null,
    input: null,
    dropdown: null,
    dropdownList: null,
    cache: [],
    results: [],
    lastAbbreviation: null,
    abbreviationBeforeFocus: null,
    selectedIndex: 0,
    picked: false,
    allowMouseMove: true,
    dropdownMouseover: false, // Workaround for poor IE behaviors

    init: function(select, options) {
      this.settings = $.extend({}, this.settings, options);
      this.select = $(select);
      this.preloadCache();
      this.renderControls();
      this.wire();
    },

    preloadCache: function() {
      this.cache = this.select.children("option").map(function() {
        return { name: $.trim($(this).text()), value: $(this).val(), score: 0.0 };
      });
    },

    renderControls: function() {
      var selected = this.settings.preSelection ? this.select.children("option:selected") : null;

      this.input = $("<input type='text' autocomplete='off' />").attr({
        id: this.settings.inputIdTransform(this.select.attr("id")),
        name: this.settings.inputNameTransform(this.select.attr("name")),
        accesskey: this.select.attr("accesskey"),
        tabindex: this.select.attr("tabindex"),
        style: this.select.attr("style"),
        placeholder: this.select.attr("data-placeholder")
      }).addClass(this.select.attr("class")).val($.trim(selected ? selected.text():  '')).css({
        visibility: 'visible'
      });

      this.dropdown = $("

").attr({
        id: this.settings.dropdownIdTransform(this.select.attr("id"))
      }).addClass(this.settings.dropdownClass);
      this.dropdownList = $("

");
      this.dropdown.append(this.dropdownList);

      this.select.after(this.input).hide();
      $("body").append(this.dropdown);
    },

    wire: function() {
      var self = this;

      this.input.click(function() {
        self.lastAbbreviation = null;
        self.focus();
      });

      this.input.mouseup(function(event) {
        // This is so Safari selection actually occurs.
        event.preventDefault();
      });

      this.input.focus(function() {
        self.abbreviationBeforeFocus = self.input.val();
        self.input.select();
        if (!self.picked) self.filterResults();
      });

      this.input.blur(function() {
        if (!self.dropdownMouseover) {
          self.hide();
          if (self.settings.allowMismatchBlank && $.trim($(this).val()) == '')
            return this.setValue('');
          if (!self.settings.allowMismatch && !self.picked)
            self.reset();
        }
      });

      this.dropdownList.mouseover(function(event) {
        if (!self.allowMouseMove) {
          self.allowMouseMove = true;
    	  return;
        }

    	if (event.target.tagName == "LI") {
          var rows = self.dropdown.find("li");
          self.markSelected(rows.index($(event.target)));
        }
      });
      this.dropdownList.mouseleave(function() {
        self.markSelected(-1);
      });
      this.dropdownList.mouseup(function(event) {
        self.pickSelected();
        self.focusAndHide();
      });
      this.dropdown.mouseover(function(event) {
        self.dropdownMouseover = true;
      });
      this.dropdown.mouseleave(function(event) {
        self.dropdownMouseover = false;
      });
      this.dropdown.mousedown(function(event) {
        event.preventDefault();
      });

      this.input.keyup(function(event) {
        switch (event.keyCode) {
          case 13: // return
            event.preventDefault();
            self.pickSelected();
            self.focusAndHide();
            break;
          case 27: // esc
            event.preventDefault();
            self.reset();
            self.focusAndHide();
            break;
          default:
            self.filterResults();
            break;
        }
      });

      this.input.keydown(function(event) {
        switch (event.keyCode) {
          case 9:  // tab
            self.pickSelected();
            self.hide();
            break;
          case 33: // pgup
            event.preventDefault();
            self.markFirst();
            break;
          case 34: // pgedown
            event.preventDefault();
            self.markLast();
            break;
          case 38: // up
            event.preventDefault();
            self.moveSelected(-1);
            break;
          case 40: // down
            event.preventDefault();
            self.moveSelected(1);
            break;
          case 13: // return
          case 27: // esc
            event.preventDefault();
            event.stopPropagation();
            break;
        }
      });

      if (this.settings.preSelection) {
        var input = this.input;
        this.select.change(function () {
          input.val($.trim($(this).children('option:selected').text()));
        });
      }
    },

    filterResults: function() {
      var abbreviation = this.input.val();
      if (abbreviation == this.lastAbbreviation) return;

      var results = [];
      $.each(this.cache, function() {
        this.score = LiquidMetal.score(this.name, abbreviation);
        if (this.score > 0.0) results.push(this);
      });
      this.results = results;

      if (this.settings.sortBy == 'score')
        this.sortResultsByScore();
      else if (this.settings.sortBy == 'name')
        this.sortResultsByName();

      this.renderDropdown();
      this.markFirst();
      this.lastAbbreviation = abbreviation;
      this.picked = false;
      this.allowMouseMove = false;
    },

    sortResultsByScore: function() {
      this.results.sort(function(a, b) { return b.score - a.score; });
    },

    sortResultsByName: function() {
      this.results.sort(function(a, b) { return a.name  b.name ? 1 : 0); });
    },

    renderDropdown: function() {
      var dropdownBorderWidth = this.dropdown.outerWidth() - this.dropdown.innerWidth();
      var inputOffset = this.input.offset();
      this.dropdown.css({
        width: (this.input.outerWidth() - dropdownBorderWidth) + "px",
        top: (inputOffset.top + this.input.outerHeight()) + "px",
        left: inputOffset.left + "px",
        maxHeight: ''
      });

      var html = '';
      $.each(this.results, function() {
        //html += '
' + this.name + ' [' + Math.round(this.score*100)/100 + ']
';
        html += '
' + this.name + '
';
      });
      this.dropdownList.html(html);
      this.adjustMaxHeight();
      this.dropdown.show();
    },

    adjustMaxHeight: function() {
      var maxTop = $(window).height() + $(window).scrollTop() - this.dropdown.outerHeight();
      var top = parseInt(this.dropdown.css('top'), 10);
      this.dropdown.css('max-height', top > maxTop ? (Math.max(0, maxTop - top + this.dropdown.innerHeight()) + 'px') : '');
    },

    markSelected: function(n) {
      if (n < 0 || n >= this.results.length) return;

      var rows = this.dropdown.find("li");
      rows.removeClass(this.settings.selectedClass);
      this.selectedIndex = n;

      var row = $(rows[n]).addClass(this.settings.selectedClass);
      var top = row.position().top;
      var delta = top + row.outerHeight() - this.dropdown.height();
      if (delta > 0) {
        this.allowMouseMove = false;
        this.dropdown.scrollTop(this.dropdown.scrollTop() + delta);
      } else if (top < 0) {
        this.allowMouseMove = false;
        this.dropdown.scrollTop(Math.max(0, this.dropdown.scrollTop() + top));
      }
    },

    pickSelected: function() {
      var selected = this.results[this.selectedIndex];
      if (selected) {
        this.input.val(selected.name);
        this.setValue(selected.value);
        this.picked = true;
      } else if (this.settings.allowMismatch) {
        this.setValue.val("");
      } else {
        this.reset();
      }
    },

    setValue: function(val) {
      if (this.select.val() === val) return;
      this.select.val(val).change();
    },

    hide: function() {
      this.dropdown.hide();
      this.lastAbbreviation = null;
    },

    moveSelected: function(n) { this.markSelected(this.selectedIndex+n); },
    markFirst:    function()  { this.markSelected(0); },
    markLast:     function()  { this.markSelected(this.results.length - 1); },
    reset:        function()  { this.input.val(this.abbreviationBeforeFocus); },
    focus:        function()  { this.input.focus(); },
    focusAndHide: function()  { this.focus(); this.hide(); }
  });

  $.fn.flexselect = function(options) {
    this.each(function() {
      if (this.tagName == "SELECT") new $.flexselect(this, options);
    });
    return this;
  };
})(jQuery);<commit_msg>Fixed invalid `this` reference<commit_after>/**
 * flexselect: a jQuery plugin, version: %RELEASE_VERSION% (%RELEASE_DATE%)
 * @requires jQuery v1.3 or later
 *
 * FlexSelect is a jQuery plugin that makes it easy to convert a select box into
 * a Quicksilver-style, autocompleting, flex matching selection tool.
 *
 * For usage and examples, visit:
 * http://rmm5t.github.com/jquery-flexselect/
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2009-2012, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
 */
(function($) {
  $.flexselect = function(select, options) { this.init(select, options); };

  $.extend($.flexselect.prototype, {
    settings: {
      allowMismatch: false,
      allowMismatchBlank: true, // If "true" a user can backspace such that the value is nothing (even if no blank value was provided in the original criteria)
      sortBy: 'score', // 'score' || 'name'
      preSelection: true,
      selectedClass: "flexselect_selected",
      dropdownClass: "flexselect_dropdown",
      inputIdTransform:    function(id)   { return id + "_flexselect"; },
      inputNameTransform:  function(name) { return; },
      dropdownIdTransform: function(id)   { return id + "_flexselect_dropdown"; }
    },
    select: null,
    input: null,
    dropdown: null,
    dropdownList: null,
    cache: [],
    results: [],
    lastAbbreviation: null,
    abbreviationBeforeFocus: null,
    selectedIndex: 0,
    picked: false,
    allowMouseMove: true,
    dropdownMouseover: false, // Workaround for poor IE behaviors

    init: function(select, options) {
      this.settings = $.extend({}, this.settings, options);
      this.select = $(select);
      this.preloadCache();
      this.renderControls();
      this.wire();
    },

    preloadCache: function() {
      this.cache = this.select.children("option").map(function() {
        return { name: $.trim($(this).text()), value: $(this).val(), score: 0.0 };
      });
    },

    renderControls: function() {
      var selected = this.settings.preSelection ? this.select.children("option:selected") : null;

      this.input = $("<input type='text' autocomplete='off' />").attr({
        id: this.settings.inputIdTransform(this.select.attr("id")),
        name: this.settings.inputNameTransform(this.select.attr("name")),
        accesskey: this.select.attr("accesskey"),
        tabindex: this.select.attr("tabindex"),
        style: this.select.attr("style"),
        placeholder: this.select.attr("data-placeholder")
      }).addClass(this.select.attr("class")).val($.trim(selected ? selected.text():  '')).css({
        visibility: 'visible'
      });

      this.dropdown = $("

").attr({
        id: this.settings.dropdownIdTransform(this.select.attr("id"))
      }).addClass(this.settings.dropdownClass);
      this.dropdownList = $("

");
      this.dropdown.append(this.dropdownList);

      this.select.after(this.input).hide();
      $("body").append(this.dropdown);
    },

    wire: function() {
      var self = this;

      this.input.click(function() {
        self.lastAbbreviation = null;
        self.focus();
      });

      this.input.mouseup(function(event) {
        // This is so Safari selection actually occurs.
        event.preventDefault();
      });

      this.input.focus(function() {
        self.abbreviationBeforeFocus = self.input.val();
        self.input.select();
        if (!self.picked) self.filterResults();
      });

      this.input.blur(function() {
        if (!self.dropdownMouseover) {
          self.hide();
          if (self.settings.allowMismatchBlank && $.trim($(this).val()) == '')
            self.setValue('');
          if (!self.settings.allowMismatch && !self.picked)
            self.reset();
        }
      });

      this.dropdownList.mouseover(function(event) {
        if (!self.allowMouseMove) {
          self.allowMouseMove = true;
    	  return;
        }

    	if (event.target.tagName == "LI") {
          var rows = self.dropdown.find("li");
          self.markSelected(rows.index($(event.target)));
        }
      });
      this.dropdownList.mouseleave(function() {
        self.markSelected(-1);
      });
      this.dropdownList.mouseup(function(event) {
        self.pickSelected();
        self.focusAndHide();
      });
      this.dropdown.mouseover(function(event) {
        self.dropdownMouseover = true;
      });
      this.dropdown.mouseleave(function(event) {
        self.dropdownMouseover = false;
      });
      this.dropdown.mousedown(function(event) {
        event.preventDefault();
      });

      this.input.keyup(function(event) {
        switch (event.keyCode) {
          case 13: // return
            event.preventDefault();
            self.pickSelected();
            self.focusAndHide();
            break;
          case 27: // esc
            event.preventDefault();
            self.reset();
            self.focusAndHide();
            break;
          default:
            self.filterResults();
            break;
        }
      });

      this.input.keydown(function(event) {
        switch (event.keyCode) {
          case 9:  // tab
            self.pickSelected();
            self.hide();
            break;
          case 33: // pgup
            event.preventDefault();
            self.markFirst();
            break;
          case 34: // pgedown
            event.preventDefault();
            self.markLast();
            break;
          case 38: // up
            event.preventDefault();
            self.moveSelected(-1);
            break;
          case 40: // down
            event.preventDefault();
            self.moveSelected(1);
            break;
          case 13: // return
          case 27: // esc
            event.preventDefault();
            event.stopPropagation();
            break;
        }
      });

      if (this.settings.preSelection) {
        var input = this.input;
        this.select.change(function () {
          input.val($.trim($(this).children('option:selected').text()));
        });
      }
    },

    filterResults: function() {
      var abbreviation = this.input.val();
      if (abbreviation == this.lastAbbreviation) return;

      var results = [];
      $.each(this.cache, function() {
        this.score = LiquidMetal.score(this.name, abbreviation);
        if (this.score > 0.0) results.push(this);
      });
      this.results = results;

      if (this.settings.sortBy == 'score')
        this.sortResultsByScore();
      else if (this.settings.sortBy == 'name')
        this.sortResultsByName();

      this.renderDropdown();
      this.markFirst();
      this.lastAbbreviation = abbreviation;
      this.picked = false;
      this.allowMouseMove = false;
    },

    sortResultsByScore: function() {
      this.results.sort(function(a, b) { return b.score - a.score; });
    },

    sortResultsByName: function() {
      this.results.sort(function(a, b) { return a.name  b.name ? 1 : 0); });
    },

    renderDropdown: function() {
      var dropdownBorderWidth = this.dropdown.outerWidth() - this.dropdown.innerWidth();
      var inputOffset = this.input.offset();
      this.dropdown.css({
        width: (this.input.outerWidth() - dropdownBorderWidth) + "px",
        top: (inputOffset.top + this.input.outerHeight()) + "px",
        left: inputOffset.left + "px",
        maxHeight: ''
      });

      var html = '';
      $.each(this.results, function() {
        //html += '
' + this.name + ' [' + Math.round(this.score*100)/100 + ']
';
        html += '
' + this.name + '
';
      });
      this.dropdownList.html(html);
      this.adjustMaxHeight();
      this.dropdown.show();
    },

    adjustMaxHeight: function() {
      var maxTop = $(window).height() + $(window).scrollTop() - this.dropdown.outerHeight();
      var top = parseInt(this.dropdown.css('top'), 10);
      this.dropdown.css('max-height', top > maxTop ? (Math.max(0, maxTop - top + this.dropdown.innerHeight()) + 'px') : '');
    },

    markSelected: function(n) {
      if (n < 0 || n >= this.results.length) return;

      var rows = this.dropdown.find("li");
      rows.removeClass(this.settings.selectedClass);
      this.selectedIndex = n;

      var row = $(rows[n]).addClass(this.settings.selectedClass);
      var top = row.position().top;
      var delta = top + row.outerHeight() - this.dropdown.height();
      if (delta > 0) {
        this.allowMouseMove = false;
        this.dropdown.scrollTop(this.dropdown.scrollTop() + delta);
      } else if (top < 0) {
        this.allowMouseMove = false;
        this.dropdown.scrollTop(Math.max(0, this.dropdown.scrollTop() + top));
      }
    },

    pickSelected: function() {
      var selected = this.results[this.selectedIndex];
      if (selected) {
        this.input.val(selected.name);
        this.setValue(selected.value);
        this.picked = true;
      } else if (this.settings.allowMismatch) {
        this.setValue.val("");
      } else {
        this.reset();
      }
    },

    setValue: function(val) {
      if (this.select.val() === val) return;
      this.select.val(val).change();
    },

    hide: function() {
      this.dropdown.hide();
      this.lastAbbreviation = null;
    },

    moveSelected: function(n) { this.markSelected(this.selectedIndex+n); },
    markFirst:    function()  { this.markSelected(0); },
    markLast:     function()  { this.markSelected(this.results.length - 1); },
    reset:        function()  { this.input.val(this.abbreviationBeforeFocus); },
    focus:        function()  { this.input.focus(); },
    focusAndHide: function()  { this.focus(); this.hide(); }
  });

  $.fn.flexselect = function(options) {
    this.each(function() {
      if (this.tagName == "SELECT") new $.flexselect(this, options);
    });
    return this;
  };
})(jQuery);<|endoftext|>


<commit_before>(function($) {

// Simple UID from http://forum.jquery.com/topic/return-unique-id-with-jquery-data-elem
var uid = 0;
$.getUID = function() {
  uid++;
  return 'jQ-uid-'+uid;
};

/**
 * Table chart plugin
 */
$.fn.tablechart = function(options) {
  var options = $.extend(true, {}, $.fn.tablechart.defaults, options);
  this.each(function(i) {
    var charts = $(this).data('tablechart') || {};
    if (charts[options.chartName] == undefined) {
      charts[options.chartName] = new $.tablechart(this, options);
      $(this).data('tablechart', charts);
    }
    charts[options.chartName].draw();
  });
  return this;
};

/**
 * Tablechart object constructor
 */
$.tablechart = function(el, options) {
  // Properties
  this.options = options;
  this.el = el;

  // Create container
  this.chartId = 'chart-' + $.getUID();
  var test = $.data(this);
  this.chartContainer = $('
').attr('id', this.chartId);

  if (options.height) { this.chartContainer.height(options.height); }
  if (options.width)  { this.chartContainer.width(options.width); }

  // Attach container
  options.attachMethod.call(this, this.chartContainer);
}

/**
 * Tablechart draw method
 */
$.tablechart.prototype.draw = function() {
  var tables, data;

  // Is matched element a table?
  if (!$.nodeName(this.el, 'table')) {
    tables = $('table', this.el);
    data = this.options.scrapeMultiple.call(this, tables);
  } else {
    tables = $(this.el);
    data = this.options.scrapeSingle.call(this, tables);
  }

  // Hide tables
  if (this.options.hideTables && $.isFunction(this.options.hideTables)) {
    this.options.hideTables.call(this, tables);
  }
  else if (this.options.hideTables) {
    tables.hide();
  }

  // Add class
  if (this.options.tableClass) {
    $(this.el).addClass(this.options.tableClass);
  }

  // @TODO Because I don't understand replotting in jqPlot (and/or it is buggy),
  // we simply clear the container and redraw.  This is possibly not ideal, but
  // it works reliably.
  $('#' + this.chartId).html('');
  if (data.series.length > 0) {
    $.extend(true, this.options.plotOptions.series, data.options);
    this.chart = $.jqplot(this.chartId, data.series, this.options.plotOptions);
  }
}

/**
 * Utility function: Scrape single table for values
 */
$.tablechart.scrapeSingle = function(table) {
  var series = [],
      options = this.options,
      tablechart = this,
      seriesOptions = [];

  if (options.headerSeriesLabels) {
    $(table).find('thead th:gt(0)').each(function(i) {
      options.plotOptions.series[i] = $.extend(
        {label: $(this).text()},
        options.plotOptions.series[i]
      );

      // Extend options with custom data attribute
      var seriesData = $(this).data('jqplotSeriesOptions');
      if (typeof seriesData != 'undefined') {
        seriesOptions[i] = seriesData;
      }
    });
  }

  $(table).find('tbody tr').each(function() {
    var x = 0, y = 0;
    $(this).find('th').each(function() {
      x = options.parseX.call(tablechart, this);
    });
    $(this).find('td').each(function(i) {
      if (!series[i]) {
        series[i] = [];
      }
      y = options.parseY.call(tablechart, this);
      series[i].push([x, y]);
    });
  });

  return { 'series' : series, 'options' : seriesOptions };
}

/**
 * Utility function: Scrape multiple tables for values
 */
$.tablechart.scrapeMultiple = function(tables) {
  var series = [],
      options = this.options,
      tablechart = this,
      seriesOptions = [];

  // Flip on magical "internal" option if scraping multiple
  if (options.headerSeriesLabels) {
    options.headerSeriesLabels = false;
    options.multitablesHeaderSeriesLabels = true;
  }

  var series_idx = 0;
  $(tables)
  .not('.jqplot-target table') // Filter out jqplot-added tables
  .each(function(i) {
    var table = this;
    seriesOptions[i] = {};

    // Extend options with custom data attribute
    var inlineOptions = $(this).data('jqplotSeriesOptions');
    if (typeof inlineOptions != 'undefined') {
      seriesOptions[i] = $.extend(seriesOptions[i], inlineOptions);
    }

    // Scrape each matched table
    data = $.tablechart.scrapeSingle.call(tablechart, this);
    series = series.concat(data.series);

    // Options passed in constructor override others
    seriesOptions[i] =  $.extend(seriesOptions[i], data.options, options.plotOptions.series[i]);
  });

  return { 'series' : series, 'options' : seriesOptions };
}

/**
 * Utility function: Parse text
 */
$.tablechart.parseText = function(el) {
  return $(el).text();
}

/**
 * Utility function: Parse text to floating point
 */
$.tablechart.parseFloat = function(el) {
  return parseFloat($(el).text());
}

/**
 * Defaults
 */
$.fn.tablechart.defaults = {
  height: null,
  width: null,
  chartName: 'default',
  headerSeriesLabels: true,
  parseX: $.tablechart.parseText,
  parseY: $.tablechart.parseFloat,
  scrapeSingle: $.tablechart.scrapeSingle,
  scrapeMultiple: $.tablechart.scrapeMultiple,
  attachMethod: function(container) { $(this.el).before(container); },
  hideTables: false,
  tableClass: 'jqplot-data',
  plotOptions: {
    series: [],
    axes:{
      xaxis: {
        renderer: $.jqplot.CategoryAxisRenderer
      }
    },
    legend: {
      show: true,
      location: 'se'
    },
    grid: {
      background: '#ffffff',
      gridLineColor: '#dddddd',
      shadow: false
    },
    seriesDefaults: {
      lineWidth: 1.5,
      shadow: false,
      markerOptions: {
        size: 7,
        shadow: false
      }
    }
  }
};

})(jQuery);
<commit_msg>Add better default colors, bar chart defaults.<commit_after>(function($) {

// Simple UID from http://forum.jquery.com/topic/return-unique-id-with-jquery-data-elem
var uid = 0;
$.getUID = function() {
  uid++;
  return 'jQ-uid-'+uid;
};

/**
 * Table chart plugin
 */
$.fn.tablechart = function(options) {
  var options = $.extend(true, {}, $.fn.tablechart.defaults, options);
  this.each(function(i) {
    var charts = $(this).data('tablechart') || {};
    if (charts[options.chartName] == undefined) {
      charts[options.chartName] = new $.tablechart(this, options);
      $(this).data('tablechart', charts);
    }
    charts[options.chartName].draw();
  });
  return this;
};

/**
 * Tablechart object constructor
 */
$.tablechart = function(el, options) {
  // Properties
  this.options = options;
  this.el = el;

  // Create container
  this.chartId = 'chart-' + $.getUID();
  var test = $.data(this);
  this.chartContainer = $('
').attr('id', this.chartId);

  if (options.height) { this.chartContainer.height(options.height); }
  if (options.width)  { this.chartContainer.width(options.width); }

  // Attach container
  options.attachMethod.call(this, this.chartContainer);
}

/**
 * Tablechart draw method
 */
$.tablechart.prototype.draw = function() {
  var tables, data;

  // Is matched element a table?
  if (!$.nodeName(this.el, 'table')) {
    tables = $('table', this.el);
    data = this.options.scrapeMultiple.call(this, tables);
  } else {
    tables = $(this.el);
    data = this.options.scrapeSingle.call(this, tables);
  }

  // Hide tables
  if (this.options.hideTables && $.isFunction(this.options.hideTables)) {
    this.options.hideTables.call(this, tables);
  }
  else if (this.options.hideTables) {
    tables.hide();
  }

  // Add class
  if (this.options.tableClass) {
    $(this.el).addClass(this.options.tableClass);
  }

  // @TODO Because I don't understand replotting in jqPlot (and/or it is buggy),
  // we simply clear the container and redraw.  This is possibly not ideal, but
  // it works reliably.
  $('#' + this.chartId).html('');
  if (data.series.length > 0) {
    $.extend(true, this.options.plotOptions.series, data.options);
    this.chart = $.jqplot(this.chartId, data.series, this.options.plotOptions);
  }
}

/**
 * Utility function: Scrape single table for values
 */
$.tablechart.scrapeSingle = function(table) {
  var series = [],
      options = this.options,
      tablechart = this,
      seriesOptions = [];

  if (options.headerSeriesLabels) {
    $(table).find('thead th:gt(0)').each(function(i) {
      options.plotOptions.series[i] = $.extend(
        {label: $(this).text()},
        options.plotOptions.series[i]
      );

      // Extend options with custom data attribute
      var seriesData = $(this).data('jqplotSeriesOptions');
      if (typeof seriesData != 'undefined') {
        seriesOptions[i] = seriesData;
      }
    });
  }

  $(table).find('tbody tr').each(function() {
    var x = 0, y = 0;
    $(this).find('th').each(function() {
      x = options.parseX.call(tablechart, this);
    });
    $(this).find('td').each(function(i) {
      if (!series[i]) {
        series[i] = [];
      }
      y = options.parseY.call(tablechart, this);
      series[i].push([x, y]);
    });
  });

  return { 'series' : series, 'options' : seriesOptions };
}

/**
 * Utility function: Scrape multiple tables for values
 */
$.tablechart.scrapeMultiple = function(tables) {
  var series = [],
      options = this.options,
      tablechart = this,
      seriesOptions = [];

  // Flip on magical "internal" option if scraping multiple
  if (options.headerSeriesLabels) {
    options.headerSeriesLabels = false;
    options.multitablesHeaderSeriesLabels = true;
  }

  var series_idx = 0;
  $(tables)
  .not('.jqplot-target table') // Filter out jqplot-added tables
  .each(function(i) {
    var table = this;
    seriesOptions[i] = {};

    // Extend options with custom data attribute
    var inlineOptions = $(this).data('jqplotSeriesOptions');
    if (typeof inlineOptions != 'undefined') {
      seriesOptions[i] = $.extend(seriesOptions[i], inlineOptions);
    }

    // Scrape each matched table
    data = $.tablechart.scrapeSingle.call(tablechart, this);
    series = series.concat(data.series);

    // Options passed in constructor override others
    seriesOptions[i] =  $.extend(seriesOptions[i], data.options, options.plotOptions.series[i]);
  });

  return { 'series' : series, 'options' : seriesOptions };
}

/**
 * Utility function: Parse text
 */
$.tablechart.parseText = function(el) {
  return $(el).text();
}

/**
 * Utility function: Parse text to floating point
 */
$.tablechart.parseFloat = function(el) {
  return parseFloat($(el).text());
}

/**
 * Defaults
 */
$.fn.tablechart.defaults = {
  height: null,
  width: null,
  chartName: 'default',
  headerSeriesLabels: true,
  parseX: $.tablechart.parseText,
  parseY: $.tablechart.parseFloat,
  scrapeSingle: $.tablechart.scrapeSingle,
  scrapeMultiple: $.tablechart.scrapeMultiple,
  attachMethod: function(container) { $(this.el).before(container); },
  hideTables: false,
  tableClass: 'jqplot-data',
  plotOptions: {
    series: [],
    seriesColors: [ '#b2182b', '#2166ac', '#542788', '#b35806', '#8073ac', '#fdb863' ],
    axes:{
      xaxis: {
        renderer: $.jqplot.CategoryAxisRenderer
      }
    },
    legend: {
      show: true,
      location: 'se'
    },
    grid: {
      background: '#ffffff',
      gridLineColor: '#dddddd',
      shadow: false
    },
    seriesDefaults: {
      lineWidth: 1.5,
      shadow: false,
      markerOptions: {
        size: 7,
        shadow: false
      },
      rendererOptions: {
        barPadding: 4
      }
    },
  }
};

})(jQuery);
<|endoftext|>


<commit_before>jQuery.event.special.touchclick = {
	setup: function (data, namespaces) {
		var elem = this,
			$elem = jQuery(elem);

		if (typeof window.ontouchstart !== "undefined") {
			$elem.on('touchstart', jQuery.event.special.touchclick.touchstart);
			$elem.on('touchmove', jQuery.event.special.touchclick.touchmove);
			$elem.on('touchend', jQuery.event.special.touchclick.touchend);
		} else {
			$elem.on("click", jQuery.event.special.touchclick.click);
		}
	},

	click: function (event) {
		event.type = "touchclick";
		jQuery.event.handle.apply(this, arguments);
	},

	teardown: function (namespaces) {
		if (typeof window.ontouchstart !== "undefined") {
			$elem.off("touchstart", jQuery.event.special.touchclick.touchstart);
			$elem.off("touchmove", jQuery.event.special.touchclick.touchmove);
			$elem.off("touchend", jQuery.event.special.touchclick.touchend);
		} else {
			$elem.off("click", jQuery.event.special.touchclick.click);
		}
	},

	touchstart: function (event) {
		this.moved = false;
		$(this).addClass("touchactive");
	},

	touchmove: function (event) {
		this.moved = true;
		$(this).removeClass("touchactive");
	},

	touchend: function (event) {
		if (!this.moved) {
			event.type = "touchclick";
			jQuery.event.handle.apply(this, arguments);
		}
		$(this).removeClass("touchactive");
	}
};<commit_msg>fixed Reference Error in teardown.<commit_after>jQuery.event.special.touchclick = {
	setup: function (data, namespaces) {
		var elem = this,
		$elem = jQuery(elem);

		if (typeof window.ontouchstart !== "undefined") {
			$elem.on('touchstart', jQuery.event.special.touchclick.touchstart);
			$elem.on('touchmove', jQuery.event.special.touchclick.touchmove);
			$elem.on('touchend', jQuery.event.special.touchclick.touchend);
		} else {
			$elem.on("click", jQuery.event.special.touchclick.click);
		}
	},

	click: function (event) {
		event.type = "touchclick";
		jQuery.event.handle.apply(this, arguments);
	},

	teardown: function (namespaces) {

		var elem = this,
		$elem = jQuery(elem);

		if (typeof window.ontouchstart !== "undefined") {
			$elem.off("touchstart", jQuery.event.special.touchclick.touchstart);
			$elem.off("touchmove", jQuery.event.special.touchclick.touchmove);
			$elem.off("touchend", jQuery.event.special.touchclick.touchend);
		} else {
			$elem.off("click", jQuery.event.special.touchclick.click);
		}
	},

	touchstart: function (event) {
		this.moved = false;
		$(this).addClass("touchactive");
	},

	touchmove: function (event) {
		this.moved = true;
		$(this).removeClass("touchactive");
	},

	touchend: function (event) {
		if (!this.moved) {
			event.type = "touchclick";
			jQuery.event.handle.apply(this, arguments);
		}
		$(this).removeClass("touchactive");
	}
};<|endoftext|>


<commit_before>(function(j){"use strict";var q=function(){Error.apply(this,arguments)};q.prototype=new Error();q.prototype.type='XML-RPC fault';var d=j.xmlrpc=function(a,b){if(arguments.length==2){b.url=a}else{b=a;a=b.url}b.dataType='xml json';b.type='POST';b.contentType='text/xml';b.converters={'xml json':d.parseDocument};var c=d.document(b.methodName,b.params);var f=new XMLSerializer();b.data=f.serializeToString(c);return j.ajax(b)};d.document=function(c,f){var g=document.implementation.createDocument(null,null,null);var e=function(a){return j(g.createElement(a))};var i=e('methodName').text(c);var h=e('params').append(j.map(f,function(a){var b=e('value').append(d.toXmlRpc(a,e));return e('param').append(b)}));var k=e('methodCall').append(i,h);g.appendChild(k.get(0));return g};var s=function(a){return(a===parseInt(a,10))&&!isNaN(a)};d.toXmlRpc=function(a,b){if(a instanceof r)return a.toXmlRpc(b);var c=j.xmlrpc.types;var f=j.type(a);switch(f){case"undefined":case"null":return c.nil.encode(a,b);case"date":return c['date.iso8601'].encode(a,b);case"object":if(a instanceof ArrayBuffer){return c.base64.encode(a,b)}else{return c.struct.encode(a,b)}break;case"number":if(s(a)){return c['int'].encode(a,b)}else{return c['double'].encode(a,b)}break;case"array":case"boolean":case"string":return c[f].encode(a,b);default:throw new Error("Unknown type",a);}};d.parseDocument=function(a){var b=j(a);var c=b.children('methodresponse');var f;var g=c.find('> fault');if(g.length===0){var e=c.find('> params > param > value > *');var i=e.toArray().map(d.parseNode);return i}else{var h=d.parseNode(g.find('> value > *').get(0));var k=new q(h.faultString);k.msg=k.message=h.faultString;k.type=k.code=h.faultCode;throw k;}};d.parseNode=function(a){var b=a.nodeName.toLowerCase();if(b in d.types){return d.types[b].decode(a)}else{throw new Error('Unknown type '+b);}};var r=function(){};j.xmlrpc.types={};d.makeType=function(f,g,e,i){var h;h=function(a){this.value=a};h.prototype=new r();h.prototype.tagName=f;if(g){var k=e,l=i;e=function(a,b){var c=k(a);return b(h.tagName).text(c)};i=function(a){return l(j(a).text(),a)}}h.prototype.toXmlRpc=function(a){return h.encode(this.value,a)};h.tagName=f;h.encode=e;h.decode=i;d.types[f]=h};var m=function(a){return''+Math.floor(a)};var n=function(a,b){return parseInt(a,10)};d.makeType('int',true,m,n),d.makeType('i4',true,m,n),d.makeType('i8',true,m,n),d.makeType('i16',true,m,n),d.makeType('i32',true,m,n),d.makeType('double',true,String,function(a){return parseFloat(a,10)});d.makeType('string',true,String,String);d.makeType('boolean',true,function(a){return a?'1':'0'},function(a){return a=='1'});var o=function(a){return a<10?'0'+a:a};d.makeType('date.iso8601',true,function(a){return[a.getUTCFullYear(),'-',o(a.getUTCMonth()+1),'-',o(a.getUTCDate()),'T',o(a.getUTCHours()),':',o(a.getUTCMinutes()),':',o(a.getUTCSeconds()),'Z'].join('')},function(a){return new Date(a)});d.binary=(function(){var k='=';var l=('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/').split("");var p=l.reduce(function(a,b,c){a[b]=c;return a},{});return{toBase64:function(a){var b=[];var c=new Uint8Array(a);var f=0,g;for(;f>18)%64]);b.push(l[(g>>12)%64]);b.push(l[(g>>6)%64]);b.push(l[(g>>0)%64])}var e=3-((a.byteLength%3)||3);while(e--){b[b.length-e-1]=k}return b.join('')},fromBase64:function(a){var b=a.length;var c=(b/4)*3;if(a.charAt(b-1)==k)c--;if(a.charAt(b-2)==k)c--;var f=new ArrayBuffer(c);var g=new Uint8Array(f);var e=0,i=0,h;for(;e>16)%256;g[i+1]=(h>>8)%256;g[i+2]=(h>>0)%256}return f}}})();d.makeType('base64',true,function(a){return d.binary.toBase64(a)},function(a){return d.binary.fromBase64(a)});d.makeType('nil',false,function(a,b){return b('nil')},function(a){return null});d.makeType('struct',false,function(g,e){var i=e('struct');j.each(g,function(a,b){var c=e('name').text(a);var f=e('value').append(d.toXmlRpc(b,e));i.append(e('member').append(c,f))});return i},function(e){return j(e).find('> member').toArray().reduce(function(a,b){var c=j(b);var f=c.find('> name').text();var g=d.parseNode(c.find('> value > *').get(0));a[f]=g;return a},{})}
<commit_msg>Minify the source<commit_after>(function(j){"use strict";var q=function(){Error.apply(this,arguments)};q.prototype=new Error();q.prototype.type='XML-RPC fault';var c=j.xmlrpc=function(a,b){if(arguments.length==2){b.url=a}else{b=a;a=b.url}b.dataType='xml json';b.type='POST';b.contentType='text/xml';b.converters={'xml json':c.parseDocument};var d=c.document(b.methodName,b.params);var f=new XMLSerializer();b.data=f.serializeToString(d);return j.ajax(b)};c.document=function(d,f){var g=document.implementation.createDocument(null,null,null);var e=function(a){return j(g.createElement(a))};var i=e('methodName').text(d);var h=e('params').append(j.map(f,function(a){var b=e('value').append(c.toXmlRpc(a,e));return e('param').append(b)}));var k=e('methodCall').append(i,h);g.appendChild(k.get(0));return g};var s=function(a){return(a===parseInt(a,10))&&!isNaN(a)};c.toXmlRpc=function(a,b){if(a instanceof r)return a.toXmlRpc(b);var d=j.xmlrpc.types;var f=j.type(a);switch(f){case"undefined":case"null":return d.nil.encode(a,b);case"date":return d['date.iso8601'].encode(a,b);case"object":if(a instanceof ArrayBuffer){return d.base64.encode(a,b)}else{return d.struct.encode(a,b)}break;case"number":if(s(a)){return d['int'].encode(a,b)}else{return d['double'].encode(a,b)}break;case"array":case"boolean":case"string":return d[f].encode(a,b);default:throw new Error("Unknown type",a);}};c.parseDocument=function(a){var b=j(a);var d=b.children('methodresponse');var f;var g=d.find('> fault');if(g.length===0){var e=d.find('> params > param > value > *');var i=e.toArray().map(c.parseNode);return i}else{var h=c.parseNode(g.find('> value > *').get(0));var k=new q(h.faultString);k.msg=k.message=h.faultString;k.type=k.code=h.faultCode;throw k;}};c.parseNode=function(a){if(a===undefined){return null}var b=a.nodeName.toLowerCase();if(b in c.types){return c.types[b].decode(a)}else{throw new Error('Unknown type '+b);}};var r=function(){};j.xmlrpc.types={};c.makeType=function(f,g,e,i){var h;h=function(a){this.value=a};h.prototype=new r();h.prototype.tagName=f;if(g){var k=e,l=i;e=function(a,b){var d=k(a);return b(h.tagName).text(d)};i=function(a){return l(j(a).text(),a)}}h.prototype.toXmlRpc=function(a){return h.encode(this.value,a)};h.tagName=f;h.encode=e;h.decode=i;c.types[f]=h};var m=function(a){return''+Math.floor(a)};var n=function(a,b){return parseInt(a,10)};c.makeType('int',true,m,n),c.makeType('i4',true,m,n),c.makeType('i8',true,m,n),c.makeType('i16',true,m,n),c.makeType('i32',true,m,n),c.makeType('double',true,String,function(a){return parseFloat(a,10)});c.makeType('string',true,String,String);c.makeType('boolean',true,function(a){return a?'1':'0'},function(a){return a=='1'});var o=function(a){return a<10?'0'+a:a};c.makeType('date.iso8601',true,function(a){return[a.getUTCFullYear(),'-',o(a.getUTCMonth()+1),'-',o(a.getUTCDate()),'T',o(a.getUTCHours()),':',o(a.getUTCMinutes()),':',o(a.getUTCSeconds()),'Z'].join('')},function(a){return new Date(a)});c.binary=(function(){var k='=';var l=('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/').split("");var p=l.reduce(function(a,b,d){a[b]=d;return a},{});return{toBase64:function(a){var b=[];var d=new Uint8Array(a);var f=0,g;for(;f>18)%64]);b.push(l[(g>>12)%64]);b.push(l[(g>>6)%64]);b.push(l[(g>>0)%64])}var e=3-((a.byteLength%3)||3);while(e--){b[b.length-e-1]=k}return b.join('')},fromBase64:function(a){var b=a.length;var d=(b/4)*3;if(a.charAt(b-1)==k)d--;if(a.charAt(b-2)==k)d--;var f=new ArrayBuffer(d);var g=new Uint8Array(f);var e=0,i=0,h;for(;e>16)%256;g[i+1]=(h>>8)%256;g[i+2]=(h>>0)%256}return f}}})();c.makeType('base64',true,function(a){return c.binary.toBase64(a)},function(a){return c.binary.fromBase64(a)});c.makeType('nil',false,function(a,b){return b('nil')},function(a){return null});c.makeType('struct',false,function(g,e){var i=e('struct');j.each(g,function(a,b){var d=e('name').text(a);var f=e('value').append(c.toXmlRpc(b,e));i.append(e('member').append(d,f))});return i},function(i){return j(i).find('> member').toArray().reduce(function(a,b){var d=j(b);var f=d.find('> name').text();var g=d.find('> value').children()[0];var e=c.parseNode(g);a[f]=e;return a},{})});c.makeType('array',false,function(d,f){var g=f('array');var e=f('data');j.each(d,function(a,b){e.append(f('value').append(c.toXmlRpc(b,f)))});g.append(e);return g},function(b){return j(b).find('> data > value').toArray().map(function(a){return j(a).children()[0]}).map(c.parseNode)});c.force=function(a,b){return new c.types[a](b)}})(jQuery);<|endoftext|>


<commit_before>module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['babel-plugin-react-native-web', '@babel/plugin-transform-runtime'],
  };
};
<commit_msg>[ncl] Do not apply babel-plugin-react-native-web when running in RN environment (#2985)<commit_after>module.exports = function(api) {
  api.cache(true);
  const plugins = process.env.REACT_NATIVE_APP_ROOT
    ? ['@babel/plugin-transform-runtime']
    : ['babel-plugin-react-native-web', '@babel/plugin-transform-runtime']
  return {
    presets: ['babel-preset-expo'],
    plugins,
  };
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import CheckList from './CheckList';

class Card extends Component {
  render() {
    return (

                 { this.props.title }

                     { this.props.description }
                     <CheckList cardId={ this.props.id } tasks={ this.props.tasks } />

 );
  }
}
export default Card;<commit_msg>add a constructor function to define a new key showDetails in the component’s state; declare a local variable called cardDetails, and only assign actual data if the current state showDetails is true. add a click event handler to change the internal state i.e. toggle the Boolean property showDetails<commit_after>import React, { Component } from 'react';
import CheckList from './CheckList';

class Card extends Component {
  constructor() {
    super(...arguments);
    this.state = {
      showDetails: false
    }
  }

  render() {
    let cardDetails;
    if (this.state.showDetails) {
      cardDetails = (

             { this.props.description }
             <CheckList cardId={ this.props.id } tasks={ this.props.tasks } />

        )
    }
    return (

 this.setState({showDetails: !this.state.showDetails}) }>
                 { this.props.title }

               {cardDetails}

 );
  }
}
export default Card;<|endoftext|>


<commit_before>class EtherAddressLookup {

    constructor()
    {
        this.setDefaultExtensionSettings();
        this.init();
    }

    setDefaultExtensionSettings()
    {
        this.blHighlight = false;
        this.strBlockchainExplorer = "https://etherscan.io/address";

        this.intSettingsCount = 0;
        this.intSettingsTotalCount = 2;
    }

    //Gets extension settings and then converts addresses to links
    init()
    {
        //Get the highlight option for the user
        chrome.runtime.sendMessage({func: "highlight_option"}, function(objResponse) {
            if(objResponse && objResponse.hasOwnProperty("resp")) {
                this.blHighlight = (objResponse.resp == 1 ? true : false);
            }
            ++this.intSettingsCount;
        }.bind(this));

        //Get the blockchain explorer for the user
        chrome.runtime.sendMessage({func: "blockchain_explorer"}, function(objResponse) {
            this.strBlockchainExplorer = objResponse.resp;
            ++this.intSettingsCount;
        }.bind(this));

        //Update the DOM once all settings have been received...
        setTimeout(function() {
            if(this.intSettingsCount === this.intSettingsTotalCount) {
                this.convertAddressToLink();
            }
        }.bind(this), 1)
    }

    //Finds Ethereum addresses and converts to a link to a block explorer
    convertAddressToLink()
    {
        var arrWhitelistedTags = new Array("code", "span", "p", "td");
        var strRegex = /(?:^|\s)((?:0x)?[0-9a-fA-F]{40})(?:\s|$)/gi;

        //Get the whitelisted nodes
        for(var i=0; i<arrWhitelistedTags.length; i++) {
            var objNodes = document.getElementsByTagName(arrWhitelistedTags[i]);
            //Loop through the whitelisted content
            for(var x=0; x<objNodes.length; x++) {
                var strContent = objNodes[x].innerText;
                if( /((?:0x)?[0-9a-fA-F]{40})/gi.exec(strContent) !== null) {
                    objNodes[x].innerHTML = strContent.replace(
                        new RegExp(strRegex, "gi"),
                        '$1'
                    );
                }
            }
        }

        if(this.blHighlight) {
            this.addHighlightStyle();
        }
    }

    //Removes the highlight style from Ethereum addresses
    removeHighlightStyle()
    {
        var objEtherAddresses = document.getElementsByClassName("ext-etheraddresslookup-link");
        for (var i = 0; i < objEtherAddresses.length; i++) {
            objEtherAddresses[i].classList.add("ext-etheraddresslookup-link-no_highlight");
            objEtherAddresses[i].classList.add("ext-etheraddresslookup-link-highlight");
        }
        return false;
    }

    //Adds the highlight style
    addHighlightStyle()
    {
        var objEtherAddresses = document.getElementsByClassName("ext-etheraddresslookup-link");
        for (var i = 0; i < objEtherAddresses.length; i++) {
            objEtherAddresses[i].classList.add("ext-etheraddresslookup-link-highlight");
            objEtherAddresses[i].classList.remove("ext-etheraddresslookup-link-no_highlight");
        }
        return false;
    }
}

window.addEventListener("load", function() {
    let objEtherAddressLookup = new EtherAddressLookup();
});

//Send message from the extension to here.
chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        let objEtherAddressLookup = new EtherAddressLookup();
        if(typeof request.func !== "undefined") {
            if(typeof objEtherAddressLookup[request.func] == "function") {
                objEtherAddressLookup[request.func]();
                sendResponse({status: "ok"});
                return true;
            }
        }
        sendResponse({status: "fail"});
    }
);<commit_msg>Opens the address block explorer in a new tab<commit_after>class EtherAddressLookup {

    constructor()
    {
        this.setDefaultExtensionSettings();
        this.init();
    }

    setDefaultExtensionSettings()
    {
        this.blHighlight = false;
        this.strBlockchainExplorer = "https://etherscan.io/address";

        this.intSettingsCount = 0;
        this.intSettingsTotalCount = 2;
    }

    //Gets extension settings and then converts addresses to links
    init()
    {
        //Get the highlight option for the user
        chrome.runtime.sendMessage({func: "highlight_option"}, function(objResponse) {
            if(objResponse && objResponse.hasOwnProperty("resp")) {
                this.blHighlight = (objResponse.resp == 1 ? true : false);
            }
            ++this.intSettingsCount;
        }.bind(this));

        //Get the blockchain explorer for the user
        chrome.runtime.sendMessage({func: "blockchain_explorer"}, function(objResponse) {
            this.strBlockchainExplorer = objResponse.resp;
            ++this.intSettingsCount;
        }.bind(this));

        //Update the DOM once all settings have been received...
        setTimeout(function() {
            if(this.intSettingsCount === this.intSettingsTotalCount) {
                this.convertAddressToLink();
            }
        }.bind(this), 1)
    }

    //Finds Ethereum addresses and converts to a link to a block explorer
    convertAddressToLink()
    {
        var arrWhitelistedTags = new Array("code", "span", "p", "td");
        var strRegex = /(?:^|\s)((?:0x)?[0-9a-fA-F]{40})(?:\s|$)/gi;

        //Get the whitelisted nodes
        for(var i=0; i<arrWhitelistedTags.length; i++) {
            var objNodes = document.getElementsByTagName(arrWhitelistedTags[i]);
            //Loop through the whitelisted content
            for(var x=0; x<objNodes.length; x++) {
                var strContent = objNodes[x].innerText;
                if( /((?:0x)?[0-9a-fA-F]{40})/gi.exec(strContent) !== null) {
                    objNodes[x].innerHTML = strContent.replace(
                        new RegExp(strRegex, "gi"),
                        '$1'
                    );
                }
            }
        }

        if(this.blHighlight) {
            this.addHighlightStyle();
        }
    }

    //Removes the highlight style from Ethereum addresses
    removeHighlightStyle()
    {
        var objEtherAddresses = document.getElementsByClassName("ext-etheraddresslookup-link");
        for (var i = 0; i < objEtherAddresses.length; i++) {
            objEtherAddresses[i].classList.add("ext-etheraddresslookup-link-no_highlight");
            objEtherAddresses[i].classList.add("ext-etheraddresslookup-link-highlight");
        }
        return false;
    }

    //Adds the highlight style
    addHighlightStyle()
    {
        var objEtherAddresses = document.getElementsByClassName("ext-etheraddresslookup-link");
        for (var i = 0; i < objEtherAddresses.length; i++) {
            objEtherAddresses[i].classList.add("ext-etheraddresslookup-link-highlight");
            objEtherAddresses[i].classList.remove("ext-etheraddresslookup-link-no_highlight");
        }
        return false;
    }
}

window.addEventListener("load", function() {
    let objEtherAddressLookup = new EtherAddressLookup();
});

//Send message from the extension to here.
chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        let objEtherAddressLookup = new EtherAddressLookup();
        if(typeof request.func !== "undefined") {
            if(typeof objEtherAddressLookup[request.func] == "function") {
                objEtherAddressLookup[request.func]();
                sendResponse({status: "ok"});
                return true;
            }
        }
        sendResponse({status: "fail"});
    }
);<|endoftext|>