<commit_before>// A simple tracker dependency that we invalidates every time the window is
// resized. This is used to reactively re-calculate the popup position in case
// of a window resize.
var windowResizeDep = new Tracker.Dependency;
$(window).on('resize', function() { windowResizeDep.changed() });

Popup = {
    /// This function returns a callback that can be used in an event map:
    ///
    ///   Template.tplName.events({
    ///      'click .elementClass': Popup.open("popupName")
    ///   });
    ///
    /// The popup inherit the data context of its parent.
    open: function(name) {
        var self = this;
        var popupName = name + "Popup";

        return function(evt, tpl) {
            // We determine the openerElement (the DOM element that is being
            // clicked and the one to take in reference for the popup position)
            // from the event if the popup has no parent, or from the parent
            // openerElement if it has one. That allow use to position a
            // sub-popup exactly at the same position of its parent.
            if (self._hasPopupParent()) {
                var parentData = self._stack[self._stack.length - 1];
                var openerElement = parentData.openerElement;
            } else {
                var openerElement = evt.currentTarget;
            }

            // If a popup is already openened, clicking again on the opener
            // element should close it -- and stop the current function.
            if (self.current && openerElement === evt.currentTarget) {
                return self.close();
            }

            // We modify the event to prevent the popup being closed when the
            // event bubble up to the document element.
            evt.originalEvent.clickInPopup = true;
            evt.preventDefault();

            // We push our popup data to the stack. The top of the stack is
            // always used as the data source for our current popup.
            self._stack.push({
                __isPopup: true,
                popupName: popupName,
                hasPopupParent: self._hasPopupParent(),
                title: self._getTitle(popupName),
                openerElement: openerElement,
                offset: self._getOffset(openerElement),
                dataContext: this
            });

            // If there are no popup currently opened we use the Blaze API to
            // render one into the DOM. We use a reactive function as the data
            // parameter that just return the top element on the stack and
            // depends on our internal dependency that is being invalidated
            // every time the top element of the stack has changed and we want
            // to update the popup.
            //
            // Otherwise if there is already a popup open we just need to
            // invalidate our internal dependency, and since we just changed the
            // top element of our internal stack, the popup will be updated with
            // the new data.
            if (! self.current) {
                self.current = Blaze.renderWithData(self.template, function() {
                    self._dep.depend();
                    return self._stack[self._stack.length - 1];
                }, document.body);

            } else {
                self._dep.changed();
            }
        }
    },

    /// This function returns a callback that can be used in an event map:
    ///
    ///   Template.tplName.events({
    ///      'click .elementClass': Popup.afterConfirm("popupName", function() {
    ///          // What to do after the user has confirmed the action
    ///      })
    ///   });
    afterConfirm: function(name, action) {
        var self = this;

        return function(evt, tpl) {
            var context = this;
            context.__afterConfirmAction = action;
            self.open(name).call(context, evt, tpl);
        }
    },

    /// In case the popup was opened from a parent popup we can get back to it
    /// with this `Popup.back()` function. You can go back several steps at once
    /// by providing a number to this function, e.g. `Popup.back(2)`. In this
    /// case intermediate popup won't even be rendered on the DOM.
    back: function(n) {
        n = n || 1;
        var self = this;
        if (self._stack.length >= n + 1) {
            _.times(n, function() { self._stack.pop() });
            self._dep.changed();
        }
    },

    /// Close the current opened popup.
    close: function() {
        if (this.current) {
            Blaze.remove(this.current);
            this.current = null;
            this._stack = [];
        }
    },

    // The template we use for every popup
    template: Template.popup,

    // We only want to display one popup at a time and we keep the view object
    // in this `Popup._current` variable. If there is no popup currently opened
    // the value is `null`.
    _current: null,

    // It's possible to open a sub-popup B from a popup A. In that case we keep
    // the data of popup A so we can return back to it. Every time we open a new
    // popup the stack grows, every time we go back the stack decrease, and if
    // we close the popup the stack is reseted to the empty stack [].
    _stack: [],

    // We invalidate this internal dependency every time the top of the stack
    // has changed and we want to render a popup with the new top-stack data.
    _dep: new Tracker.Dependency,

    // We use the blaze API to determine if the current popup has been opened
    // from a parent popup. The number we give to the `Template.parentData` has
    // been determined experimentally and is susceptible to change if you modify
    // the `Popup.template`
    _hasPopupParent: function() {
        var tryParentData = Template.parentData(3);
        return !! (tryParentData && tryParentData.__isPopup);
    },

    // We automatically calculate the popup offset from the reference element
    // position and dimensions. We also reactively use the window dimensions
    // to ensure that the popup is always visible on the screen.
    _getOffset: function(element) {
        var $element = $(element);
        return function() {
            windowResizeDep.depend();
            var offset = $element.offset();
            var popupWidth = 300 + 15;
            return {
                left: Math.min(offset.left, $(window).width() - popupWidth),
                top: offset.top + $element.outerHeight()
            };
        };
    },

    // We get the title from the translation files. Instead of returning the
    // result, we return a function that compute the result and since
    // `TAPi18n.__` is a reactive data source, the title will be changed
    // reactively
    _getTitle: function(popupName) {
        return function () {
            var translationKey = popupName + "-title";
            // XXX There is no public API to check if there is an available
            // translation for a given key. So we try to translate the key and
            // if the translation output equals the key input we deduce that no
            // translation was available and returns `false`. There is a (small)
            // risk a false positives.
            var title = TAPi18n.__(translationKey);
            return title !== translationKey ? title : false;
        }
    }
};

Popup.template.events({
    'click': function(event) {
        if (event.originalEvent)  {
            event.originalEvent.clickInPopup = true;
        }
    },
    'click .js-back-view': function() {
        Popup.back();
    },
    'click .js-close-popover': function() {
        Popup.close();
    },
    'click .js-confirm': function() {
        this.__afterConfirmAction.call(this);
    }
});

// We automatically close a potential opened popup on any left click on the
// document. To avoid closing it unexpectedly we modify the bubbled event in
// case the click event happen in the popup or in a button that open a popup.
$(document).on('click', function (event) {
    if (event.which === 1 &&
        ! (event.originalEvent && event.originalEvent.clickInPopup)) {
        Popup.close();
    }
});
<commit_msg>Improve the popup system<commit_after>// A simple tracker dependency that we invalidates every time the window is
// resized. This is used to reactively re-calculate the popup position in case
// of a window resize.
var windowResizeDep = new Tracker.Dependency;
$(window).on('resize', function() { windowResizeDep.changed() });

Popup = {
    /// This function returns a callback that can be used in an event map:
    ///
    ///   Template.tplName.events({
    ///      'click .elementClass': Popup.open("popupName")
    ///   });
    ///
    /// The popup inherit the data context of its parent.
    open: function(name) {
        var self = this;
        var popupName = name + "Popup";

        return function(evt, tpl) {
            // We determine the openerElement (the DOM element that is being
            // clicked and the one we take in reference for the popup position)
            // from the event if the popup has no parent, or from the parent
            // openerElement if it has one. That allow us to position a
            // sub-popup exactly at the same position than its parent.
            if (self._hasPopupParent()) {
                var openerElement = self._getTopStack().openerElement;

            // If a popup is already openened, clicking again on the opener
            // element should close it -- and stop the current function.
            } else if (self.current &&
                      self._getTopStack().openerElement === evt.currentTarget) {
                return self.close();

            } else {
                var openerElement = evt.currentTarget;
            }

            // We modify the event to prevent the popup being closed when the
            // event bubble up to the document element.
            evt.originalEvent.clickInPopup = true;
            evt.preventDefault();

            // We push our popup data to the stack. The top of the stack is
            // always used as the data source for our current popup.
            self._stack.push({
                __isPopup: true,
                popupName: popupName,
                hasPopupParent: self._hasPopupParent(),
                title: self._getTitle(popupName),
                openerElement: openerElement,
                offset: self._getOffset(openerElement),
                dataContext: this
            });

            // If there are no popup currently opened we use the Blaze API to
            // render one into the DOM. We use a reactive function as the data
            // parameter that just return the top element on the stack and
            // depends on our internal dependency that is being invalidated
            // every time the top element of the stack has changed and we want
            // to update the popup.
            //
            // Otherwise if there is already a popup open we just need to
            // invalidate our internal dependency, and since we just changed the
            // top element of our internal stack, the popup will be updated with
            // the new data.
            if (! self.current) {
                self.current = Blaze.renderWithData(self.template, function() {
                    self._dep.depend();
                    return self._stack[self._stack.length - 1];
                }, document.body);

            } else {
                self._dep.changed();
            }
        }
    },

    /// This function returns a callback that can be used in an event map:
    ///
    ///   Template.tplName.events({
    ///      'click .elementClass': Popup.afterConfirm("popupName", function() {
    ///          // What to do after the user has confirmed the action
    ///      })
    ///   });
    afterConfirm: function(name, action) {
        var self = this;

        return function(evt, tpl) {
            var context = this;
            context.__afterConfirmAction = action;
            self.open(name).call(context, evt, tpl);
        }
    },

    /// In case the popup was opened from a parent popup we can get back to it
    /// with this `Popup.back()` function. You can go back several steps at once
    /// by providing a number to this function, e.g. `Popup.back(2)`. In this
    /// case intermediate popup won't even be rendered on the DOM.
    back: function(n) {
        n = n || 1;
        var self = this;
        if (self._stack.length >= n + 1) {
            _.times(n, function() { self._stack.pop() });
            self._dep.changed();
        }
    },

    /// Close the current opened popup.
    close: function() {
        if (this.current) {
            Blaze.remove(this.current);
            this.current = null;
            this._stack = [];
        }
    },

    // The template we use for every popup
    template: Template.popup,

    // We only want to display one popup at a time and we keep the view object
    // in this `Popup._current` variable. If there is no popup currently opened
    // the value is `null`.
    _current: null,

    // It's possible to open a sub-popup B from a popup A. In that case we keep
    // the data of popup A so we can return back to it. Every time we open a new
    // popup the stack grows, every time we go back the stack decrease, and if
    // we close the popup the stack is reseted to the empty stack [].
    _stack: [],

    // We invalidate this internal dependency every time the top of the stack
    // has changed and we want to render a popup with the new top-stack data.
    _dep: new Tracker.Dependency,

    // An utility fonction that returns the top element of the internal stack
    _getTopStack: function() {
        return this._stack[this._stack.length - 1];
    },

    // We use the blaze API to determine if the current popup has been opened
    // from a parent popup. The number we give to the `Template.parentData` has
    // been determined experimentally and is susceptible to change if you modify
    // the `Popup.template`
    _hasPopupParent: function() {
        var tryParentData = Template.parentData(3);
        return !! (tryParentData && tryParentData.__isPopup);
    },

    // We automatically calculate the popup offset from the reference element
    // position and dimensions. We also reactively use the window dimensions
    // to ensure that the popup is always visible on the screen.
    _getOffset: function(element) {
        var $element = $(element);
        return function() {
            windowResizeDep.depend();
            var offset = $element.offset();
            var popupWidth = 300 + 15;
            return {
                left: Math.min(offset.left, $(window).width() - popupWidth),
                top: offset.top + $element.outerHeight()
            };
        };
    },

    // We get the title from the translation files. Instead of returning the
    // result, we return a function that compute the result and since
    // `TAPi18n.__` is a reactive data source, the title will be changed
    // reactively
    _getTitle: function(popupName) {
        return function () {
            var translationKey = popupName + "-title";
            // XXX There is no public API to check if there is an available
            // translation for a given key. So we try to translate the key and
            // if the translation output equals the key input we deduce that no
            // translation was available and returns `false`. There is a (small)
            // risk a false positives.
            var title = TAPi18n.__(translationKey);
            return title !== translationKey ? title : false;
        }
    }
};

Popup.template.events({
    'click': function(event) {
        if (event.originalEvent)  {
            event.originalEvent.clickInPopup = true;
        }
    },
    'click .js-back-view': function() {
        Popup.back();
    },
    'click .js-close-popover': function() {
        Popup.close();
    },
    'click .js-confirm': function() {
        this.__afterConfirmAction.call(this);
    }
});

// We automatically close a potential opened popup on any left click on the
// document. To avoid closing it unexpectedly we modify the bubbled event in
// case the click event happen in the popup or in a button that open a popup.
$(document).on('click', function (event) {
    if (event.which === 1 &&
        ! (event.originalEvent && event.originalEvent.clickInPopup)) {
        Popup.close();
    }
});
<|endoftext|>


<commit_before>Utils = {
  // XXX We should remove these two methods
  goBoardId(_id) {
    const board = Boards.findOne(_id);
    return board && FlowRouter.go('board', {
      id: board._id,
      slug: board.slug,
    });
  },

  goCardId(_id) {
    const card = Cards.findOne(_id);
    const board = Boards.findOne(card.boardId);
    return board && FlowRouter.go('card', {
      cardId: card._id,
      boardId: board._id,
      slug: board.slug,
    });
  },

  capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
  },

  windowResizeDep: new Tracker.Dependency(),

  // in fact, what we really care is screen size
  // large mobile device like iPad or android Pad has a big screen, it should also behave like a desktop
  // in a small window (even on desktop), Wekan run in compact mode.
  // we can easily debug with a small window of desktop browser. :-)
  isMiniScreen() {
    this.windowResizeDep.depend();
    return $(window).width() <= 800;
  },

  calculateIndexData(prevData, nextData, nItems = 1) {
    let base, increment;
    // If we drop the card to an empty column
    if (!prevData && !nextData) {
      base = 0;
      increment = 1;
    // If we drop the card in the first position
    } else if (!prevData) {
      base = nextData.sort - 1;
      increment = -1;
    // If we drop the card in the last position
    } else if (!nextData) {
      base = prevData.sort + 1;
      increment = 1;
    }
    // In the general case take the average of the previous and next element
    // sort indexes.
    else {
      const prevSortIndex = prevData.sort;
      const nextSortIndex = nextData.sort;
      increment = (nextSortIndex - prevSortIndex) / (nItems + 1);
      base = prevSortIndex + increment;
    }
    // XXX Return a generator that yield values instead of a base with a
    // increment number.
    return {
      base,
      increment,
    };
  },

  // Determine the new sort index
  calculateIndex(prevCardDomElement, nextCardDomElement, nCards = 1) {
    let base, increment;
    // If we drop the card to an empty column
    if (!prevCardDomElement && !nextCardDomElement) {
      base = 0;
      increment = 1;
    // If we drop the card in the first position
    } else if (!prevCardDomElement) {
      base = Blaze.getData(nextCardDomElement).sort - 1;
      increment = -1;
    // If we drop the card in the last position
    } else if (!nextCardDomElement) {
      base = Blaze.getData(prevCardDomElement).sort + 1;
      increment = 1;
    }
    // In the general case take the average of the previous and next element
    // sort indexes.
    else {
      const prevSortIndex = Blaze.getData(prevCardDomElement).sort;
      const nextSortIndex = Blaze.getData(nextCardDomElement).sort;
      increment = (nextSortIndex - prevSortIndex) / (nCards + 1);
      base = prevSortIndex + increment;
    }
    // XXX Return a generator that yield values instead of a base with a
    // increment number.
    return {
      base,
      increment,
    };
  },

  // Detect touch device
  isTouchDevice() {
    const isTouchable = (() => {
      const prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
      const mq = function(query) {
        return window.matchMedia(query).matches;
      };

      if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) {
        return true;
      }

      // include the 'heartz' as a way to have a non matching MQ to help terminate the join
      // https://git.io/vznFH
      const query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
      return mq(query);
    })();
    return isTouchable;
  },

  calculateTouchDistance(touchA, touchB) {
    return Math.sqrt(
      Math.pow(touchA.screenX - touchB.screenX, 2) +
      Math.pow(touchA.screenY - touchB.screenY, 2)
    );
  },

  enableClickOnTouch(selector) {
    let touchStart = null;
    let lastTouch = null;

    $(document).on('touchstart', selector, function(e) {
      touchStart = e.originalEvent.touches[0];
    });
    $(document).on('touchmove', selector, function(e) {
      const touches = e.originalEvent.touches;
      lastTouch = touches[touches.length - 1];
    });
    $(document).on('touchend', selector, function(e) {
      if (touchStart && lastTouch && Utils.calculateTouchDistance(touchStart, lastTouch) <= 20) {
        const clickEvent = document.createEvent('MouseEvents');
        clickEvent.initEvent('click', true, true);
        e.target.dispatchEvent(clickEvent);
      }
    });
  },
};

// A simple tracker dependency that we invalidate every time the window is
// resized. This is used to reactively re-calculate the popup position in case
// of a window resize. This is the equivalent of a "Signal" in some other
// programming environments (eg, elm).
$(window).on('resize', () => Utils.windowResizeDep.changed());
<commit_msg>Avoid default behavior<commit_after>Utils = {
  // XXX We should remove these two methods
  goBoardId(_id) {
    const board = Boards.findOne(_id);
    return board && FlowRouter.go('board', {
      id: board._id,
      slug: board.slug,
    });
  },

  goCardId(_id) {
    const card = Cards.findOne(_id);
    const board = Boards.findOne(card.boardId);
    return board && FlowRouter.go('card', {
      cardId: card._id,
      boardId: board._id,
      slug: board.slug,
    });
  },

  capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
  },

  windowResizeDep: new Tracker.Dependency(),

  // in fact, what we really care is screen size
  // large mobile device like iPad or android Pad has a big screen, it should also behave like a desktop
  // in a small window (even on desktop), Wekan run in compact mode.
  // we can easily debug with a small window of desktop browser. :-)
  isMiniScreen() {
    this.windowResizeDep.depend();
    return $(window).width() <= 800;
  },

  calculateIndexData(prevData, nextData, nItems = 1) {
    let base, increment;
    // If we drop the card to an empty column
    if (!prevData && !nextData) {
      base = 0;
      increment = 1;
    // If we drop the card in the first position
    } else if (!prevData) {
      base = nextData.sort - 1;
      increment = -1;
    // If we drop the card in the last position
    } else if (!nextData) {
      base = prevData.sort + 1;
      increment = 1;
    }
    // In the general case take the average of the previous and next element
    // sort indexes.
    else {
      const prevSortIndex = prevData.sort;
      const nextSortIndex = nextData.sort;
      increment = (nextSortIndex - prevSortIndex) / (nItems + 1);
      base = prevSortIndex + increment;
    }
    // XXX Return a generator that yield values instead of a base with a
    // increment number.
    return {
      base,
      increment,
    };
  },

  // Determine the new sort index
  calculateIndex(prevCardDomElement, nextCardDomElement, nCards = 1) {
    let base, increment;
    // If we drop the card to an empty column
    if (!prevCardDomElement && !nextCardDomElement) {
      base = 0;
      increment = 1;
    // If we drop the card in the first position
    } else if (!prevCardDomElement) {
      base = Blaze.getData(nextCardDomElement).sort - 1;
      increment = -1;
    // If we drop the card in the last position
    } else if (!nextCardDomElement) {
      base = Blaze.getData(prevCardDomElement).sort + 1;
      increment = 1;
    }
    // In the general case take the average of the previous and next element
    // sort indexes.
    else {
      const prevSortIndex = Blaze.getData(prevCardDomElement).sort;
      const nextSortIndex = Blaze.getData(nextCardDomElement).sort;
      increment = (nextSortIndex - prevSortIndex) / (nCards + 1);
      base = prevSortIndex + increment;
    }
    // XXX Return a generator that yield values instead of a base with a
    // increment number.
    return {
      base,
      increment,
    };
  },

  // Detect touch device
  isTouchDevice() {
    const isTouchable = (() => {
      const prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
      const mq = function(query) {
        return window.matchMedia(query).matches;
      };

      if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) {
        return true;
      }

      // include the 'heartz' as a way to have a non matching MQ to help terminate the join
      // https://git.io/vznFH
      const query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
      return mq(query);
    })();
    return isTouchable;
  },

  calculateTouchDistance(touchA, touchB) {
    return Math.sqrt(
      Math.pow(touchA.screenX - touchB.screenX, 2) +
      Math.pow(touchA.screenY - touchB.screenY, 2)
    );
  },

  enableClickOnTouch(selector) {
    let touchStart = null;
    let lastTouch = null;

    $(document).on('touchstart', selector, function(e) {
      touchStart = e.originalEvent.touches[0];
    });
    $(document).on('touchmove', selector, function(e) {
      const touches = e.originalEvent.touches;
      lastTouch = touches[touches.length - 1];
    });
    $(document).on('touchend', selector, function(e) {
      if (touchStart && lastTouch && Utils.calculateTouchDistance(touchStart, lastTouch) <= 20) {
        e.preventDefault();
        const clickEvent = document.createEvent('MouseEvents');
        clickEvent.initEvent('click', true, true);
        e.target.dispatchEvent(clickEvent);
      }
    });
  },
};

// A simple tracker dependency that we invalidate every time the window is
// resized. This is used to reactively re-calculate the popup position in case
// of a window resize. This is the equivalent of a "Signal" in some other
// programming environments (eg, elm).
$(window).on('resize', () => Utils.windowResizeDep.changed());
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import ReactDOM from 'react-dom';

// COMPONENTS
import NavBar from './NavBar.js';
import Loading from './Loading.js'

// MEDIA PLAYER
import Sound from '../../node_modules/react-sound';

//  RESPONSIVE CSS
import MediaQuery from '../../node_modules/react-responsive';

// MATERIAL DESIGN
import Card from '../../node_modules/material-ui/lib/card/card';
import CardActions from '../../node_modules/material-ui/lib/card/card-actions';
import CardMedia from '../../node_modules/material-ui/lib/card/card-media';
import CardText from '../../node_modules/material-ui/lib/card/card-text';
import CardTitle from '../../node_modules/material-ui/lib/card/card-title';
import FloatingActionButton from '../../node_modules/material-ui/lib/floating-action-button';
import Play from '../../node_modules/material-ui/lib/svg-icons/av/play-arrow';
import Pause from '../../node_modules/material-ui/lib/svg-icons/av/pause';
import Favorite from '../../node_modules/material-ui/lib/svg-icons/action/favorite';
import AppBar from '../../node_modules/material-ui/lib/app-bar';
// import CardHeader from '../../node_modules/material-ui/lib/card/card-header';
// import CardText from '../../node_modules/material-ui/lib/card/card-text';
import $ from '../../public/js/jquery-1.11.1.min';

var BASE_URL = 'http://' + document.location.host;

class StreamLive extends React.Component {

  constructor(props){
    super(props);

    this.state = {
      status : "STOPPED",
      disabled : false,
      desc: "",
      name: "",
      broadcaster: "",
      description: "",
      image: "",
      listenerLiveCount: "",
      creator: "",
      isLoading: true
    }
  }

  componentWillMount() {
    this.fetchStreamData();
  }

  playSong() {
    console.log("playSong")
    this.setState({
      status: "PLAYING",
      disabled: true
    });
  }

  stopSong() {
    console.log("stopSong")
    this.setState({
      status: "STOPPED",
      disabled: false
    });
  }

  addHeart() {
    var PUT_HEART = BASE_URL + '/api/stream/' + this.props.params.streamId;

    // fetch(PUT_HEART, {
    //   method: 'PUT',
    //   body: JSON.stringify()
    // })
    // .then((response) => response.json())
    // .then((responseData) => {
    //   this.setState({
    //     heartCount: responseData.heartCountNum.length > 5 ? '> 9 999' : responseData.heartCountNum
    //   });
    // })
    $.ajax({
        url: PUT_HEART,
        method: 'PUT',
        contentType: "application/x-www-form-urlencoded",
        data: ''
      })
      .done((responseData) => {
        this.setState({
          heartCount: responseData.heartCountNum.length > 5 ? '> 9 999' : responseData.heartCountNum
        });
      });
  }

  fetchStreamData() {
    $.ajax({
      url: BASE_URL + '/api/stream/' + this.props.params.streamId
    })
    .done((streamData) => {
      console.log(streamData)
      $.ajax({
        url: BASE_URL + '/api/user/' + streamData.creator
      })
      .done((userData) => {
        console.log(userData)
        this.setState({
          name: streamData.name,
          broadcaster: streamData.broadcaster,
          desc: streamData.description,
          image: userData.scAvatarUri,
          listenerLiveCount: streamData.listenerLiveCount,
          creator: streamData.creator,
          isLoading: false
        })
      })
    })
  }

  render() {
    var partial = <Loading />
    if (!this.state.isLoading) {
      partial = (

          <Card style={styles.card}>
            <CardMedia style={styles.image} >

            </CardMedia>
            <CardTitle title={this.state.name} subtitle={this.state.broadcaster}  />
            <CardText>
              {this.state.desc}
            </CardText>
            <CardActions>
              <FloatingActionButton onClick={this.playSong.bind(this)} secondary={true} disabled={this.state.disabled}>
                <Play />
              </FloatingActionButton>

              <FloatingActionButton onClick={this.stopSong.bind(this)} secondary={true}  disabled={!this.state.disabled}>
                <Pause />
              </FloatingActionButton>
              <FloatingActionButton onClick={this.addHeart.bind(this)}>
                <Favorite />
              </FloatingActionButton>
            </CardActions>
          </Card>

      )
    }
    return (

          <NavBar title={'Now Playing'} history={this.props.history}/>

        {partial}

        <Sound
          url={'/stream/' + this.props.params.streamId}
          playStatus={this.state.status}
          onLoading={this.handleSongLoading}
          onPlaying={this.handleSongPlaying}
          onFinishedPlaying={this.handleSongFinishedPlaying} />

    )
  }
}

var styles = {

  mainContainer: {
    'display': 'flex',
    'flexDirection':'column',
    // 'border': '10px solid purple',
    // 'height': '100vh'
  },

  playerContainer: {
    'display': 'flex',
    'flexDirection':'row',
    'justifyContent':'center',
    // 'border': '10px solid goldenrod',
  },

  card: {
    'flexGrow':1,
    'alignContent': 'center',
    'maxWidth': 325
    // 'border': '10px solid yellow',
    // 'height': '100vh'
  },

  padding: {
    // 'flex':1,
    // 'border': '10px solid red',
  }
}

export default StreamLive;<commit_msg>Minor update to match new response format. - Also: removed old diagnostic code.<commit_after>import React, { Component } from 'react';
import ReactDOM from 'react-dom';

// COMPONENTS
import NavBar from './NavBar.js';
import Loading from './Loading.js'

// MEDIA PLAYER
import Sound from '../../node_modules/react-sound';

//  RESPONSIVE CSS
import MediaQuery from '../../node_modules/react-responsive';

// MATERIAL DESIGN
import Card from '../../node_modules/material-ui/lib/card/card';
import CardActions from '../../node_modules/material-ui/lib/card/card-actions';
import CardMedia from '../../node_modules/material-ui/lib/card/card-media';
import CardText from '../../node_modules/material-ui/lib/card/card-text';
import CardTitle from '../../node_modules/material-ui/lib/card/card-title';
import FloatingActionButton from '../../node_modules/material-ui/lib/floating-action-button';
import Play from '../../node_modules/material-ui/lib/svg-icons/av/play-arrow';
import Pause from '../../node_modules/material-ui/lib/svg-icons/av/pause';
import Favorite from '../../node_modules/material-ui/lib/svg-icons/action/favorite';
import AppBar from '../../node_modules/material-ui/lib/app-bar';
// import CardHeader from '../../node_modules/material-ui/lib/card/card-header';
// import CardText from '../../node_modules/material-ui/lib/card/card-text';
import $ from '../../public/js/jquery-1.11.1.min';

var BASE_URL = 'http://' + document.location.host;

class StreamLive extends React.Component {

  constructor(props){
    super(props);

    this.state = {
      status : "STOPPED",
      disabled : false,
      desc: "",
      name: "",
      broadcaster: "",
      description: "",
      image: "",
      listenerLiveCount: "",
      creator: "",
      isLoading: true
    }
  }

  componentWillMount() {
    this.fetchStreamData();
  }

  playSong() {
    console.log("playSong")
    this.setState({
      status: "PLAYING",
      disabled: true
    });
  }

  stopSong() {
    console.log("stopSong")
    this.setState({
      status: "STOPPED",
      disabled: false
    });
  }

  addHeart() {
    var PUT_HEART = BASE_URL + '/api/stream/' + this.props.params.streamId;

    // fetch(PUT_HEART, {
    //   method: 'PUT',
    //   body: JSON.stringify()
    // })
    // .then((response) => response.json())
    // .then((responseData) => {
    //   this.setState({
    //     heartCount: responseData.heartCountNum.length > 5 ? '> 9 999' : responseData.heartCountNum
    //   });
    // })
    $.ajax({
        url: PUT_HEART,
        method: 'PUT',
        contentType: "application/x-www-form-urlencoded",
        data: ''
      })
      .done((responseData) => {
        this.setState({
          heartCount: responseData.heartCountNum.length > 5 ? '> 9 999' : responseData.heartCountNum
        });
      });
  }

  fetchStreamData() {
    $.ajax({
      url: BASE_URL + '/api/stream/' + this.props.params.streamId
    })
    .done((streamData) => {
      $.ajax({
        url: BASE_URL + '/api/user/' + streamData.creator
      })
      .done((userData) => {
        this.setState({
          name: streamData.name,
          broadcaster: streamData.broadcaster,
          desc: streamData.description,
          image: userData.user.scAvatarUri,
          listenerLiveCount: streamData.listenerLiveCount,
          creator: streamData.creator,
          isLoading: false
        })
      })
    })
  }

  render() {
    var partial = <Loading />
    if (!this.state.isLoading) {
      partial = (

          <Card style={styles.card}>
            <CardMedia style={styles.image} >

            </CardMedia>
            <CardTitle title={this.state.name} subtitle={this.state.broadcaster}  />
            <CardText>
              {this.state.desc}
            </CardText>
            <CardActions>
              <FloatingActionButton onClick={this.playSong.bind(this)} secondary={true} disabled={this.state.disabled}>
                <Play />
              </FloatingActionButton>

              <FloatingActionButton onClick={this.stopSong.bind(this)} secondary={true}  disabled={!this.state.disabled}>
                <Pause />
              </FloatingActionButton>
              <FloatingActionButton onClick={this.addHeart.bind(this)}>
                <Favorite />
              </FloatingActionButton>
            </CardActions>
          </Card>

      )
    }
    return (

          <NavBar title={'Now Playing'} history={this.props.history}/>

        {partial}

        <Sound
          url={'/stream/' + this.props.params.streamId}
          playStatus={this.state.status}
          onLoading={this.handleSongLoading}
          onPlaying={this.handleSongPlaying}
          onFinishedPlaying={this.handleSongFinishedPlaying} />

    )
  }
}

var styles = {

  mainContainer: {
    'display': 'flex',
    'flexDirection':'column',
    // 'border': '10px solid purple',
    // 'height': '100vh'
  },

  playerContainer: {
    'display': 'flex',
    'flexDirection':'row',
    'justifyContent':'center',
    // 'border': '10px solid goldenrod',
  },

  card: {
    'flexGrow':1,
    'alignContent': 'center',
    'maxWidth': 325
    // 'border': '10px solid yellow',
    // 'height': '100vh'
  },

  padding: {
    // 'flex':1,
    // 'border': '10px solid red',
  }
}

export default StreamLive;<|endoftext|>


<commit_before>({
	block: 'document',
	title: 'SafeSecret.Info',
	styles: ['css/main.css'],
	scripts: ['js/main.js'],
	content: [
		{
			block: 'fs-form',
			attrs: {
				id: 'fs-form'
			},
			content: [
				{
					block: 'header',
					content: 'SafeSecret.Info'
				},
				{
					elem: 'content',
					elemMods: { full: true },
					tag: 'form',
					attrs: {
						autocomplete: 'off'
					},
					content: [
						{
							block: 'fields',
							content: [
								{
									block: 'field',
									id: 'text',
									title: 'What information do you want to share?',
									content: {
										block: 'textarea',
										id: 'text',
										placeholder: 'Enter here'
									}
								},
								{
									block: 'field',
									id: 'time',
									title: 'How long to keep?',
									content: [
										{
											block: 'input',
											mods: { type: 'number' },
											id: 'time',
											placeholder: '10'
										},
										{
											elem: 'desc',
											content: 'How many minutes?'
										}
									]
								},
								{
									block: 'field',
									id: 'pin',
									title: 'Enter the PIN to protect your information',
									content: [
										{
											block: 'input',
											mods: { type: 'pin' },
											id: 'pin',
											placeholder: (function() {
												var text = '';
											    var possible = '0123456789';

											    for (var i = 0; i < 5; i++)
											        text += possible.charAt(Math.floor(Math.random() * possible.length));

											    return text;
											})()
										},
										{
											elem: 'desc',
											content: 'PIN is a 5-digit password.'
										}
									]
								}
							]
						},
						{
							block: 'result',
							content: [
								{
									elem: 'throbber',
									content: 'Loading..'
								},
								{
									elem: 'tip',
									content: 'Here is your link and don\'t forget your PIN!'
								},
								{
									block: 'textarea',
									mods: { result: true, size: 'm' },
									mix: { block: 'result', elem: 'info' },
									attrs: {
										id: 'result__info'
									}
								},
								{
									block: 'description',
									mix: { block: 'result', elem: 'desc' },
									content: [
										'Use this link to access to saving information. ',
										{
											block: 'link',
											url: 'javascript:location.reload()',
											content: 'Save yet another information?'
										}
									]
								},
								{
									block: 'button',
									mods: { content: 'copy', shown: true },
									mix: { block: 'result', elem: 'button' },
									attrs: {
										'data-clipboard-target': '#result__info'
									},
									content: 'Copy'
								}
							]
						}
					]
				}
			]
		}
	]
})<commit_msg>fix spelling<commit_after>({
	block: 'document',
	title: 'SafeSecret.Info',
	styles: ['css/main.css'],
	scripts: ['js/main.js'],
	content: [
		{
			block: 'fs-form',
			attrs: {
				id: 'fs-form'
			},
			content: [
				{
					block: 'header',
					content: 'SafeSecret.Info'
				},
				{
					elem: 'content',
					elemMods: { full: true },
					tag: 'form',
					attrs: {
						autocomplete: 'off'
					},
					content: [
						{
							block: 'fields',
							content: [
								{
									block: 'field',
									id: 'text',
									title: 'What information do you want to share?',
									content: {
										block: 'textarea',
										id: 'text',
										placeholder: 'Enter here'
									}
								},
								{
									block: 'field',
									id: 'time',
									title: 'How long to keep?',
									content: [
										{
											block: 'input',
											mods: { type: 'number' },
											id: 'time',
											placeholder: '10'
										},
										{
											elem: 'desc',
											content: 'How many minutes?'
										}
									]
								},
								{
									block: 'field',
									id: 'pin',
									title: 'Enter the PIN to protect your information',
									content: [
										{
											block: 'input',
											mods: { type: 'pin' },
											id: 'pin',
											placeholder: (function() {
												var text = '';
											    var possible = '0123456789';

											    for (var i = 0; i < 5; i++)
											        text += possible.charAt(Math.floor(Math.random() * possible.length));

											    return text;
											})()
										},
										{
											elem: 'desc',
											content: 'PIN is a 5-digit password.'
										}
									]
								}
							]
						},
						{
							block: 'result',
							content: [
								{
									elem: 'throbber',
									content: 'Loading..'
								},
								{
									elem: 'tip',
									content: 'Here is your link and don\'t forget your PIN!'
								},
								{
									block: 'textarea',
									mods: { result: true, size: 'm' },
									mix: { block: 'result', elem: 'info' },
									attrs: {
										id: 'result__info'
									}
								},
								{
									block: 'description',
									mix: { block: 'result', elem: 'desc' },
									content: [
										'Use this link to access to saving information. ',
										{
											block: 'link',
											url: 'javascript:location.reload()',
											content: 'Save yet another one?'
										}
									]
								},
								{
									block: 'button',
									mods: { content: 'copy', shown: true },
									mix: { block: 'result', elem: 'button' },
									attrs: {
										'data-clipboard-target': '#result__info'
									},
									content: 'Copy'
								}
							]
						}
					]
				}
			]
		}
	]
})<|endoftext|>


<commit_before>/* Test ruleset, used for development */

var ruleset = server.getRuleset();
ruleset = new Ruleset(server);

ruleset.properties.name = "test";

ruleset.properties.botsPerTeam = 4;

ruleset.properties.bots = {
	'angleStep': 0.1,
	'speed': 5,
	'radius': 10,
	'radiusMargin': 0,
	'colors': [ "#01eb5f", "#b11e1e" ]
};

ruleset.properties.weapons.bullet.speed = 8;
ruleset.properties.weapons.bullet.strength = 3;
ruleset.properties.weapons.bullet.waitTime = 15;
ruleset.properties.weapons.bullet.numAllowed = 3;

ruleset.generateObstacles = function() {
	// Simpler obstacle generation for now
	var obstacles = [];

	return obstacles;
};

server.setRuleset(ruleset);
<commit_msg>Added obstacles back to test2<commit_after>/* Test ruleset, used for development */

var ruleset = server.getRuleset();
ruleset = new Ruleset(server);

ruleset.properties.name = "test";

ruleset.properties.botsPerTeam = 4;

ruleset.properties.bots = {
	'angleStep': 0.1,
	'speed': 5,
	'radius': 10,
	'radiusMargin': 0,
	'colors': [ "#01eb5f", "#b11e1e" ]
};

ruleset.properties.weapons.bullet.speed = 8;
ruleset.properties.weapons.bullet.strength = 3;
ruleset.properties.weapons.bullet.waitTime = 15;
ruleset.properties.weapons.bullet.numAllowed = 3;

ruleset.generateObstacles = function() {
	// Simpler obstacle generation for now
	var obstacles = [
		{ "x": 50, "y": 200, "width": 50, "height": 200 },
		{ "x": 900, "y": 200, "width": 50, "height": 200 },
		{ "x": 450, "y": 250, "width": 100, "height": 100 },
		{ "x": 100, "y": 40, "width": 800, "height": 40 },
		{ "x": 100, "y": 520, "width": 800, "height": 40 }
	];

	return obstacles;
};

server.setRuleset(ruleset);
<|endoftext|>


<commit_before><commit_msg>Added test requirements<commit_after><|endoftext|>


<commit_before>var nj = function(x) {

  function dim(m) {
    var d = [];
    for (;;) {
      d.push(m.length);

      if (Array.isArray(m[0])) {
        m = m[0];
      } else {
        break;
      }
    }

    return d;
  }

  /**
  * nj.add
  * Addition
  */
  function add(x, y) {
    return x + y;
  }

  this.add = function(x, y) {
    this.value = add(x, y);
  }

  /**
  * nj.sub
  * Subtraction
  */
  function sub(x, y) {
    return x - y;
  }

  this.sub = function(x, y) {
    this.value = sub(x, y);
  }

  /**
  * nj.mul
  * Multiplication
  */
  function mul(x, y) {
    return x * y;
  }

  this.mul = function(x, y) {
    this.value = mul(x, y);
  }

  /**
  * nj.div
  * Division
  */
  function div(x, y) {
    return x / y;
  }

  this.div = function(x, y) {
    this.value = div(x, y);
  }

  /**
  * nj.abs
  * Return the absolute value of x
  */
  function abs(x) {
    return Math.abs(x);
  }

  this.abs = function(x) {
    this.value = abs(x);
  }

  /**
  * nj.ceil
  * Returns x, rounded upwards to the nearest integer
  */
  function ceil(x) {
    return Math.ceil(x);
  }

  this.ceil = function(x) {
    this.value = ceil(x);
  }

  /**
  * nj.floor
  * Returns x, rounded downwards to the nearest integer
  */
  function floor(x) {
    return Math.floor(x);
  }

  this.floor = function(x) {
    this.value = floor(x);
  }

  /**
  * nj.exp
  * Returns the value of E^x
  */
  function exp(x) {
    return Math.exp(x);
  }

  this.exp = function(x) {
    this.value = exp(x);
  }

  /**
  * nj.log
  * Returns the natural logarithm (base E) of x
  */
  function log(x) {
    return Math.log(x);
  }

  this.log = function(x) {
    this.value = log(x);
  }

  /**
  * nj.pow
  * Returns the value of x to the power of y
  */
  function pow(x, y) {
    return Math.pow(x, y);
  }

  this.pow = function(x, y) {
    this.value = pow(x, y);
  }

  /**
  * nj.round
  * Rounds x to the nearest integer
  */
  function round(x) {
    return Math.round(x);
  }

  this.round = function(x) {
    this.value = round(x);
  }

  /**
  * nj.sqrt
  * Rounds x to the nearest integer
  */
  function sqrt(x) {
    return Math.sqrt(x);
  }

  this.sqrt = function(x) {
    this.value = sqrt(x);
  }

  /**
  * nj.random
  * Returns a random number between x and y
  */
  function random(x, y) {
    return Math.random() * (y - x) + x;
  }

  this.random = function(x, y) {
    this.value = random(x, y);
  }

  /**
  * nj.max
  * Returns the number with the highest value
  */
  function max() {
    return Math.max(arguments);
  }

  this.max = function() {
    var max = arguments[0];

    for(var i = 1; i < arguments.length; i++) {
      if(max <= arguments[i]) {
        max = arguments[i];
      }
    }

    this.value = max;
  }

  /**
  * nj.min
  * Returns the number with the lowest value
  */
  function min() {
    return Math.min(arguments);
  }

  this.min = function() {
    var min = arguments[0];

    for(var i = 1; i < arguments.length; i++) {
      if(min >= arguments[i]) {
        min = arguments[i];
      }
    }

    this.value = min;
  }

  /**
  * nj.PI
  * PI
  */
  function PI() {
    return Math.PI;
  }

  this.PI = function() {
    this.value = Math.PI;
  }

  /**
  * nj.cos
  * Cosine
  */
  function cos(deg) {
    return Math.cos((deg / 180) * PI());
  }

  this.cos = function(deg) {
    this.value = cos(deg);
  }

  /**
  * nj.sin
  * Sine
  */
  function sin(deg) {
    return Math.sin((deg / 180) * PI());
  }

  this.sin = function(deg) {
    this.value = sin(deg);
  }

  /**
  * nj.tan
  * Tangent
  */
  function tan(deg) {
    return Math.tan((deg / 180) * PI());
  }

  this.tan = function(deg) {
    this.value = tan(deg);
  }

  /**
  * nj.acos
  * Arcosine
  */
  function acos(deg) {
    return Math.acos((deg / 180) * PI());
  }

  this.acos = function(deg) {
    this.value = acos(deg);
  }

  /**
  * nj.asin
  * Arcine
  */
  function asin(deg) {
    return Math.asin((deg / 180) * PI());
  }

  this.asin = function(deg) {
    this.value = asin(deg);
  }

  /**
  * nj.atan
  * Arctangent
  */
  function atan(deg) {
    return Math.atan((deg / 180) * PI());
  }

  this.atan = function(deg) {
    this.value = atan(deg);
  }

  /**
  * nj.cosh
  * Hyperbolic Cosine
  */
  function cosh(deg) {
    return Math.cosh((deg / 180) * PI());
  }

  this.cosh = function(deg) {
    this.value = cosh(deg);
  }

  /**
  * nj.sinh
  * Hyperbolic Sine
  */
  function sinh(deg) {
    return Math.sinh((deg / 180) * PI());
  }

  this.sinh = function(deg) {
    this.value = sinh(deg);
  }

  /**
  * nj.tanh
  * Hyperbolic Tangent
  */
  function tanh(deg) {
    return Math.ttanhan((deg / 180) * PI());
  }

  this.tanh = function(deg) {
    this.value = tanh(deg);
  }

  /**
  * nj.sum
  * Summation
  */
  function sum() {
    var s = 0;

    for(var i = 0; i < arguments.length; i++) {
      s += arguments[i];
    }

    return s;
  }

  this.sum = function() {
    var s = 0;

    for(var i = 0; i < arguments.length; i++) {
      s += arguments[i];
    }

    this.matrix = s;
  }

  /**
  * nj.array
  * Return a new array of given shape and type, filled with zeros.
  */
  this.array = function(m) {
    this.insert = function() {
      var value = arguments[arguments.length - 1];

      // for (var i = 0; i < arguments.length - 1; i++) {
      //   alert(arguments[i]);
      // }

      this.matrix[arguments[0]][arguments[1]] = value;
    }

    this.matrix = m;
    this.shape = "(" + dim(this.matrix) + ")";
    this.type = "njarray";
  }

  /**
  * nj.zeros
  * Return a new array of given shape and type, filled with zeros.
  */
  function zeros(d) {
    var m = [];

    for (var i = 0; i < d[0]; ++i) {
      m.push(d.length == 1 ? 0 : zeros(d.slice(1)));
    }

    return m;
  }

  this.zeros = function(d) {
    this.matrix = zeros(d);
    this.shape = "(" + dim(this.matrix) + ")";
    this.type = "njarray";
  }

  /**
  * nj.ones
  * Return a new array of given shape and type, filled with ones.
  */
  function ones(d) {
    var m = [];

    for (var i = 0; i < d[0]; ++i) {
      m.push(d.length == 1 ? 1 : ones(d.slice(1)));
    }

    return m;
  }

  this.ones = function(d) {
    this.matrix = ones(d);
    this.shape = "(" + dim(this.matrix) + ")";
    this.type = "njarray";
  }

  /**
  * nj.eye
  * Return a 2-D array with ones on the diagonal and zeros elsewhere.
  */
  function set_eye(d) {
    return Array.apply(null, new Array(d)).map(function(x, i, a) { return a.map(function(y, k) { return i === k ? 1 : 0; }) });
  }

  this.eye = function(d) {
    this.matrix = set_eye(d);
    this.shape = "(" + dim(this.matrix) + ")";
    this.type = "njarray";
  }

  /**
  * nj.inner
  * Return dot product of two matrices
  */
  function inner(v1, v2) {
    if (dim(v1)[0] != dim(v2)[0]) {
      throw "Error: Arrays have different lengths";
    }

    var p = 0;
    for (var i = 0; i < dim(v1)[0]; i++) {
      p += v1[i] * v2[i];
    }

    return p;
  }

  this.inner = function(v1, v2) {
    this.matrix = inner(v1, v2)
  }

  /**
  * nj.dot
  * Return dot product of two matrices
  */
  function dot(m1, m2) {
    if(dim(m1)[0] == dim(m2)[0]) {
      return inner(m1, m2);
    } else if (dim(m1)[1] != dim(m2)[0]) {
      throw "Error: Incompatible size";
    }

    var p = zeros([dim(m1)[0], dim(m2)[1]]);

    for (var i = 0; i < dim(m1)[0]; i++) {
      p[i] = [];

      for (var j = 0; j < dim(m2)[1]; j++) {
        var sum = 0;

        for (var k = 0; k < dim(m1)[1]; k++) {
          sum += m1[i][k] * m2[k][j];
        }

        p[i][j] = sum;
      }
    }

    return p;
  }

  this.dot = function(m1, m2) {
    this.matrix = dot(m1, m2)
  }
}

var nj = new nj();
<commit_msg>Add Logic Gates<commit_after>var nj = function(x) {

  function dim(m) {
    var d = [];
    for (;;) {
      d.push(m.length);

      if (Array.isArray(m[0])) {
        m = m[0];
      } else {
        break;
      }
    }

    return d;
  }

  /****************/
  /**    Math    **/
  /****************/

  /**
  * nj.add
  * Addition
  */
  function add(x, y) {
    return x + y;
  }

  this.add = function(x, y) {
    this.value = add(x, y);
  }

  /**
  * nj.sub
  * Subtraction
  */
  function sub(x, y) {
    return x - y;
  }

  this.sub = function(x, y) {
    this.value = sub(x, y);
  }

  /**
  * nj.mul
  * Multiplication
  */
  function mul(x, y) {
    return x * y;
  }

  this.mul = function(x, y) {
    this.value = mul(x, y);
  }

  /**
  * nj.div
  * Division
  */
  function div(x, y) {
    return x / y;
  }

  this.div = function(x, y) {
    this.value = div(x, y);
  }

  /**
  * nj.abs
  * Return the absolute value of x
  */
  function abs(x) {
    return Math.abs(x);
  }

  this.abs = function(x) {
    this.value = abs(x);
  }

  /**
  * nj.ceil
  * Returns x, rounded upwards to the nearest integer
  */
  function ceil(x) {
    return Math.ceil(x);
  }

  this.ceil = function(x) {
    this.value = ceil(x);
  }

  /**
  * nj.floor
  * Returns x, rounded downwards to the nearest integer
  */
  function floor(x) {
    return Math.floor(x);
  }

  this.floor = function(x) {
    this.value = floor(x);
  }

  /**
  * nj.exp
  * Returns the value of E^x
  */
  function exp(x) {
    return Math.exp(x);
  }

  this.exp = function(x) {
    this.value = exp(x);
  }

  /**
  * nj.log
  * Returns the natural logarithm (base E) of x
  */
  function log(x) {
    return Math.log(x);
  }

  this.log = function(x) {
    this.value = log(x);
  }

  /**
  * nj.pow
  * Returns the value of x to the power of y
  */
  function pow(x, y) {
    return Math.pow(x, y);
  }

  this.pow = function(x, y) {
    this.value = pow(x, y);
  }

  /**
  * nj.round
  * Rounds x to the nearest integer
  */
  function round(x) {
    return Math.round(x);
  }

  this.round = function(x) {
    this.value = round(x);
  }

  /**
  * nj.sqrt
  * Rounds x to the nearest integer
  */
  function sqrt(x) {
    return Math.sqrt(x);
  }

  this.sqrt = function(x) {
    this.value = sqrt(x);
  }

  /**
  * nj.random
  * Returns a random number between x and y
  */
  function random(x, y) {
    return Math.random() * (y - x) + x;
  }

  this.random = function(x, y) {
    this.value = random(x, y);
  }

  /**
  * nj.max
  * Returns the number with the highest value
  */
  function max() {
    return Math.max(arguments);
  }

  this.max = function() {
    var max = arguments[0];

    for(var i = 1; i < arguments.length; i++) {
      if(max <= arguments[i]) {
        max = arguments[i];
      }
    }

    this.value = max;
  }

  /**
  * nj.min
  * Returns the number with the lowest value
  */
  function min() {
    return Math.min(arguments);
  }

  this.min = function() {
    var min = arguments[0];

    for(var i = 1; i < arguments.length; i++) {
      if(min >= arguments[i]) {
        min = arguments[i];
      }
    }

    this.value = min;
  }

  /**
  * nj.PI
  * PI
  */
  function PI() {
    return Math.PI;
  }

  this.PI = function() {
    this.value = Math.PI;
  }

  /**
  * nj.cos
  * Cosine
  */
  function cos(deg) {
    return Math.cos((deg / 180) * PI());
  }

  this.cos = function(deg) {
    this.value = cos(deg);
  }

  /**
  * nj.sin
  * Sine
  */
  function sin(deg) {
    return Math.sin((deg / 180) * PI());
  }

  this.sin = function(deg) {
    this.value = sin(deg);
  }

  /**
  * nj.tan
  * Tangent
  */
  function tan(deg) {
    return Math.tan((deg / 180) * PI());
  }

  this.tan = function(deg) {
    this.value = tan(deg);
  }

  /**
  * nj.acos
  * Arcosine
  */
  function acos(deg) {
    return Math.acos((deg / 180) * PI());
  }

  this.acos = function(deg) {
    this.value = acos(deg);
  }

  /**
  * nj.asin
  * Arcine
  */
  function asin(deg) {
    return Math.asin((deg / 180) * PI());
  }

  this.asin = function(deg) {
    this.value = asin(deg);
  }

  /**
  * nj.atan
  * Arctangent
  */
  function atan(deg) {
    return Math.atan((deg / 180) * PI());
  }

  this.atan = function(deg) {
    this.value = atan(deg);
  }

  /**
  * nj.cosh
  * Hyperbolic Cosine
  */
  function cosh(deg) {
    return Math.cosh((deg / 180) * PI());
  }

  this.cosh = function(deg) {
    this.value = cosh(deg);
  }

  /**
  * nj.sinh
  * Hyperbolic Sine
  */
  function sinh(deg) {
    return Math.sinh((deg / 180) * PI());
  }

  this.sinh = function(deg) {
    this.value = sinh(deg);
  }

  /**
  * nj.tanh
  * Hyperbolic Tangent
  */
  function tanh(deg) {
    return Math.ttanhan((deg / 180) * PI());
  }

  this.tanh = function(deg) {
    this.value = tanh(deg);
  }

  /**
  * nj.sum
  * Summation
  */
  function sum() {
    var s = 0;

    for(var i = 0; i < arguments.length; i++) {
      s += arguments[i];
    }

    return s;
  }

  this.sum = function() {
    var s = 0;

    for(var i = 0; i < arguments.length; i++) {
      s += arguments[i];
    }

    this.matrix = s;
  }

  /*****************/
  /** Logic Gates **/
  /*****************/

  /**
  * nj.not
  * NOT Gate
  */
  function not(x) {
    return !Boolean(x);
  }

  this.not = function(x) {
    this.value = not(x);
  }

  /**
  * nj.and
  * AND Gate
  */
  function and(x, y) {
    if(Boolean(x) == 0 || Boolean(y) == 0) {
      return false;
    } else {
      return true;
    }
  }

  this.and = function(x, y) {
    this.value = and(x, y);
  }

  /**
  * nj.or
  * OR Gate
  */
  function or(x, y) {
    if(Boolean(x) == 1 || Boolean(y) == 1) {
      return true;
    } else {
      return false;
    }
  }

  this.or = function(x, y) {
    this.value = or(x, y);
  }

  /**
  * nj.nand
  * NAND Gate
  */
  function nand(x, y) {
    return not(and(x, y));
  }

  this.nand = function(x, y) {
    this.value = nand(x, y);
  }

  /**
  * nj.nor
  * NOR Gate
  */
  function nor(x, y) {
    return not(or(x, y));
  }

  this.nor = function(x, y) {
    this.value = nor(x, y);
  }

  /**
  * nj.xor
  * XOR Gate
  */
  function xor(x, y) {
    if(Boolean(x) != Boolean(y)) {
      return true;
    } else {
      return false;
    }
  }

  this.xor = function(x, y) {
    this.value = xor(x, y);
  }

  /**
  * nj.xnor
  * XNOR Gate
  */
  function xnor(x, y) {
    return not(xor(x, y));
  }

  this.xnor = function(x, y) {
    this.value = xnor(x, y);
  }

  /********************/
  /** Linear Algebra **/
  /********************/

  /**
  * nj.array
  * Return a new array of given shape and type, filled with zeros.
  */
  this.array = function(m) {
    this.insert = function() {
      var value = arguments[arguments.length - 1];

      // for (var i = 0; i < arguments.length - 1; i++) {
      //   alert(arguments[i]);
      // }

      this.matrix[arguments[0]][arguments[1]] = value;
    }

    this.matrix = m;
    this.shape = "(" + dim(this.matrix) + ")";
    this.type = "njarray";
  }

  /**
  * nj.zeros
  * Return a new array of given shape and type, filled with zeros.
  */
  function zeros(d) {
    var m = [];

    for (var i = 0; i < d[0]; ++i) {
      m.push(d.length == 1 ? 0 : zeros(d.slice(1)));
    }

    return m;
  }

  this.zeros = function(d) {
    this.matrix = zeros(d);
    this.shape = "(" + dim(this.matrix) + ")";
    this.type = "njarray";
  }

  /**
  * nj.ones
  * Return a new array of given shape and type, filled with ones.
  */
  function ones(d) {
    var m = [];

    for (var i = 0; i < d[0]; ++i) {
      m.push(d.length == 1 ? 1 : ones(d.slice(1)));
    }

    return m;
  }

  this.ones = function(d) {
    this.matrix = ones(d);
    this.shape = "(" + dim(this.matrix) + ")";
    this.type = "njarray";
  }

  /**
  * nj.eye
  * Return a 2-D array with ones on the diagonal and zeros elsewhere.
  */
  function set_eye(d) {
    return Array.apply(null, new Array(d)).map(function(x, i, a) { return a.map(function(y, k) { return i === k ? 1 : 0; }) });
  }

  this.eye = function(d) {
    this.matrix = set_eye(d);
    this.shape = "(" + dim(this.matrix) + ")";
    this.type = "njarray";
  }

  /**
  * nj.inner
  * Return dot product of two matrices
  */
  function inner(v1, v2) {
    if (dim(v1)[0] != dim(v2)[0]) {
      throw "Error: Arrays have different lengths";
    }

    var p = 0;
    for (var i = 0; i < dim(v1)[0]; i++) {
      p += v1[i] * v2[i];
    }

    return p;
  }

  this.inner = function(v1, v2) {
    this.matrix = inner(v1, v2)
  }

  /**
  * nj.dot
  * Return dot product of two matrices
  */
  function dot(m1, m2) {
    if(dim(m1)[0] == dim(m2)[0]) {
      return inner(m1, m2);
    } else if (dim(m1)[1] != dim(m2)[0]) {
      throw "Error: Incompatible size";
    }

    var p = zeros([dim(m1)[0], dim(m2)[1]]);

    for (var i = 0; i < dim(m1)[0]; i++) {
      p[i] = [];

      for (var j = 0; j < dim(m2)[1]; j++) {
        var sum = 0;

        for (var k = 0; k < dim(m1)[1]; k++) {
          sum += m1[i][k] * m2[k][j];
        }

        p[i][j] = sum;
      }
    }

    return p;
  }

  this.dot = function(m1, m2) {
    this.matrix = dot(m1, m2)
  }
}

var nj = new nj();
<|endoftext|>


<commit_before>angular.module(PKG.name + '.feature.flows')
  .config(function($stateProvider, $urlRouterProvider, MYAUTH_ROLE) {
    $stateProvider
      .state('flows', {
        url: '/flows',
        abstract: true,
        parent: 'programs',
        data: {
          authorizedRoles: MYAUTH_ROLE.all,
          highlightTab: 'development'
        },
        template: '<ui-view/>'
      })

      .state('flows.detail', {
        url: '/:programId',
        data: {
          authorizedRoles: MYAUTH_ROLE.all,
          highlightTab: 'development'
        },
        ncyBreadcrumb: {
          parent: 'apps.detail.overview',
          label: 'Flows',
          skip: true
        },
        templateUrl: '/assets/features/flows/templates/detail.html',
        controller: 'FlowsDetailController'
      })

      .state('flows.detail.status', {
        url: '/status',
        data: {
          authorizedRoles: MYAUTH_ROLE.all,
          highlightTab: 'development'
        },
        ncyBreadcrumb: {
          label: '{{$state.params.programId}}'
        },
        templateUrl: '/assets/features/flows/templates/tabs/status.html',
        controller: 'FlowsDetailController'
      })

      .state('flows.detail.runs', {
        url: '/runs',
        templateUrl: '/assets/features/flows/templates/tabs/runs.html',
        controller: 'FlowsRunsController'
      })
        .state('flows.detail.runs.run', {
          url: '/:runid',
          templateUrl: '/assets/features/flows/templates/tabs/runs/run-detail.html',
          controller: 'FlowsRunDetailController'
        })

      .state('flows.detail.history', {
        url: '/history',
        data: {
          authorizedRoles: MYAUTH_ROLE.all,
          highlightTab: 'development'
        },
        templateUrl: '/assets/features/flows/templates/tabs/history.html',
        controller: 'FlowsRunsController'
      })
  });
<commit_msg>Fixes breadcrumbs for runid views of flow feature:<commit_after>angular.module(PKG.name + '.feature.flows')
  .config(function($stateProvider, $urlRouterProvider, MYAUTH_ROLE) {
    $stateProvider
      .state('flows', {
        url: '/flows',
        abstract: true,
        parent: 'programs',
        data: {
          authorizedRoles: MYAUTH_ROLE.all,
          highlightTab: 'development'
        },
        template: '<ui-view/>'
      })

      .state('flows.detail', {
        url: '/:programId',
        data: {
          authorizedRoles: MYAUTH_ROLE.all,
          highlightTab: 'development'
        },
        ncyBreadcrumb: {
          parent: 'apps.detail.overview',
          label: 'Flows',
          skip: true
        },
        templateUrl: '/assets/features/flows/templates/detail.html',
        controller: 'FlowsDetailController'
      })

      .state('flows.detail.status', {
        url: '/status',
        data: {
          authorizedRoles: MYAUTH_ROLE.all,
          highlightTab: 'development'
        },
        ncyBreadcrumb: {
          label: '{{$state.params.programId}}'
        },
        templateUrl: '/assets/features/flows/templates/tabs/status.html',
        controller: 'FlowsDetailController'
      })

      .state('flows.detail.runs', {
        url: '/runs',
        templateUrl: '/assets/features/flows/templates/tabs/runs.html',
        controller: 'FlowsRunsController',
        ncyBreadcrumb: {
          label: 'Runs'
        }
      })
        .state('flows.detail.runs.run', {
          url: '/:runid',
          templateUrl: '/assets/features/flows/templates/tabs/runs/run-detail.html',
          controller: 'FlowsRunDetailController',
          ncyBreadcrumb: {
            label: '{{$state.params.runid}}'
          }
        })

      .state('flows.detail.history', {
        url: '/history',
        data: {
          authorizedRoles: MYAUTH_ROLE.all,
          highlightTab: 'development'
        },
        templateUrl: '/assets/features/flows/templates/tabs/history.html',
        controller: 'FlowsRunsController'
      })
  });
<|endoftext|>


<commit_before>var d = require('./date_helpers.js')
var date = d.today(process.env.NODE_ENV)
var set_current = d.set_current(process.env.NODE_ENV)

const columns = `first_name, last_name, title, address1, address2,
  address3, address4, county, postcode, primary_email, secondary_email`

exports.subsQueryTemplate = news_type => (
  `select ${columns},
  datediff(${date}, max(payments.date)) as overdue,
  members.standing_order, members.due_date, members.id,
  sum(case payments.category
    when 'payment' then -payments.amount
    else                 payments.amount
    end) as amount
    from members right outer join payments
    on members.id = payments.member
    where members.primary_email is${news_type === 'online' ? ' not' : ''} null
    and members.membership_type in
    ('annual-single', 'annual-double', 'annual-family')
    and activation_status='activated'
    group by members.id
    having sum(case payments.category
      when 'payment' then -payments.amount
      else                 payments.amount
      end) > 0
      and datediff(${date}, max(payments.date)) > 30;`
)

exports.newsletterQueryTemplate = news_type => (
  `select ${columns}
  from members
  where news_type = '${news_type}'
  and activation_status='activated';`
)

exports.update_subscription = body =>
  `insert into payments (member, category, description, amount, date, createdAt)
  select id, 'subscription', 'Subscription', amount, ${set_current('due_date')}, now()
  from members, membershiptypes
  where members.membership_type = membershiptypes.value
  and members.membership_type in
  ('annual-single', 'annual-double', 'annual-family', 'annual-corporate', 'annual-group')
  and members.primary_email is${body.news_type === 'online' ? ' not' : ''} null
  and
    date_sub(${date}, interval 1 year)
    > (select max(date) from payments
      where members.id = payments.member
      and payments.category = 'subscription'
    )
  and ${d.due_dates(body.start)(body.end)('members.due_date')}
  and activation_status='activated';`

exports.subscription_due_template = body =>
  `select ${columns}, id, due_date, membership_type, amount
  from members, membershiptypes
  where members.membership_type = membershiptypes.value
  and (standing_order is null or standing_order=false)
  and members.membership_type in
  ('annual-single', 'annual-double', 'annual-family', 'annual-corporate', 'annual-group')
  and members.primary_email is${body.news_type === 'online' ? ' not' : ''} null
  and
    date_sub(${date}, interval 1 year)
    > (select max(date) from payments
      where members.id = payments.member
      and payments.category = 'subscription'
    )
  and ${d.due_dates(body.start)(body.end)('members.due_date')}
  and activation_status='activated';`

exports.custom_email = () =>
  `select first_name, last_name, title, primary_email, secondary_email
  from members
  where primary_email is not null
  and activation_status='activated';`

exports.newsletter_labels = () =>
  `select title, first_name, last_name, initials,
  address1, address2, address3, address4,
  postcode, deliverer from members
  where members.news_type = 'post'
  or members.email_bounced = true
  and activation_status='activated';`
<commit_msg>Change labels queries to filter out deactivated users.<commit_after>var d = require('./date_helpers.js')
var date = d.today(process.env.NODE_ENV)
var set_current = d.set_current(process.env.NODE_ENV)

const columns = `first_name, last_name, title, address1, address2,
  address3, address4, county, postcode, primary_email, secondary_email`

exports.subsQueryTemplate = news_type => (
  `select ${columns},
  datediff(${date}, max(payments.date)) as overdue,
  members.standing_order, members.due_date, members.id,
  sum(case payments.category
    when 'payment' then -payments.amount
    else                 payments.amount
    end) as amount
    from members right outer join payments
    on members.id = payments.member
    where members.primary_email is${news_type === 'online' ? ' not' : ''} null
    and members.membership_type in
    ('annual-single', 'annual-double', 'annual-family')
    and activation_status='activated'
    group by members.id
    having sum(case payments.category
      when 'payment' then -payments.amount
      else                 payments.amount
      end) > 0
      and datediff(${date}, max(payments.date)) > 30;`
)

exports.newsletterQueryTemplate = news_type => (
  `select ${columns}
  from members
  where news_type = '${news_type}'
  and activation_status='activated';`
)

exports.update_subscription = body =>
  `insert into payments (member, category, description, amount, date, createdAt)
  select id, 'subscription', 'Subscription', amount, ${set_current('due_date')}, now()
  from members, membershiptypes
  where members.membership_type = membershiptypes.value
  and members.membership_type in
  ('annual-single', 'annual-double', 'annual-family', 'annual-corporate', 'annual-group')
  and members.primary_email is${body.news_type === 'online' ? ' not' : ''} null
  and
    date_sub(${date}, interval 1 year)
    > (select max(date) from payments
      where members.id = payments.member
      and payments.category = 'subscription'
    )
  and ${d.due_dates(body.start)(body.end)('members.due_date')}
  and activation_status='activated';`

exports.subscription_due_template = body =>
  `select ${columns}, id, due_date, membership_type, amount
  from members, membershiptypes
  where members.membership_type = membershiptypes.value
  and (standing_order is null or standing_order=false)
  and members.membership_type in
  ('annual-single', 'annual-double', 'annual-family', 'annual-corporate', 'annual-group')
  and members.primary_email is${body.news_type === 'online' ? ' not' : ''} null
  and
    date_sub(${date}, interval 1 year)
    > (select max(date) from payments
      where members.id = payments.member
      and payments.category = 'subscription'
    )
  and ${d.due_dates(body.start)(body.end)('members.due_date')}
  and activation_status='activated';`

exports.custom_email = () =>
  `select first_name, last_name, title, primary_email, secondary_email
  from members
  where primary_email is not null
  and activation_status='activated';`

exports.newsletter_labels = () =>
  `select title, first_name, last_name, initials,
  address1, address2, address3, address4,
  postcode, deliverer from members
  where members.news_type = 'post'
  and activation_status='activated'
  or members.email_bounced = true;`
<|endoftext|>


<commit_before>
import Ember from "ember";

export default Ember.Component.extend({

  tagName: 'div',
  classNames: ['ui', 'selection', 'dropdown', 'fluid'],
  classNameBindings: ['multiple', 'search'],

  content: null,
  optionValuePath: null,
  optionLabelPath: null,
  allowAdditions: null,

  bindAttributes: ['optionValuePath', 'optionLabelPath', 'content', 'allowAdditions'],

  actions: {},

  options: function () {
    var optionLabelPath = this.get('optionLabelPath');
    var optionValuePath = this.get('optionValuePath');
    var selectContent = this.get('content');

    return selectContent ? selectContent.map(function (item, index, list) {
      return {
        value: optionValuePath ? item.get(optionValuePath) : item,
        label: optionLabelPath ? item.get(optionLabelPath) : item
      };
    }, this) : [];

  }.property('content.@each'),

  setup: function () {
    this.$().dropdown({
      allowAdditions: this.allowAdditions,
      onChange: Ember.run.bind(this, this.onChange)
    }).dropdown('set selected', this.get('value'));
  }.on('didInsertElement'),

  onChange: function (value, text, $choice) {
    if (this.optionValuePath) {
      value = this.get('content').findBy(this.optionValuePath, value);
    }

    if (this.get('multiple')) {
      this.set('value', value ? Ember.A(value.split(',')) : undefined);

    } else {
      this.set('value', value);
    }

  }

});
<commit_msg>Bind attr value<commit_after>
import Ember from "ember";

export default Ember.Component.extend({

  tagName: 'div',
  classNames: ['ui', 'selection', 'dropdown', 'fluid'],
  classNameBindings: ['multiple', 'search'],

  content: null,
  value: null,
  optionValuePath: null,
  optionLabelPath: null,
  allowAdditions: null,

  bindAttributes: ['optionValuePath', 'optionLabelPath', 'value', 'content', 'allowAdditions'],

  actions: {},

  options: function () {
    var optionLabelPath = this.get('optionLabelPath');
    var optionValuePath = this.get('optionValuePath');
    var selectContent = this.get('content');

    return selectContent ? selectContent.map(function (item, index, list) {
      return {
        value: optionValuePath ? item.get(optionValuePath) : item,
        label: optionLabelPath ? item.get(optionLabelPath) : item
      };
    }, this) : [];

  }.property('content.@each'),

  setup: function () {
    this.$().dropdown({
      allowAdditions: this.allowAdditions,
      onChange: Ember.run.bind(this, this.onChange)
    }).dropdown('set selected', this.get('value'));
  }.on('didInsertElement'),

  onChange: function (value, text, $choice) {
    if (this.optionValuePath) {
      value = this.get('content').findBy(this.optionValuePath, value);
    }

    if (this.get('multiple')) {
      this.set('value', value ? Ember.A(value.split(',')) : undefined);

    } else {
      this.set('value', value);
    }

  }

});
<|endoftext|>


<commit_before>
import Ember from "ember";

export default Ember.Component.extend({

  tagName: 'div',
  classNames: ['ui', 'selection', 'dropdown', 'fluid'],
  classNameBindings: ['multiple', 'search'],

  content: null,
  value: null,
  optionValuePath: null,
  optionLabelPath: null,
  allowAdditions: null,

  bindAttributes: ['optionValuePath', 'optionLabelPath', 'value', 'content', 'allowAdditions'],

  actions: {},

  options: function () {
    var optionLabelPath = this.get('optionLabelPath');
    var optionValuePath = this.get('optionValuePath');
    var selectContent = this.get('content');

    return selectContent ? selectContent.map(function (item, index, list) {
      return {
        value: optionValuePath ? item.get(optionValuePath) : item,
        label: optionLabelPath ? item.get(optionLabelPath) : item
      };
    }, this) : [];

  }.property('content.@each'),

  setup: function () {
    this.$().dropdown({
      allowAdditions: this.allowAdditions,
      onChange: Ember.run.bind(this, this.onChange)
    }).dropdown('set selected', this.get('value'));
  }.on('didInsertElement'),

  onChange: function (value, text, $choice) {
    if (this.optionValuePath) {
      value = this.get('content').findBy(this.optionValuePath, value);
    }

    if (this.get('multiple')) {
     value = value ? Ember.A(value.split(',')) : undefined;
    }

    this.set('value', value);

  }

});
<commit_msg>Use set exactly to replace value instead of adding and update if value is changed other places than in component (async)<commit_after>
import Ember from "ember";

export default Ember.Component.extend({

  tagName: 'div',
  classNames: ['ui', 'selection', 'dropdown', 'fluid'],
  classNameBindings: ['multiple', 'search'],

  content: null,
  value: null,
  optionValuePath: null,
  optionLabelPath: null,
  allowAdditions: null,

  bindAttributes: ['optionValuePath', 'optionLabelPath', 'value', 'content', 'allowAdditions'],

  actions: {},

  options: function () {
    var optionLabelPath = this.get('optionLabelPath');
    var optionValuePath = this.get('optionValuePath');
    var selectContent = this.get('content');

    return selectContent ? selectContent.map(function (item, index, list) {
      return {
        value: optionValuePath ? item.get(optionValuePath) : item,
        label: optionLabelPath ? item.get(optionLabelPath) : item
      };
    }, this) : [];

  }.property('content.@each'),

  setup: function () {
    this.$().dropdown({
      allowAdditions: this.allowAdditions,
      onChange: Ember.run.bind(this, this.onChange)
    }).dropdown('set exactly', this.value);

  }.on('didInsertElement'),

  onValueChange: function () {
    if (typeof this.value === 'undefined') {
      return;
    }

    this.$().dropdown('set exactly', Ember.A(this.value.map(function (item, index, list) {
      return item.replace(',', '');
    })));

  }.observes('value'),

  onChange: function (value, text, $choice) {

    // NOTE: This will have to be improved, can not assume ignoring value === undefined is okay
    if ((this.value && this.value.toString() === value) || (this.value === undefined)) {
      return;
    }

    if (this.optionValuePath) {
      value = this.get('content').findBy(this.optionValuePath, value);
    }

    if (this.get('multiple')) {
     value = value ? Ember.A(value.split(',')) : undefined;
    }

    this.set('value', value);

  }

});
<|endoftext|>


<commit_before>'use strict';

/* jshint -W067 */
export
  const curry = (fn, aux) => (
    aux = args => args.length < fn.length ? (...newArgs) => aux(args.concat(newArgs))
                                          : fn(...args)
  )([]);
/* jshint +W067 */

export
  const head = y => y[0];

export
  const last = arr => arr.slice(-1)[0];

export
  const init = arr => arr.slice(0, -1);

export
  const tail = arr => arr.slice(1);

export
  const reduce = curry((op, a, [x, ...y]) => x !== undefined ? reduce(op, op(a, x), y) : a);

export
  const reduceRight = curry((op, a, y) => last(y) !== undefined ? reduceRight(op, op(last(y), a), init(y)) : a);

export
  const map = curry((op, y) => reduce((a, x) => [...a, op(x)], [], y));

export
  const filter = curry((op, y) => reduce((a, x) => {return op(x) ? [...a, x] : a}, [], y));

export
  const reverse = (y) => reduce((a, x)=> [x,...a], [] ,y);

export
  const sequence = (...ops) => (a) => reduce((a, op) => op(a), a, ops);

export
  const compose = (...ops) => sequence(...reverse(ops));

export
  const all = curry(
                (fn, [x,...y]) => x === undefined ? true :
                                  fn(x)           ? all(fn, y)
                                                  : false
              );

export
  const any = curry(
                (fn, [x,...y]) => x === undefined ? false :
                                  fn(x)           ? true
                                                  : any(fn, y)
              );

export
  const none = curry(
                (fn, [x,...y]) => x === undefined ? true :
                                  fn(x)           ? false
                                                  : none(fn, y)
              );

/* jshint -W067 */
export
  const zip = curry((y1, y2) => (
     ((aux) =>
        (aux = ([x1,...y1], [x2,...y2], acc) =>
          x1 === undefined || x2 === undefined ? acc
                                               : aux(y1, y2, acc.concat([[x1, x2]]))
        )(y1, y2, [])
      )()
  ));
/* jshint +W067 */
<commit_msg>refactor(curry): simplify reading avoiding arr.concat<commit_after>'use strict';

/* jshint -W067 */
export
  const curry = (fn, aux) => (
    aux = args => args.length < fn.length ? (...more) => aux([...args, ...more])
                                          : fn(...args)
  )([]);
/* jshint +W067 */

export
  const head = y => y[0];

export
  const last = arr => arr.slice(-1)[0];

export
  const init = arr => arr.slice(0, -1);

export
  const tail = arr => arr.slice(1);

export
  const reduce = curry((op, a, [x, ...y]) => x !== undefined ? reduce(op, op(a, x), y) : a);

export
  const reduceRight = curry((op, a, y) => last(y) !== undefined ? reduceRight(op, op(last(y), a), init(y)) : a);

export
  const map = curry((op, y) => reduce((a, x) => [...a, op(x)], [], y));

export
  const filter = curry((op, y) => reduce((a, x) => {return op(x) ? [...a, x] : a}, [], y));

export
  const reverse = (y) => reduce((a, x)=> [x,...a], [] ,y);

export
  const sequence = (...ops) => (a) => reduce((a, op) => op(a), a, ops);

export
  const compose = (...ops) => sequence(...reverse(ops));

export
  const all = curry(
                (fn, [x,...y]) => x === undefined ? true :
                                  fn(x)           ? all(fn, y)
                                                  : false
              );

export
  const any = curry(
                (fn, [x,...y]) => x === undefined ? false :
                                  fn(x)           ? true
                                                  : any(fn, y)
              );

export
  const none = curry(
                (fn, [x,...y]) => x === undefined ? true :
                                  fn(x)           ? false
                                                  : none(fn, y)
              );

/* jshint -W067 */
export
  const zip = curry((y1, y2) => (
     ((aux) =>
        (aux = ([x1,...y1], [x2,...y2], acc) =>
          x1 === undefined || x2 === undefined ? acc
                                               : aux(y1, y2, acc.concat([[x1, x2]]))
        )(y1, y2, [])
      )()
  ));
/* jshint +W067 */
<|endoftext|>


<commit_before>'use strict';

var through = require('through2');
var fs = require('fs-extra');
var Gemini = require('gemini/api');
var spawn = require('child_process').spawn;
var path = require('path');
var gutil = require('gulp-util');

var phantomProcess;
var runPhantom = function() {
    phantomProcess = spawn('phantomjs',  ['--webdriver', '4444', '--disk-cache', 'true'],  {setsid:true});
    phantomProcess.stdout.pipe(process.stdout);
};

function getGenimi = function(options) {
    var gemini = new Gemini({
        rootUrl: options.rootUrl,
        projectRoot: './',
        gridUrl: 'http://127.0.0.1:4444/wd/hub',
        screenshotsDir: options.gridScreenshotsDir,
        browsers: {
          chrome: {
            browserName: 'chrome',
            version: '37.0'
          }
        },
        windowSize: '1024x768'
}

module.exports.test = function(options) {

  // Gemini does not configurate report dir
  options.reportDir = 'gemini-report';

  var test = function(file, enc, callback) {

    var gemini = getGemini(options);

    // Run PhantomJs
    runPhantom();

    // Clean report
    fs.removeSync(options.reportDir);

    // Run tests and create reports
    var runTests = function() {
      var runTestsPromise = gemini.test([path.resolve(options.configDir, './basic-test.js')], {
        reporters: ['html', 'flat'],
        tempDir: options.reportDir
      });
      runTestsPromise.done(result => {
        phantomProcess.kill('SIGTERM');
        spawn('open', [`${options.reportDir}/index.html`])
      });
    };
    // TODO: remake with promises
    setTimeout(runTests, 2000);

  }

  return through.obj(test);

}

module.exports.gather = function(options) {

  var gather = function(file, enc, callback) {

    var gemini = getGemini(options);

    // Run PhantomJs
    runPhantom();

    // Clean screenshot
    fs.removeSync(options.gridScreenshotsDir);

    var runGather = function() {
      gemini.gather([path.resolve(options.configDir, './basic-test.js')], {
        reporters: ['flat'],
      })
      .done(result => {
        phantomProcess.kill('SIGTERM');
      });
    }
    // TODO: remake with promises
    setTimeout(runGather, 2000);

  };

  return through.obj(gather);

};

module.exports.configure = function(options) {

  var configure = function(file, enc, callback) {
    var getPages = function(path) {
      var styleguideData = JSON.parse(fs.readFileSync(`${path}/styleguide.json`));
      var examples = [];
      styleguideData.sections.forEach(section => {
        if (!section.markup) { // For sections with markup only
          return;
        }
        if (section.modifiers.length === 0) {
          // Only for the pages with markup
          // Exclude pages
          if (options.excludePages.indexOf(section.reference) !== -1) {
            return;
          }
          examples.push(section.reference);
        } else {
          for(var m = 1;m<=section.modifiers.length;m++) {
            // Exclude pages
            if (options.excludePages.indexOf(`${section.reference}-${m}`) !== -1) {
              continue;
            }
            examples.push(`${section.reference}-${m}`);
          }
        }
      });
      return examples;
    };

    var styleguidePath = file.path;

    var pages = getPages(styleguidePath);

    // list of pages
    var file = new gutil.File({
      base: path.join(__dirname),
      cwd: __dirname,
      path: path.join(__dirname, './pages-list.js'),
      contents: new Buffer(`module.exports = ${JSON.stringify(pages, null, 4)}`)
    });
    this.push(file);

    // basic test
    var file = new gutil.File({
      base: path.join(__dirname),
      cwd: __dirname,
      path: path.join(__dirname, './basic-test.js'),
      contents: new Buffer(fs.readFileSync(path.join(__dirname, './basic-test.js')))
    });
    this.push(file);

    callback();
  };

  return through.obj(configure);

};
<commit_msg>Js Error<commit_after>'use strict';

var through = require('through2');
var fs = require('fs-extra');
var Gemini = require('gemini/api');
var spawn = require('child_process').spawn;
var path = require('path');
var gutil = require('gulp-util');

var phantomProcess;
var runPhantom = function() {
    phantomProcess = spawn('phantomjs',  ['--webdriver', '4444', '--disk-cache', 'true'],  {setsid:true});
    phantomProcess.stdout.pipe(process.stdout);
};

var getGenimi = function(options) {
    var gemini = new Gemini({
        rootUrl: options.rootUrl,
        projectRoot: './',
        gridUrl: 'http://127.0.0.1:4444/wd/hub',
        screenshotsDir: options.gridScreenshotsDir,
        browsers: {
          chrome: {
            browserName: 'chrome',
            version: '37.0'
          }
        },
        windowSize: '1024x768'
}

module.exports.test = function(options) {

  // Gemini does not configurate report dir
  options.reportDir = 'gemini-report';

  var test = function(file, enc, callback) {

    var gemini = getGemini(options);

    // Run PhantomJs
    runPhantom();

    // Clean report
    fs.removeSync(options.reportDir);

    // Run tests and create reports
    var runTests = function() {
      var runTestsPromise = gemini.test([path.resolve(options.configDir, './basic-test.js')], {
        reporters: ['html', 'flat'],
        tempDir: options.reportDir
      });
      runTestsPromise.done(result => {
        phantomProcess.kill('SIGTERM');
        spawn('open', [`${options.reportDir}/index.html`])
      });
    };
    // TODO: remake with promises
    setTimeout(runTests, 2000);

  }

  return through.obj(test);

}

module.exports.gather = function(options) {

  var gather = function(file, enc, callback) {

    var gemini = getGemini(options);

    // Run PhantomJs
    runPhantom();

    // Clean screenshot
    fs.removeSync(options.gridScreenshotsDir);

    var runGather = function() {
      gemini.gather([path.resolve(options.configDir, './basic-test.js')], {
        reporters: ['flat'],
      })
      .done(result => {
        phantomProcess.kill('SIGTERM');
      });
    }
    // TODO: remake with promises
    setTimeout(runGather, 2000);

  };

  return through.obj(gather);

};

module.exports.configure = function(options) {

  var configure = function(file, enc, callback) {
    var getPages = function(path) {
      var styleguideData = JSON.parse(fs.readFileSync(`${path}/styleguide.json`));
      var examples = [];
      styleguideData.sections.forEach(section => {
        if (!section.markup) { // For sections with markup only
          return;
        }
        if (section.modifiers.length === 0) {
          // Only for the pages with markup
          // Exclude pages
          if (options.excludePages.indexOf(section.reference) !== -1) {
            return;
          }
          examples.push(section.reference);
        } else {
          for(var m = 1;m<=section.modifiers.length;m++) {
            // Exclude pages
            if (options.excludePages.indexOf(`${section.reference}-${m}`) !== -1) {
              continue;
            }
            examples.push(`${section.reference}-${m}`);
          }
        }
      });
      return examples;
    };

    var styleguidePath = file.path;

    var pages = getPages(styleguidePath);

    // list of pages
    var file = new gutil.File({
      base: path.join(__dirname),
      cwd: __dirname,
      path: path.join(__dirname, './pages-list.js'),
      contents: new Buffer(`module.exports = ${JSON.stringify(pages, null, 4)}`)
    });
    this.push(file);

    // basic test
    var file = new gutil.File({
      base: path.join(__dirname),
      cwd: __dirname,
      path: path.join(__dirname, './basic-test.js'),
      contents: new Buffer(fs.readFileSync(path.join(__dirname, './basic-test.js')))
    });
    this.push(file);

    callback();
  };

  return through.obj(configure);

};
<|endoftext|>