<commit_before>'use strict';

import React, {
  Alert,
  AsyncStorage,
  Component,
  ListView,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';

import Firebase from 'firebase';
import Icon from 'react-native-vector-icons/FontAwesome';
import Share from 'react-native-share';

import Button from '../components/button';
import TextStyles from '../styles/text-styles';
import TitleBar from '../components/title-bar';

let database = new Firebase("poopapp1.firebaseio.com/");
let userdata = new Firebase("poopapp1.firebaseio.com/events");
class Notification extends Component {
  constructor(props) {
    super(props);
    /*const ds = new ListView.DataSource({
      rowHasChanged: (row1, row2) => row1 !== row2,
    });*/
    this.state = {
      /*dataSource: ds.cloneWithRows([
        'You have 1 new follower: tester',
        'You followed tester'
      ])*/
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      })
    };
  }

  componentDidMount() {
    var notes = [];
    {this.event(notes)};
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows([notes])
    });
  }

  render() {
    return (
      <View style = {{flex: 1}}>
        <TitleBar
          navigator = {this.props.navigator}
          text = "Notification"
        />
        <View style = {{flex:1, backgroundColor: 'white'}}>
        <ListView
          dataSource = {this.state.dataSource}
          renderRow = {(rowData) =>
            <TouchableOpacity onPress = {this.test} underlayColor = 'lemonchiffon'>
              <View style = {{flex: 1, height: 50, backgroundColor: 'azure', padding: 10, alignItems: 'center'}}>
                <Text style = {TextStyles.text}>
                  {rowData}
                </Text>
              </View>
            </TouchableOpacity>
          }
        />
        </View>
      </View>
    );
  }

  test(){
    alert ("you press an item!");
  }

  event(notes){
    userdata.on('child_removed', function (snap){
      alert ("event removed");
      notes.push("remove ya!\n");
    });
    var newItems = false;
    userdata.on('child_added',function (snap){
      if(!newItems) return;
      alert ("event added");
      notes.push("someone just added an event yo!\n");
    });
    userdata.once('value', function(snap){
      newItems = true;
    });
    userdata.on('child_changed',function (snap){
      alert ("event changed");
      notes.push("change! boi impossible! haven't implemented yet!\n");
    });
  }

  following(){
    alert ("someone stalking you!");
  }

  posts(){
    alert ("you post some random stuff!");
  }

  events() {
  }
}

module.exports = Notification;
<commit_msg>Implemented event creation notifications. Clicking on the notification navigates user to event details page.<commit_after>'use strict';

import React, {
  AsyncStorage,
  Component,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';

import Firebase from 'firebase';
import Icon from 'react-native-vector-icons/FontAwesome';
import Share from 'react-native-share';

import EventDetails from './event-details';
import GridView from '../components/grid-view';
import Button from '../components/button';
import TextStyles from '../styles/text-styles';
import TitleBar from '../components/title-bar';

let database = new Firebase("poopapp1.firebaseio.com/");

class Notification extends Component {
  constructor(props) {
    super(props);
    /*new ListView.DataSource({
      rowHasChanged: (row1, row2) => row1 !== row2,
    })*/
    this.state = {
      dataSource: []
    };
  }

  componentDidMount() {
    var self = this;

    AsyncStorage.getItem('user_data', (error, result) => {
      var loggedUserId = JSON.parse(result).uid;

      var myBlob = [];

      var notifications = database.child("users/" + loggedUserId + "/notificationList");
      notifications.once("value", function(snapshot){
        snapshot.forEach(function(snapshot){
          let item = {
            user: snapshot.val().user,
            message: snapshot.val().message,
            date: snapshot.val().date,
            type: snapshot.val().type,
            id: snapshot.val().id
          };
          myBlob.push(item);
        });

        self.setState({
          userId: loggedUserId,
          dataSource: myBlob
        });
      });
    });

    this.eventListener();
    this.followingListener();
  }

  renderRow(rowData){
    return (
      <View style = {{flex: 1}}>
        <TouchableOpacity
          onPress = {() => this.goTo(rowData)}
          underlayColor = 'lemonchiffon'>
          <View style = {{flex: 1, height: 50, backgroundColor: 'azure', alignItems: 'center', justifyContent: 'center'}}>
            <Text style = {TextStyles.text}>
              {rowData.message}
            </Text>
          </View>
        </TouchableOpacity>
      </View>
    );
  }

  queryData(){

  }

  render() {
    return (
      <View style = {{flex: 1}}>
        <TitleBar
          navigator = {this.props.navigator}
          text = "Notification"
        />
        <GridView
          dataSource = {this.state.dataSource}
          onRefresh = {this.queryData.bind(this)}
          renderRow = {this.renderRow.bind(this)}
        />
      </View>
    );
  }

  goTo(rowData){
    const navigator = this.props.navigator;
    switch(rowData.type){
      case "events":
        database.child("events/" + rowData.id).once("value", function(snapshot){
          navigator.push({component: EventDetails, state: snapshot});
        });
        break;
      case "posts":
        database.child("posts/" + rowData.id).once("value", function(snapshot){
          /*
          we need to implement a postdetails page that has everything about the post like recipe
          navigator.push({component: PostDetails, state: snapshot});
          */
        });
        break;
    }
  }

  notification(u, m, t, i){
    var item = {
      user: u,
      message: m,
      date: "need date somehow",
      type: t,
      id: i,
    };

    this.state.dataSource.push(item);

    const notificationList = database.child("users/" + this.state.userId + "/notificationList");
    notificationList.push(item);

    this.forceUpdate();
  }

  eventListener(){
    let self = this;

    const events = database.child("events");

    var size = 0;
    events.once("value", function(snapshot){
      size = snapshot.numChildren();
    });

    var firstEventRemove = true;
    events.limitToLast(1).on('child_removed', function(snapshot, prevChildKey){
      if(firstEventRemove) {
        firstEventRemove = false;
      } else {
        self.notification("User", "Event Removed", "events", snapshot.key());
      }
    });
    var firstEventAdded = true;
    events.limitToLast(1).on('child_added', function(snapshot, prevChildKey){
      if(firstEventAdded) {
        firstEventAdded = false;
      } else {
        self.notification("User", "Event Added: " + snapshot.val().title, "events", snapshot.key());
      }
      /*
      doing this doesn't work because commentList doesn't exist. i think we need
      to have a events.on("child_changed") and listen for when the first comment
      is created (which will then create a commentList) and then call the stuff below...
      const commentList = snapshot.child("commentList");
      commentList.endAt().limit(1).on("child_added", function(commentSnapshot, prevChildKey){
        self.notification("User", "Comment on Event Added", "events", snapshot.key());
      });
      commentList.endAt().limit(1).on("child_removed", function(commentSnapshot, prevChildKey){
        self.notification("User", "Comment on Event Removed", "events", snapshot.key());
      });
      */
    });
  }

  followingListener(){
  }
}

module.exports = Notification;
<|endoftext|>


<commit_before>;(function ($, window, document, undefined) {
  'use strict';

  var Pizza = {
    version : '0.0.1',

    settings : {
      donut: false,
      donut_inner_ratio: 0.4,   // between 0 and 1
      percent_offset: 35,       // relative to radius
      stroke_color: '#333',
      stroke_width: 0,
      show_percent: true,       // show or hide the percentage on the chart.
      animation_speed: 500,
      animation_type: 'elastic' // options: backin, backout, bounce, easein,
                                //          easeinout, easeout, linear
    },

    init : function (scope, options) {
      var self = this;
      this.scope = scope || document.body;

      var pies = $('[data-pie-id]', this.scope);

      if (pies.length > 1) {
        pies.each(function () {
          return self.build($(this), options);
        });
      } else {
        this.build($(this.scope), options);
      }

      this.events();
    },

    events : function () {
      var self = this;

      $(window).off('.pizza').on('resize.pizza', self.throttle(function () {
        self.init();
      }, 100));

      $(this.scope).off('.pizza').on('mouseenter.pizaa mouseleave.pizza touchstart.pizza', '[data-pie-id] li', function (e) {
        var parent = $(this).parent(),
            path = Snap($('#' + parent.data('pie-id') + ' path[data-id="s' + $(this).index() + '"]')[0]),
            text = Snap($(path.node).parent()
              .find('text[data-id="' + path.node.getAttribute('data-id') + '"]')[0]),
            settings = $(this).parent().data('settings');

        if (/start/i.test(e.type)) {
          $(path.node).siblings('path').each(function () {
            if (this.nodeName) {
              path.animate({
                transform: 's1 1 ' + path.node.getAttribute('data-cx') + ' ' + path.node.getAttribute('data-cy')
              }, settings.animation_speed, mina[settings.animation_type]);
              Snap($(this).next()[0]).animate({
                opacity: 0
              }, settings.animation_speed);
            }
          });
        }

        if (/enter|start/i.test(e.type)) {
          path.animate({
            transform: 's1.05 1.05 ' + path.node.getAttribute('data-cx') + ' ' + path.node.getAttribute('data-cy')
          }, settings.animation_speed, mina[settings.animation_type]);

          if (settings.show_percent) {
            text.animate({
              opacity: 1
            }, settings.animation_speed);
          }
        } else {
          path.animate({
            transform: 's1 1 ' + path.node.getAttribute('data-cx') + ' ' + path.node.getAttribute('data-cy')
          }, settings.animation_speed, mina[settings.animation_type]);
          text.animate({
            opacity: 0
          }, settings.animation_speed);
        }
      });
    },

    build : function(legends, options) {
      var self = this;

      var legend = legends, graph;
      legend.data('settings', $.extend({}, self.settings, options, legend.data('options')));
      self.data(legend, options || {});

      return self.update_DOM(self.pie(legend));
    },

    data : function (legend, options) {
      var data = [],
          count = 0;

      $('li', legend).each(function () {
        var segment = $(this);

        if (options.data) {
          data.push({
            value: options.data[segment.index()],
            color: segment.css('color'),
            segment: segment
          });
        } else {
          data.push({
            value: segment.data('value'),
            color: segment.css('color'),
            segment: segment
          });
        }
      });

      return legend.data('graph-data', data);
    },

    update_DOM : function (parts) {
      var legend = parts[0],
          graph = parts[1];

      return $(this.identifier(legend)).html(graph);
    },

    pie : function (legend) {
      // pie chart concept from JavaScript the
      // Definitive Guide 6th edition by David Flanagan
      var settings = legend.data('settings'),
          svg = this.svg(legend, settings),
          data = legend.data('graph-data'),
          total = 0,
          angles = [],
          start_angle = 0,
          base = $(this.identifier(legend)).width() - 4;

      for (var i = 0; i < data.length; i++) {
        total += data[i].value;
      }

      for (var i = 0; i < data.length; i++) {
        angles[i] = data[i].value / total * Math.PI * 2;
      }

      for (var i = 0; i < data.length; i++) {
        var end_angle = start_angle + angles[i];
        var cx = (base / 2),
            cy = (base / 2),
            r = ((base / 2) * 0.85);

        if (!settings.donut) {
          // Compute the two points where our wedge intersects the circle
          // These formulas are chosen so that an angle of 0 is at 12 o'clock
          // and positive angles increase clockwise
          var x1 = cx + r * Math.sin(start_angle);
          var y1 = cy - r * Math.cos(start_angle);
          var x2 = cx + r * Math.sin(end_angle);
          var y2 = cy - r * Math.cos(end_angle);

          // This is a flag for angles larger than than a half circle
          // It is required by the SVG arc drawing component
          var big = 0;
          if (end_angle - start_angle > Math.PI) big = 1;

          // This string holds the path details
          var d = "M" + cx + "," + cy +  // Start at circle center
              " L" + x1 + "," + y1 +     // Draw line to (x1,y1)
              " A" + r + "," + r +       // Draw an arc of radius r
              " 0 " + big + " 1 " +      // Arc details...
              x2 + "," + y2 +            // Arc goes to to (x2,y2)
              " Z";                      // Close path back to (cx,cy)
        }

        var existing_path = $('path[data-id="s' + i + '"]', svg.node);

        if (existing_path.length > 0) {
          var path = Snap(existing_path[0]);
        } else {
          var path = svg.path();
        }

        var percent = (data[i].value / total) * 100.0;

        // thanks to Raphael.js
        var existing_text = $('text[data-id="s' + i + '"]', svg.node);

        if (existing_text.length > 0) {
          var text = Snap(existing_text[0]);
          text.attr({
            x: cx + (r + settings.percent_offset) * Math.sin(start_angle + (angles[i] / 2)),
            y: cy - (r + settings.percent_offset) * Math.cos(start_angle + (angles[i] / 2))
          });
        } else {
          var text = path.paper.text(cx + (r + settings.percent_offset) * Math.sin(start_angle + (angles[i] / 2)),
               cy - (r + settings.percent_offset) * Math.cos(start_angle + (angles[i] / 2)), Math.ceil(percent) + '%');
        }

        var left_offset = text.getBBox().width / 2;

        text.attr({
          x: text.attr('x') - left_offset,
          opacity: 0
        });

        text.node.setAttribute('data-id', 's' + i);
        path.node.setAttribute('data-cx', cx);
        path.node.setAttribute('data-cy', cy);

        if (settings.donut) {
          this.annular_sector(path.node, {
            centerX:cx, centerY:cy,
            startDegrees:start_angle, endDegrees:end_angle,
            innerRadius: (r * settings.donut_inner_ratio), outerRadius:r
          });
        } else {
          path.attr({d:d});
        }

        path.attr({
          fill: data[i].color,
          stroke: settings.stroke_color,
          strokeWidth: settings.stroke_width
        });

        path.node.setAttribute('data-id', 's' + i);

        this.animate(path, cx, cy, settings);

        // The next wedge begins where this one ends
        start_angle = end_angle;
      }

      return [legend, svg.node];
    },

    animate : function (el, cx, cy, settings) {
      var self = this;

      el.hover(function (e) {
        var path = Snap(e.target),
            text = Snap($(path.node).parent()
              .find('text[data-id="' + path.node.getAttribute('data-id') + '"]')[0]);

        path.animate({
          transform: 's1.05 1.05 ' + cx + ' ' + cy
        }, settings.animation_speed, mina[settings.animation_type]);

        text.touchend(function () {
          path.animate({
            transform: 's1.05 1.05 ' + cx + ' ' + cy
          }, settings.animation_speed, mina[settings.animation_type]);
        });

        if (settings.show_percent) {
          text.animate({
            opacity: 1
          }, settings.animation_speed);
          text.touchend(function () {
            text.animate({
              opacity: 1
            }, settings.animation_speed);
          });
        }
      }, function (e) {
        var path = Snap(e.target),
            text = Snap($(path.node).parent()
              .find('text[data-id="' + path.node.getAttribute('data-id') + '"]')[0]);

        path.animate({
          transform: 's1 1 ' + cx + ' ' + cy
        }, settings.animation_speed, mina[settings.animation_type]);

        text.animate({
          opacity: 0
        }, settings.animation_speed);
      });
    },

    svg : function (legend, settings) {
      var container = $(this.identifier(legend)),
          svg = $('svg', container),
          width = container.width(),
          height = width;

      if (svg.length > 0) {
        svg = Snap(svg[0]);
      } else {
        svg = Snap(width, height);
      }

      svg.node.setAttribute('width', width);
      svg.node.setAttribute('height', height);
      svg.node.setAttribute('viewBox', '-10 -10 ' +
        (width + (settings.percent_offset / 1.5)) + ' ' +
        (height + (settings.percent_offset / 1.3)));

      return svg;
    },

    // http://stackoverflow.com/questions/11479185/svg-donut-slice-as-path-element-annular-sector
    annular_sector : function (path, options) {
      var opts = optionsWithDefaults(options);

      var p = [ // points
        [opts.cx + opts.r2*Math.sin(opts.startRadians),
         opts.cy - opts.r2*Math.cos(opts.startRadians)],
        [opts.cx + opts.r2*Math.sin(opts.closeRadians),
         opts.cy - opts.r2*Math.cos(opts.closeRadians)],
        [opts.cx + opts.r1*Math.sin(opts.closeRadians),
         opts.cy - opts.r1*Math.cos(opts.closeRadians)],
        [opts.cx + opts.r1*Math.sin(opts.startRadians),
         opts.cy - opts.r1*Math.cos(opts.startRadians)],
      ];

      var angleDiff = opts.closeRadians - opts.startRadians;
      var largeArc = (angleDiff % (Math.PI*2)) > Math.PI ? 1 : 0;
      var cmds = [];
      cmds.push("M"+p[0].join());                                // Move to P0
      cmds.push("A"+[opts.r2,opts.r2,0,largeArc,1,p[1]].join()); // Arc to  P1
      cmds.push("L"+p[2].join());                                // Line to P2
      cmds.push("A"+[opts.r1,opts.r1,0,largeArc,0,p[3]].join()); // Arc to  P3
      cmds.push("z");                                // Close path (Line to P0)
      path.setAttribute('d',cmds.join(' '));

      function optionsWithDefaults(o){
        // Create a new object so that we don't mutate the original
        var o2 = {
          cx           : o.centerX || 0,
          cy           : o.centerY || 0,
          startRadians : (o.startDegrees || 0),
          closeRadians : (o.endDegrees   || 0),
        };

        var t = o.thickness!==undefined ? o.thickness : 100;
        if (o.innerRadius!==undefined)      o2.r1 = o.innerRadius;
        else if (o.outerRadius!==undefined) o2.r1 = o.outerRadius - t;
        else                                o2.r1 = 200           - t;
        if (o.outerRadius!==undefined)      o2.r2 = o.outerRadius;
        else                                o2.r2 = o2.r1         + t;

        if (o2.r1<0) o2.r1 = 0;
        if (o2.r2<0) o2.r2 = 0;

        return o2;
      }
    },

    identifier : function (legend) {
      if (legend.data('pie-id')) {
        return '#' + legend.data('pie-id');
      }

      return '#' + legend.data('bar-id');
    },

    throttle : function(fun, delay) {
      var timer = null;
      return function () {
        var context = this, args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function () {
          fun.apply(context, args);
        }, delay);
      };
    }
  };

  window.Pizza = Pizza;

}($, this, this.document));<commit_msg>Fix error in selector scope check.<commit_after>;(function ($, window, document, undefined) {
  'use strict';

  var Pizza = {
    version : '0.0.1',

    settings : {
      donut: false,
      donut_inner_ratio: 0.4,   // between 0 and 1
      percent_offset: 35,       // relative to radius
      stroke_color: '#333',
      stroke_width: 0,
      show_percent: true,       // show or hide the percentage on the chart.
      animation_speed: 500,
      animation_type: 'elastic' // options: backin, backout, bounce, easein,
                                //          easeinout, easeout, linear
    },

    init : function (scope, options) {
      var self = this;
      this.scope = scope || document.body;

      var pies = $('[data-pie-id]', this.scope);

      if (pies.length > 0) {
        pies.each(function () {
          return self.build($(this), options);
        });
      } else {
        this.build($(this.scope), options);
      }

      this.events();
    },

    events : function () {
      var self = this;

      $(window).off('.pizza').on('resize.pizza', self.throttle(function () {
        self.init();
      }, 100));

      $(this.scope).off('.pizza').on('mouseenter.pizaa mouseleave.pizza touchstart.pizza', '[data-pie-id] li', function (e) {
        var parent = $(this).parent(),
            path = Snap($('#' + parent.data('pie-id') + ' path[data-id="s' + $(this).index() + '"]')[0]),
            text = Snap($(path.node).parent()
              .find('text[data-id="' + path.node.getAttribute('data-id') + '"]')[0]),
            settings = $(this).parent().data('settings');

        if (/start/i.test(e.type)) {
          $(path.node).siblings('path').each(function () {
            if (this.nodeName) {
              path.animate({
                transform: 's1 1 ' + path.node.getAttribute('data-cx') + ' ' + path.node.getAttribute('data-cy')
              }, settings.animation_speed, mina[settings.animation_type]);
              Snap($(this).next()[0]).animate({
                opacity: 0
              }, settings.animation_speed);
            }
          });
        }

        if (/enter|start/i.test(e.type)) {
          path.animate({
            transform: 's1.05 1.05 ' + path.node.getAttribute('data-cx') + ' ' + path.node.getAttribute('data-cy')
          }, settings.animation_speed, mina[settings.animation_type]);

          if (settings.show_percent) {
            text.animate({
              opacity: 1
            }, settings.animation_speed);
          }
        } else {
          path.animate({
            transform: 's1 1 ' + path.node.getAttribute('data-cx') + ' ' + path.node.getAttribute('data-cy')
          }, settings.animation_speed, mina[settings.animation_type]);
          text.animate({
            opacity: 0
          }, settings.animation_speed);
        }
      });
    },

    build : function(legends, options) {
      var self = this;

      var legend = legends, graph;

      legend.data('settings', $.extend({}, self.settings, options, legend.data('options')));
      self.data(legend, options || {});

      return self.update_DOM(self.pie(legend));
    },

    data : function (legend, options) {
      var data = [],
          count = 0;

      $('li', legend).each(function () {
        var segment = $(this);

        if (options.data) {
          data.push({
            value: options.data[segment.index()],
            color: segment.css('color'),
            segment: segment
          });
        } else {
          data.push({
            value: segment.data('value'),
            color: segment.css('color'),
            segment: segment
          });
        }
      });

      return legend.data('graph-data', data);
    },

    update_DOM : function (parts) {
      var legend = parts[0],
          graph = parts[1];

      return $(this.identifier(legend)).html(graph);
    },

    pie : function (legend) {
      // pie chart concept from JavaScript the
      // Definitive Guide 6th edition by David Flanagan
      var settings = legend.data('settings'),
          svg = this.svg(legend, settings),
          data = legend.data('graph-data'),
          total = 0,
          angles = [],
          start_angle = 0,
          base = $(this.identifier(legend)).width() - 4;

      for (var i = 0; i < data.length; i++) {
        total += data[i].value;
      }

      for (var i = 0; i < data.length; i++) {
        angles[i] = data[i].value / total * Math.PI * 2;
      }

      for (var i = 0; i < data.length; i++) {
        var end_angle = start_angle + angles[i];
        var cx = (base / 2),
            cy = (base / 2),
            r = ((base / 2) * 0.85);

        if (!settings.donut) {
          // Compute the two points where our wedge intersects the circle
          // These formulas are chosen so that an angle of 0 is at 12 o'clock
          // and positive angles increase clockwise
          var x1 = cx + r * Math.sin(start_angle);
          var y1 = cy - r * Math.cos(start_angle);
          var x2 = cx + r * Math.sin(end_angle);
          var y2 = cy - r * Math.cos(end_angle);

          // This is a flag for angles larger than than a half circle
          // It is required by the SVG arc drawing component
          var big = 0;
          if (end_angle - start_angle > Math.PI) big = 1;

          // This string holds the path details
          var d = "M" + cx + "," + cy +  // Start at circle center
              " L" + x1 + "," + y1 +     // Draw line to (x1,y1)
              " A" + r + "," + r +       // Draw an arc of radius r
              " 0 " + big + " 1 " +      // Arc details...
              x2 + "," + y2 +            // Arc goes to to (x2,y2)
              " Z";                      // Close path back to (cx,cy)
        }

        var existing_path = $('path[data-id="s' + i + '"]', svg.node);

        if (existing_path.length > 0) {
          var path = Snap(existing_path[0]);
        } else {
          var path = svg.path();
        }

        var percent = (data[i].value / total) * 100.0;

        // thanks to Raphael.js
        var existing_text = $('text[data-id="s' + i + '"]', svg.node);

        if (existing_text.length > 0) {
          var text = Snap(existing_text[0]);
          text.attr({
            x: cx + (r + settings.percent_offset) * Math.sin(start_angle + (angles[i] / 2)),
            y: cy - (r + settings.percent_offset) * Math.cos(start_angle + (angles[i] / 2))
          });
        } else {
          var text = path.paper.text(cx + (r + settings.percent_offset) * Math.sin(start_angle + (angles[i] / 2)),
               cy - (r + settings.percent_offset) * Math.cos(start_angle + (angles[i] / 2)), Math.ceil(percent) + '%');
        }

        var left_offset = text.getBBox().width / 2;

        text.attr({
          x: text.attr('x') - left_offset,
          opacity: 0
        });

        text.node.setAttribute('data-id', 's' + i);
        path.node.setAttribute('data-cx', cx);
        path.node.setAttribute('data-cy', cy);

        if (settings.donut) {
          this.annular_sector(path.node, {
            centerX:cx, centerY:cy,
            startDegrees:start_angle, endDegrees:end_angle,
            innerRadius: (r * settings.donut_inner_ratio), outerRadius:r
          });
        } else {
          path.attr({d:d});
        }

        path.attr({
          fill: data[i].color,
          stroke: settings.stroke_color,
          strokeWidth: settings.stroke_width
        });

        path.node.setAttribute('data-id', 's' + i);

        this.animate(path, cx, cy, settings);

        // The next wedge begins where this one ends
        start_angle = end_angle;
      }

      return [legend, svg.node];
    },

    animate : function (el, cx, cy, settings) {
      var self = this;

      el.hover(function (e) {
        var path = Snap(e.target),
            text = Snap($(path.node).parent()
              .find('text[data-id="' + path.node.getAttribute('data-id') + '"]')[0]);

        path.animate({
          transform: 's1.05 1.05 ' + cx + ' ' + cy
        }, settings.animation_speed, mina[settings.animation_type]);

        text.touchend(function () {
          path.animate({
            transform: 's1.05 1.05 ' + cx + ' ' + cy
          }, settings.animation_speed, mina[settings.animation_type]);
        });

        if (settings.show_percent) {
          text.animate({
            opacity: 1
          }, settings.animation_speed);
          text.touchend(function () {
            text.animate({
              opacity: 1
            }, settings.animation_speed);
          });
        }
      }, function (e) {
        var path = Snap(e.target),
            text = Snap($(path.node).parent()
              .find('text[data-id="' + path.node.getAttribute('data-id') + '"]')[0]);

        path.animate({
          transform: 's1 1 ' + cx + ' ' + cy
        }, settings.animation_speed, mina[settings.animation_type]);

        text.animate({
          opacity: 0
        }, settings.animation_speed);
      });
    },

    svg : function (legend, settings) {
      var container = $(this.identifier(legend)),
          svg = $('svg', container),
          width = container.width(),
          height = width;

      if (svg.length > 0) {
        svg = Snap(svg[0]);
      } else {
        svg = Snap(width, height);
      }

      svg.node.setAttribute('width', width);
      svg.node.setAttribute('height', height);
      svg.node.setAttribute('viewBox', '-10 -10 ' +
        (width + (settings.percent_offset / 1.5)) + ' ' +
        (height + (settings.percent_offset / 1.3)));

      return svg;
    },

    // http://stackoverflow.com/questions/11479185/svg-donut-slice-as-path-element-annular-sector
    annular_sector : function (path, options) {
      var opts = optionsWithDefaults(options);

      var p = [ // points
        [opts.cx + opts.r2*Math.sin(opts.startRadians),
         opts.cy - opts.r2*Math.cos(opts.startRadians)],
        [opts.cx + opts.r2*Math.sin(opts.closeRadians),
         opts.cy - opts.r2*Math.cos(opts.closeRadians)],
        [opts.cx + opts.r1*Math.sin(opts.closeRadians),
         opts.cy - opts.r1*Math.cos(opts.closeRadians)],
        [opts.cx + opts.r1*Math.sin(opts.startRadians),
         opts.cy - opts.r1*Math.cos(opts.startRadians)],
      ];

      var angleDiff = opts.closeRadians - opts.startRadians;
      var largeArc = (angleDiff % (Math.PI*2)) > Math.PI ? 1 : 0;
      var cmds = [];
      cmds.push("M"+p[0].join());                                // Move to P0
      cmds.push("A"+[opts.r2,opts.r2,0,largeArc,1,p[1]].join()); // Arc to  P1
      cmds.push("L"+p[2].join());                                // Line to P2
      cmds.push("A"+[opts.r1,opts.r1,0,largeArc,0,p[3]].join()); // Arc to  P3
      cmds.push("z");                                // Close path (Line to P0)
      path.setAttribute('d',cmds.join(' '));

      function optionsWithDefaults(o){
        // Create a new object so that we don't mutate the original
        var o2 = {
          cx           : o.centerX || 0,
          cy           : o.centerY || 0,
          startRadians : (o.startDegrees || 0),
          closeRadians : (o.endDegrees   || 0),
        };

        var t = o.thickness!==undefined ? o.thickness : 100;
        if (o.innerRadius!==undefined)      o2.r1 = o.innerRadius;
        else if (o.outerRadius!==undefined) o2.r1 = o.outerRadius - t;
        else                                o2.r1 = 200           - t;
        if (o.outerRadius!==undefined)      o2.r2 = o.outerRadius;
        else                                o2.r2 = o2.r1         + t;

        if (o2.r1<0) o2.r1 = 0;
        if (o2.r2<0) o2.r2 = 0;

        return o2;
      }
    },

    identifier : function (legend) {
      return '#' + legend.data('pie-id');
    },

    throttle : function(fun, delay) {
      var timer = null;
      return function () {
        var context = this, args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function () {
          fun.apply(context, args);
        }, delay);
      };
    }
  };

  window.Pizza = Pizza;

}($, this, this.document));<|endoftext|>


<commit_before>'use strict';

function randomIntFromInterval(min,max){return Math.floor(Math.random()*(max-min+1)+min);};

var markovGenerator = {
	order: 2,
	table:{},
	rigorousMode:false, // Rigorous mode is intended for scientific studies. It will stop when it lacks a key, instead of trying to continue.
	load:function(text){
		//text = text.toLowerCase();
		//text.replace(/[^a-z ]/, '');

		for (var i = this.order; i < text.length; i++){
			var entry = text.slice(i-this.order, i);
			if(Array.isArray(this.table[entry])){
				this.table[entry].push(text.charAt(i));
			}else{
				this.table[entry] = [text.charAt(i)];
			}
		}
	},
	generate:function(length, start){
		if(length == undefined){
			throw 'tooFewArguments';
		}
		if(start == undefined){
			start = this.getRandomKey(); // Random start if none was specified.
		}

		var text = start;
		while(text.length < length){
			var key = text.slice(text.length-this.order, text.length);
			var possibilities = this.table[key];

			// If the sample is too small, it'll generate strings it lacks as keys.
			if (possibilities == undefined && !this.rigorousMode){
				possibilities = this.table[this.getRandomKey()];
			}

			var letter = possibilities[randomIntFromInterval(0, possibilities.length-1)];

			text += letter;
		}

		return text;
	},

	getRandomKey:function(){
		var possibleKeys = Object.keys(this.table);
		return possibleKeys[randomIntFromInterval(0, possibleKeys.length)];
	}
}<commit_msg>Fixes an off-by-one error<commit_after>'use strict';

function randomIntFromInterval(min,max){return Math.floor(Math.random()*(max-min+1)+min);};

var markovGenerator = {
	order: 2,
	table:{},
	rigorousMode:false, // Rigorous mode is intended for scientific studies. It will stop when it lacks a key, instead of trying to continue.
	load:function(text){
		//text = text.toLowerCase();
		//text.replace(/[^a-z ]/, '');

		for (var i = this.order; i < text.length; i++){
			var entry = text.slice(i-this.order, i);
			if(Array.isArray(this.table[entry])){
				this.table[entry].push(text.charAt(i));
			}else{
				this.table[entry] = [text.charAt(i)];
			}
		}
	},
	generate:function(length, start){
		if(length == undefined){
			throw 'tooFewArguments';
		}
		if(start == undefined){
			start = this.getRandomKey(); // Random start if none was specified.
		}

		var text = start;
		while(text.length < length){
			var key = text.slice(text.length-this.order, text.length);
			var possibilities = this.table[key];

			// If the sample is too small, it'll generate strings it lacks as keys.
			if (possibilities == undefined && !this.rigorousMode){
				possibilities = this.table[this.getRandomKey()];
			}

			var letter = possibilities[randomIntFromInterval(0, possibilities.length-1)];

			text += letter;
		}

		return text;
	},

	getRandomKey:function(){
		var possibleKeys = Object.keys(this.table);
		return possibleKeys[randomIntFromInterval(0, possibleKeys.length-1)];
	}
}<|endoftext|>


<commit_before>//  elmoSlider v0.0.4 by Michal Dolny
//  dependencies: jQuery

(function($){

    $.fn.elmoSlider = function(options){
        var defaults = {
            speed: 500,
            pause: 1000,
            anim: 'slide',
            slideWidth: $(this).find('.slider-content').children().width(),
            autoPlay: false
        };
        options = $.extend(defaults, options);

        var slider = $(this);
        var state = [0];
        var i = 0;
        var j = 0;

        slider.find('.slide').each(function(){
            state[j]=-(j * $(this).width());
            j++;
        });

        slider.find('.slider-wrap').addBack('.slider-wrap').css({
            width: options.slideWidth
        })

        if(options.autoPlay === false){
            $(slider).on('click', '.slide-left', function(){
                i--;
                if( i < 0 ){ i = 2 };
                if(options.anim == 'opacity'){
                    $('.active-slide').removeClass('active-slide');
                    $('.slide'+(i+1)).addClass('active-slide');
                }else{
                    $(slider).find('.slider-content').animate({'margin-left': state[i]}, options.speed);
                };
            });
            $(slider).on('click', '.slide-right', function(){
                i++;
                if( i > 2 ){ i = 0 };
                if(options.anim == 'opacity'){
                    $('.active-slide').removeClass('active-slide');
                    $('.slide'+(i+1)).addClass('active-slide');
                }else{
                    $(slider).find('.slider-content').animate({'margin-left': state[i]}, options.speed);
                };
            });
        }

    };

})(jQuery);
<commit_msg>change css  width calculations<commit_after>//  elmoSlider v0.0.4 by Michal Dolny
//  dependencies: jQuery

(function($){

    $.fn.elmoSlider = function(options){
        var defaults = {
            speed: 500,
            pause: 1000,
            anim: 'slide',
            autoPlay: false
        };
        options = $.extend(defaults, options);

        var slider = $(this);
        var state = [0];
        var i = 0;
        var j = 0;

        slider.find('.slide').each(function(){
            state[j]=-(j * $(this).width());
            j++;
        });

        slider.find('.slider-content').css({
            width: (state.length * 100 + '%')
        });
        slider.find('.slide').css({
            width: (100 / state.length + '%')
        });

        if(options.autoPlay === false){
            $(slider).on('click', '.slide-left', function(){
                i--;
                if( i < 0 ){ i = 2 };
                if(options.anim == 'opacity'){
                    $('.active-slide').removeClass('active-slide');
                    $('.slide'+(i+1)).addClass('active-slide');
                }else{
                    $(slider).find('.slider-content').animate({'margin-left': state[i]}, options.speed);
                };
            });
            $(slider).on('click', '.slide-right', function(){
                i++;
                if( i > 2 ){ i = 0 };
                if(options.anim == 'opacity'){
                    $('.active-slide').removeClass('active-slide');
                    $('.slide'+(i+1)).addClass('active-slide');
                }else{
                    $(slider).find('.slider-content').animate({'margin-left': state[i]}, options.speed);
                };
            });
        }

    };

})(jQuery);
<|endoftext|>


<commit_before>/**
 * @preserve jquery.fullscreen 1.1.5
 * https://github.com/kayahr/jquery-fullscreen-plugin
 * Copyright (C) 2012-2013 Klaus Reimer <k@ailis.de>
 * Licensed under the MIT license
 * (See http://www.opensource.org/licenses/mit-license)
 */

(function(jQuery) {

/**
 * Sets or gets the fullscreen state.
 *
 * @param {boolean=} state
 *            True to enable fullscreen mode, false to disable it. If not
 *            specified then the current fullscreen state is returned.
 * @return {boolean|Element|jQuery|null}
 *            When querying the fullscreen state then the current fullscreen
 *            element (or true if browser doesn't support it) is returned
 *            when browser is currently in full screen mode. False is returned
 *            if browser is not in full screen mode. Null is returned if
 *            browser doesn't support fullscreen mode at all. When setting
 *            the fullscreen state then the current jQuery selection is
 *            returned for chaining.
 * @this {jQuery}
 */
function fullScreen(state)
{
    var e, func, doc;

    // Do nothing when nothing was selected
    if (!this.length) return this;

    // We only use the first selected element because it doesn't make sense
    // to fullscreen multiple elements.
    e = (/** @type {Element} */ this[0]);

    // Find the real element and the document (Depends on whether the
    // document itself or a HTML element was selected)
    if (e.ownerDocument)
    {
        doc = e.ownerDocument;
    }
    else
    {
        doc = e;
        e = doc.documentElement;
    }

    // When no state was specified then return the current state.
    if (state == null)
    {
        // When fullscreen mode is not supported then return null
        if (!((/** @type {?Function} */ doc["exitFullscreen"])
            || (/** @type {?Function} */ doc["webkitExitFullscreen"])
            || (/** @type {?Function} */ doc["webkitCancelFullScreen"])
            || (/** @type {?Function} */ doc["msExitFullscreen"])
            || (/** @type {?Function} */ doc["mozCancelFullScreen"])))
        {
            return null;
        }

        // Check fullscreen state
        state = fullScreenState(doc);
        if (!state) return state;

        // Return current fullscreen element or "true" if browser doesn't
        // support this
        return (/** @type {?Element} */ doc["fullscreenElement"])
            || (/** @type {?Element} */ doc["webkitFullscreenElement"])
            || (/** @type {?Element} */ doc["webkitCurrentFullScreenElement"])
            || (/** @type {?Element} */ doc["msFullscreenElement"])
            || (/** @type {?Element} */ doc["mozFullScreenElement"])
            || state;
    }

    // When state was specified then enter or exit fullscreen mode.
    if (state)
    {
        // Enter fullscreen
        func = (/** @type {?Function} */ e["requestFullscreen"])
            || (/** @type {?Function} */ e["webkitRequestFullscreen"])
            || (/** @type {?Function} */ e["webkitRequestFullScreen"])
            || (/** @type {?Function} */ e["msRequestFullscreen"])
            || (/** @type {?Function} */ e["mozRequestFullScreen"]);
        if (func)
        {
            func.call(e);
        }
        return this;
    }
    else
    {
        // Exit fullscreen
        func = (/** @type {?Function} */ doc["exitFullscreen"])
            || (/** @type {?Function} */ doc["webkitExitFullscreen"])
            || (/** @type {?Function} */ doc["webkitCancelFullScreen"])
            || (/** @type {?Function} */ doc["msExitFullscreen"])
            || (/** @type {?Function} */ doc["mozCancelFullScreen"]);
        if (func && fullScreenState(doc)) func.call(doc);
        return this;
    }
}

/**
 * Check fullscreen state
 *
 * @param {Document} doc The content document
 * @return {Boolean}
 */
function fullScreenState(doc) {
    return !!(doc["fullscreenElement"] || doc["msFullscreenElement"] || doc["webkitIsFullScreen"] || doc["mozFullScreen"]);
}

/**
 * Toggles the fullscreen mode.
 *
 * @return {!jQuery}
 *            The jQuery selection for chaining.
 * @this {jQuery}
 */
function toggleFullScreen()
{
    return (/** @type {!jQuery} */ fullScreen.call(this,
        !fullScreen.call(this)));
}

/**
 * Handles the browser-specific fullscreenchange event and triggers
 * a jquery event for it.
 *
 * @param {?Event} event
 *            The fullscreenchange event.
 */
function fullScreenChangeHandler(event)
{
    jQuery(document).trigger(new jQuery.Event("fullscreenchange"));
}

/**
 * Handles the browser-specific fullscreenerror event and triggers
 * a jquery event for it.
 *
 * @param {?Event} event
 *            The fullscreenerror event.
 */
function fullScreenErrorHandler(event)
{
    jQuery(document).trigger(new jQuery.Event("fullscreenerror"));
}

/**
 * Installs the fullscreenchange event handler.
 */
function installFullScreenHandlers()
{
    var e, change, error;

    // Determine event name
    e = document;
    if (e["webkitCancelFullScreen"])
    {
        change = "webkitfullscreenchange";
        error = "webkitfullscreenerror";
    }
    else if (e["msExitFullscreen"])
    {
        change = "MSFullscreenChange";
        error = "MSFullscreenError";
    }
    else if (e["mozCancelFullScreen"])
    {
        change = "mozfullscreenchange";
        error = "mozfullscreenerror";
    }
    else
    {
        change = "fullscreenchange";
        error = "fullscreenerror";
    }

    // Install the event handlers
    jQuery(document).bind(change, fullScreenChangeHandler);
    jQuery(document).bind(error, fullScreenErrorHandler);
}

jQuery.fn["fullScreen"] = fullScreen;
jQuery.fn["toggleFullScreen"] = toggleFullScreen;
installFullScreenHandlers();

})(jQuery);
<commit_msg>Remove trailing whitespaces<commit_after>/**
 * @preserve jquery.fullscreen 1.1.5
 * https://github.com/kayahr/jquery-fullscreen-plugin
 * Copyright (C) 2012-2013 Klaus Reimer <k@ailis.de>
 * Licensed under the MIT license
 * (See http://www.opensource.org/licenses/mit-license)
 */

(function(jQuery) {

/**
 * Sets or gets the fullscreen state.
 *
 * @param {boolean=} state
 *            True to enable fullscreen mode, false to disable it. If not
 *            specified then the current fullscreen state is returned.
 * @return {boolean|Element|jQuery|null}
 *            When querying the fullscreen state then the current fullscreen
 *            element (or true if browser doesn't support it) is returned
 *            when browser is currently in full screen mode. False is returned
 *            if browser is not in full screen mode. Null is returned if
 *            browser doesn't support fullscreen mode at all. When setting
 *            the fullscreen state then the current jQuery selection is
 *            returned for chaining.
 * @this {jQuery}
 */
function fullScreen(state)
{
    var e, func, doc;

    // Do nothing when nothing was selected
    if (!this.length) return this;

    // We only use the first selected element because it doesn't make sense
    // to fullscreen multiple elements.
    e = (/** @type {Element} */ this[0]);

    // Find the real element and the document (Depends on whether the
    // document itself or a HTML element was selected)
    if (e.ownerDocument)
    {
        doc = e.ownerDocument;
    }
    else
    {
        doc = e;
        e = doc.documentElement;
    }

    // When no state was specified then return the current state.
    if (state == null)
    {
        // When fullscreen mode is not supported then return null
        if (!((/** @type {?Function} */ doc["exitFullscreen"])
            || (/** @type {?Function} */ doc["webkitExitFullscreen"])
            || (/** @type {?Function} */ doc["webkitCancelFullScreen"])
            || (/** @type {?Function} */ doc["msExitFullscreen"])
            || (/** @type {?Function} */ doc["mozCancelFullScreen"])))
        {
            return null;
        }

        // Check fullscreen state
        state = fullScreenState(doc);
        if (!state) return state;

        // Return current fullscreen element or "true" if browser doesn't
        // support this
        return (/** @type {?Element} */ doc["fullscreenElement"])
            || (/** @type {?Element} */ doc["webkitFullscreenElement"])
            || (/** @type {?Element} */ doc["webkitCurrentFullScreenElement"])
            || (/** @type {?Element} */ doc["msFullscreenElement"])
            || (/** @type {?Element} */ doc["mozFullScreenElement"])
            || state;
    }

    // When state was specified then enter or exit fullscreen mode.
    if (state)
    {
        // Enter fullscreen
        func = (/** @type {?Function} */ e["requestFullscreen"])
            || (/** @type {?Function} */ e["webkitRequestFullscreen"])
            || (/** @type {?Function} */ e["webkitRequestFullScreen"])
            || (/** @type {?Function} */ e["msRequestFullscreen"])
            || (/** @type {?Function} */ e["mozRequestFullScreen"]);
        if (func)
        {
            func.call(e);
        }
        return this;
    }
    else
    {
        // Exit fullscreen
        func = (/** @type {?Function} */ doc["exitFullscreen"])
            || (/** @type {?Function} */ doc["webkitExitFullscreen"])
            || (/** @type {?Function} */ doc["webkitCancelFullScreen"])
            || (/** @type {?Function} */ doc["msExitFullscreen"])
            || (/** @type {?Function} */ doc["mozCancelFullScreen"]);
        if (func && fullScreenState(doc)) func.call(doc);
        return this;
    }
}

/**
 * Check fullscreen state
 *
 * @param {Document} doc The content document
 * @return {Boolean}
 */
function fullScreenState(doc) {
    return !!(doc["fullscreenElement"] || doc["msFullscreenElement"] || doc["webkitIsFullScreen"] || doc["mozFullScreen"]);
}

/**
 * Toggles the fullscreen mode.
 *
 * @return {!jQuery}
 *            The jQuery selection for chaining.
 * @this {jQuery}
 */
function toggleFullScreen()
{
    return (/** @type {!jQuery} */ fullScreen.call(this,
        !fullScreen.call(this)));
}

/**
 * Handles the browser-specific fullscreenchange event and triggers
 * a jquery event for it.
 *
 * @param {?Event} event
 *            The fullscreenchange event.
 */
function fullScreenChangeHandler(event)
{
    jQuery(document).trigger(new jQuery.Event("fullscreenchange"));
}

/**
 * Handles the browser-specific fullscreenerror event and triggers
 * a jquery event for it.
 *
 * @param {?Event} event
 *            The fullscreenerror event.
 */
function fullScreenErrorHandler(event)
{
    jQuery(document).trigger(new jQuery.Event("fullscreenerror"));
}

/**
 * Installs the fullscreenchange event handler.
 */
function installFullScreenHandlers()
{
    var e, change, error;

    // Determine event name
    e = document;
    if (e["webkitCancelFullScreen"])
    {
        change = "webkitfullscreenchange";
        error = "webkitfullscreenerror";
    }
    else if (e["msExitFullscreen"])
    {
        change = "MSFullscreenChange";
        error = "MSFullscreenError";
    }
    else if (e["mozCancelFullScreen"])
    {
        change = "mozfullscreenchange";
        error = "mozfullscreenerror";
    }
    else
    {
        change = "fullscreenchange";
        error = "fullscreenerror";
    }

    // Install the event handlers
    jQuery(document).bind(change, fullScreenChangeHandler);
    jQuery(document).bind(error, fullScreenErrorHandler);
}

jQuery.fn["fullScreen"] = fullScreen;
jQuery.fn["toggleFullScreen"] = toggleFullScreen;
installFullScreenHandlers();

})(jQuery);
<|endoftext|>


<commit_before>var count = function (collection, message, criteria, callback) {
  var total = 0;
  var maximum = 0;
  var maximum_id = null;
  var minimum = Infinity;
  var minimum_id = null;
  var counts = [];

  db[collection].find(criteria).forEach(function (obj) {
    var count = callback.call(obj);
    counts.push(count);
    total += count;
    if (count > maximum) {
      maximum = count;
      maximum_id = obj._id;
    }
    if (count < minimum) {
      minimum = count;
      minimum_id = obj._id;
    }
  });

  var median;
  var index = Math.floor(counts.length / 2);
  counts.sort();
  if (counts.length % 2 === 1) {
    median = counts[index];
  }
  else {
    median = (counts[index - 1] + counts[index]) / 2;
  }

  print('\n' + collection + ': ' + message);
  print('mean   ' + (Math.round(total / db[collection].count(criteria) * 10) / 10));
  print('median ' + median);
  print('max    (' + maximum_id + ') ' + maximum);
  print('min    (' + minimum_id + ') ' + minimum);
}

count('bills', 'actions', {
  actions: {
    '$ne': [],
  }
}, function () {
  return this.actions.length;
});

count('bills', 'documents', {
  documents: {
    '$ne': [],
  },
}, function () {
  return this.documents.length;
});

count('bills', 'actions.related_entities', {
  'actions.related_entities': {
    '$nin': [[], null],
  },
}, function () {
  var count = 0;
  this.actions.forEach(function (action) {
    if (action.related_entities) {
      count += action.related_entities.length;
    }
  });
  return count;
});

count('bills', 'sponsors', {
  sponsors: {
    '$ne': [],
  },
}, function () {
  return this.sponsors.length;
});

count('bills', 'primary sponsors', {
  sponsors: {
    '$ne': [],
  },
}, function () {
  var count = 0;
  this.sponsors.forEach(function (sponsor) {
    if (sponsor.type == 'primary') {
      count += 1;
    }
  });
  return count;
});

count('bills', 'versions', {
  versions: {
    '$ne': [],
  },
}, function () {
  return this.versions.length;
});

count('bills', 'title length', {
  title: {
    '$exists': true,
  },
}, function () {
  return this.title.length;
});

count('bills', 'summary length', {
  summary: {
    '$nin': ['', null],
  },
}, function () {
  return this.summary.length;
});

count('committees', 'committee length', {}, function () {
  return this.committee.length;
});

count('committees', 'members', {
  members: {
    '$ne': [],
  },
}, function () {
  return this.members.length;
});

count('committees', 'subcommittee length', {
  subcommittee: {
    '$ne': null,
  },
}, function () {
  return this.subcommittee.length;
});

count('committees', 'sponsored bills', {}, function () {
  return db.bills.count({'sponsors.committee_id': this._id});
});

count('committees', 'related bills', {}, function () {
  return db.bills.count({'actions.related_entities.id': this._id});
});

count('committees', 'actioned bills', {}, function () {
  return db.bills.count({'actions.committee': this._id});
});

count('legislators', 'full_name length', {}, function () {
  return this.full_name.length;
});

count('legislators', 'roles', {
  roles: {
    '$ne': [],
  },
}, function () {
  return this.roles.length;
});

count('legislators', 'committee roles', {
  'roles.committee': {
    '$exists': true,
  }
}, function () {
  var count = 0;
  this.roles.forEach(function (role) {
    if (role.committee) {
      count += 1;
    }
  });
  return count;
});

count('legislators', 'sponsored bills', {}, function () {
  return db.bills.count({'sponsors.leg_id': this._id});
});

count('legislators', 'related bills', {}, function () {
  return db.bills.count({'actions.related_entities.id': this._id});
});
<commit_msg>add state-level counts<commit_after>var count = function (collection, message, criteria, callback) {
  var total = 0;
  var maximum = 0;
  var maximum_id = null;
  var minimum = Infinity;
  var minimum_id = null;
  var counts = [];

  db[collection].find(criteria).forEach(function (obj) {
    var count = callback.call(obj);
    counts.push(count);
    total += count;
    if (count > maximum) {
      maximum = count;
      maximum_id = obj._id;
    }
    if (count < minimum) {
      minimum = count;
      minimum_id = obj._id;
    }
  });

  var median;
  var index = Math.floor(counts.length / 2);
  counts.sort();
  if (counts.length % 2 === 1) {
    median = counts[index];
  }
  else {
    median = (counts[index - 1] + counts[index]) / 2;
  }

  print('\n' + collection + ': ' + message);
  print('mean   ' + (Math.round(total / db[collection].count(criteria) * 10) / 10));
  print('median ' + median);
  print('max    (' + maximum_id + ') ' + maximum);
  print('min    (' + minimum_id + ') ' + minimum);
}

['bills', 'committees', 'events', 'legislators', 'votes'].forEach(function (collection) {
  count('metadata', collection, {}, function () {
    return db[collection].count({state: this._id});
  });
});
count('metadata', 'bills in current session', {}, function () {
  return db.bills.count({state: this._id, _current_session: true});
});
count('metadata', 'active legislators', {}, function () {
  return db.legislators.count({state: this._id, active: true});
});
count('metadata', 'districts', {}, function () {
  return db.districts.count({abbr: this._id});
});

count('bills', 'actions', {
  actions: {
    '$ne': [],
  }
}, function () {
  return this.actions.length;
});

count('bills', 'documents', {
  documents: {
    '$ne': [],
  },
}, function () {
  return this.documents.length;
});

count('bills', 'actions.related_entities', {
  'actions.related_entities': {
    '$nin': [[], null],
  },
}, function () {
  var count = 0;
  this.actions.forEach(function (action) {
    if (action.related_entities) {
      count += action.related_entities.length;
    }
  });
  return count;
});

count('bills', 'sponsors', {
  sponsors: {
    '$ne': [],
  },
}, function () {
  return this.sponsors.length;
});

count('bills', 'primary sponsors', {
  sponsors: {
    '$ne': [],
  },
}, function () {
  var count = 0;
  this.sponsors.forEach(function (sponsor) {
    if (sponsor.type == 'primary') {
      count += 1;
    }
  });
  return count;
});

count('bills', 'versions', {
  versions: {
    '$ne': [],
  },
}, function () {
  return this.versions.length;
});

count('bills', 'title length', {
  title: {
    '$exists': true,
  },
}, function () {
  return this.title.length;
});

count('bills', 'summary length', {
  summary: {
    '$nin': ['', null],
  },
}, function () {
  return this.summary.length;
});

count('committees', 'committee length', {}, function () {
  return this.committee.length;
});

count('committees', 'members', {
  members: {
    '$ne': [],
  },
}, function () {
  return this.members.length;
});

count('committees', 'subcommittee length', {
  subcommittee: {
    '$ne': null,
  },
}, function () {
  return this.subcommittee.length;
});

count('committees', 'sponsored bills', {}, function () {
  return db.bills.count({'sponsors.committee_id': this._id});
});

count('committees', 'related bills', {}, function () {
  return db.bills.count({'actions.related_entities.id': this._id});
});

count('committees', 'actioned bills', {}, function () {
  return db.bills.count({'actions.committee': this._id});
});

count('legislators', 'full_name length', {}, function () {
  return this.full_name.length;
});

count('legislators', 'roles', {
  roles: {
    '$ne': [],
  },
}, function () {
  return this.roles.length;
});

count('legislators', 'committee roles', {
  'roles.committee': {
    '$exists': true,
  }
}, function () {
  var count = 0;
  this.roles.forEach(function (role) {
    if (role.committee) {
      count += 1;
    }
  });
  return count;
});

count('legislators', 'sponsored bills', {}, function () {
  return db.bills.count({'sponsors.leg_id': this._id});
});

count('legislators', 'related bills', {}, function () {
  return db.bills.count({'actions.related_entities.id': this._id});
});
<|endoftext|>


<commit_before>/**
 * AJAX Nette Framwork plugin for jQuery
 *
 * @copyright Copyright (c) 2009, 2010 Jan Marek
 * @copyright Copyright (c) 2009, 2010 David Grudl
 * @copyright Copyright (c) 2012 Vojtěch Dobeš
 * @license MIT
 */

(function($, undefined) {

if (typeof $ != 'function') return;

var nette = function () {
	var inner = {
		self: this,
		initialized: false,
		contexts: {},
		extensions: {},
		on: {
			init: {},
			load: {},
			before: {},
			start: {},
			success: {},
			complete: {}
		},
		fire: function () {
			var result = true;
			var args = Array.prototype.slice.call(arguments);
			var name = args.shift();
			args.push(inner.self);
			$.each(inner.on[name], function (index, reaction) {
				var temp = reaction.apply(inner.contexts[index], args);
				return result = (temp === undefined || temp);
			});
			return result;
		},
		requestHandler: function (e) {
			e.preventDefault();
			if (inner.fire('before', this)) {
				var req = $.post(this.href, {}, function (payload) {
					inner.fire('success', payload);
				}).complete(function () {
					inner.fire('complete');
				});
				inner.fire('start', req);
			}
		}
	};

	this.ext = function (name, callbacks, context) {
		if (inner.initialized) throw 'Cannot manipulate nette-ajax extensions after initialization.';

		if (callbacks === undefined) {
			return inner.extensions[name];
		} else if (!callbacks) {
			inner.extensions[name] = undefined;
			return this;
		} else if (inner.extensions[name]) {
			throw 'Cannot override already registered nette-ajax extension.';
		} else {
			return inner.extensions[name] = {
				name: name,
				on: callbacks,
				context: context
			};
		}
	};

	this.init = function (load, loadContext) {
		if (typeof load == 'function') {
			this.ext('n:init', null);
			this.ext('n:init', {
				load: load,
			}, loadContext);
		} else if (typeof load == 'object') {
			this.ext('n:init', null);
			this.ext('n:init', load, loadContext);
		} else if (load !== undefined) {
			throw 'Argument of init() can be function or function-hash only.';
		} else {
			if (inner.initialized) throw 'Cannot initialize nette-ajax twice.';
		}

		inner.initialized = true;

		$.each(inner.extensions, function (index, extension) {
			$.each(['init', 'load', 'before', 'start', 'success', 'complete'], function (index, reaction) {
				if (extension !== undefined) {
					if (extension.on[reaction] !== undefined) {
						inner.on[reaction][extension.name] = extension.on[reaction];
					}
					inner.contexts[extension.name] = extension.context ? extension.context : {};
				}
			});
		});

		inner.fire('init');
		this.load();
		return this;
	};

	this.load = function () {
		inner.fire('load', inner.requestHandler);
	};
};

$.nette = new ($.extend(nette, $.nette ? $.nette : {}));

// default snippet handler
$.nette.ext('snippets', {
	success: function (payload) {
		if (payload.snippets) {
			for (var i in payload.snippets) {
				this.updateSnippet(i, payload.snippets[i]);
			}
		}
	}
}, {
	updateSnippet: function (id, html) {
		var $el = $('#' + id);
		// Fix for setting document title in IE
		if ($el.eq(0).tagName == 'TITLE') {
			document.title = html;
		} else {
			this.applySnippet($el, html);
		}
	},
	applySnippet: function ($el, html) {
		$el.html(html);
	}
});

// support $this->redirect()
$.nette.ext('redirect', {
	success: function (payload) {
		if (payload.redirect) {
			window.location.href = payload.redirect;
			return false;
		}
	}
});

// change URL (requires HTML5)
$.nette.ext('history', {
	before: function (ui) {
		this.href = ui.href;
	},
	success: function (payload) {
		if (payload.url) {
			this.href = payload.url;
		}
		if (!payload.signal && window.history && history.pushState && this.href) {
			history.pushState({href: this.href}, '', this.href);
		}
	}
}, {href: null});

// current page state
$.nette.ext('state', {
	success: function (payload) {
		if (payload.state) {
			this.state = payload.state;
		}
	}
}, {state: null});

// abort last request if new started
$.nette.ext('unique', {
	start: function (req) {
		if (this.req) {
			this.req.abort();
		}
		this.req = req;
	},
	complete: function () {
		this.req = null;
	}
}, {req: null});

})(jQuery);
<commit_msg>Added default ajaxification to 'a.ajax' + AJAX type changed to 'get'<commit_after>/**
 * AJAX Nette Framwork plugin for jQuery
 *
 * @copyright Copyright (c) 2009, 2010 Jan Marek
 * @copyright Copyright (c) 2009, 2010 David Grudl
 * @copyright Copyright (c) 2012 Vojtěch Dobeš
 * @license MIT
 */

(function($, undefined) {

if (typeof $ != 'function') return;

var nette = function () {
	var inner = {
		self: this,
		initialized: false,
		contexts: {},
		extensions: {},
		on: {
			init: {},
			load: {},
			before: {},
			start: {},
			success: {},
			complete: {}
		},
		fire: function () {
			var result = true;
			var args = Array.prototype.slice.call(arguments);
			var name = args.shift();
			args.push(inner.self);
			$.each(inner.on[name], function (index, reaction) {
				var temp = reaction.apply(inner.contexts[index], args);
				return result = (temp === undefined || temp);
			});
			return result;
		},
		requestHandler: function (e) {
			e.preventDefault();
			if (inner.fire('before', this)) {
				var $el, data = {};

				$el = $(this);
				var req = $.ajax({
					url: this.href,
					data: data,
					type: 'get',
					success: function (payload) {
						inner.fire('success', payload);
					},
					complete: function () {
						inner.fire('complete');
					}
				});
				inner.fire('start', req);
			}
		}
	};

	this.ext = function (name, callbacks, context) {
		if (inner.initialized) throw 'Cannot manipulate nette-ajax extensions after initialization.';

		if (callbacks === undefined) {
			return inner.extensions[name];
		} else if (!callbacks) {
			inner.extensions[name] = undefined;
			return this;
		} else if (inner.extensions[name]) {
			throw 'Cannot override already registered nette-ajax extension.';
		} else {
			return inner.extensions[name] = {
				name: name,
				on: callbacks,
				context: context
			};
		}
	};

	this.init = function (load, loadContext) {
		if (typeof load == 'function') {
			this.ext('n:init', null);
			this.ext('n:init', {
				load: load,
			}, loadContext);
		} else if (typeof load == 'object') {
			this.ext('n:init', null);
			this.ext('n:init', load, loadContext);
		} else if (load !== undefined) {
			throw 'Argument of init() can be function or function-hash only.';
		} else {
			if (inner.initialized) throw 'Cannot initialize nette-ajax twice.';
		}

		inner.initialized = true;

		$.each(inner.extensions, function (index, extension) {
			$.each(['init', 'load', 'before', 'start', 'success', 'complete'], function (index, reaction) {
				if (extension !== undefined) {
					if (extension.on[reaction] !== undefined) {
						inner.on[reaction][extension.name] = extension.on[reaction];
					}
					inner.contexts[extension.name] = extension.context ? extension.context : {};
				}
			});
		});

		inner.fire('init');
		this.load();
		return this;
	};

	this.load = function () {
		inner.fire('load', inner.requestHandler);
	};
};

$.nette = new ($.extend(nette, $.nette ? $.nette : {}));

// default snippet handler
$.nette.ext('snippets', {
	success: function (payload) {
		if (payload.snippets) {
			for (var i in payload.snippets) {
				this.updateSnippet(i, payload.snippets[i]);
			}
		}
	}
}, {
	updateSnippet: function (id, html) {
		var $el = $('#' + id);
		// Fix for setting document title in IE
		if ($el.eq(0).tagName == 'TITLE') {
			document.title = html;
		} else {
			this.applySnippet($el, html);
		}
	},
	applySnippet: function ($el, html) {
		$el.html(html);
	}
});

// support $this->redirect()
$.nette.ext('redirect', {
	success: function (payload) {
		if (payload.redirect) {
			window.location.href = payload.redirect;
			return false;
		}
	}
});

// change URL (requires HTML5)
$.nette.ext('history', {
	before: function (ui) {
		this.href = ui.href;
	},
	success: function (payload) {
		if (payload.url) {
			this.href = payload.url;
		}
		if (!payload.signal && window.history && history.pushState && this.href) {
			history.pushState({href: this.href}, '', this.href);
		}
	}
}, {href: null});

// current page state
$.nette.ext('state', {
	success: function (payload) {
		if (payload.state) {
			this.state = payload.state;
		}
	}
}, {state: null});

// abort last request if new started
$.nette.ext('unique', {
	start: function (req) {
		if (this.req) {
			this.req.abort();
		}
		this.req = req;
	},
	complete: function () {
		this.req = null;
	}
}, {req: null});

// current page state
$.nette.ext('n:init', {
	load: function (rh) {
		$(this.linkSelector).off('click', rh).on('click', rh);
	},
	success: function () {
		$.nette.load();
	}
}, {
	linkSelector: 'a.ajax'
});

})(jQuery);
<|endoftext|>