<commit_before>/*=============================================================
************   Hide/show Toolbar/Navbar on scroll   ************
=============================================================*/
app.initScrollToolbars = function (pageContainer) {
    pageContainer = $(pageContainer);
    var scrollContent = pageContainer.find('.page-content');
    if (scrollContent.length === 0) return;
    var hideNavbar = app.params.hideNavbarOnPageScroll || scrollContent.hasClass('hide-navbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll');
    var hideToolbar = app.params.hideToolbarOnPageScroll || scrollContent.hasClass('hide-toolbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll');
    var hideTabbar = app.params.hideTabbarOnPageScroll || scrollContent.hasClass('hide-tabbar-on-scroll');

    if (!(hideNavbar || hideToolbar || hideTabbar)) return;

    var viewContainer = scrollContent.parents('.' + app.params.viewClass);
    if (viewContainer.length === 0) return;

    var navbar = viewContainer.find('.navbar'),
        toolbar = viewContainer.find('.toolbar'),
        tabbar;
    if (hideTabbar) {
        tabbar = viewContainer.find('.tabbar');
        if (tabbar.length === 0) tabbar = viewContainer.parents('.' + app.params.viewsClass).find('.tabbar');
    }

    var hasNavbar = navbar.length > 0,
        hasToolbar = toolbar.length > 0,
        hasTabbar = tabbar && tabbar.length > 0;

    var previousScroll, currentScroll;
        previousScroll = currentScroll = app.scrollTop(pageContainer);

    var scrollHeight, offsetHeight, reachEnd, action, navbarHidden, toolbarHidden, tabbarHidden;

    var toolbarHeight = (hasToolbar && hideToolbar) ? toolbar[0].offsetHeight : 0;
    var tabbarHeight = (hasTabbar && hideTabbar) ? tabbar[0].offsetHeight : 0;
    var bottomBarHeight = tabbarHeight || toolbarHeight;

    function handleScroll(e) {
        if (pageContainer.hasClass('page-on-left')) return;
        currentScroll = app.scrollTop(pageContainer);
        scrollHeight = app.getScrollHeight(pageContainer);
        offsetHeight = pageContainer[0].offsetHeight;
        reachEnd = app.params.showBarsOnPageScrollEnd && (currentScroll + offsetHeight >= scrollHeight - bottomBarHeight);
        navbarHidden = navbar.hasClass('navbar-hidden');
        toolbarHidden = toolbar.hasClass('toolbar-hidden');
        tabbarHidden = tabbar && tabbar.hasClass('toolbar-hidden');

        if (previousScroll > currentScroll || reachEnd) {
            action = 'show';
        }
        else {
            if (currentScroll > 44) {
                action = 'hide';
            }
            else {
                action = 'show';
            }
        }

        if (action === 'show') {
            if (hasNavbar && hideNavbar && navbarHidden) {
                app.showNavbar(navbar);
                pageContainer.removeClass('no-navbar-by-scroll');
                navbarHidden = false;
            }
            if (hasToolbar && hideToolbar && toolbarHidden) {
                app.showToolbar(toolbar);
                pageContainer.removeClass('no-toolbar-by-scroll');
                toolbarHidden = false;
            }
            if (hasTabbar && hideTabbar && tabbarHidden) {
                app.showToolbar(tabbar);
                pageContainer.removeClass('no-tabbar-by-scroll');
                tabbarHidden = false;
            }
        }
        else {
            if (hasNavbar && hideNavbar && !navbarHidden) {
                app.hideNavbar(navbar);
                pageContainer.addClass('no-navbar-by-scroll');
                navbarHidden = true;
            }
            if (hasToolbar && hideToolbar && !toolbarHidden) {
                app.hideToolbar(toolbar);
                pageContainer.addClass('no-toolbar-by-scroll');
                toolbarHidden = true;
            }
            if (hasTabbar && hideTabbar && !tabbarHidden) {
                app.hideToolbar(tabbar);
                pageContainer.addClass('no-tabbar-by-scroll');
                tabbarHidden = true;
            }
        }

        previousScroll = currentScroll;
    }
    pageContainer[0].scroller.on('scroll', handleScroll);
    scrollContent[0].f7ScrollToolbarsHandler = handleScroll;
};
app.destroyScrollToolbars = function (pageContainer) {
    pageContainer = $(pageContainer);
    var scrollContent = pageContainer.find('.page-content');
    if (scrollContent.length === 0) return;
    var handler = scrollContent[0].f7ScrollToolbarsHandler;
    if (!handler) return;
    scrollContent.off('scroll', scrollContent[0].f7ScrollToolbarsHandler);
};
<commit_msg>fix navbar auto hide on scroll bug<commit_after>/*=============================================================
************   Hide/show Toolbar/Navbar on scroll   ************
=============================================================*/
app.initScrollToolbars = function (pageContainer) {
    pageContainer = $(pageContainer);
    var scrollContent = pageContainer.find('.page-content');
    if (scrollContent.length === 0) return;
    var hideNavbar = app.params.hideNavbarOnPageScroll || scrollContent.hasClass('hide-navbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll');
    var hideToolbar = app.params.hideToolbarOnPageScroll || scrollContent.hasClass('hide-toolbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll');
    var hideTabbar = app.params.hideTabbarOnPageScroll || scrollContent.hasClass('hide-tabbar-on-scroll');

    if (!(hideNavbar || hideToolbar || hideTabbar)) return;

    var viewContainer = scrollContent.parents('.' + app.params.viewClass);
    if (viewContainer.length === 0) return;

    var navbar = viewContainer.find('.navbar'),
        toolbar = viewContainer.find('.toolbar'),
        tabbar;
    if (hideTabbar) {
        tabbar = viewContainer.find('.tabbar');
        if (tabbar.length === 0) tabbar = viewContainer.parents('.' + app.params.viewsClass).find('.tabbar');
    }

    var hasNavbar = navbar.length > 0,
        hasToolbar = toolbar.length > 0,
        hasTabbar = tabbar && tabbar.length > 0;

    var previousScroll, currentScroll;
        previousScroll = currentScroll = app.scrollTop(pageContainer);

    var scrollHeight, offsetHeight, reachEnd, action, navbarHidden, toolbarHidden, tabbarHidden;

    var toolbarHeight = (hasToolbar && hideToolbar) ? toolbar[0].offsetHeight : 0;
    var tabbarHeight = (hasTabbar && hideTabbar) ? tabbar[0].offsetHeight : 0;
    var bottomBarHeight = tabbarHeight || toolbarHeight;

    function handleScroll(e) {
        if (pageContainer.hasClass('page-on-left')) return;
        currentScroll = app.scrollTop(pageContainer);
        scrollHeight = app.getScrollHeight(pageContainer);
        offsetHeight = pageContainer[0].offsetHeight;
        reachEnd = app.params.showBarsOnPageScrollEnd && (currentScroll + offsetHeight >= scrollHeight - bottomBarHeight);
        navbarHidden = navbar.hasClass('navbar-hidden');
        toolbarHidden = toolbar.hasClass('toolbar-hidden');
        tabbarHidden = tabbar && tabbar.hasClass('toolbar-hidden');

        if (previousScroll === currentScroll && !reachEnd) {  //some time, iscroll fire scroll event, but the scrolltop is the save
          return;
        }
        if (previousScroll > currentScroll || reachEnd) {
            action = 'show';
        }
        else {
            if (currentScroll > 44) {
                action = 'hide';
            }
            else {
                action = 'show';
            }
        }
        console.log(action, previousScroll, currentScroll);

        if (action === 'show') {
            if (hasNavbar && hideNavbar && navbarHidden) {
                app.showNavbar(navbar);
                pageContainer.removeClass('no-navbar-by-scroll');
                navbarHidden = false;
            }
            if (hasToolbar && hideToolbar && toolbarHidden) {
                app.showToolbar(toolbar);
                pageContainer.removeClass('no-toolbar-by-scroll');
                toolbarHidden = false;
            }
            if (hasTabbar && hideTabbar && tabbarHidden) {
                app.showToolbar(tabbar);
                pageContainer.removeClass('no-tabbar-by-scroll');
                tabbarHidden = false;
            }
        }
        else {
            if (hasNavbar && hideNavbar && !navbarHidden) {
                app.hideNavbar(navbar);
                pageContainer.addClass('no-navbar-by-scroll');
                navbarHidden = true;
            }
            if (hasToolbar && hideToolbar && !toolbarHidden) {
                app.hideToolbar(toolbar);
                pageContainer.addClass('no-toolbar-by-scroll');
                toolbarHidden = true;
            }
            if (hasTabbar && hideTabbar && !tabbarHidden) {
                app.hideToolbar(tabbar);
                pageContainer.addClass('no-tabbar-by-scroll');
                tabbarHidden = true;
            }
        }

        previousScroll = currentScroll;
    }
    pageContainer[0].scroller.on('scroll', handleScroll);
    scrollContent[0].f7ScrollToolbarsHandler = handleScroll;
};
app.destroyScrollToolbars = function (pageContainer) {
    pageContainer = $(pageContainer);
    var scrollContent = pageContainer.find('.page-content');
    if (scrollContent.length === 0) return;
    var handler = scrollContent[0].f7ScrollToolbarsHandler;
    if (!handler) return;
    pageContainer[0].scroller.scroller.off('scroll', scrollContent[0].f7ScrollToolbarsHandler);
};
<|endoftext|>


<commit_before>'use strict';

angular.module('jqplay.controllers', []).controller('JqplayCtrl', function JqplayCtrl($scope, $timeout, jqplayService) {
  $scope.result = "";

  $scope.$watch('jq', function(newValue, oldValue) {
    if ($scope.input.$valid && !angular.equals(newValue, oldValue)) {
      if ($scope.runTimeout != null) {
        $timeout.cancel($scope.runTimeout);
        $scope.runTimeout = null;
      }

      $scope.runTimeout = $timeout(function() {
        $scope.run($scope.jq);
        $scope.runTimeout = null;
      }, 1000);
    }
  }, true);

  $scope.run = function(jq) {
    $scope.result = "Loading...";

    var promise = jqplayService.run(jq);
    promise.success(function(data) {
      $scope.result = data.result;
    });
    promise.error(function(data) {
      $scope.result = data.message;
    });
  };
});
<commit_msg>No need to check equality again inside $watch<commit_after>'use strict';

angular.module('jqplay.controllers', []).controller('JqplayCtrl', function JqplayCtrl($scope, $timeout, jqplayService) {
  $scope.result = "";

  $scope.$watch('jq', function(newValue, oldValue) {
    if ($scope.input.$valid) {
      if ($scope.runTimeout != null) {
        $timeout.cancel($scope.runTimeout);
        $scope.runTimeout = null;
      }

      $scope.runTimeout = $timeout(function() {
        $scope.run($scope.jq);
        $scope.runTimeout = null;
      }, 1000);
    }
  }, true);

  $scope.run = function(jq) {
    $scope.result = "Loading...";

    var promise = jqplayService.run(jq);
    promise.success(function(data) {
      $scope.result = data.result;
    });
    promise.error(function(data) {
      $scope.result = data.message;
    });
  };
});
<|endoftext|>


<commit_before>/*
|--------------------------------------------------------------------------
| Requires
|--------------------------------------------------------------------------
*/

import { EventEmitter } from 'events';
import objectAssign     from 'object-assign';
import path             from 'path';

import app from '../constants/app';

import AppDispatcher from '../dispatcher/AppDispatcher';
import AppConstants  from '../constants/AppConstants';

import utils from '../utils/utils';

var CHANGE_EVENT = 'change';

/*
|--------------------------------------------------------------------------
| Store
|--------------------------------------------------------------------------
*/

var AppStore = objectAssign({}, EventEmitter.prototype, {

    library           :  null,  // All tracks
    tracks            :  null,  // All tracks shown on the view
    playlist          :  [],    // Tracks to be played
    playlistCursor    :  null,  // The cursor of the playlist
    oldPlaylist       :  null,  // Playlist backup
    oldPlaylistCursor :  null,  // The last cursor backup (to roll stuff back, e.g. unshuffle)
    playerStatus      : 'stop', // Player status
    notifications     :  {},    // The array of notifications
    refreshingLibrary :  false, // If the app is currently refreshing the app
    repeat            :  false, // the current repeat state (one, all, false)
    shuffle           :  false, // If shuffle mode is enabled

    getStore: function() {
        return {
            config            :  JSON.parse(localStorage.getItem('config')),
            library           :  this.library,
            tracks            :  this.tracks,
            playlist          :  this.playlist,
            playlistCursor    :  this.playlistCursor,
            playerStatus      :  this.playerStatus,
            notifications     :  this.notifications,
            refreshingLibrary :  this.refreshingLibrary,
            repeat            :  this.repeat,
            shuffle           :  this.shuffle
        };
    },

    addChangeListener: function(cb){
        this.on(CHANGE_EVENT, cb);
    },

    removeChangeListener: function(cb){
        this.removeListener(CHANGE_EVENT, cb);
    }
});

export default AppStore;

/*
|--------------------------------------------------------------------------
| Dispatcher Listener
|--------------------------------------------------------------------------
*/

AppDispatcher.register(function(payload) {

    switch(payload.actionType) {

        case(AppConstants.APP_REFRESH_LIBRARY):
            AppStore.library = payload.tracks;
            AppStore.tracks  = payload.tracks;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_REFRESH_CONFIG):
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_SELECT_AND_PLAY):

            var playlist       = AppStore.tracks.slice();
            var id             = payload.id;
            var playlistCursor = payload.id;

            var uri = utils.parseURI(playlist[id].path);
                app.audio.src = uri;
                app.audio.play();

            // Check if we have to shuffle the queue
            if(AppStore.shuffle) {

                var firstTrack = playlist[id];

                var m = playlist.length, t, i;
                while (m) {

                    // Pick a remaining element…
                    i = Math.floor(Math.random() * m--);

                    // And swap it with the current element.
                    t = playlist[m];
                    playlist[m] = playlist[i];
                    playlist[i] = t;
                }

                playlist.unshift(firstTrack);

                // Let's set the cursor to 0
                playlistCursor = 0;
            }

            // Backup that and change the UI
            AppStore.playerStatus      = 'play';
            AppStore.playlist          =  playlist;
            AppStore.playlistCursor    =  playlistCursor;
            AppStore.oldPlaylistCursor =  id;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_FILTER_SEARCH):

            var search = payload.search;

            var library = AppStore.library;
            var tracks  = [];

            for(var i = 0; i < library.length; i++) {

                var track = library[i];

                if(search != '' && search != undefined) {

                    if(track.lArtist.indexOf(search) === -1
                        && track.album.toLowerCase().indexOf(search) === -1
                        && track.genre.join(', ').toLowerCase().indexOf(search) === -1
                        && track.title.toLowerCase().indexOf(search) === -1) {

                        continue;

                    } else {
                        tracks.push(track);
                    }

                } else {
                    tracks.push(track);
                }
            }

            AppStore.tracks = tracks;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_TOGGLE):
            if(app.audio.paused && AppStore.playlist !== null) {
                AppStore.playerStatus = 'play';
                app.audio.play();
            } else {
                AppStore.playerStatus = 'pause';
                app.audio.pause();
            }
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_PLAY):
            if(AppStore.playlist !== null) {
                AppStore.playerStatus = 'play';
                app.audio.play();
                AppStore.emit(CHANGE_EVENT);
            }
            break;

        case(AppConstants.APP_PLAYER_PAUSE):
            AppStore.playerStatus = 'pause';
            app.audio.pause();
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_STOP):
            app.audio.pause();
            AppStore.library           =  null;
            AppStore.tracks            =  null;
            AppStore.playlist          =  [];
            AppStore.playlistCursor    =  null;
            AppStore.oldPlaylistCursor =  null;
            AppStore.playerStatus      = 'stop'
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_NEXT):
            var e = payload.e;

            if(e !== undefined) e.target.removeEventListener(e.type);

            var playlist = AppStore.playlist;

            if(AppStore.repeat === 'one') {
                newPlaylistCursor = AppStore.playlistCursor;
            } else if (
                AppStore.repeat === 'all' &&
                AppStore.playlistCursor === playlist.length - 1 // is last track
            ) {
                newPlaylistCursor = 0; // start with new track
            } else {
                var newPlaylistCursor  = AppStore.playlistCursor + 1;
            }

            if (playlist[newPlaylistCursor] !== undefined) {

                var uri = utils.parseURI(playlist[newPlaylistCursor].path); ;
                app.audio.src = uri;
                app.audio.play();

                AppStore.playlistCursor = newPlaylistCursor;

            } else {

                app.audio.pause();
                app.audio.src = '';

                AppStore.playlist = [];
                AppStore.playlistCursor = null;
            }
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_PREVIOUS):
            if (app.audio.currentTime < 5) {

                var newPlaylistCursor = AppStore.playlistCursor - 1;

            } else {

                var newPlaylistCursor = AppStore.playlistCursor
            }

            var newTrack = AppStore.playlist[newPlaylistCursor];

            if (newTrack !== undefined) {

                var uri = utils.parseURI(newTrack.path);
                app.audio.src = uri;

                app.audio.play();

                AppStore.playlistCursor = newPlaylistCursor;

            } else {

                AppStore.playlist = null;
            }
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_SHUFFLE):

            if(!AppStore.shuffle) {

                AppStore.oldPlaylist       = AppStore.playlist;
                AppStore.oldPlaylistCursor = AppStore.oldPlaylistCursor;

                // Let's shuffle that
                var playlist       = AppStore.playlist.slice();
                var playlistCursor = AppStore.playlistCursor;

                var firstTrack = playlist[playlistCursor];

                var m = playlist.length, t, i;
                while (m) {

                    // Pick a remaining element…
                    i = Math.floor(Math.random() * m--);

                    // And swap it with the current element.
                    t = playlist[m];
                    playlist[m] = playlist[i];
                    playlist[i] = t;
                }

                playlist.unshift(firstTrack);

                AppStore.shuffle           = true;
                AppStore.playlist          = playlist;
                AppStore.playlistCursor    = 0;
                AppStore.oldPlaylistCursor = playlistCursor;

            } else {

                AppStore.playlist          = AppStore.oldPlaylist;
                AppStore.oldPlaylistCursor = AppStore.oldPlaylistCursor;
                AppStore.shuffle           = false;

            }

            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_REPEAT):
            var repeatState = AppStore.repeat;
            var newRepeatState;

            if(repeatState === 'all') {
                newRepeatState = 'one';
            } else if (repeatState === 'one') {
                newRepeatState = false;
            } else if (repeatState === false) {
                newRepeatState = 'all';
            }
            AppStore.repeat = newRepeatState;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_JUMP_TO):
            app.audio.currentTime = payload.to;
            break;

        case(AppConstants.APP_QUEUE_CLEAR):
            AppStore.playlist.splice(AppStore.playlistCursor + 1, AppStore.playlist.length - AppStore.playlistCursor);
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_QUEUE_REMOVE):
            AppStore.playlist.splice(AppStore.playlistCursor + payload.index + 1, 1)
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_QUEUE_ADD):
            var selected = payload.selected;
            var playlist = AppStore.playlist.slice();
            var tracks   = AppStore.tracks;

            for(var i = 0; i < selected.length; i++) {
                playlist.push(tracks[selected[i]]);
            }

            AppStore.playlist = playlist;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_QUEUE_ADD_NEXT):
            var selected = payload.selected;
            var playlist = AppStore.playlist;
            var tracks   = AppStore.tracks;
            var cursor   = AppStore.playlistCursor;

            for(var i = 0; i < selected.length; i++) {
                playlist.splice(cursor + 1, 0, tracks[selected[selected.length - i - 1]]);
            }

            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_QUEUE_SET_PLAYLIST):
            AppStore.playlist = payload.playlist;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_LIBRARY_ADD_FOLDERS):
            var config  = JSON.parse(localStorage.getItem('config'));
            var folders = payload.folders;

            if(folders !== undefined) {
                folders.forEach(function (folder) {
                    config.musicFolders.push(folder);
                });
                config.musicFolders.sort();
                localStorage.setItem('config', JSON.stringify(config));
                AppStore.emit(CHANGE_EVENT);
            }
            break;

        case(AppConstants.APP_LIBRARY_REMOVE_FOLDER):
            var config = JSON.parse(localStorage.getItem('config'));
            config.musicFolders.splice(payload.index, 1);
            localStorage.setItem('config', JSON.stringify(config));

            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_LIBRARY_RESET):
            // nothing here for the moment
            break;

        case(AppConstants.APP_LIBRARY_REFRESH_START):
            AppStore.refreshingLibrary = true;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_LIBRARY_REFRESH_END):
            AppStore.refreshingLibrary = false;
            AppStore.emit(CHANGE_EVENT);
            break;
    }
});
<commit_msg>Fix shuffle generation<commit_after>/*
|--------------------------------------------------------------------------
| Requires
|--------------------------------------------------------------------------
*/

import { EventEmitter } from 'events';
import objectAssign     from 'object-assign';
import path             from 'path';

import app from '../constants/app';

import AppDispatcher from '../dispatcher/AppDispatcher';
import AppConstants  from '../constants/AppConstants';

import utils from '../utils/utils';

var CHANGE_EVENT = 'change';

/*
|--------------------------------------------------------------------------
| Store
|--------------------------------------------------------------------------
*/

var AppStore = objectAssign({}, EventEmitter.prototype, {

    library           :  null,  // All tracks
    tracks            :  null,  // All tracks shown on the view
    playlist          :  [],    // Tracks to be played
    playlistCursor    :  null,  // The cursor of the playlist
    oldPlaylist       :  null,  // Playlist backup
    oldPlaylistCursor :  null,  // The last cursor backup (to roll stuff back, e.g. unshuffle)
    playerStatus      : 'stop', // Player status
    notifications     :  {},    // The array of notifications
    refreshingLibrary :  false, // If the app is currently refreshing the app
    repeat            :  false, // the current repeat state (one, all, false)
    shuffle           :  false, // If shuffle mode is enabled

    getStore: function() {
        return {
            config            :  JSON.parse(localStorage.getItem('config')),
            library           :  this.library,
            tracks            :  this.tracks,
            playlist          :  this.playlist,
            playlistCursor    :  this.playlistCursor,
            playerStatus      :  this.playerStatus,
            notifications     :  this.notifications,
            refreshingLibrary :  this.refreshingLibrary,
            repeat            :  this.repeat,
            shuffle           :  this.shuffle
        };
    },

    addChangeListener: function(cb){
        this.on(CHANGE_EVENT, cb);
    },

    removeChangeListener: function(cb){
        this.removeListener(CHANGE_EVENT, cb);
    }
});

export default AppStore;

/*
|--------------------------------------------------------------------------
| Dispatcher Listener
|--------------------------------------------------------------------------
*/

AppDispatcher.register(function(payload) {

    switch(payload.actionType) {

        case(AppConstants.APP_REFRESH_LIBRARY):
            AppStore.library = payload.tracks;
            AppStore.tracks  = payload.tracks;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_REFRESH_CONFIG):
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_SELECT_AND_PLAY):

            var playlist       = AppStore.tracks.slice();
            var id             = payload.id;
            var playlistCursor = payload.id;

            var uri = utils.parseURI(playlist[id].path);
                app.audio.src = uri;
                app.audio.play();

            // Check if we have to shuffle the queue
            if(AppStore.shuffle) {

                var firstTrack = playlist[id];

                var m = playlist.length, t, i;
                while (m) {

                    // Pick a remaining element…
                    i = Math.floor(Math.random() * m--);

                    // And swap it with the current element.
                    t = playlist[m];
                    playlist[m] = playlist[i];
                    playlist[i] = t;
                }

                playlist.unshift(firstTrack);

                // Let's set the cursor to 0
                playlistCursor = 0;
            }

            // Backup that and change the UI
            AppStore.playerStatus      = 'play';
            AppStore.playlist          =  playlist;
            AppStore.playlistCursor    =  playlistCursor;
            AppStore.oldPlaylistCursor =  id;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_FILTER_SEARCH):

            var search = payload.search;

            var library = AppStore.library;
            var tracks  = [];

            for(var i = 0; i < library.length; i++) {

                var track = library[i];

                if(search != '' && search != undefined) {

                    if(track.lArtist.indexOf(search) === -1
                        && track.album.toLowerCase().indexOf(search) === -1
                        && track.genre.join(', ').toLowerCase().indexOf(search) === -1
                        && track.title.toLowerCase().indexOf(search) === -1) {

                        continue;

                    } else {
                        tracks.push(track);
                    }

                } else {
                    tracks.push(track);
                }
            }

            AppStore.tracks = tracks;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_TOGGLE):
            if(app.audio.paused && AppStore.playlist !== null) {
                AppStore.playerStatus = 'play';
                app.audio.play();
            } else {
                AppStore.playerStatus = 'pause';
                app.audio.pause();
            }
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_PLAY):
            if(AppStore.playlist !== null) {
                AppStore.playerStatus = 'play';
                app.audio.play();
                AppStore.emit(CHANGE_EVENT);
            }
            break;

        case(AppConstants.APP_PLAYER_PAUSE):
            AppStore.playerStatus = 'pause';
            app.audio.pause();
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_STOP):
            app.audio.pause();
            AppStore.library           =  null;
            AppStore.tracks            =  null;
            AppStore.playlist          =  [];
            AppStore.playlistCursor    =  null;
            AppStore.oldPlaylistCursor =  null;
            AppStore.playerStatus      = 'stop'
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_NEXT):
            var e = payload.e;

            if(e !== undefined) e.target.removeEventListener(e.type);

            var playlist = AppStore.playlist;

            if(AppStore.repeat === 'one') {
                newPlaylistCursor = AppStore.playlistCursor;
            } else if (
                AppStore.repeat === 'all' &&
                AppStore.playlistCursor === playlist.length - 1 // is last track
            ) {
                newPlaylistCursor = 0; // start with new track
            } else {
                var newPlaylistCursor  = AppStore.playlistCursor + 1;
            }

            if (playlist[newPlaylistCursor] !== undefined) {

                var uri = utils.parseURI(playlist[newPlaylistCursor].path); ;
                app.audio.src = uri;
                app.audio.play();

                AppStore.playlistCursor = newPlaylistCursor;

            } else {

                app.audio.pause();
                app.audio.src = '';

                AppStore.playlist = [];
                AppStore.playlistCursor = null;
            }
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_PREVIOUS):
            if (app.audio.currentTime < 5) {

                var newPlaylistCursor = AppStore.playlistCursor - 1;

            } else {

                var newPlaylistCursor = AppStore.playlistCursor
            }

            var newTrack = AppStore.playlist[newPlaylistCursor];

            if (newTrack !== undefined) {

                var uri = utils.parseURI(newTrack.path);
                app.audio.src = uri;

                app.audio.play();

                AppStore.playlistCursor = newPlaylistCursor;

            } else {

                AppStore.playlist = null;
            }
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_SHUFFLE):

            if(!AppStore.shuffle) {

                AppStore.oldPlaylist       = AppStore.playlist;
                AppStore.oldPlaylistCursor = AppStore.oldPlaylistCursor;

                // Let's shuffle that
                var playlistCursor = AppStore.playlistCursor;
                var playlist       = AppStore.playlist.slice().splice(playlistCursor + 1, AppStore.playlist.length - (playlistCursor + 1));

                var firstTrack = playlist[playlistCursor];

                var m = playlist.length, t, i;
                while (m) {

                    // Pick a remaining element…
                    i = Math.floor(Math.random() * m--);

                    // And swap it with the current element.
                    t = playlist[m];
                    playlist[m] = playlist[i];
                    playlist[i] = t;
                }

                playlist.unshift(firstTrack);

                AppStore.shuffle           = true;
                AppStore.playlist          = playlist;
                AppStore.playlistCursor    = 0;
                AppStore.oldPlaylistCursor = playlistCursor;

            } else {

                AppStore.playlist          = AppStore.oldPlaylist;
                AppStore.oldPlaylistCursor = AppStore.oldPlaylistCursor;
                AppStore.shuffle           = false;

            }

            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_REPEAT):
            var repeatState = AppStore.repeat;
            var newRepeatState;

            if(repeatState === 'all') {
                newRepeatState = 'one';
            } else if (repeatState === 'one') {
                newRepeatState = false;
            } else if (repeatState === false) {
                newRepeatState = 'all';
            }
            AppStore.repeat = newRepeatState;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_PLAYER_JUMP_TO):
            app.audio.currentTime = payload.to;
            break;

        case(AppConstants.APP_QUEUE_CLEAR):
            AppStore.playlist.splice(AppStore.playlistCursor + 1, AppStore.playlist.length - AppStore.playlistCursor);
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_QUEUE_REMOVE):
            AppStore.playlist.splice(AppStore.playlistCursor + payload.index + 1, 1)
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_QUEUE_ADD):
            var selected = payload.selected;
            var playlist = AppStore.playlist.slice();
            var tracks   = AppStore.tracks;

            for(var i = 0; i < selected.length; i++) {
                playlist.push(tracks[selected[i]]);
            }

            AppStore.playlist = playlist;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_QUEUE_ADD_NEXT):
            var selected = payload.selected;
            var playlist = AppStore.playlist;
            var tracks   = AppStore.tracks;
            var cursor   = AppStore.playlistCursor;

            for(var i = 0; i < selected.length; i++) {
                playlist.splice(cursor + 1, 0, tracks[selected[selected.length - i - 1]]);
            }

            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_QUEUE_SET_PLAYLIST):
            AppStore.playlist = payload.playlist;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_LIBRARY_ADD_FOLDERS):
            var config  = JSON.parse(localStorage.getItem('config'));
            var folders = payload.folders;

            if(folders !== undefined) {
                folders.forEach(function (folder) {
                    config.musicFolders.push(folder);
                });
                config.musicFolders.sort();
                localStorage.setItem('config', JSON.stringify(config));
                AppStore.emit(CHANGE_EVENT);
            }
            break;

        case(AppConstants.APP_LIBRARY_REMOVE_FOLDER):
            var config = JSON.parse(localStorage.getItem('config'));
            config.musicFolders.splice(payload.index, 1);
            localStorage.setItem('config', JSON.stringify(config));

            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_LIBRARY_RESET):
            // nothing here for the moment
            break;

        case(AppConstants.APP_LIBRARY_REFRESH_START):
            AppStore.refreshingLibrary = true;
            AppStore.emit(CHANGE_EVENT);
            break;

        case(AppConstants.APP_LIBRARY_REFRESH_END):
            AppStore.refreshingLibrary = false;
            AppStore.emit(CHANGE_EVENT);
            break;
    }
});
<|endoftext|>


<commit_before>/*
 * Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
 * http://paperjs.org/
 *
 * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

module('Rectangle');

test('new Rectangle(new Point(10, 20), new Size(30, 40));', function() {
	var rect = new Rectangle(new Point(10, 20), new Size(30, 40));
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle({ point: [10, 20], size: [30, 40] });', function() {
	var rect = new Rectangle({ point: [10, 20], size: [30, 40] });
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle({ point: new Point(10, 20), size: new Size(30, 40)});', function() {
	var rect = new Rectangle({ point: new Point(10, 20), size: new Size(30, 40)});
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle([10, 20], [30, 40]);', function() {
	var rect = new Rectangle([10, 20], [30, 40]);
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle({from: [10, 20], to: [30, 40]});', function() {
	var rect = new Rectangle({from: [10, 20], to: [30, 40]});
	equals(rect.toString(), '{ x: 10, y: 20, width: 20, height: 20 }');
});

test('new Rectangle(new Point(10, 20), new Point(30, 40));', function() {
	var rect = new Rectangle(new Point(10, 20), new Point(30, 40));
	equals(rect.toString(), '{ x: 10, y: 20, width: 20, height: 20 }');
});

test('new Rectangle(10, 20, 30, 40);', function() {
	var rect = new Rectangle(10, 20, 30, 40);
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle({x: 10, y: 20, width: 30, height: 40});', function() {
	var rect = new Rectangle({x: 10, y: 20, width: 30, height: 40});
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('get size', function() {
	var rect = new Rectangle(10, 10, 20, 30);
	equals(function() {
		return rect.size.equals([20, 30]);
	}, true);
});

test('set size', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.size = new Size(30, 30);
	equals(rect.toString(), '{ x: 10, y: 10, width: 30, height: 30 }');
});

test('topLeft', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.topLeft;
	equals(point.toString(), '{ x: 10, y: 10 }');
});

test('set topLeft', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.topLeft = [10, 15];
	var point = rect.topLeft;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get topRight', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.topRight;
	equals(point.toString(), '{ x: 30, y: 10 }');
});

test('set topRight', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.topRight = [10, 15];
	var point = rect.topRight;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get bottomLeft', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.bottomLeft;
	equals(point.toString(), '{ x: 10, y: 30 }');
});

test('set bottomLeft', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.bottomLeft = [10, 15];
	var point = rect.bottomLeft;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get bottomRight', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.bottomRight;
	equals(point.toString(), '{ x: 30, y: 30 }');
});

test('set bottomRight', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.bottomRight = [10, 15];
	var point = rect.bottomRight;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get bottomCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.bottomCenter;
	equals(point.toString(), '{ x: 20, y: 30 }');
});

test('set bottomCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.bottomCenter = [10, 15];
	var point = rect.bottomCenter;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get topCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.topCenter;
	equals(point.toString(), '{ x: 20, y: 10 }');
});

test('set topCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.topCenter = [10, 15];
	var point = rect.topCenter;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get leftCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.leftCenter;
	equals(point.toString(), '{ x: 10, y: 20 }');
});

test('set leftCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.leftCenter = [10, 15];
	var point = rect.leftCenter;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get rightCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.rightCenter;
	equals(point.toString(), '{ x: 30, y: 20 }');
});

test('set rightCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.rightCenter = [10, 15];
	var point = rect.rightCenter;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('intersects(rect)', function() {
	var rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var rect2 = { x: 195, y: 301, width: 19, height: 19 };
	equals(function() {
		return rect1.intersects(rect2);
	}, false);
	rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	rect2 = { x: 170.5, y: 280.5, width: 19, height: 19 };
	equals(function() {
		return rect1.intersects(rect2);
	}, true);
});

test('contains(rect)', function() {
	var rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var rect2 = { x: 195, y: 301, width: 19, height: 19 };
	equals(function() {
		return rect1.contains(rect2);
	}, false);
	rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	rect2 = new Rectangle({ x: 170.5, y: 280.5, width: 19, height: 19 });
	equals(function() {
		return rect1.contains(rect2);
	}, false);

	rect1 = new Rectangle({ x: 299, y: 161, width: 137, height: 129 });
	rect2 = new Rectangle({ x: 340, y: 197, width: 61, height: 61 });
	equals(function() {
		return rect1.contains(rect2);
	}, true);
	equals(function() {
		return rect2.contains(rect1);
	}, false);
});

test('contains(point)', function() {
	var rect = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var point = new Point(166, 280);
	equals(function() {
		return rect.contains(point);
	}, true);
	var point = new Point(30, 30);
	equals(function() {
		return rect.contains(point);
	}, false);
});

test('intersect(rect)', function() {
	var rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var rect2 = { x: 170.5, y: 280.5, width: 19, height: 19 };
	var intersected = rect1.intersect(rect2);
	equals(function() {
		return intersected.equals({ x: 170.5, y: 280.5, width: 9.5, height: 9.5 });
	}, true);
});

test('unite(rect)', function() {
	var rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var rect2 = { x: 170.5, y: 280.5, width: 19, height: 19 };
	var united = rect1.unite(rect2);
	equals(function() {
		return united.equals({ x: 160, y: 270, width: 29.5, height: 29.5 });
	}, true);
});

test('include(point)', function() {
	var rect1 = new Rectangle({ x: 95, y: 151, width: 20, height: 20 });
	var included = rect1.include([50, 50]);
	equals(function() {
		return included.equals({ x: 50, y: 50, width: 65, height: 121 });
	}, true);
});

test('toString()', function() {
	var string = new Rectangle(10, 20, 30, 40).toString();
	equals(string, '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle(object)', function() {
	equals(function() {
		return new Rectangle({
			center: [50, 100],
			size: [100, 200]
		}).toString();
	}, '{ x: 0, y: 0, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			topLeft: [100, 50],
			size: [100, 200]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			topRight: [200, 50],
			size: [100, 200]
		}).toString();
	}, '{ x: 100, y: -150, width: 100, height: 200 }');

});
<commit_msg>Add more failing tests for new Rectangle(object) constructors.<commit_after>/*
 * Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
 * http://paperjs.org/
 *
 * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

module('Rectangle');

test('new Rectangle(new Point(10, 20), new Size(30, 40));', function() {
	var rect = new Rectangle(new Point(10, 20), new Size(30, 40));
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle({ point: [10, 20], size: [30, 40] });', function() {
	var rect = new Rectangle({ point: [10, 20], size: [30, 40] });
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle({ point: new Point(10, 20), size: new Size(30, 40)});', function() {
	var rect = new Rectangle({ point: new Point(10, 20), size: new Size(30, 40)});
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle([10, 20], [30, 40]);', function() {
	var rect = new Rectangle([10, 20], [30, 40]);
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle({from: [10, 20], to: [30, 40]});', function() {
	var rect = new Rectangle({from: [10, 20], to: [30, 40]});
	equals(rect.toString(), '{ x: 10, y: 20, width: 20, height: 20 }');
});

test('new Rectangle(new Point(10, 20), new Point(30, 40));', function() {
	var rect = new Rectangle(new Point(10, 20), new Point(30, 40));
	equals(rect.toString(), '{ x: 10, y: 20, width: 20, height: 20 }');
});

test('new Rectangle(10, 20, 30, 40);', function() {
	var rect = new Rectangle(10, 20, 30, 40);
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle({x: 10, y: 20, width: 30, height: 40});', function() {
	var rect = new Rectangle({x: 10, y: 20, width: 30, height: 40});
	equals(rect.toString(), '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('get size', function() {
	var rect = new Rectangle(10, 10, 20, 30);
	equals(function() {
		return rect.size.equals([20, 30]);
	}, true);
});

test('set size', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.size = new Size(30, 30);
	equals(rect.toString(), '{ x: 10, y: 10, width: 30, height: 30 }');
});

test('topLeft', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.topLeft;
	equals(point.toString(), '{ x: 10, y: 10 }');
});

test('set topLeft', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.topLeft = [10, 15];
	var point = rect.topLeft;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get topRight', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.topRight;
	equals(point.toString(), '{ x: 30, y: 10 }');
});

test('set topRight', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.topRight = [10, 15];
	var point = rect.topRight;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get bottomLeft', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.bottomLeft;
	equals(point.toString(), '{ x: 10, y: 30 }');
});

test('set bottomLeft', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.bottomLeft = [10, 15];
	var point = rect.bottomLeft;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get bottomRight', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.bottomRight;
	equals(point.toString(), '{ x: 30, y: 30 }');
});

test('set bottomRight', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.bottomRight = [10, 15];
	var point = rect.bottomRight;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get bottomCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.bottomCenter;
	equals(point.toString(), '{ x: 20, y: 30 }');
});

test('set bottomCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.bottomCenter = [10, 15];
	var point = rect.bottomCenter;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get topCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.topCenter;
	equals(point.toString(), '{ x: 20, y: 10 }');
});

test('set topCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.topCenter = [10, 15];
	var point = rect.topCenter;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get leftCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.leftCenter;
	equals(point.toString(), '{ x: 10, y: 20 }');
});

test('set leftCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.leftCenter = [10, 15];
	var point = rect.leftCenter;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('get rightCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	var point = rect.rightCenter;
	equals(point.toString(), '{ x: 30, y: 20 }');
});

test('set rightCenter', function() {
	var rect = new Rectangle(10, 10, 20, 20);
	rect.rightCenter = [10, 15];
	var point = rect.rightCenter;
	equals(point.toString(), '{ x: 10, y: 15 }');
});

test('intersects(rect)', function() {
	var rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var rect2 = { x: 195, y: 301, width: 19, height: 19 };
	equals(function() {
		return rect1.intersects(rect2);
	}, false);
	rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	rect2 = { x: 170.5, y: 280.5, width: 19, height: 19 };
	equals(function() {
		return rect1.intersects(rect2);
	}, true);
});

test('contains(rect)', function() {
	var rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var rect2 = { x: 195, y: 301, width: 19, height: 19 };
	equals(function() {
		return rect1.contains(rect2);
	}, false);
	rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	rect2 = new Rectangle({ x: 170.5, y: 280.5, width: 19, height: 19 });
	equals(function() {
		return rect1.contains(rect2);
	}, false);

	rect1 = new Rectangle({ x: 299, y: 161, width: 137, height: 129 });
	rect2 = new Rectangle({ x: 340, y: 197, width: 61, height: 61 });
	equals(function() {
		return rect1.contains(rect2);
	}, true);
	equals(function() {
		return rect2.contains(rect1);
	}, false);
});

test('contains(point)', function() {
	var rect = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var point = new Point(166, 280);
	equals(function() {
		return rect.contains(point);
	}, true);
	var point = new Point(30, 30);
	equals(function() {
		return rect.contains(point);
	}, false);
});

test('intersect(rect)', function() {
	var rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var rect2 = { x: 170.5, y: 280.5, width: 19, height: 19 };
	var intersected = rect1.intersect(rect2);
	equals(function() {
		return intersected.equals({ x: 170.5, y: 280.5, width: 9.5, height: 9.5 });
	}, true);
});

test('unite(rect)', function() {
	var rect1 = new Rectangle({ x: 160, y: 270, width: 20, height: 20 });
	var rect2 = { x: 170.5, y: 280.5, width: 19, height: 19 };
	var united = rect1.unite(rect2);
	equals(function() {
		return united.equals({ x: 160, y: 270, width: 29.5, height: 29.5 });
	}, true);
});

test('include(point)', function() {
	var rect1 = new Rectangle({ x: 95, y: 151, width: 20, height: 20 });
	var included = rect1.include([50, 50]);
	equals(function() {
		return included.equals({ x: 50, y: 50, width: 65, height: 121 });
	}, true);
});

test('toString()', function() {
	var string = new Rectangle(10, 20, 30, 40).toString();
	equals(string, '{ x: 10, y: 20, width: 30, height: 40 }');
});

test('new Rectangle(object)', function() {
	equals(function() {
		return new Rectangle({
			center: [50, 100],
			size: [100, 200]
		}).toString();
	}, '{ x: 0, y: 0, width: 100, height: 200 }');

	equals(function() {
		var rect = new Rectangle({
			topLeft: [100, 50],
			size: [100, 200]
		});
		rect.topLeft = [100, 50];
		rect.size = [100, 200];
		return rect.toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			size: [100, 200],
			topLeft: [100, 50]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			topRight: [200, 50],
			size: [100, 200]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			size: [100, 200],
			topRight: [200, 50]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			bottomRight: [200, 250],
			size: [100, 200]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			size: [100, 200],
			bottomRight: [200, 250]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			bottomLeft: [100, 250],
			size: [100, 200]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			size: [100, 200],
			bottomLeft: [100, 250]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			topRight: [200, 50],
			bottomLeft: [100, 250]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			topLeft: [100, 50],
			bottomRight: [200, 250]
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');

	equals(function() {
		return new Rectangle({
			top: 50,
			right: 200,
			bottom: 250,
			left: 100
		}).toString();
	}, '{ x: 100, y: 50, width: 100, height: 200 }');
});
<|endoftext|>


<commit_before>function onError(callback) {
  var tryCount = 0;
  var retryLimit = 2;
  return function(jqXHR, textStatus) {
    if (++tryCount < retryLimit) $.ajax(this);
    else callback(textStatus);
  };
}

app.get.byURNs = function(urns, callback) {
  if (!urns.length) return callback(null);
  $.ajax({
    dataType: 'json',
    url: '/api/schools',
    data: {
      urns: urns.join(',')
    },
    success: function(json) {
      callback(null, json.results, json);
    },
    error: onError(callback)
  });
};

app.get.byLocation = function(location, options, callback) {
  $.ajax({
    dataType: 'json',
    url: '/api/schools/near',
    data: {
      lng: location[0],
      lat: location[1],
      limit: options.limit,
      distance: options.distance
    },
    success: function(json) {
      callback(null, json.results, json);
    },
    error: onError(callback)
  });
};

app.get.postcode = function(postcode, callback) {
  postcode = postcode.replace(/\s+/g,'').toUpperCase();
  $.ajax({
    url: 'https://maps.googleapis.com/maps/api/geocode/json',
    dataType: 'json',
    data: {
      address: postcode,
      components: 'country:UK',
      region: 'uk',
      sensor: 'false'
    },
    success: function(json) {
      try {
        var location = json.results[0].geometry.location;
        callback(null, [location.lng, location.lat]);
      } catch(e) {
        callback(e);
      }
    },
    error: onError(callback)
  });
};<commit_msg>Remove "sensor" field from Google Maps querystring<commit_after>function onError(callback) {
  var tryCount = 0;
  var retryLimit = 2;
  return function(jqXHR, textStatus) {
    if (++tryCount < retryLimit) $.ajax(this);
    else callback(textStatus);
  };
}

app.get.byURNs = function(urns, callback) {
  if (!urns.length) return callback(null);
  $.ajax({
    dataType: 'json',
    url: '/api/schools',
    data: {
      urns: urns.join(',')
    },
    success: function(json) {
      callback(null, json.results, json);
    },
    error: onError(callback)
  });
};

app.get.byLocation = function(location, options, callback) {
  $.ajax({
    dataType: 'json',
    url: '/api/schools/near',
    data: {
      lng: location[0],
      lat: location[1],
      limit: options.limit,
      distance: options.distance
    },
    success: function(json) {
      callback(null, json.results, json);
    },
    error: onError(callback)
  });
};

app.get.postcode = function(postcode, callback) {
  postcode = postcode.replace(/\s+/g,'').toUpperCase();
  $.ajax({
    url: 'https://maps.googleapis.com/maps/api/geocode/json',
    dataType: 'json',
    data: {
      address: postcode,
      components: 'country:UK',
      region: 'uk'
    },
    success: function(json) {
      try {
        var location = json.results[0].geometry.location;
        callback(null, [location.lng, location.lat]);
      } catch(e) {
        callback(e);
      }
    },
    error: onError(callback)
  });
};<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 */

/**
 * A replacement for instanceof which includes an error warning when multi-realm
 * constructors are detected.
 */
declare function instanceOf(
  value: mixed,
  constructor: mixed,
): boolean %checks(value instanceof constructor);

export default (process && process.env.NODE_ENV !== 'production'
  ? // eslint-disable-next-line no-shadow
    function instanceOf(value: any, constructor: any) {
      if (value instanceof constructor) {
        return true;
      }
      if (value) {
        const valueClass = value.constructor;
        const className = constructor.name;
        if (valueClass && valueClass.name === className) {
          throw new Error(
            `Cannot use ${className} "${value}" from another module or realm.

Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.

https://yarnpkg.com/en/docs/selective-version-resolutions

Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.`,
          );
        }
      }
      return false;
    }
  : // eslint-disable-next-line no-shadow
    function instanceOf(value: any, constructor: any) {
      return value instanceof constructor;
    });
<commit_msg>Remove spurious reference to `process`.<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 */

/**
 * A replacement for instanceof which includes an error warning when multi-realm
 * constructors are detected.
 */
declare function instanceOf(
  value: mixed,
  constructor: mixed,
): boolean %checks(value instanceof constructor);

// See: https://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production
// See: https://webpack.js.org/guides/production/
export default (process.env.NODE_ENV === 'production'
  ? // eslint-disable-next-line no-shadow
    function instanceOf(value: any, constructor: any) {
      return value instanceof constructor;
    }
  : // eslint-disable-next-line no-shadow
    function instanceOf(value: any, constructor: any) {
      if (value instanceof constructor) {
        return true;
      }
      if (value) {
        const valueClass = value.constructor;
        const className = constructor.name;
        if (valueClass && valueClass.name === className) {
          throw new Error(
            `Cannot use ${className} "${value}" from another module or realm.

Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.

https://yarnpkg.com/en/docs/selective-version-resolutions

Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.`,
          );
        }
      }
      return false;
    });
<|endoftext|>


<commit_before>
function RestRoutingViewModel() {
    var self = this;

    self.available_method    = ko.observableArray(['GET',
                                                   'POST',
                                                   'PUT',
                                                   'DELETE',
                                                   'OPTIONS',
                                                   'HEAD',
                                                   'TRACE'
                                                  ]);
    self.method              = ko.observable();
    self.address             = ko.observable();
    self.format              = ko.observable();
    self.field_list          = ko.observableArray();
    self.field_edit          = ko.observable();
    self.field_selected      = ko.observable();
    self.content             = ko.observable();

    self.return_code         = ko.observable();
    self.return_content_type = ko.observable();
    self.content_length      = ko.observable();
    self.all_headers         = ko.observableArray();
    self.answer              = ko.observable();

    self.can_send = function() {
        if (self.address() === undefined) {
            return false;
        }
        return _.isEmpty(self.address().trim()) === false;
    };

    self.is_add_available = function() {
        return true;
    };

    self.is_remove_available = function() {
        return true;
    };

    self.remove_field = function() {
        var selected = self.field_selected();
        if (selected === undefined) {
            return report_error('No field was selected to be removed');
        }

        if (! _.isEmpty(selected.trim())) {
            if (_.indexOf(self.field_list(), selected) > -1) {
              self.field_list.remove(selected);
            } else {
                report_error('Unable to find selected field to remove');
            }
        } else {
            report_error('The selected field to be removed is empty');
        }

    };

    self.add_field = function() {
        var field = self.field_edit();
        if (field === undefined) {
            return report_error('Field Edit is empty');
        }
        if (! _.isEmpty(field.trim())) {
            if (_.indexOf(self.field_list(), field) === -1) {
                self.field_list.push(field);
            } else {
                report_error('Field alreay exists in the list');
            }
        } else {
            report_error('The field to be added is empty');
        }
    };

    self.execRest = function() {
        var params = {method: self.method(),
                      address: self.address(),
                      format: self.format() || '',
                      content: self.content() || ''};
        $.post('/request', params).
            done(function(data, req_status, req_obj) {
                if (_.has(data, 'return_code')) {
                    self.return_code(data.return_code);
                }

                if (_.has(data, 'content_type')) {
                    self.return_content_type(data.content_type);
                }

                if (_.has(data, 'body')) {
                    self.answer(data.body);
                }

                if (_.has(data, 'content_length')) {
                    self.content_length(data.content_length);
                }

                if (_.has(data, 'all_headers')) {
                    self.all_headers(data.all_headers);
                }

            }).
        error(function(){
            console.log(arguments.length);
        });

    };
}

var rest_client;
$(function(){
    rest_client = new RestRoutingViewModel();
    ko.applyBindings(rest_client);
});
<commit_msg>disabeling add and remove buttons<commit_after>
function RestRoutingViewModel() {
    var self = this;

    self.available_method    = ko.observableArray(['GET',
                                                   'POST',
                                                   'PUT',
                                                   'DELETE',
                                                   'OPTIONS',
                                                   'HEAD',
                                                   'TRACE'
                                                  ]);
    self.method              = ko.observable();
    self.address             = ko.observable();
    self.format              = ko.observable();
    self.field_list          = ko.observableArray();
    self.field_edit          = ko.observable();
    self.field_selected      = ko.observable();
    self.content             = ko.observable();

    self.return_code         = ko.observable();
    self.return_content_type = ko.observable();
    self.content_length      = ko.observable();
    self.all_headers         = ko.observableArray();
    self.answer              = ko.observable();

    self.can_send = function() {
        if (self.address() === undefined) {
            return false;
        }
        return _.isEmpty(self.address().trim()) === false;
    };

    self.is_add_available = function() {
        var field = self.field_edit();
        return field !== undefined && _.indexOf(self.field_list(), field) === -1;
    };

    self.is_remove_available = function() {
        var selected = self.field_selected();
        return selected !== undefined && _.indexOf(self.field_list(), selected) > -1;
    };

    self.remove_field = function() {
        var selected = self.field_selected();
        if (selected === undefined) {
            return report_error('No field was selected to be removed');
        }

        if (! _.isEmpty(selected.trim())) {
            if (_.indexOf(self.field_list(), selected) > -1) {
              self.field_list.remove(selected);
            } else {
                report_error('Unable to find selected field to remove');
            }
        } else {
            report_error('The selected field to be removed is empty');
        }

    };

    self.add_field = function() {
        var field = self.field_edit();
        if (field === undefined) {
            return report_error('Field Edit is empty');
        }
        if (! _.isEmpty(field.trim())) {
            if (_.indexOf(self.field_list(), field) === -1) {
                self.field_list.push(field);
            } else {
                report_error('Field alreay exists in the list');
            }
        } else {
            report_error('The field to be added is empty');
        }
    };

    self.execRest = function() {
        var params = {method: self.method(),
                      address: self.address(),
                      format: self.format() || '',
                      content: self.content() || ''};
        $.post('/request', params).
            done(function(data, req_status, req_obj) {
                if (_.has(data, 'return_code')) {
                    self.return_code(data.return_code);
                }

                if (_.has(data, 'content_type')) {
                    self.return_content_type(data.content_type);
                }

                if (_.has(data, 'body')) {
                    self.answer(data.body);
                }

                if (_.has(data, 'content_length')) {
                    self.content_length(data.content_length);
                }

                if (_.has(data, 'all_headers')) {
                    self.all_headers(data.all_headers);
                }

            }).
        error(function(){
            console.log(arguments.length);
        });

    };
}

var rest_client;
$(function(){
    rest_client = new RestRoutingViewModel();
    ko.applyBindings(rest_client);
});
<|endoftext|>


<commit_before>var successes = 0
var failures = 0
var convergenceCounts = []

$().ready(function(){
  $('#testFrame').height($(window).height() - $('.hud').height() -10)
  $('#testFrame').attr('src',location.href.substring(0, location.href.lastIndexOf("/")+1)+ 'index.html')
  setInterval(function(){
  	var v = $('#testFrame').contents().find('#firstConvergence').html()
  	if(v != ''){
  		console.log('experiment succeeded')
  		successes += 1
  		updateConvergenceCounts(v)
  		$('#testFrame').attr('src',location.href.substring(0, location.href.lastIndexOf("/")+1)+ 'index.html?' + new Date().getTime())
  		$('#successes').html(successes)
  		updatePerformance()
  	} else if(parseInt($('#testFrame').contents().find('#firstConvergence').html()) > 300){
  		failures += 1
  		updatePerformance()
  	}
  },10000)
})

function updatePerformance(){
	if(failures == 0){
		$('#successRate').html('100%')
	} else {
		$('#successRate').html(Math.floor(successes/failures * 10000)/100 + '%')
	}
}

function updateConvergenceCounts(newValue){
	convergenceCounts.push(newValue)
	if(convergenceCounts.length > 10){
		convergenceCounts.shift()
	}
	var totalConvergence = 0
	for(i = 0; i < convergenceCounts.length;i++){
		totalConvergence += parseInt(convergenceCounts[i])
	}
	$('#aveSucGen').html(totalConvergence / convergenceCounts.length )

	return
}<commit_msg>made testing less frequent so we stand a chance of seeing convergence.<commit_after>var successes = 0
var failures = 0
var convergenceCounts = []

$().ready(function(){
  $('#testFrame').height($(window).height() - $('.hud').height() -10)
  $('#testFrame').attr('src',location.href.substring(0, location.href.lastIndexOf("/")+1)+ 'index.html')
  setInterval(function(){
  	var v = $('#testFrame').contents().find('#firstConvergence').html()
  	if(v != ''){
  		console.log('experiment succeeded')
  		successes += 1
  		updateConvergenceCounts(v)
  		$('#testFrame').attr('src',location.href.substring(0, location.href.lastIndexOf("/")+1)+ 'index.html?' + new Date().getTime())
  		$('#successes').html(successes)
  		updatePerformance()
  	} else if(parseInt($('#testFrame').contents().find('#firstConvergence').html()) > 300){
  		failures += 1
  		updatePerformance()
  	}
  },60000)
})

function updatePerformance(){
	if(failures == 0){
		$('#successRate').html('100%')
	} else {
		$('#successRate').html(Math.floor(successes/failures * 10000)/100 + '%')
	}
}

function updateConvergenceCounts(newValue){
	convergenceCounts.push(newValue)
	if(convergenceCounts.length > 10){
		convergenceCounts.shift()
	}
	var totalConvergence = 0
	for(i = 0; i < convergenceCounts.length;i++){
		totalConvergence += parseInt(convergenceCounts[i])
	}
	$('#aveSucGen').html(totalConvergence / convergenceCounts.length )

	return
}<|endoftext|>


<commit_before>var nodeUrl = require("url");
//var RpcProtocol = require('../protocol/rpc-protocol.js');
var channel = require('../infrastructure/channel.js');
var uuid = require('node-uuid');
var RSVP = require('rsvp');
require('sexylog');
var handler = require('../infrastructure/handler.js');
var messages = require('../domain/messages.js');

var handlerMappings = {};
var serviceName;
var protocolName = 'rpc';
exports.getApi = function(name, transport) {
    serviceName = name;

    var api = {
        name: function() {
            return protocolName;
        },
        request: function(remoteServiceUrl, data, clientCallback) {
           var serviceRequest = nodeUrl.parse(remoteServiceUrl, true);
           var transChannel = transport.openChannel(serviceRequest.hostname, protocolName);
           var clientChannel = channel.create("client-api");
           var rpcProtocolClientHandler = clientHandler(remoteServiceUrl);
           clientChannel.rightHandler(rpcProtocolClientHandler);
           transChannel.handler(rpcProtocolClientHandler);

           var promise = new RSVP.Promise(function(resolve, reject) {
                var callback = function(event) {
                        if (! event) {
                            logger.warn('client-api promise failed check! calling promise.reject()');
                            reject(event);
                        } else {
                            logger.trace('promise calling promise.resolve() event.id=' + event.id);
                            resolve(event);
                        }
                };
                if (clientCallback) callback = clientCallback;
                clientChannel.leftConnection().listen(callback);
                clientChannel.leftConnection().send(data);
            });

            return promise;

        },
        handle: function(endpoint, callback) {
            logger.debug('[*** API ***] registering handler endpoint: ' + endpoint);
            handlerMappings[endpoint] = callback;
        },
        protocolHandler: function() {
            return {
                server: function() {
                    return serverHandler();
                },
                client: function(remoteServiceUrl) {
                    return clientHandler(remoteServiceUrl);
                }
            }
        }
    }
    return api;
}

function serverHandler() {

         var rpcProtocolHandler = handler.create('server-rpc', handlerMappings);

         var incomingMuonMessage;
         //

        // OUTGOING/DOWNSTREAM event handling protocol logic
         rpcProtocolHandler.outgoing(function(serverResponseData, accept, reject, route) {
                logger.debug("[*** PROTOCOL:SERVER:RPC ***] server rpc protocol outgoing requestData=%s", JSON.stringify(serverResponseData));
                 var serverResponse = {
                      status: 200,
                      body: messages.encode(serverResponseData),
                      content_type: "application/json"
                    };
                 var outboundMuonMessage = messages.muonMessage(serverResponse, serviceName, incomingMuonMessage.origin_service, "request.response");
                 logger.trace("[*** PROTOCOL:SERVER:RPC ***] rpc protocol outgoing muonMessage=" + JSON.stringify(outboundMuonMessage));
                accept(outboundMuonMessage);
         });

         // INCOMING/UPSTREAM  event handling protocol logic
         rpcProtocolHandler.incoming(function(msg, accept, reject, route) {
                incomingMuonMessage = msg;
                logger.info("[*** PROTOCOL:SERVER:RPC ***] rpc protocol incoming event id=" + incomingMuonMessage.id);
                logger.debug("[*** PROTOCOL:SERVER:RPC ***] rpc protocol incoming message=%s", JSON.stringify(incomingMuonMessage));
                logger.trace("[*** PROTOCOL:SERVER:RPC ***] rpc protocol incoming message type=%s", (typeof incomingMuonMessage));

                var payload = messages.decode(incomingMuonMessage.payload, incomingMuonMessage.content_type);
                logger.info("[*** PROTOCOL:SERVER:RPC ***] RPC payload =%s", JSON.stringify(payload));

                var endpoint = payload.url;
                payload.body = messages.decode(payload.body, payload.content_type)

                var handler = handlerMappings[endpoint];
                if (! handler) {
                    logger.warn('[*** PROTOCOL:SERVER:RPC ***] NO HANDLER FOUND FOR ENDPOINT: "' + endpoint + '" RETURN 404! event.id=' + incomingMuonMessage.id);
                    payload.status = 404
                    var return404msg = messages.resource404(incomingMuonMessage, payload);
                    reject(return404msg);
                } else {
                    logger.info('[*** PROTOCOL:SERVER:RPC ***] Handler found for endpoint "'+ endpoint + '" event.id=' + incomingMuonMessage.id);

                    route(payload, endpoint);

                }
         });
         return rpcProtocolHandler;

}

function clientHandler(remoteServiceUrl) {
        TIMEOUT_MS = 10000;
        var responseReceived = false;
         var rpcProtocolHandler = handler.create('client-rpc');
         var remoteService = nodeUrl.parse(remoteServiceUrl, true).hostname;

        // OUTGOING/DOWNSTREAM event handling protocol logic
         rpcProtocolHandler.outgoing(function(requestData, accept, reject, route) {
                logger.debug("[*** PROTOCOL:CLIENT:RPC ***] client rpc protocol outgoing requestData=%s", JSON.stringify(requestData));

                 var request = {
                      url: remoteServiceUrl,
                      body: messages.encode(requestData),
                      content_type: "application/json"
                    };
                 var muonMessage = messages.muonMessage(request, serviceName, remoteService, "request.made");
                 logger.trace("[*** PROTOCOL:CLIENT:RPC ***] client rpc protocol outgoing muonMessage=%s", JSON.stringify(muonMessage));
                accept(muonMessage);

                setTimeout(function () {
                    if (! responseReceived) {
                          logger.info('[*** PROTOCOL:CLIENT:RPC ***] timeout reached responding with timeout message');
                          var timeoutMsg = rpcMessage("timeout", remoteServiceUrl, {}, {status: 'timeout', message: 'rpc response timeout exceeded'});
                          reject(timeoutMsg);
                    }
                }, TIMEOUT_MS);
         });

         // INCOMING/UPSTREAM  event handling protocol logic
         rpcProtocolHandler.incoming(function(rpcResponse, accept, reject, route) {
                logger.info("[*** PROTOCOL:CLIENT:RPC ***] rpc protocol incoming event id=" + rpcResponse.id);
                logger.debug("[*** PROTOCOL:CLIENT:RPC ***] rpc protocol incoming message=%s", JSON.stringify(rpcResponse));
                responseReceived = true;
                var rpcMessage =  messages.decode(rpcResponse.payload, rpcResponse.content_type)
                if (rpcMessage.body != undefined) {
                    rpcMessage.body = messages.decode(rpcMessage.body, rpcMessage.content_type)
                }
             logger.info ("Sending the response payload " + rpcMessage)
                accept(rpcMessage);
         });
         //logger.trace('**** rpc proto: '+JSON.stringify(rpcProtocolHandler));
         return rpcProtocolHandler;

}

function rpcMessage(statusCode, url, body, error) {
    if (! body) body = {};
    if (! error) error = {};
    if (! statusCode)  {
        var error = new Error('rpcMessage() invalid status: "' + statusCode + '"');
        logger.error(error);
        throw error;
    }
    var rpcMsg = {
        body: body,
        statusCode: statusCode,
        url: url,
        error: error,
        endpoint: function() {
             return nodeUrl.parse(url, true).path;
        }
    }
    return rpcMsg;
}

function rpcRequest(statusCode, url, body, error) {
    if (! body) body = {};
    if (! error) error = {};
    if (! statusCode)  {
        var error = new Error('rpcMessage() invalid status: "' + statusCode + '"');
        logger.error(error);
        throw error;
    }
    var rpcMsg = {
        body: body,
        statusCode: statusCode,
        url: url,
        error: error,
        endpoint: function() {
             return nodeUrl.parse(url, true).path;
        }
    }
    return rpcMsg;
}
<commit_msg>changed statusCode in rpc timeout message to status<commit_after>var nodeUrl = require("url");
//var RpcProtocol = require('../protocol/rpc-protocol.js');
var channel = require('../infrastructure/channel.js');
var uuid = require('node-uuid');
var RSVP = require('rsvp');
require('sexylog');
var handler = require('../infrastructure/handler.js');
var messages = require('../domain/messages.js');

var handlerMappings = {};
var serviceName;
var protocolName = 'rpc';
exports.getApi = function(name, transport) {
    serviceName = name;

    var api = {
        name: function() {
            return protocolName;
        },
        request: function(remoteServiceUrl, data, clientCallback) {
           var serviceRequest = nodeUrl.parse(remoteServiceUrl, true);
           var transChannel = transport.openChannel(serviceRequest.hostname, protocolName);
           var clientChannel = channel.create("client-api");
           var rpcProtocolClientHandler = clientHandler(remoteServiceUrl);
           clientChannel.rightHandler(rpcProtocolClientHandler);
           transChannel.handler(rpcProtocolClientHandler);

           var promise = new RSVP.Promise(function(resolve, reject) {
                var callback = function(event) {
                        if (! event) {
                            logger.warn('client-api promise failed check! calling promise.reject()');
                            reject(event);
                        } else {
                            logger.trace('promise calling promise.resolve() event.id=' + event.id);
                            resolve(event);
                        }
                };
                if (clientCallback) callback = clientCallback;
                clientChannel.leftConnection().listen(callback);
                clientChannel.leftConnection().send(data);
            });

            return promise;

        },
        handle: function(endpoint, callback) {
            logger.debug('[*** API ***] registering handler endpoint: ' + endpoint);
            handlerMappings[endpoint] = callback;
        },
        protocolHandler: function() {
            return {
                server: function() {
                    return serverHandler();
                },
                client: function(remoteServiceUrl) {
                    return clientHandler(remoteServiceUrl);
                }
            }
        }
    }
    return api;
}

function serverHandler() {

         var rpcProtocolHandler = handler.create('server-rpc', handlerMappings);

         var incomingMuonMessage;
         //

        // OUTGOING/DOWNSTREAM event handling protocol logic
         rpcProtocolHandler.outgoing(function(serverResponseData, accept, reject, route) {
                logger.debug("[*** PROTOCOL:SERVER:RPC ***] server rpc protocol outgoing requestData=%s", JSON.stringify(serverResponseData));
                 var serverResponse = {
                      status: 200,
                      body: messages.encode(serverResponseData),
                      content_type: "application/json"
                    };
                 var outboundMuonMessage = messages.muonMessage(serverResponse, serviceName, incomingMuonMessage.origin_service, "request.response");
                 logger.trace("[*** PROTOCOL:SERVER:RPC ***] rpc protocol outgoing muonMessage=" + JSON.stringify(outboundMuonMessage));
                accept(outboundMuonMessage);
         });

         // INCOMING/UPSTREAM  event handling protocol logic
         rpcProtocolHandler.incoming(function(msg, accept, reject, route) {
                incomingMuonMessage = msg;
                logger.info("[*** PROTOCOL:SERVER:RPC ***] rpc protocol incoming event id=" + incomingMuonMessage.id);
                logger.debug("[*** PROTOCOL:SERVER:RPC ***] rpc protocol incoming message=%s", JSON.stringify(incomingMuonMessage));
                logger.trace("[*** PROTOCOL:SERVER:RPC ***] rpc protocol incoming message type=%s", (typeof incomingMuonMessage));

                var payload = messages.decode(incomingMuonMessage.payload, incomingMuonMessage.content_type);
                logger.info("[*** PROTOCOL:SERVER:RPC ***] RPC payload =%s", JSON.stringify(payload));

                var endpoint = payload.url;
                payload.body = messages.decode(payload.body, payload.content_type)

                var handler = handlerMappings[endpoint];
                if (! handler) {
                    logger.warn('[*** PROTOCOL:SERVER:RPC ***] NO HANDLER FOUND FOR ENDPOINT: "' + endpoint + '" RETURN 404! event.id=' + incomingMuonMessage.id);
                    payload.status = 404
                    var return404msg = messages.resource404(incomingMuonMessage, payload);
                    reject(return404msg);
                } else {
                    logger.info('[*** PROTOCOL:SERVER:RPC ***] Handler found for endpoint "'+ endpoint + '" event.id=' + incomingMuonMessage.id);

                    route(payload, endpoint);

                }
         });
         return rpcProtocolHandler;

}

function clientHandler(remoteServiceUrl) {
        TIMEOUT_MS = 10000;
        var responseReceived = false;
         var rpcProtocolHandler = handler.create('client-rpc');
         var remoteService = nodeUrl.parse(remoteServiceUrl, true).hostname;

        // OUTGOING/DOWNSTREAM event handling protocol logic
         rpcProtocolHandler.outgoing(function(requestData, accept, reject, route) {
                logger.debug("[*** PROTOCOL:CLIENT:RPC ***] client rpc protocol outgoing requestData=%s", JSON.stringify(requestData));

                 var request = {
                      url: remoteServiceUrl,
                      body: messages.encode(requestData),
                      content_type: "application/json"
                    };
                 var muonMessage = messages.muonMessage(request, serviceName, remoteService, "request.made");
                 logger.trace("[*** PROTOCOL:CLIENT:RPC ***] client rpc protocol outgoing muonMessage=%s", JSON.stringify(muonMessage));
                accept(muonMessage);

                setTimeout(function () {
                    if (! responseReceived) {
                          logger.info('[*** PROTOCOL:CLIENT:RPC ***] timeout reached responding with timeout message');
                          var timeoutMsg = rpcMessage("timeout", remoteServiceUrl, {}, {status: 'timeout', body: 'rpc response timeout exceeded'});
                          reject(timeoutMsg);
                    }
                }, TIMEOUT_MS);
         });

         // INCOMING/UPSTREAM  event handling protocol logic
         rpcProtocolHandler.incoming(function(rpcResponse, accept, reject, route) {
                logger.info("[*** PROTOCOL:CLIENT:RPC ***] rpc protocol incoming event id=" + rpcResponse.id);
                logger.debug("[*** PROTOCOL:CLIENT:RPC ***] rpc protocol incoming message=%s", JSON.stringify(rpcResponse));
                responseReceived = true;
                var rpcMessage =  messages.decode(rpcResponse.payload, rpcResponse.content_type)
                if (rpcMessage.body != undefined) {
                    rpcMessage.body = messages.decode(rpcMessage.body, rpcMessage.content_type)
                }
             logger.info ("Sending the response payload " + rpcMessage)
                accept(rpcMessage);
         });
         //logger.trace('**** rpc proto: '+JSON.stringify(rpcProtocolHandler));
         return rpcProtocolHandler;

}

function rpcMessage(statusCode, url, body, error) {
    if (! body) body = {};
    if (! error) error = {};
    if (! statusCode)  {
        var error = new Error('rpcMessage() invalid status: "' + statusCode + '"');
        logger.error(error);
        throw error;
    }
    var rpcMsg = {
        body: body,
        status: statusCode,
        url: url,
        error: error,
        endpoint: function() {
             return nodeUrl.parse(url, true).path;
        }
    }
    return rpcMsg;
}

function rpcRequest(statusCode, url, body, error) {
    if (! body) body = {};
    if (! error) error = {};
    if (! statusCode)  {
        var error = new Error('rpcMessage() invalid status: "' + statusCode + '"');
        logger.error(error);
        throw error;
    }
    var rpcMsg = {
        body: body,
        status: statusCode,
        url: url,
        error: error,
        endpoint: function() {
             return nodeUrl.parse(url, true).path;
        }
    }
    return rpcMsg;
}
<|endoftext|>