<commit_before>/* Adapted from https://gist.github.com/299789 */

/* Ismael Celis 2010
Simplified WebSocket events dispatcher (no channels, no users)

var socket = new FancyWebSocket();

// bind to server events
socket.bind('some_event', function(data){
  alert(data.name + ' says: ' + data.message)
});

// broadcast events to all connected users
socket.send( 'some_event', {name: 'ismael', message : 'Hello world'} );

The server has to send websocket data of form
  JSON.stringify({ event: EVENT_NAME, data: DATA })
*/

var FancyWebSocket = function(url){
  var conn = new WebSocket(url);

  var callbacks = {};

  this.bind = function(event_name, callback){
    callbacks[event_name] = callbacks[event_name] || [];
    callbacks[event_name].push(callback);
    return this;// chainable
  };

  this.send = function(event_name, event_data){
    var payload = JSON.stringify({event:event_name, data: event_data});
    conn.send( payload ); // <= send JSON data to socket server
    return this;
  };

  // dispatch to the right handlers
  conn.onmessage = function(evt){
    var json = JSON.parse(evt.data)
    dispatch(json.event, json.data)
  };

  conn.onclose = function(){dispatch('close',null)}
  conn.onopen = function(){dispatch('open',null)}

  var dispatch = function(event_name, message){
    var chain = callbacks[event_name];
    if(typeof chain == 'undefined') return; // no callbacks for this event
    for(var i = 0; i < chain.length; i++){
      chain[i]( message )
    }
  }
};
<commit_msg>/websocket-json-events: Fall back to MozWebSocket<commit_after>/* Adapted from https://gist.github.com/299789 */

/* Ismael Celis 2010
Simplified WebSocket events dispatcher (no channels, no users)

var socket = new FancyWebSocket();

// bind to server events
socket.bind('some_event', function(data){
  alert(data.name + ' says: ' + data.message)
});

// broadcast events to all connected users
socket.send( 'some_event', {name: 'ismael', message : 'Hello world'} );

The server has to send websocket data of form
  JSON.stringify({ event: EVENT_NAME, data: DATA })
*/

var FancyWebSocket = function(url){
  if (typeof WebSocket !== 'undefined')
    var conn = new WebSocket(url);
  else if (typeof MozWebSocket !== 'undefined')
    var conn = new MozWebSocket(url);
  else
    throw 'WebSocket seems to not be supported by this browser!';

  var callbacks = {};

  this.bind = function(event_name, callback){
    callbacks[event_name] = callbacks[event_name] || [];
    callbacks[event_name].push(callback);
    return this;// chainable
  };

  this.send = function(event_name, event_data){
    var payload = JSON.stringify({event:event_name, data: event_data});
    conn.send( payload ); // <= send JSON data to socket server
    return this;
  };

  // dispatch to the right handlers
  conn.onmessage = function(evt){
    var json = JSON.parse(evt.data)
    dispatch(json.event, json.data)
  };

  conn.onclose = function(){dispatch('close',null)}
  conn.onopen = function(){dispatch('open',null)}

  var dispatch = function(event_name, message){
    var chain = callbacks[event_name];
    if(typeof chain == 'undefined') return; // no callbacks for this event
    for(var i = 0; i < chain.length; i++){
      chain[i]( message )
    }
  }
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';

class UserSetUp extends Component {
  constructor(props) {
    super(props);

    this.state = {
      habitCategory: '',
      habit: '',
      habitID: '',
      error: false,
      redirect: false,
    };

    this.handleSelection = this.handleSelection.bind(this);
    this.handleInput = this.handleInput.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSelection(e) {
    this.setState({ habitCategory: e.target.value });
  }

  handleInput(e) {
    this.setState({ habit: e.target.value });
  }

  handleSubmit(e) {
    e.preventDefault();

    if (!this.state.habitCategory) {
      this.setState({ error: true });
      return;
    }

    fetch('/api/habits', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        Authorization: `Bearer ${this.props.token}`,
      },
      body: JSON.stringify({
        category: this.state.habitCategory,
        habit: this.state.habit,
      }),
    })
      .then(res => res.json())
      .then((json) => {
        this.props.updateState({
          habit: json.habit,
          habitCategory: json.category,
          habitID: json._id,
        }, () => this.setState({ redirect: true }));
      });
  }

  render() {
    // Use this logic to redirect the user after the submit, instead of the history.push method
    if (this.state.redirect) {
      return <Redirect to="/firstname" />;
    }
    return (

SetUp

        <form onSubmit={this.handleSubmit}>
          <select id="habit" onChange={this.handleSelection}>
            <option value="" disabled selected>Select habit category</option>
            <option value="Exercise">Exercise</option>
            <option value="Diet">Diet</option>
            <option value="Habit">Habit</option>
            <option value="Chore">Chore</option>
            <option value="Other">Other</option>
          </select>

          <input
            type="text"
            placeholder="habit"
            onChange={this.handleInput}
          />

          {this.state.error && (

Please select a habit category

          )}
          <button type="submit">submit</button>
        </form>

    );
  }
}

UserSetUp.propTypes = {
  updateState: PropTypes.func.isRequired,
  token: PropTypes.string.isRequired,
};

export default UserSetUp;
<commit_msg>changes text to lowercase in select form<commit_after>import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';

class UserSetUp extends Component {
  constructor(props) {
    super(props);

    this.state = {
      habitCategory: '',
      habit: '',
      habitID: '',
      error: false,
      redirect: false,
    };

    this.handleSelection = this.handleSelection.bind(this);
    this.handleInput = this.handleInput.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSelection(e) {
    this.setState({ habitCategory: e.target.value });
  }

  handleInput(e) {
    this.setState({ habit: e.target.value });
  }

  handleSubmit(e) {
    e.preventDefault();

    if (!this.state.habitCategory) {
      this.setState({ error: true });
      return;
    }

    fetch('/api/habits', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        Authorization: `Bearer ${this.props.token}`,
      },
      body: JSON.stringify({
        category: this.state.habitCategory,
        habit: this.state.habit,
      }),
    })
      .then(res => res.json())
      .then((json) => {
        this.props.updateState({
          habit: json.habit,
          habitCategory: json.category,
          habitID: json._id,
        }, () => this.setState({ redirect: true }));
      });
  }

  render() {
    // Use this logic to redirect the user after the submit, instead of the history.push method
    if (this.state.redirect) {
      return <Redirect to="/firstname" />;
    }
    return (

SetUp

        <form onSubmit={this.handleSubmit}>
          <select id="habit" onChange={this.handleSelection}>
            <option value="" disabled selected>Select habit category</option>
            <option value="exercise">Exercise</option>
            <option value="diet">Diet</option>
            <option value="habit">Habit</option>
            <option value="chore">Chore</option>
          </select>

          <input
            type="text"
            placeholder="habit"
            onChange={this.handleInput}
          />

          {this.state.error && (

Please select a habit category

          )}
          <button type="submit">submit</button>
        </form>

    );
  }
}

UserSetUp.propTypes = {
  updateState: PropTypes.func.isRequired,
  token: PropTypes.string.isRequired,
};

export default UserSetUp;
<|endoftext|>


<commit_before>Template.eventsList.rendered = function() {
  $('#problematicToggle').bootstrapToggle();
}

Template.eventsList.helpers({
  totalEventCount: function() {
    return EventsCount.findOne().count;
  },
  eventsStart: function() {
    var from = Session.get("EventsFromCount");
    return from;
  },
  eventsEnd: function() {
    var from = Session.get("EventsFromCount");
    return from + Events.find().count();
  },
  isLastPage: function() {
    var from = Session.get("EventsFromCount");
    var max = EventsCount.findOne().count;
    return from === (max - 10)?{class: "disabled"}:{};
  },

  isFirstPage: function() {
    var from = Session.get("EventsFromCount");
    return from === 0?{class: "disabled"}:{};
  },
  paginationElems: function() {
    var numEvt = EventsCount.findOne().count;
    var elems = [];
    var index = 0;
    for (var i=0;i<numEvt;i+=10) {
      elems[index] = {offset: i, page: index + 1};
      index++;
    }
    return elems;
  },
  isSorted: function(sortFieldName) {
    var sortingClass="sorting_poss";
    var sorting = Session.get("eventsSorting");
    if ((typeof sorting != 'undefined') && (sortFieldName === sorting.by)) {
      sortingClass = sorting.order === -1?"sorting_desc":"sorting_asc";
    }
    return sortingClass;
  },
  showProblematicOnly: function() {
    var filters = Session.get("eventsFilter");
    if (typeof filters == 'undefined'){
      filters = {isProblematic: false};
    } else if (filters.isProblematic == 'undefined') {
      filters.isProblematic = false;
    }
    return filters.isProblematic ? {checked:"checked"} : "";
  },
  jobIdFilters: function() {
    var query = {};
    query.field = "jobId";
    query.default = "∋";
    query.filters = [
      {symbol: "∈", desc: "In"},
      {symbol: "∉", desc: "Not in"}
    ];
    query.help = "
An identifier for the jobs (e.g.: dexr-comp).

The identifier can be partial, to match any job whose id contains the supplied string (e.g.: dexr to match dexr-json and dexr-gen).

Multiple identifiers can be supplied, using a whitespace as separator (e.g.: dexr-json dexr-gen).

Use ∈ to include the matching jobs in the results.

Use ∉ to exclude the matching jobs from the results.
";
    return query;
  },
  statusFilters: function() {
    var query = {};
    query.field = "status";
    query.default = "∈";
    query.filters = [
      {symbol: "∈", desc: "In"},
      {symbol: "∉", desc: "Not in"}
    ];
    query.help = "
The response HTTP status code (e.g.: 200).

Multiple codes can be supplied, using a whitespace as separator (e.g.: 200 302).

Use ∈ to include the events with the matching status codes in the results.

Use ∉ to exclude the events with the matching status codes from the results.
";
    return query;
  },
  sizeFilters: function() {
    var query = {};
    query.field = "size";
    query.default = "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The size of the response message, in bytes.

Use ≥ to include all the events whose size was larger than or equal to the supplied number and ≤ to include all the events whose size was smaller than or equal to the supplied number.

Use [,] and supply 2 sizes separated by a whitespace to include all events whose size was between the supplied numbers.
";
    return query;
  },
  obsFilters: function() {
    var query = {};
    query.field = "obs";
    query.default = "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The number of observations included in the response message.

Use ≥ to include all the events whose number of observations was larger than or equal to the supplied number and ≤ to include all the events whose number of observations was smaller than or equal to the supplied number.

Use [,] and supply 2 numbers separated by a whitespace to include all events whose number of observations was between the supplied numbers.
";
    return query;
  },
  seriesFilters: function() {
    var query = {};
    query.field = "series";
    query.default = "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The number of series included in the response message.

Use ≥ to include all the events whose number of series was larger than or equal to the supplied number and ≤ to include all the events whose number of series was smaller than or equal to the supplied number.

Use [,] and supply 2 numbers separated by a whitespace to include all events whose number of series was between the supplied numbers.
";
    return query;
  },
  rtFilters: function() {
    var query = {};
    query.field = "responseTime";
    query.default = "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The time it took to receive the response, in milliseconds.

Use ≥ to include all the events that took longer to complete than to the supplied number and ≤ to include all the events that finished faster than the supplied number.

Use [,] and supply 2 numbers separated by a whitespace to include all events that finished within the supplied times.
";
    return query;
  },
  etimeFilters: function() {
    var query = {};
    query.field = "etime";
    query.default = "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The time when the query was executed, in the ISO8601 format (e.g.: 2015-03-24T09:02:00+01:00).

Partial dates can be supplied (e.g.: 2015, 2015-01, 2015-01-01, etc.)

Use ≥ to include all the events that were executed at or after the supplied time and ≤ to include all the events that were executed at or before the supplied time.

Use [,] and supply 2 timestamps separated by a whitespace to include all events that were executed between the 2 supplied times (e.g.: 2015-03-24T09:02:00+01:00 2015-03-24T11:02:00+01:00).
";
    return query;
  }
});

Template.eventsList.events({
  'change #problematicToggle': function(e) {
    applyFilters();
  },
  'click .sortByJobId': function(e) {
    e.preventDefault();
    triggerSort("jobId");
  },
  'click .sortByETime': function(e) {
    e.preventDefault();
    triggerSort("etime");
  },
  'click .sortByStatus': function(e) {
    e.preventDefault();
    triggerSort("status");
  },
  'click .sortByResponseTime': function(e) {
    e.preventDefault();
    triggerSort("responseTime");
  },
  'click .sortBySeries': function(e) {
    e.preventDefault();
    triggerSort("series");
  },
  'click .sortByObservations': function(e) {
    e.preventDefault();
    triggerSort("observations");
  },
  'click .sortBySize': function(e) {
    e.preventDefault();
    triggerSort("size");
  },
  'click .firstEvents': function (e) {
    e.preventDefault();
    Router.go("eventsList" , {fromCount: 0});
  },
  'click .previousEvents': function (e) {
    e.preventDefault();
    var from = Session.get("EventsFromCount");
    Router.go("eventsList" , {fromCount: (from >= 10)?(from-10):0});
  },
  'click .nextEvents': function (e) {
    e.preventDefault();
    var from = Session.get("EventsFromCount");
    var max = EventsCount.findOne().count;
    Router.go("eventsList" , {fromCount: (from + 10 <= max-10)?(from+10):(max-10)});
  },
  'click .lastEvents': function (e) {
    e.preventDefault();
    Router.go("eventsList" , {fromCount: (EventsCount.findOne().count - 10 )});
  },
  'click #filterBtn': function (e) {
    $("#filtersRow").toggleClass('hide');
    $("#runFiltersBtn").toggleClass('hide');
  },
  'click #runFiltersBtn':function(e) {
    applyFilters();
  },
  'submit form': function(e) {
    e.preventDefault();
    applyFilters();
  }
});

var triggerSort = function(sortField) {
  var sorting = Session.get("eventsSorting");
  if (typeof sorting == 'undefined') {
    sorting = {by: sortField, order: 1};
    Session.set("eventsSorting", sorting);
  }
  if (sorting.by === sortField) {
    sorting.order === 1?sorting.order=-1:sorting.order=1;
  }
  else {
    sorting.by = sortField
  }
  Session.set("eventsSorting", sorting);
};

var mapOperator = function(operator) {
  var value;
  switch(operator) {
    case "≥":
      value = "gte";
      break;
    case "≤":
      value = "lte";
      break;
    case "[,]":
      value = "rg";
      break;
    case "∋":
      value = "in";
      break;
    case "∉":
      value = "nin";
      break;
  }
  return value;
}

var applyFilters = function() {
  var query = {};
  $('#filtersRow').find('input').each(function(index) {
    var value = $(this).val();
    if (value) {
      var field = $(this).attr("id");
      var symbol = $(this).closest('div').find("button").first().text();
      var mSymbol = mapOperator(symbol)
      query[field] = {
        op: mSymbol,
        val: value
      }
    }
  });

  var isProblematic = $("#problematicToggle").prop('checked');
  query.isProblematic = isProblematic;
  Session.set("eventsFilter", query);
}
<commit_msg>Preserve user choices for the event filters<commit_after>Template.eventsList.rendered = function() {
  $('#problematicToggle').bootstrapToggle();
}

Template.eventsList.helpers({
  totalEventCount: function() {
    return EventsCount.findOne().count;
  },
  eventsStart: function() {
    var from = Session.get("EventsFromCount");
    return from;
  },
  eventsEnd: function() {
    var from = Session.get("EventsFromCount");
    return from + Events.find().count();
  },
  isLastPage: function() {
    var from = Session.get("EventsFromCount");
    var max = EventsCount.findOne().count;
    return from === (max - 10)?{class: "disabled"}:{};
  },

  isFirstPage: function() {
    var from = Session.get("EventsFromCount");
    return from === 0?{class: "disabled"}:{};
  },
  paginationElems: function() {
    var numEvt = EventsCount.findOne().count;
    var elems = [];
    var index = 0;
    for (var i=0;i<numEvt;i+=10) {
      elems[index] = {offset: i, page: index + 1};
      index++;
    }
    return elems;
  },
  isSorted: function(sortFieldName) {
    var sortingClass="sorting_poss";
    var sorting = Session.get("eventsSorting");
    if ((typeof sorting != 'undefined') && (sortFieldName === sorting.by)) {
      sortingClass = sorting.order === -1?"sorting_desc":"sorting_asc";
    }
    return sortingClass;
  },
  showProblematicOnly: function() {
    var filters = Session.get("eventsFilter");
    if (typeof filters == 'undefined'){
      filters = {isProblematic: false};
    } else if (filters.isProblematic == 'undefined') {
      filters.isProblematic = false;
    }
    return filters.isProblematic ? {checked:"checked"} : "";
  },
  jobIdFilters: function() {
    var filters = Session.get("eventsFilter") || {};
    var query = {};
    query.field = "jobId";
    query.default = filters.hasOwnProperty(query.field) ? mapOperatorToSymbol(filters[query.field].op) : "∋";
    query.filters = [
      {symbol: "∈", desc: "In"},
      {symbol: "∉", desc: "Not in"}
    ];
    query.help = "
An identifier for the jobs (e.g.: dexr-comp).

The identifier can be partial, to match any job whose id contains the supplied string (e.g.: dexr to match dexr-json and dexr-gen).

Multiple identifiers can be supplied, using a whitespace as separator (e.g.: dexr-json dexr-gen).

Use ∈ to include the matching jobs in the results.

Use ∉ to exclude the matching jobs from the results.
";
    query.fieldValue = filters.hasOwnProperty(query.field) ? filters[query.field].val : "";
    return query;
  },
  statusFilters: function() {
    var filters = Session.get("eventsFilter") || {};
    var query = {};
    query.field = "status";
    query.default = filters.hasOwnProperty(query.field) ? mapOperatorToSymbol(filters[query.field].op) : "∈";
    query.filters = [
      {symbol: "∈", desc: "In"},
      {symbol: "∉", desc: "Not in"}
    ];
    query.help = "
The response HTTP status code (e.g.: 200).

Multiple codes can be supplied, using a whitespace as separator (e.g.: 200 302).

Use ∈ to include the events with the matching status codes in the results.

Use ∉ to exclude the events with the matching status codes from the results.
";
    query.fieldValue = filters.hasOwnProperty(query.field) ? filters[query.field].val : "";
    return query;
  },
  sizeFilters: function() {
    var filters = Session.get("eventsFilter") || {};
    var query = {};
    query.field = "size";
    query.default = filters.hasOwnProperty(query.field) ? mapOperatorToSymbol(filters[query.field].op) : "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The size of the response message, in bytes.

Use ≥ to include all the events whose size was larger than or equal to the supplied number and ≤ to include all the events whose size was smaller than or equal to the supplied number.

Use [,] and supply 2 sizes separated by a whitespace to include all events whose size was between the supplied numbers.
";
    query.fieldValue = filters.hasOwnProperty(query.field) ? filters[query.field].val : "";
    return query;
  },
  obsFilters: function() {
    var filters = Session.get("eventsFilter") || {};
    var query = {};
    query.field = "obs";
    query.default = filters.hasOwnProperty(query.field) ? mapOperatorToSymbol(filters[query.field].op) : "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The number of observations included in the response message.

Use ≥ to include all the events whose number of observations was larger than or equal to the supplied number and ≤ to include all the events whose number of observations was smaller than or equal to the supplied number.

Use [,] and supply 2 numbers separated by a whitespace to include all events whose number of observations was between the supplied numbers.
";
    query.fieldValue = filters.hasOwnProperty(query.field) ? filters[query.field].val : "";
    return query;
  },
  seriesFilters: function() {
    var filters = Session.get("eventsFilter") || {};
    var query = {};
    query.field = "series";
    query.default = filters.hasOwnProperty(query.field) ? mapOperatorToSymbol(filters[query.field].op) : "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The number of series included in the response message.

Use ≥ to include all the events whose number of series was larger than or equal to the supplied number and ≤ to include all the events whose number of series was smaller than or equal to the supplied number.

Use [,] and supply 2 numbers separated by a whitespace to include all events whose number of series was between the supplied numbers.
";
    query.fieldValue = filters.hasOwnProperty(query.field) ? filters[query.field].val : "";
    return query;
  },
  rtFilters: function() {
    var filters = Session.get("eventsFilter") || {};
    var query = {};
    query.field = "responseTime";
    query.default = filters.hasOwnProperty(query.field) ? mapOperatorToSymbol(filters[query.field].op) : "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The time it took to receive the response, in milliseconds.

Use ≥ to include all the events that took longer to complete than to the supplied number and ≤ to include all the events that finished faster than the supplied number.

Use [,] and supply 2 numbers separated by a whitespace to include all events that finished within the supplied times.
";
    query.fieldValue = filters.hasOwnProperty(query.field) ? filters[query.field].val : "";
    return query;
  },
  etimeFilters: function() {
    var filters = Session.get("eventsFilter") || {};
    var query = {};
    query.field = "etime";
    query.default = filters.hasOwnProperty(query.field) ? mapOperatorToSymbol(filters[query.field].op) : "≥";
    query.filters = [
      {symbol: "≥", desc: "Greater than or equal"},
      {symbol: "≤", desc: "Less than or equal"},
      {symbol: "[,]", desc: "Between"}
    ];
    query.help = "
The time when the query was executed, in the ISO8601 format (e.g.: 2015-03-24T09:02:00+01:00).

Partial dates can be supplied (e.g.: 2015, 2015-01, 2015-01-01, etc.)

Use ≥ to include all the events that were executed at or after the supplied time and ≤ to include all the events that were executed at or before the supplied time.

Use [,] and supply 2 timestamps separated by a whitespace to include all events that were executed between the 2 supplied times (e.g.: 2015-03-24T09:02:00+01:00 2015-03-24T11:02:00+01:00).
";
    query.fieldValue = filters.hasOwnProperty(query.field) ? filters[query.field].val : "";
    return query;
  }
});

Template.eventsList.events({
  'change #problematicToggle': function(e) {
    applyFilters();
  },
  'click .sortByJobId': function(e) {
    e.preventDefault();
    triggerSort("jobId");
  },
  'click .sortByETime': function(e) {
    e.preventDefault();
    triggerSort("etime");
  },
  'click .sortByStatus': function(e) {
    e.preventDefault();
    triggerSort("status");
  },
  'click .sortByResponseTime': function(e) {
    e.preventDefault();
    triggerSort("responseTime");
  },
  'click .sortBySeries': function(e) {
    e.preventDefault();
    triggerSort("series");
  },
  'click .sortByObservations': function(e) {
    e.preventDefault();
    triggerSort("observations");
  },
  'click .sortBySize': function(e) {
    e.preventDefault();
    triggerSort("size");
  },
  'click .firstEvents': function (e) {
    e.preventDefault();
    Router.go("eventsList" , {fromCount: 0});
  },
  'click .previousEvents': function (e) {
    e.preventDefault();
    var from = Session.get("EventsFromCount");
    Router.go("eventsList" , {fromCount: (from >= 10)?(from-10):0});
  },
  'click .nextEvents': function (e) {
    e.preventDefault();
    var from = Session.get("EventsFromCount");
    var max = EventsCount.findOne().count;
    Router.go("eventsList" , {fromCount: (from + 10 <= max-10)?(from+10):(max-10)});
  },
  'click .lastEvents': function (e) {
    e.preventDefault();
    Router.go("eventsList" , {fromCount: (EventsCount.findOne().count - 10 )});
  },
  'click #filterBtn': function (e) {
    $("#filtersRow").toggleClass('hide');
    $("#runFiltersBtn").toggleClass('hide');
  },
  'click #runFiltersBtn':function(e) {
    applyFilters();
  },
  'submit form': function(e) {
    e.preventDefault();
    applyFilters();
  }
});

var triggerSort = function(sortField) {
  var sorting = Session.get("eventsSorting");
  if (typeof sorting == 'undefined') {
    sorting = {by: sortField, order: 1};
    Session.set("eventsSorting", sorting);
  }
  if (sorting.by === sortField) {
    sorting.order === 1?sorting.order=-1:sorting.order=1;
  }
  else {
    sorting.by = sortField
  }
  Session.set("eventsSorting", sorting);
};

var mapSymbolToOperator = function(symbol) {
  var value;
  switch(symbol) {
    case "≥":
      value = "gte";
      break;
    case "≤":
      value = "lte";
      break;
    case "[,]":
      value = "rg";
      break;
    case "∋":
      value = "in";
      break;
    case "∉":
      value = "nin";
      break;
  }
  return value;
}

var mapOperatorToSymbol = function(operator) {
  var value;
  switch(operator) {
    case "gte":
      value = "≥";
      break;
    case "lte":
      value = "≤";
      break;
    case "rg":
      value = "[,]";
      break;
    case "in":
      value = "∋";
      break;
    case "nin":
      value = "∉";
      break;
  }
  return value;
}

var applyFilters = function() {
  var query = {};
  $('#filtersRow').find('input').each(function(index) {
    var value = $(this).val();
    if (value) {
      var field = $(this).attr("id");
      var symbol = $(this).closest('div').find("button").first().text();
      var mSymbol = mapSymbolToOperator(symbol)
      query[field] = {
        op: mSymbol,
        val: value
      }
    }
  });

  var isProblematic = $("#problematicToggle").prop('checked');
  query.isProblematic = isProblematic;
  Session.set("eventsFilter", query);
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Input Date Picker implementation.  Pairs a
 * goog.ui.PopupDatePicker with an input element and handles the input from
 * either.
 *
 * @see ../demos/inputdatepicker.html
 */

goog.provide('goog.ui.InputDatePicker');

goog.require('goog.date.DateTime');
goog.require('goog.dom');
goog.require('goog.dom.InputType');
goog.require('goog.dom.TagName');
goog.require('goog.i18n.DateTimeParse');
goog.require('goog.string');
goog.require('goog.ui.Component');
goog.require('goog.ui.DatePicker');
/** @suppress {extraRequire} */
goog.require('goog.ui.LabelInput');
goog.require('goog.ui.PopupBase');
goog.require('goog.ui.PopupDatePicker');
goog.requireType('goog.date.Date');
goog.requireType('goog.date.DateLike');
goog.requireType('goog.events.Event');
goog.requireType('goog.ui.DatePickerEvent');

/**
 * Input date picker widget.
 *
 * @param {!goog.ui.InputDatePicker.DateFormatter} dateTimeFormatter A formatter
 *     instance used to format the date picker's date for display in the input
 *     element.
 * @param {!goog.ui.InputDatePicker.DateParser} dateTimeParser A parser instance
 *     used to parse the input element's string as a date to set the picker.
 * @param {goog.ui.DatePicker=} opt_datePicker Optional DatePicker.  This
 *     enables the use of a custom date-picker instance.
 * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
 * @extends {goog.ui.Component}
 * @constructor
 */
goog.ui.InputDatePicker = function(
    dateTimeFormatter, dateTimeParser, opt_datePicker, opt_domHelper) {
  'use strict';
  goog.ui.Component.call(this, opt_domHelper);

  this.dateTimeFormatter_ = dateTimeFormatter;
  this.dateTimeParser_ = dateTimeParser;

  this.popupDatePicker_ =
      new goog.ui.PopupDatePicker(opt_datePicker, opt_domHelper);
  this.addChild(this.popupDatePicker_);
  this.popupDatePicker_.setAllowAutoFocus(false);
};
goog.inherits(goog.ui.InputDatePicker, goog.ui.Component);

/**
 * Used to format the date picker's date for display in the input element.
 * @type {?goog.ui.InputDatePicker.DateFormatter}
 * @private
 */
goog.ui.InputDatePicker.prototype.dateTimeFormatter_ = null;

/**
 * Used to parse the input element's string as a date to set the picker.
 * @type {?goog.ui.InputDatePicker.DateParser}
 * @private
 */
goog.ui.InputDatePicker.prototype.dateTimeParser_ = null;

/**
 * The instance of goog.ui.PopupDatePicker used to pop up and select the date.
 * @type {?goog.ui.PopupDatePicker}
 * @private
 */
goog.ui.InputDatePicker.prototype.popupDatePicker_ = null;

/**
 * The element that the PopupDatePicker should be parented to. Defaults to the
 * body element of the page.
 * @type {?Element}
 * @private
 */
goog.ui.InputDatePicker.prototype.popupParentElement_ = null;

/**
 * Returns the PopupDatePicker's internal DatePicker instance.  This can be
 * used to customize the date picker's styling.
 *
 * @return {goog.ui.DatePicker} The internal DatePicker instance.
 */
goog.ui.InputDatePicker.prototype.getDatePicker = function() {
  'use strict';
  return this.popupDatePicker_.getDatePicker();
};

/**
 * Returns the PopupDatePicker instance.
 *
 * @return {goog.ui.PopupDatePicker} Popup instance.
 */
goog.ui.InputDatePicker.prototype.getPopupDatePicker = function() {
  'use strict';
  return this.popupDatePicker_;
};

/**
 * Returns the selected date, if any.  Compares the dates from the date picker
 * and the input field, causing them to be synced if different.
 * @return {goog.date.DateTime} The selected date, if any.
 */
goog.ui.InputDatePicker.prototype.getDate = function() {
  'use strict';
  // The user expectation is that the date be whatever the input shows.
  // This method biases towards the input value to conform to that expectation.

  var inputDate = this.getInputValueAsDate_();
  var pickerDate = this.popupDatePicker_.getDate();

  if (inputDate && pickerDate) {
    if (!inputDate.equals(pickerDate)) {
      this.popupDatePicker_.setDate(inputDate);
    }
  } else {
    this.popupDatePicker_.setDate(null);
  }

  return inputDate;
};

/**
 * Sets the selected date.  See goog.ui.PopupDatePicker.setDate().
 * @param {goog.date.Date} date The date to set.
 */
goog.ui.InputDatePicker.prototype.setDate = function(date) {
  'use strict';
  this.popupDatePicker_.setDate(date);
};

/**
 * Sets the value of the input element.  This can be overridden to support
 * alternative types of input setting.
 * @param {string} value The value to set.
 * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration
 */
goog.ui.InputDatePicker.prototype.setInputValue = function(value) {
  'use strict';
  var el = this.getElement();
  if (el.labelInput_) {
    var labelInput = /** @type {goog.ui.LabelInput} */ (el.labelInput_);
    labelInput.setValue(value);
  } else {
    el.value = value;
  }
};

/**
 * Returns the value of the input element.  This can be overridden to support
 * alternative types of input getting.
 * @return {string} The input value.
 * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration
 */
goog.ui.InputDatePicker.prototype.getInputValue = function() {
  'use strict';
  var el = this.getElement();
  if (el.labelInput_) {
    var labelInput = /** @type {goog.ui.LabelInput} */ (el.labelInput_);
    return labelInput.getValue();
  } else {
    return el.value;
  }
};

/**
 * Sets the value of the input element from date object.
 *
 * @param {?goog.date.Date} date The value to set.
 * @private
 */
goog.ui.InputDatePicker.prototype.setInputValueAsDate_ = function(date) {
  'use strict';
  this.setInputValue(date ? this.dateTimeFormatter_.format(date) : '');
};

/**
 * Gets the input element value and attempts to parse it as a date.
 *
 * @return {goog.date.DateTime} The date object is returned if the parse
 *      is successful, null is returned on failure.
 * @private
 */
goog.ui.InputDatePicker.prototype.getInputValueAsDate_ = function() {
  'use strict';
  var value = goog.string.trim(this.getInputValue());
  if (value) {
    var date = new goog.date.DateTime();
    // DateTime needed as parse assumes it can call getHours(), getMinutes(),
    // etc, on the date if hours and minutes aren't defined.
    if (this.dateTimeParser_.strictParse(value, date) > 0) {
      // Parser with YYYY format string will interpret 1 as year 1 A.D.
      // However, datepicker.setDate() method will change it into 1901.
      // Same is true for any other pattern when number entered by user is
      // different from number of digits in the pattern. (YY and 1 will be 1AD).
      // See i18n/datetimeparse.js
      // Conversion happens in goog.date.Date/DateTime constructor
      // when it calls new Date(year...). See ui/datepicker.js.
      return date;
    }
  }

  return null;
};

/**
 * Creates an input element for use with the popup date picker.
 * @override
 */
goog.ui.InputDatePicker.prototype.createDom = function() {
  'use strict';
  this.setElementInternal(this.getDomHelper().createDom(
      goog.dom.TagName.INPUT, {'type': goog.dom.InputType.TEXT}));
  this.popupDatePicker_.createDom();
};

/**
 * Sets the element that the PopupDatePicker should be parented to. If not set,
 * defaults to the body element of the page.
 * @param {Element} el The element that the PopupDatePicker should be parented
 *     to.
 */
goog.ui.InputDatePicker.prototype.setPopupParentElement = function(el) {
  'use strict';
  this.popupParentElement_ = el;
};

/** @override */
goog.ui.InputDatePicker.prototype.enterDocument = function() {
  'use strict';
  // this.popupDatePicker_ has been added as a child even though it isn't really
  // a child (since its root element is not within InputDatePicker's DOM tree).
  // The PopupDatePicker will have its enterDocument method called as a result
  // of calling the superClass's enterDocument method. The PopupDatePicker needs
  // to be attached to the document *before* calling enterDocument so that when
  // PopupDatePicker decorates its element as a DatePicker, the element will be
  // in the document and enterDocument will be called for the DatePicker. Having
  // the PopupDatePicker's element in the document before calling enterDocument
  // will ensure that the event handlers for DatePicker are attached.
  //
  // An alternative could be to stop adding popupDatePicker_ as a child and
  // instead keep a reference to it and sync some event handlers, etc. but
  // appending the element to the document before calling enterDocument is a
  // less intrusive option.
  //
  // See cl/100837907 for more context and the discussion around this decision.
  (this.popupParentElement_ || this.getDomHelper().getDocument().body)
      .appendChild(/** @type {!Node} */ (this.popupDatePicker_.getElement()));

  goog.ui.InputDatePicker.superClass_.enterDocument.call(this);
  var el = this.getElement();

  this.popupDatePicker_.attach(el);

  // Set the date picker to have the input's initial value, if any.
  this.popupDatePicker_.setDate(this.getInputValueAsDate_());

  var handler = this.getHandler();
  handler.listen(
      this.popupDatePicker_, goog.ui.DatePicker.Events.CHANGE,
      this.onDateChanged_);
  handler.listen(
      this.popupDatePicker_, goog.ui.PopupBase.EventType.SHOW, this.onPopup_);
};

/** @override */
goog.ui.InputDatePicker.prototype.exitDocument = function() {
  'use strict';
  goog.ui.InputDatePicker.superClass_.exitDocument.call(this);
  var el = this.getElement();

  this.popupDatePicker_.detach(el);
  this.popupDatePicker_.exitDocument();
  goog.dom.removeNode(this.popupDatePicker_.getElement());
};

/** @override */
goog.ui.InputDatePicker.prototype.decorateInternal = function(element) {
  'use strict';
  goog.ui.InputDatePicker.superClass_.decorateInternal.call(this, element);

  this.popupDatePicker_.createDom();
};

/** @override */
goog.ui.InputDatePicker.prototype.disposeInternal = function() {
  'use strict';
  goog.ui.InputDatePicker.superClass_.disposeInternal.call(this);
  this.popupDatePicker_.dispose();
  this.popupDatePicker_ = null;
  this.popupParentElement_ = null;
};

/**
 * See goog.ui.PopupDatePicker.showPopup().
 * @param {Element} element Reference element for displaying the popup -- popup
 *     will appear at the bottom-left corner of this element.
 */
goog.ui.InputDatePicker.prototype.showForElement = function(element) {
  'use strict';
  this.popupDatePicker_.showPopup(element);
};

/**
 * See goog.ui.PopupDatePicker.hidePopup().
 */
goog.ui.InputDatePicker.prototype.hidePopup = function() {
  'use strict';
  this.popupDatePicker_.hidePopup();
};

/**
 * Event handler for popup date picker popup events.
 *
 * @param {goog.events.Event} e popup event.
 * @private
 */
goog.ui.InputDatePicker.prototype.onPopup_ = function(e) {
  'use strict';
  var inputValueAsDate = this.getInputValueAsDate_();
  this.setDate(inputValueAsDate);
  // don't overwrite the input value with empty date if input is not valid
  if (inputValueAsDate) {
    this.setInputValueAsDate_(this.getDatePicker().getDate());
  }
};

/**
 * Event handler for date change events.  Called when the date changes.
 *
 * @param {goog.ui.DatePickerEvent} e Date change event.
 * @private
 */
goog.ui.InputDatePicker.prototype.onDateChanged_ = function(e) {
  'use strict';
  this.setInputValueAsDate_(e.date);
};

/**
 * A DateFormatter implements functionality to convert a Date into
 * human-readable text. text into a Date. This interface is expected to accept
 * an instance of goog.i18n.DateTimeFormat directly, and as such the method
 * signatures directly match those found on that class.
 * @record
 */
goog.ui.InputDatePicker.DateFormatter = function() {};

/**
 * @param {!goog.date.DateLike} date The Date object that is being formatted.
 * @return {string} The formatted date value.
 */
goog.ui.InputDatePicker.DateFormatter.prototype.format = function(date) {};

/**
 * A DateParser implements functionality to parse text into a Date. This
 * interface is expected to accept an instance of goog.i18n.DateTimeParse
 * directly, and as such the method signatures directly match those found on
 * that class.
 * @record
 */
goog.ui.InputDatePicker.DateParser = function() {};

/**
 * @param {string} text The string being parsed.
 * @param {!goog.date.DateLike} date The Date object to hold the parsed date.
 * @return {number} How many characters parser advanced.
 * @deprecated See the deprecation warning on
 *     goog.i18n.DateTimeParse#strictParse - this will be deprecated in favour
 *     of only using the `parse` signature with options.
 */
goog.ui.InputDatePicker.DateParser.prototype.strictParse = function(
    text, date) {};

/**
 * @param {string} text The string being parsed.
 * @param {!goog.date.DateLike} date The Date object to hold the parsed date.
 * @param {!goog.i18n.DateTimeParse.ParseOptions=} options The options object.
 * @return {number} How many characters parser advanced.
 */
goog.ui.InputDatePicker.DateParser.prototype.parse = function(
    text, date, options) {};
<commit_msg>Stop using the deprecated strictParse method in InputDatePicker. RELNOTES: n/a<commit_after>/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Input Date Picker implementation.  Pairs a
 * goog.ui.PopupDatePicker with an input element and handles the input from
 * either.
 *
 * @see ../demos/inputdatepicker.html
 */

goog.provide('goog.ui.InputDatePicker');

goog.require('goog.date.DateTime');
goog.require('goog.dom');
goog.require('goog.dom.InputType');
goog.require('goog.dom.TagName');
goog.require('goog.i18n.DateTimeParse');
goog.require('goog.string');
goog.require('goog.ui.Component');
goog.require('goog.ui.DatePicker');
/** @suppress {extraRequire} */
goog.require('goog.ui.LabelInput');
goog.require('goog.ui.PopupBase');
goog.require('goog.ui.PopupDatePicker');
goog.requireType('goog.date.Date');
goog.requireType('goog.date.DateLike');
goog.requireType('goog.events.Event');
goog.requireType('goog.ui.DatePickerEvent');

/**
 * Input date picker widget.
 *
 * @param {!goog.ui.InputDatePicker.DateFormatter} dateTimeFormatter A formatter
 *     instance used to format the date picker's date for display in the input
 *     element.
 * @param {!goog.ui.InputDatePicker.DateParser} dateTimeParser A parser instance
 *     used to parse the input element's string as a date to set the picker.
 * @param {goog.ui.DatePicker=} opt_datePicker Optional DatePicker.  This
 *     enables the use of a custom date-picker instance.
 * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
 * @extends {goog.ui.Component}
 * @constructor
 */
goog.ui.InputDatePicker = function(
    dateTimeFormatter, dateTimeParser, opt_datePicker, opt_domHelper) {
  'use strict';
  goog.ui.Component.call(this, opt_domHelper);

  this.dateTimeFormatter_ = dateTimeFormatter;
  this.dateTimeParser_ = dateTimeParser;

  this.popupDatePicker_ =
      new goog.ui.PopupDatePicker(opt_datePicker, opt_domHelper);
  this.addChild(this.popupDatePicker_);
  this.popupDatePicker_.setAllowAutoFocus(false);
};
goog.inherits(goog.ui.InputDatePicker, goog.ui.Component);

/**
 * Used to format the date picker's date for display in the input element.
 * @type {?goog.ui.InputDatePicker.DateFormatter}
 * @private
 */
goog.ui.InputDatePicker.prototype.dateTimeFormatter_ = null;

/**
 * Used to parse the input element's string as a date to set the picker.
 * @type {?goog.ui.InputDatePicker.DateParser}
 * @private
 */
goog.ui.InputDatePicker.prototype.dateTimeParser_ = null;

/**
 * The instance of goog.ui.PopupDatePicker used to pop up and select the date.
 * @type {?goog.ui.PopupDatePicker}
 * @private
 */
goog.ui.InputDatePicker.prototype.popupDatePicker_ = null;

/**
 * The element that the PopupDatePicker should be parented to. Defaults to the
 * body element of the page.
 * @type {?Element}
 * @private
 */
goog.ui.InputDatePicker.prototype.popupParentElement_ = null;

/**
 * Returns the PopupDatePicker's internal DatePicker instance.  This can be
 * used to customize the date picker's styling.
 *
 * @return {goog.ui.DatePicker} The internal DatePicker instance.
 */
goog.ui.InputDatePicker.prototype.getDatePicker = function() {
  'use strict';
  return this.popupDatePicker_.getDatePicker();
};

/**
 * Returns the PopupDatePicker instance.
 *
 * @return {goog.ui.PopupDatePicker} Popup instance.
 */
goog.ui.InputDatePicker.prototype.getPopupDatePicker = function() {
  'use strict';
  return this.popupDatePicker_;
};

/**
 * Returns the selected date, if any.  Compares the dates from the date picker
 * and the input field, causing them to be synced if different.
 * @return {goog.date.DateTime} The selected date, if any.
 */
goog.ui.InputDatePicker.prototype.getDate = function() {
  'use strict';
  // The user expectation is that the date be whatever the input shows.
  // This method biases towards the input value to conform to that expectation.

  var inputDate = this.getInputValueAsDate_();
  var pickerDate = this.popupDatePicker_.getDate();

  if (inputDate && pickerDate) {
    if (!inputDate.equals(pickerDate)) {
      this.popupDatePicker_.setDate(inputDate);
    }
  } else {
    this.popupDatePicker_.setDate(null);
  }

  return inputDate;
};

/**
 * Sets the selected date.  See goog.ui.PopupDatePicker.setDate().
 * @param {goog.date.Date} date The date to set.
 */
goog.ui.InputDatePicker.prototype.setDate = function(date) {
  'use strict';
  this.popupDatePicker_.setDate(date);
};

/**
 * Sets the value of the input element.  This can be overridden to support
 * alternative types of input setting.
 * @param {string} value The value to set.
 * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration
 */
goog.ui.InputDatePicker.prototype.setInputValue = function(value) {
  'use strict';
  var el = this.getElement();
  if (el.labelInput_) {
    var labelInput = /** @type {goog.ui.LabelInput} */ (el.labelInput_);
    labelInput.setValue(value);
  } else {
    el.value = value;
  }
};

/**
 * Returns the value of the input element.  This can be overridden to support
 * alternative types of input getting.
 * @return {string} The input value.
 * @suppress {strictMissingProperties} Part of the go/strict_warnings_migration
 */
goog.ui.InputDatePicker.prototype.getInputValue = function() {
  'use strict';
  var el = this.getElement();
  if (el.labelInput_) {
    var labelInput = /** @type {goog.ui.LabelInput} */ (el.labelInput_);
    return labelInput.getValue();
  } else {
    return el.value;
  }
};

/**
 * Sets the value of the input element from date object.
 *
 * @param {?goog.date.Date} date The value to set.
 * @private
 */
goog.ui.InputDatePicker.prototype.setInputValueAsDate_ = function(date) {
  'use strict';
  this.setInputValue(date ? this.dateTimeFormatter_.format(date) : '');
};

/**
 * Gets the input element value and attempts to parse it as a date.
 *
 * @return {goog.date.DateTime} The date object is returned if the parse
 *      is successful, null is returned on failure.
 * @private
 */
goog.ui.InputDatePicker.prototype.getInputValueAsDate_ = function() {
  'use strict';
  var value = goog.string.trim(this.getInputValue());
  if (value) {
    var date = new goog.date.DateTime();
    // DateTime needed as parse assumes it can call getHours(), getMinutes(),
    // etc, on the date if hours and minutes aren't defined.
    if (this.dateTimeParser_.parse(value, date, {validate: true}) > 0) {
      // Parser with YYYY format string will interpret 1 as year 1 A.D.
      // However, datepicker.setDate() method will change it into 1901.
      // Same is true for any other pattern when number entered by user is
      // different from number of digits in the pattern. (YY and 1 will be 1AD).
      // See i18n/datetimeparse.js
      // Conversion happens in goog.date.Date/DateTime constructor
      // when it calls new Date(year...). See ui/datepicker.js.
      return date;
    }
  }

  return null;
};

/**
 * Creates an input element for use with the popup date picker.
 * @override
 */
goog.ui.InputDatePicker.prototype.createDom = function() {
  'use strict';
  this.setElementInternal(this.getDomHelper().createDom(
      goog.dom.TagName.INPUT, {'type': goog.dom.InputType.TEXT}));
  this.popupDatePicker_.createDom();
};

/**
 * Sets the element that the PopupDatePicker should be parented to. If not set,
 * defaults to the body element of the page.
 * @param {Element} el The element that the PopupDatePicker should be parented
 *     to.
 */
goog.ui.InputDatePicker.prototype.setPopupParentElement = function(el) {
  'use strict';
  this.popupParentElement_ = el;
};

/** @override */
goog.ui.InputDatePicker.prototype.enterDocument = function() {
  'use strict';
  // this.popupDatePicker_ has been added as a child even though it isn't really
  // a child (since its root element is not within InputDatePicker's DOM tree).
  // The PopupDatePicker will have its enterDocument method called as a result
  // of calling the superClass's enterDocument method. The PopupDatePicker needs
  // to be attached to the document *before* calling enterDocument so that when
  // PopupDatePicker decorates its element as a DatePicker, the element will be
  // in the document and enterDocument will be called for the DatePicker. Having
  // the PopupDatePicker's element in the document before calling enterDocument
  // will ensure that the event handlers for DatePicker are attached.
  //
  // An alternative could be to stop adding popupDatePicker_ as a child and
  // instead keep a reference to it and sync some event handlers, etc. but
  // appending the element to the document before calling enterDocument is a
  // less intrusive option.
  //
  // See cl/100837907 for more context and the discussion around this decision.
  (this.popupParentElement_ || this.getDomHelper().getDocument().body)
      .appendChild(/** @type {!Node} */ (this.popupDatePicker_.getElement()));

  goog.ui.InputDatePicker.superClass_.enterDocument.call(this);
  var el = this.getElement();

  this.popupDatePicker_.attach(el);

  // Set the date picker to have the input's initial value, if any.
  this.popupDatePicker_.setDate(this.getInputValueAsDate_());

  var handler = this.getHandler();
  handler.listen(
      this.popupDatePicker_, goog.ui.DatePicker.Events.CHANGE,
      this.onDateChanged_);
  handler.listen(
      this.popupDatePicker_, goog.ui.PopupBase.EventType.SHOW, this.onPopup_);
};

/** @override */
goog.ui.InputDatePicker.prototype.exitDocument = function() {
  'use strict';
  goog.ui.InputDatePicker.superClass_.exitDocument.call(this);
  var el = this.getElement();

  this.popupDatePicker_.detach(el);
  this.popupDatePicker_.exitDocument();
  goog.dom.removeNode(this.popupDatePicker_.getElement());
};

/** @override */
goog.ui.InputDatePicker.prototype.decorateInternal = function(element) {
  'use strict';
  goog.ui.InputDatePicker.superClass_.decorateInternal.call(this, element);

  this.popupDatePicker_.createDom();
};

/** @override */
goog.ui.InputDatePicker.prototype.disposeInternal = function() {
  'use strict';
  goog.ui.InputDatePicker.superClass_.disposeInternal.call(this);
  this.popupDatePicker_.dispose();
  this.popupDatePicker_ = null;
  this.popupParentElement_ = null;
};

/**
 * See goog.ui.PopupDatePicker.showPopup().
 * @param {Element} element Reference element for displaying the popup -- popup
 *     will appear at the bottom-left corner of this element.
 */
goog.ui.InputDatePicker.prototype.showForElement = function(element) {
  'use strict';
  this.popupDatePicker_.showPopup(element);
};

/**
 * See goog.ui.PopupDatePicker.hidePopup().
 */
goog.ui.InputDatePicker.prototype.hidePopup = function() {
  'use strict';
  this.popupDatePicker_.hidePopup();
};

/**
 * Event handler for popup date picker popup events.
 *
 * @param {goog.events.Event} e popup event.
 * @private
 */
goog.ui.InputDatePicker.prototype.onPopup_ = function(e) {
  'use strict';
  var inputValueAsDate = this.getInputValueAsDate_();
  this.setDate(inputValueAsDate);
  // don't overwrite the input value with empty date if input is not valid
  if (inputValueAsDate) {
    this.setInputValueAsDate_(this.getDatePicker().getDate());
  }
};

/**
 * Event handler for date change events.  Called when the date changes.
 *
 * @param {goog.ui.DatePickerEvent} e Date change event.
 * @private
 */
goog.ui.InputDatePicker.prototype.onDateChanged_ = function(e) {
  'use strict';
  this.setInputValueAsDate_(e.date);
};

/**
 * A DateFormatter implements functionality to convert a Date into
 * human-readable text. text into a Date. This interface is expected to accept
 * an instance of goog.i18n.DateTimeFormat directly, and as such the method
 * signatures directly match those found on that class.
 * @record
 */
goog.ui.InputDatePicker.DateFormatter = function() {};

/**
 * @param {!goog.date.DateLike} date The Date object that is being formatted.
 * @return {string} The formatted date value.
 */
goog.ui.InputDatePicker.DateFormatter.prototype.format = function(date) {};

/**
 * A DateParser implements functionality to parse text into a Date. This
 * interface is expected to accept an instance of goog.i18n.DateTimeParse
 * directly, and as such the method signatures directly match those found on
 * that class.
 * @record
 */
goog.ui.InputDatePicker.DateParser = function() {};

/**
 * @param {string} text The string being parsed.
 * @param {!goog.date.DateLike} date The Date object to hold the parsed date.
 * @param {!goog.i18n.DateTimeParse.ParseOptions=} options The options object.
 * @return {number} How many characters parser advanced.
 */
goog.ui.InputDatePicker.DateParser.prototype.parse = function(
    text, date, options) {};
<|endoftext|>


<commit_before>/*
---

script: Properties.js

description: A watchable proxy object that holds internal widget properties

license: Public domain (http://unlicense.org).

authors: Yaroslaff Fedin

requires:
  - LSD.Module
  - LSD.Script/LSD.Script.Scope
  - LSD.Script/LSD.Object.Stack
  - LSD.Module.Options
  - LSD.Module.Events
  - LSD.Module.Attributes

provides:
  - LSD.Module.Properties

...
*/

LSD.Module.Properties = new Class({
  options: {
    context: 'element',
    namespace: 'LSD'
  },

  constructors: {
    properties: function() {
      var self = this;
      this.storage = new LSD.Object;
      this.properties = (new LSD.Object.Stack).addEvent('change', function(name, value, state, old, memo) {
        var property = LSD.Module.Properties.Exported[name] || name;
        var method = LSD.Module.Properties.Methods[name];
        var alias = LSD.Module.Properties.Aliased[name];
        var events = self.events && self.events[name];
        if (!state) old = value;
        if (state && value != null) {
          if (alias) self[alias] = value;
          self[property] = value;
          self.fireEvent('set' + name.capitalize(), value);
          if (events) LSD.Module.Events.setStoredEvents.call(value, events, true, self);
          if (method) method.call(self, value, true, old, memo);
        }
        if (old != null) {
          if (alias) delete self[alias];
          delete self[property];
          self.fireEvent('unset' + name.capitalize(), old);
          if (events) LSD.Module.Events.setStoredEvents.call(old, events, false, self);
          if (method) method.call(self, old, false, value, memo);
        }
      });
      LSD.Script.Scope(this);
    },
  },

  store: function(name, value) {
    return this.storage.set(name, value);
  },

  retrieve: function(name, placeholder) {
    var value = this.storage[name];
    if (value == null) {
      if (placeholder != null) this.store(name, placeholder);
      return placeholder
    }
    return value;
  },

  eliminate: function(name, value) {
    return this.storage.unset(name, value)
  }
});

LSD.Module.Events.addEvents.call(LSD.Module.Properties.prototype, {
  beforeBuild: function() {
    if (this.source == null)
      this.properties.set('source', LSD.Module.Properties.getSource(this));
  },
  finalize: function() {
    if (this.source || this.attributes.type || this.attributes.kind) {
      var role = LSD.Module.Properties.getRole(this);
      if (this.role !== role) this.properties.set('role', role)
    }
  }
});

['tag', 'context', 'source', 'scope'].each(function(name) {
  LSD.Options[name] = {
    add: function(value) {
      this.properties.set(name, value);
    },
    remove: function(value) {
      this.properties.unset(name, value);
    }
  }
});

LSD.Module.Properties.Methods = {

  context: function(value, state, old) {
    var source = this.source;
    if (source) this.properties.unset('source', source);
    if (state) {
      var camel = LSD.toClassName(value);
      this.factory = window[this.options.namespace][camel];
      if (!this.factory) throw "Can not find LSD.Type in " + ['window', this.options.namespace, camel].join('.');
    }
    if (source) this.properties.set('source', source);
  },

  tag: function(value, state, old) {
    if (!this.options.source && this.prepared) {
      if (state && value) this.properties.set('source', value)
      else if (old) this.properties.unset('source', old);
    }
  },

  source: function(value, state, old) {
    if (state && value) {
      var role = LSD.Module.Properties.getRole(this);
      if (role && this.role === role) return;
    }
    if (this.prepared) {
      if (state) {
        this.properties.set('role', role);
      } else {
        if (this.properties.role)
          this.properties.unset('role', this.role);
      }
    }
  },

  role: function(value, state, old) {
    if (state) return LSD.Module.Properties.setRole(this, value)
    else if (old) LSD.Module.Properties.unsetRole(this, old)
  },

  scope: function(value, state, old) {
    if (state) return LSD.Script.Scope.setScope(this, value)
    else if (old) LSD.Script.Scope.unsetScope(this, old);
  }
};

Object.append(LSD.Module.Properties, {
  getSource: function(widget, tagName) {
    var source = LSD.Layout.getSource(widget.attributes, tagName === false ? null : tagName || widget.options.source || widget.tagName);
    return source && source.join ? source.join('-') : source;
  },

  getRole: function(widget, tagName) {
    var source = LSD.Module.Properties.getSource(widget, tagName);
    if (!source) return;
    if (widget.attributes.type) source += '-' + widget.attributes.type;
    if (widget.attributes.kind) source += '-' + widget.attributes.kind;
    return widget.factory && widget.factory.find(source);
  },

  setRole: function(widget, role) {
    if (role == null) role = LSD.Module.Properties.getRole(widget)
    if (role) {
      widget.mixin(role);
      if ((widget.sourced = widget.captureEvent('setRole', role)))
        widget.setOptions(widget.sourced);
    }
    return role;
  },

  unsetRole: function(widget, role) {
    widget.unmix(role);
    var options = widget.sourced;
    if (options) {
      delete widget.sourced;
      widget.unsetOptions(options);
    }
  }
});

LSD.Module.Properties.Exported = {
  parent: 'parentNode',
  next: 'nextSibling',
  previous: 'previousSibling',
  first: 'firstChild',
  last: 'lastChild',
  tag: 'tagName'
};

LSD.Module.Properties.Aliased = {
  document: 'ownerDocument',
  tag: 'nodeName'
};<commit_msg>Unset old value, instead of new in properties<commit_after>/*
---

script: Properties.js

description: A watchable proxy object that holds internal widget properties

license: Public domain (http://unlicense.org).

authors: Yaroslaff Fedin

requires:
  - LSD.Module
  - LSD.Script/LSD.Script.Scope
  - LSD.Script/LSD.Object.Stack
  - LSD.Module.Options
  - LSD.Module.Events
  - LSD.Module.Attributes

provides:
  - LSD.Module.Properties

...
*/

LSD.Module.Properties = new Class({
  options: {
    context: 'element',
    namespace: 'LSD'
  },

  constructors: {
    properties: function() {
      var self = this;
      this.storage = new LSD.Object;
      this.properties = (new LSD.Object.Stack).addEvent('change', function(name, value, state, old, memo) {
        var property = LSD.Module.Properties.Exported[name] || name;
        var method = LSD.Module.Properties.Methods[name];
        var alias = LSD.Module.Properties.Aliased[name];
        var events = self.events && self.events[name];
        if (!state) old = value;
        if (state && value != null) {
          if (alias) self[alias] = value;
          self[property] = value;
          self.fireEvent('set' + name.capitalize(), value);
          if (events) LSD.Module.Events.setStoredEvents.call(value, events, true, self);
          if (method) method.call(self, value, true, old, memo);
        }
        if (old != null) {
          if (alias) delete self[alias];
          delete self[property];
          self.fireEvent('unset' + name.capitalize(), old);
          if (events) LSD.Module.Events.setStoredEvents.call(old, events, false, self);
          if (method) method.call(self, old, false, value, memo);
        }
      });
      LSD.Script.Scope(this);
    },
  },

  store: function(name, value) {
    return this.storage.set(name, value);
  },

  retrieve: function(name, placeholder) {
    var value = this.storage[name];
    if (value == null) {
      if (placeholder != null) this.store(name, placeholder);
      return placeholder
    }
    return value;
  },

  eliminate: function(name, value) {
    return this.storage.unset(name, value)
  }
});

LSD.Module.Events.addEvents.call(LSD.Module.Properties.prototype, {
  beforeBuild: function() {
    if (this.source == null)
      this.properties.set('source', LSD.Module.Properties.getSource(this));
  },
  finalize: function() {
    if (this.source || this.attributes.type || this.attributes.kind) {
      var role = LSD.Module.Properties.getRole(this);
      if (this.role !== role) this.properties.set('role', role)
    }
  }
});

['tag', 'context', 'source', 'scope'].each(function(name) {
  LSD.Options[name] = {
    add: function(value) {
      this.properties.set(name, value);
    },
    remove: function(value) {
      this.properties.unset(name, value);
    }
  }
});

LSD.Module.Properties.Methods = {

  context: function(value, state, old) {
    var source = this.source;
    if (source) this.properties.unset('source', source);
    if (state) {
      var camel = LSD.toClassName(value);
      this.factory = window[this.options.namespace][camel];
      if (!this.factory) throw "Can not find LSD.Type in " + ['window', this.options.namespace, camel].join('.');
    }
    if (source) this.properties.set('source', source);
  },

  tag: function(value, state, old) {
    if (!this.options.source && this.prepared) {
      if (state && value) this.properties.set('source', value)
      else if (old) this.properties.unset('source', value);
    }
  },

  source: function(value, state, old) {
    if (state && value) {
      var role = LSD.Module.Properties.getRole(this);
      if (role && this.role === role) return;
    }
    if (this.prepared) {
      if (state) {
        this.properties.set('role', role);
      } else if (this.properties.role) {
        this.properties.unset('role', this.role);
      }
    }
  },

  role: function(value, state, old) {
    if (state) return LSD.Module.Properties.setRole(this, value)
    else if (old) LSD.Module.Properties.unsetRole(this, value)
  },

  scope: function(value, state, old) {
    if (state) return LSD.Script.Scope.setScope(this, value)
    else if (old) LSD.Script.Scope.unsetScope(this, value);
  }
};

Object.append(LSD.Module.Properties, {
  getSource: function(widget, tagName) {
    var source = LSD.Layout.getSource(widget.attributes, tagName === false ? null : tagName || widget.options.source || widget.tagName);
    return source && source.join ? source.join('-') : source;
  },

  getRole: function(widget, tagName) {
    var source = LSD.Module.Properties.getSource(widget, tagName);
    if (!source) return;
    if (widget.attributes.type) source += '-' + widget.attributes.type;
    if (widget.attributes.kind) source += '-' + widget.attributes.kind;
    return widget.factory && widget.factory.find(source);
  },

  setRole: function(widget, role) {
    if (role == null) role = LSD.Module.Properties.getRole(widget)
    if (role) {
      widget.mixin(role);
      if ((widget.sourced = widget.captureEvent('setRole', role)))
        widget.setOptions(widget.sourced);
    }
    return role;
  },

  unsetRole: function(widget, role) {
    widget.unmix(role);
    var options = widget.sourced;
    if (options) {
      delete widget.sourced;
      widget.unsetOptions(options);
    }
  }
});

LSD.Module.Properties.Exported = {
  parent: 'parentNode',
  next: 'nextSibling',
  previous: 'previousSibling',
  first: 'firstChild',
  last: 'lastChild',
  tag: 'tagName'
};

LSD.Module.Properties.Aliased = {
  document: 'ownerDocument',
  tag: 'nodeName'
};<|endoftext|>


<commit_before>/*global defineSuite*/
defineSuite(['DynamicScene/KmlDataSource',
             'DynamicScene/DynamicObjectCollection',
             'Core/loadXML',
             'Core/Event'
            ], function(
                    KmlDataSource,
                    loadXML,
                    DynamicObjectCollection,
                    Event) {
    "use strict";
    /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

    it('default constructor has expected values', function() {
        var dataSource = new KmlDataSource();
        expect(dataSource.getChangedEvent()).toBeInstanceOf(Event);
        expect(dataSource.getErrorEvent()).toBeInstanceOf(Event);
        expect(dataSource.getClock()).toBeUndefined();
        expect(dataSource.getDynamicObjectCollection()).toBeInstanceOf(DynamicObjectCollection);
        expect(dataSource.getDynamicObjectCollection().getObjects().length).toEqual(0);
        expect(dataSource.getIsTimeVarying()).toEqual(false);
    });

    it('Simple Test loading Kml', function() {
        var dataSource = new KmlDataSource();
        var url = 'http://localhost:8080/Apps/CesiumViewer/Gallery/simplePlacemark.kml';

        dataSource.loadUrl(url);
    });

    it('Test loading Kml', function() {
        var dataSource = new KmlDataSource();
        var url = 'http://localhost:8080/Apps/CesiumViewer/Gallery/KML_Samples.kml';

        dataSource.loadUrl(url);
    });
});<commit_msg>Add spec to test Point geometry<commit_after>/*global defineSuite*/
defineSuite(['DynamicScene/KmlDataSource',
             'DynamicScene/DynamicObjectCollection',
             'DynamicScene/DynamicBillboard',
             'Core/loadXML',
             'Core/Event'
            ], function(
                    KmlDataSource,
                    DynamicObjectCollection,
                    DynamicBillboard,
                    loadXML,
                    Event) {
    "use strict";
    /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

    it('default constructor has expected values', function() {
        var dataSource = new KmlDataSource();
        expect(dataSource.getChangedEvent()).toBeInstanceOf(Event);
        expect(dataSource.getErrorEvent()).toBeInstanceOf(Event);
        expect(dataSource.getClock()).toBeUndefined();
        expect(dataSource.getDynamicObjectCollection()).toBeInstanceOf(DynamicObjectCollection);
        expect(dataSource.getDynamicObjectCollection().getObjects().length).toEqual(0);
        expect(dataSource.getIsTimeVarying()).toEqual(true);
    });

    it('handlesPointGeometry', function() {
        var txt = '<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document>';
        txt = txt + '<Style id="randomColorIcon">    <IconStyle>    <color>ffffff00</color>  <scale>2</scale>';
        txt = txt + '<Icon>  <href>http://maps.google.com/mapfiles/kml/pal3/icon23.png</href>  </Icon>  </IconStyle>   </Style>';
        txt = txt + '<Placemark>  <name>IconStyle.kml</name>      <styleUrl>#randomColorIcon</styleUrl>';
        txt = txt + '<Point>  <coordinates>-9.171441666666666,38.67883055555556,0</coordinates>   </Point>   </Placemark></Document></kml>';
        var dataSource = new KmlDataSource();

        var parser=new DOMParser();
        var xmlDoc=parser.parseFromString(txt,"text/xml");

        dataSource.load(xmlDoc);
        expect(dataSource.getDynamicObjectCollection()).toBeInstanceOf(DynamicObjectCollection);
        expect(dataSource.getDynamicObjectCollection().getObjects().length).toEqual(1);
        expect(dataSource.getDynamicObjectCollection().getObjects()[0].billboard).toBeInstanceOf(DynamicBillboard);
        expect(dataSource.getDynamicObjectCollection().getObjects()[0].position).toBeDefined();
    });

    it('Simple Test loading Kml', function() {
        var dataSource = new KmlDataSource();
        var url = 'http://localhost:8080/Apps/CesiumViewer/Gallery/simplePlacemark.kml';

        dataSource.loadUrl(url);
    });

    it('Test loading Kml', function() {
        var dataSource = new KmlDataSource();
        var url = 'http://localhost:8080/Apps/CesiumViewer/Gallery/KML_Samples.kml';

        dataSource.loadUrl(url);
    });
});<|endoftext|>


<commit_before>'use strict';

var Path = require('path');
var expect = require('unexpected').clone();
var tolk = require('../lib/baby-tolk');

function getPath(path) {
  return Path.join(process.cwd(), 'fixtures/source', path);
}

describe('readCompiled', function () {
  it('should read a file directly if there is no adapter', function () {
    return expect(tolk.read(getPath('unchanged.txt')), 'to be fulfilled with', {
      result: 'I am the same\n'
    });
  });

  it('should throw when reading a file that does not exist', function () {
    return expect(tolk.read(getPath('does-not-exist.txt')), 'when rejected', 'to satisfy', {
      code: 'ENOENT',
      path: /fixtures\/source\/does-not-exist\.txt$/,
      message: /^ENOENT.*?, open '.+?fixtures\/source\/does-not-exist\.txt'$/
    });
  });

  it('should compile a file if there is an adapter', function () {
    return expect(tolk.read(getPath('babel/simplest.jsx')), 'to be fulfilled with', {
      result: expect.it('to begin with', '\'use strict\';\n\nvar foo = \'bar\';'),
      extension: expect.it('to be', '.js'),
    });
  });

  it('should output source map if there is an adapter that supports source maps', function () {
    return expect(tolk.read(getPath('less/external.less')), 'to be fulfilled with', {
      sourcemap: {
        sources: expect.it('to have length', 2),
        mappings: expect.it('to begin with', 'AAAA;EACE,')
      }
    });
  });

  it('should output source map if there is an adapter that supports source maps', function () {
    return expect(tolk.read(getPath('coffee/basic.coffee')), 'to be fulfilled with', {
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'AAAA;EAAA,'),
        file: expect.it('to be', 'basic.js')
      }
    });
  });

  it('should support CSS minification (with compilation)', function () {
    return expect(tolk.read(getPath('less/external.less'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '.bar{wow:\'foo\'}'),
      sourcemap: {
        sources: expect.it('to have length', 2),
        mappings: expect.it('to begin with', 'AAAA,KACE,')
      }
    });
  });

  it('should support CSS minification (without compilation)', function () {
    return expect(tolk.read(getPath('csso/basic.css'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '/*! keep this comment */.hello{margin:0;color:silver'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'wBAGA,OACE,')
      }
    });
  });

  it('should support JS minification (with compilation)', function () {
    return expect(tolk.read(getPath('coffee/basic.coffee'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '(function(){console.log(15)})'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'CAAA,WAAAA')
      }
    });
  });

  it('should support JS minification (without compilation)', function () {
    return expect(tolk.read(getPath('minify-js/basic.js'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', 'for(var stuff=[1,2,3,4,5],i=0;i<stuff.length;i++)'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'AACA,IAAK,')
      }
    });
  });

  it('should support HTML minification (with compilation)', function () {
    return expect(tolk.read(getPath('jade/client-complex.jade'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '
1

1

2

2

3

3

4

4

')
    });
  });

  it('should support HTML minification (without compilation)', function () {
    return expect(tolk.read(getPath('minify-html/basic.html'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '

wowlaween

')
    });
  });

  it('should not compile files beginning with underscore', function () {
    return expect(tolk.read(getPath('scss/_mixin_lib.scss'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '@mixin set_color($color) {\n  color: $color;')
    });
  });

  it('should throw when compiling a file that does not exist', function () {
    return expect(tolk.read(getPath('does-not-exist.scss')), 'when rejected', 'to satisfy', {
      code: 'ENOENT',
      path: /fixtures\/source\/does-not-exist\.scss$/,
      message: /^ENOENT.*?, open '.+?fixtures\/source\/does-not-exist\.scss'$/
    });
  });

  it('should throw when compiling a file with syntax errors', function () {
    return expect(tolk.read(getPath('scss/syntaxerror.scss')), 'when rejected', 'to satisfy', {
      status: 1,
      file: /fixtures\/source\/scss\/syntaxerror\.scss$/,
      line: 2,
      column: 3,
      message: 'property "color" must be followed by a \':\'',
    });
  });

});
<commit_msg>Test for #1<commit_after>'use strict';

var Path = require('path');
var expect = require('unexpected').clone();
var tolk = require('../lib/baby-tolk');

function getPath(path) {
  return Path.join(process.cwd(), 'fixtures/source', path);
}

describe('readCompiled', function () {
  it('should read a file directly if there is no adapter', function () {
    return expect(tolk.read(getPath('unchanged.txt')), 'to be fulfilled with', {
      result: 'I am the same\n'
    });
  });

  it('should throw when reading a file that does not exist', function () {
    return expect(tolk.read(getPath('does-not-exist.txt')), 'when rejected', 'to satisfy', {
      code: 'ENOENT',
      path: /fixtures\/source\/does-not-exist\.txt$/,
      message: /^ENOENT.*?, open '.+?fixtures\/source\/does-not-exist\.txt'$/
    });
  });

  it('should compile a file if there is an adapter', function () {
    return expect(tolk.read(getPath('babel/simplest.jsx')), 'to be fulfilled with', {
      result: expect.it('to begin with', '\'use strict\';\n\nvar foo = \'bar\';'),
      extension: expect.it('to be', '.js'),
    });
  });

  it('should output source map if there is an adapter that supports source maps', function () {
    return expect(tolk.read(getPath('less/external.less')), 'to be fulfilled with', {
      sourcemap: {
        sources: expect.it('to have length', 2),
        mappings: expect.it('to begin with', 'AAAA;EACE,')
      }
    });
  });

  it('should have a fix for issue #1 (buggy uglifyJS2)', function () {
    return expect(tolk.read(getPath('coffee/basic.coffee'), {minify: true}), 'to be fulfilled with', {
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'CAAA,WAAAA'),
        file: expect.it('to be', 'basic.js')
      }
    });
  });

  it('should support CSS minification (with compilation)', function () {
    return expect(tolk.read(getPath('less/external.less'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '.bar{wow:\'foo\'}'),
      sourcemap: {
        sources: expect.it('to have length', 2),
        mappings: expect.it('to begin with', 'AAAA,KACE,')
      }
    });
  });

  it('should support CSS minification (without compilation)', function () {
    return expect(tolk.read(getPath('csso/basic.css'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '/*! keep this comment */.hello{margin:0;color:silver'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'wBAGA,OACE,')
      }
    });
  });

  it('should support JS minification (with compilation)', function () {
    return expect(tolk.read(getPath('coffee/basic.coffee'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '(function(){console.log(15)})'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'CAAA,WAAAA')
      }
    });
  });

  it('should support JS minification (without compilation)', function () {
    return expect(tolk.read(getPath('minify-js/basic.js'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', 'for(var stuff=[1,2,3,4,5],i=0;i<stuff.length;i++)'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'AACA,IAAK,')
      }
    });
  });

  it('should support HTML minification (with compilation)', function () {
    return expect(tolk.read(getPath('jade/client-complex.jade'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '
1

1

2

2

3

3

4

4

')
    });
  });

  it('should support HTML minification (without compilation)', function () {
    return expect(tolk.read(getPath('minify-html/basic.html'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '

wowlaween

')
    });
  });

  it('should not compile files beginning with underscore', function () {
    return expect(tolk.read(getPath('scss/_mixin_lib.scss'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '@mixin set_color($color) {\n  color: $color;')
    });
  });

  it('should throw when compiling a file that does not exist', function () {
    return expect(tolk.read(getPath('does-not-exist.scss')), 'when rejected', 'to satisfy', {
      code: 'ENOENT',
      path: /fixtures\/source\/does-not-exist\.scss$/,
      message: /^ENOENT.*?, open '.+?fixtures\/source\/does-not-exist\.scss'$/
    });
  });

  it('should throw when compiling a file with syntax errors', function () {
    return expect(tolk.read(getPath('scss/syntaxerror.scss')), 'when rejected', 'to satisfy', {
      status: 1,
      file: /fixtures\/source\/scss\/syntaxerror\.scss$/,
      line: 2,
      column: 3,
      message: 'property "color" must be followed by a \':\'',
    });
  });

});
<|endoftext|>


<commit_before>const { Command } = require('discord.js-commando');
const { stripIndents } = require('common-tags');

const Currency = require('../../currency/Currency');
const RussianRoulette = require('../../games/Russian-roulette');

module.exports = class RussianRouletteCommand extends Command {
	constructor(client) {
		super(client, {
			name: 'russian-roulette',
			aliases: ['rus-roulette'],
			group: 'games',
			memberName: 'russian-roulette',
			description: `Play a game of russian roulette for ${Currency.textPlural}!`,
			details: `Play a game of russian roulette for ${Currency.textPlural}.`,
			guildOnly: true,
			throttling: {
				usages: 1,
				duration: 30
			}
		});
	}

	async run(msg) {
		const donuts = 120;
		const balance = await Currency.getBalance(msg.author.id);
		let roulette = RussianRoulette.findGame(msg.guild.id);

		if (balance < donuts) {
			return msg.reply(stripIndents`
				you don't have enough ${Currency.textPlural}.
				Your current account balance is ${Currency.convert(balance)}.
				You need ${Currency.convert(donuts)} to join.
			`);
		}

		if (roulette) {
			if (roulette.hasPlayer(msg.author.id)) {
				return msg.reply('you have already joined this game of russian roulette.');
			}
			if (roulette.players.length === 6) {
				return msg.reply('only 6 people can join at a time. You\'ll have to wait for the next round');
			}

			roulette.join(msg.author, donuts);

			return msg.reply('you have successfully joined the game.');
		}

		roulette = new RussianRoulette(msg.guild.id);
		roulette.join(msg.author, donuts);

		const barrel = this.generateBarrel();

		return msg.say(stripIndents`
			A new game of russian roulette has been initiated!

			Use the ${msg.usage()} command in the next 15 seconds to join!
		`).then(async () => {
			setTimeout(() => msg.say('5 more seconds for new people to join'), 10000);
			setTimeout(() => {
				if (roulette.players.length > 1) msg.say('The game begins!');
			}, 14500);

			const players = await roulette.awaitPlayers(15000);

			if (players.length === 1) {
				return msg.say('Seems like no one else wanted to join. Ah well, maybe another time.');
			}

			let deadPlayer = null;
			let survivors = [];

			for (const slot in barrel) {
				let currentPlayer = players[slot % players.length];
				if (!deadPlayer) deadPlayer = currentPlayer;
			}

			survivors = players.filter(player => player !== deadPlayer);

			Currency.removeBalance(deadPlayer.user.id, donuts);
			survivors.forEach(survivor => Currency.addBalance(survivor.user.id, donuts / survivors.length));

			return msg.embed({
				description: stripIndents`
					__**Survivors**__
					${survivors.map(survivor => survivor.user.username).join('\n')}

					__**Reward**__
					The survivors receive ${Currency.convert(donuts / survivors.length)} each.
				`
			});
		});
	}

	generateBarrel() {
		let barrel = [0, 0, 0, 0, 0, 0];
		barrel[Math.floor(Math.random() * barrel.length)] = 1;
		return barrel;
	}
};
<commit_msg>Updated RussianRoulette<commit_after>const { Command } = require('discord.js-commando');
const { stripIndents } = require('common-tags');

const Currency = require('../../currency/Currency');
const RussianRoulette = require('../../games/Russian-roulette');

module.exports = class RussianRouletteCommand extends Command {
	constructor(client) {
		super(client, {
			name: 'russian-roulette',
			aliases: ['rus-roulette'],
			group: 'games',
			memberName: 'russian-roulette',
			description: `Play a game of russian roulette for ${Currency.textPlural}!`,
			details: `Play a game of russian roulette for ${Currency.textPlural}.`,
			guildOnly: true,
			throttling: {
				usages: 1,
				duration: 30
			}
		});
	}

	async run(msg) {
		const gems = 120;
		const balance = await Currency.getBalance(msg.author.id);
		let roulette = RussianRoulette.findGame(msg.guild.id);

		if (balance < gems) {
			return msg.reply(stripIndents`
				you don't have enough ${Currency.textPlural}.
				Your current account balance is ${Currency.convert(balance)}.
				You need ${Currency.convert(gems)} to join.
			`);
		}

		if (roulette) {
			if (roulette.hasPlayer(msg.author.id)) {
				return msg.reply('you have already joined this game of russian roulette.');
			}
			if (roulette.players.length === 6) {
				return msg.reply('only 6 people can join at a time. You\'ll have to wait for the next round');
			}

			roulette.join(msg.author, gems);

			return msg.reply('you have successfully joined the game.');
		}

		roulette = new RussianRoulette(msg.guild.id);
		roulette.join(msg.author, gems);

		const barrel = this.generateBarrel();

		return msg.say(stripIndents`
			A new game of russian roulette has been initiated!

			Use the ${msg.usage()} command in the next 15 seconds to join!
		`).then(async () => {
			setTimeout(() => msg.say('5 more seconds for new people to join'), 10000);
			setTimeout(() => {
				if (roulette.players.length > 1) msg.say('The game begins!');
			}, 14500);

			const players = await roulette.awaitPlayers(15000);

			if (players.length === 1) {
				return msg.say('Seems like no one else wanted to join. Ah well, maybe another time.');
			}

			let deadPlayer = null;
			let survivors = [];

			for (const slot in barrel) {
				let currentPlayer = players[slot % players.length];
				if (!deadPlayer) deadPlayer = currentPlayer;
			}

			survivors = players.filter(player => player !== deadPlayer);

			Currency.removeBalance(deadPlayer.user.id, gems);
			survivors.forEach(survivor => Currency.addBalance(survivor.user.id, gems / survivors.length));

			return msg.embed({
				description: stripIndents`
					__**Survivors**__
					${survivors.map(survivor => survivor.user.username).join('\n')}

					__**Reward**__
					The survivors receive ${Currency.convert(gems / survivors.length)} each.
				`
			});
		});
	}

	generateBarrel() {
		let barrel = [0, 0, 0, 0, 0, 0];
		barrel[Math.floor(Math.random() * barrel.length)] = 1;
		return barrel;
	}
};
<|endoftext|>


<commit_before>angular.module("SpeedTyperSPA", ['ngRoute'])
	.config(["$routeProvider", function ($routeProvider) {
	    $routeProvider
			.when("/",
			{
				templateUrl: "Scripts/partials/home.html",
				controller: HomeController
			})
			.when("/logout",
			{
				templateUrl: "Scripts/partials/logout.html",
				controller: LogoutController
			})
			.when("/login",
			{
				templateUrl: "Scripts/partials/login-form.html",
				controller: LoginController
			})
			.when("/register",
			{
				templateUrl: "Scripts/partials/register-form.html",
				controller: RegisterController
			})
			.when("/rooms/",
			{
				templateUrl: "Scripts/partials/all-rooms.html",
				controller: RoomsController
			})
			.when("/profile",
			{
				templateUrl: "Scripts/partials/profile.html",
				controller: ViewProfileController
			})
			.otherwise(
			{
				redirectTo: "/" }
			);
	}]);<commit_msg>added new routes to app.js for joining new room and room details<commit_after>angular.module("SpeedTyperSPA", ['ngRoute'])
	.config(["$routeProvider", function ($routeProvider) {
	    $routeProvider
			.when("/",
			{
				templateUrl: "Scripts/partials/home.html",
				controller: HomeController
			})
			.when("/logout",
			{
				templateUrl: "Scripts/partials/logout.html",
				controller: LogoutController
			})
			.when("/login",
			{
				templateUrl: "Scripts/partials/login-form.html",
				controller: LoginController
			})
			.when("/register",
			{
				templateUrl: "Scripts/partials/register-form.html",
				controller: RegisterController
			})
			.when("/rooms/",
			{
				templateUrl: "Scripts/partials/all-rooms.html",
				controller: RoomsController
			})
			.when("/rooms/join/:id",
			{
				templateUrl: "Scripts/partials/join-room.html",
				controller: JoinRoomController
			})
			.when("/rooms/details/:id",
			{
				templateUrl: "Scripts/partials/single-room.html",
				controller: SingleRoomController
			})
			.when("/profile",
			{
				templateUrl: "Scripts/partials/profile.html",
				controller: ViewProfileController
			})
			.otherwise(
			{
				redirectTo: "/" }
			);
	}]);<|endoftext|>