<commit_before>'use strict';

var app = app || {};

(function(module){
  // BEFORE SHOW QUERY
  // Populate cloud tags from database.

  // Helped Function to make onlclick event work for Handlebar populated li's
  // Referenced from: http://jsfiddle.net/fHycd/
  Handlebars.registerHelper('stringifyFunc', function(func) {
       return new Handlebars.SafeString("(" +
                  func.toString().replace(/\"/g,"'") + ")()");
  });

  module.populateGenres = (genres) => {
    genres.forEach((genre) => {
      genre.func = function(){
        $(this.event.target).addClass('selected');
      }
      var genreTemplate = Handlebars.compile($('#genre-cloud-template').html());
      $('#genreCloud').append(genreTemplate(genre));
    });
  }

  module.populateDays = (days) => {
    days.forEach((day) => {
      day.func = function(){
        $(this.event.target).addClass('selected');
      }
      var dayTemplate = Handlebars.compile($('#day-cloud-template').html());
      $('#dayCloud').append(dayTemplate(day));
    });
  }

  module.populateTimes = (times) => {
    times.forEach((time) => {
      time.func = function(){
        $(this.event.target).addClass('selected');
      }
      var timeTemplate = Handlebars.compile($('#time-cloud-template').html());
      $('#timeCloud').append(timeTemplate(time));
    });
  }

  module.packagePreferences = function(){
    var genreArray = [];
    var timeArray = [];
    var dayArray = [];
    // console.log($('li.selected.genre'));
    $.each($('li.selected.genre'), function(index, genre){
      genreArray.push(genre.value);
    });
    $.each($('li.selected.time'), function(index, time){
      timeArray.push(time.value);
    });
    $.each($('li.selected.day'), function(index, day){
      dayArray.push(day.value);
    });
    return {user_id: 1, days: dayArray, times: timeArray, genres: genreArray};
  }

  // After submit, show data in homeview template.
  module.populateResults = function(shows){
    shows.forEach(function(show){
      var resultsTemplate = Handlebars.compile($('#results-template').html());
      var html = resultsTemplate(show);
      $('#results ul').append(html);
    });
  }
})(app);
<commit_msg>Made selected class toggle<commit_after>'use strict';

var app = app || {};

(function(module){
  // BEFORE SHOW QUERY
  // Populate cloud tags from database.

  // Helped Function to make onlclick event work for Handlebar populated li's
  // Referenced from: http://jsfiddle.net/fHycd/
  Handlebars.registerHelper('stringifyFunc', function(func) {
       return new Handlebars.SafeString("(" +
                  func.toString().replace(/\"/g,"'") + ")()");
  });

  module.populateGenres = (genres) => {
    genres.forEach((genre) => {
      genre.func = function(){
        $(this.event.target).toggleClass('selected');
      }
      var genreTemplate = Handlebars.compile($('#genre-cloud-template').html());
      $('#genreCloud').append(genreTemplate(genre));
    });
  }

  module.populateDays = (days) => {
    days.forEach((day) => {
      day.func = function(){
        $(this.event.target).toggleClass('selected');
      }
      var dayTemplate = Handlebars.compile($('#day-cloud-template').html());
      $('#dayCloud').append(dayTemplate(day));
    });
  }

  module.populateTimes = (times) => {
    times.forEach((time) => {
      time.func = function(){
        $(this.event.target).toggleClass('selected');
      }
      var timeTemplate = Handlebars.compile($('#time-cloud-template').html());
      $('#timeCloud').append(timeTemplate(time));
    });
  }

  module.packagePreferences = function(){
    var genreArray = [];
    var timeArray = [];
    var dayArray = [];
    // console.log($('li.selected.genre'));
    $.each($('li.selected.genre'), function(index, genre){
      genreArray.push(genre.value);
    });
    $.each($('li.selected.time'), function(index, time){
      timeArray.push(time.value);
    });
    $.each($('li.selected.day'), function(index, day){
      dayArray.push(day.value);
    });
    return {user_id: 1, days: dayArray, times: timeArray, genres: genreArray};
  }

  // After submit, show data in homeview template.
  module.populateResults = function(shows){
    shows.forEach(function(show){
      var resultsTemplate = Handlebars.compile($('#results-template').html());
      var html = resultsTemplate(show);
      $('#results ul').append(html);
    });
  }
})(app);
<|endoftext|>


<commit_before>(function () {
    var app = angular.module('TimerApp', ['ngResource', 'ngMessages', 'ngRoute', 'ngcrea.ngStrap',
                                         'main-controller', 'countdown-directive']);

    app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
        $locationProvider.html5Mode(true);

        $routeProvider
            .when('/', {
                templateUrl: 'public/views/home.html',
                controller: 'MainController'
            })
            .otherwise({
                redirectTo: '/'
            });
    }]);
})();
<commit_msg>typo in app<commit_after>(function () {
    var app = angular.module('TimerApp', ['ngResource', 'ngMessages', 'ngRoute', 'mgcrea.ngStrap',
                                         'main-controller', 'countdown-directive']);

    app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
        $locationProvider.html5Mode(true);

        $routeProvider
            .when('/', {
                templateUrl: 'public/views/home.html',
                controller: 'MainController'
            })
            .otherwise({
                redirectTo: '/'
            });
    }]);
})();
<|endoftext|>


<commit_before>/**
 * Created by Dima on 17.02.2016.
 */

function something()
{
    var x = window.localStorage.getItem('aaa');

    window.localStorage.setItem('aaa', 555);

    alert(x);
}<commit_msg>Keep x variable in localStorage<commit_after>/**
 * Created by Dima on 17.02.2016.
 */

function something()
{
    var x = window.localStorage.getItem('bbb');
    x = x*1 + 1
    window.localStorage.setItem('bbb', x);

    alert(x);
}<|endoftext|>


<commit_before>var module = angular.module('BrainDumpApp', ['ngResource', 'textAngular', 'braindump.notebooks', 'braindump.notes']);

module.controller('AppController', [ '$scope', 'NotebookService', 'NoteService', function($scope, NotebookService, NoteService) {

	$scope.createNote = function() {
		if (NotebookService.selectedNotebook != null) {
			NoteService.createNote(NotebookService.selectedNotebook);
		}
	}

}]);

module.controller('NotebookListController', ['$scope', '$rootScope', 'NotebookService', function($scope, $rootScope, NotebookService) {

	$scope.$on('notebooks.load', function(event) {
		$scope.notebooks = NotebookService.notebooks;
		$scope.selectNotebook($scope.notebooks[0]);
	});

	$scope.$on('notebooks.create', function(event, book) {
		$scope.notebooks = NotebookService.notebooks;
		$scope.selectNotebook(book);
		$scope.notebookForm.$setPristine();
	});

	$scope.$on('notes.delete', function(event, book) {
		NotebookService.selectedNotebook.noteCount--;
	});

	$scope.init = function() {
		NotebookService.getList();
	}

	$scope.selectNotebook = function(book) {
		NotebookService.selectedNotebook = book;
		$rootScope.$broadcast('notebooks.select', book);
	}

	$scope.addNotebook = function() {
		NotebookService.addNotebook($scope.newNotebook);
	};

	$scope.deleteNotebook = function(book) {
		NotebookService.deleteNotebook(book);
	}

	$scope.notebooks = NotebookService.notebooks;
	$scope.newNotebook = {};

}]);

module.controller('NoteListController', ['$scope', '$rootScope', 'NoteService', function($scope, $rootScope, NoteService) {

	$scope.$on('notebooks.select', function(event, book) {
		$scope.selectedNotebook = book;
		NoteService.getList(book);
	});

	$scope.$on('notes.load', function(event) {
		$scope.notes = NoteService.notes;
		if ($scope.notes.length > 0) {
			$scope.selectNote($scope.notes[0]);
		}
	});

	$scope.$on('notes.delete', function(event, note) {
		console.log(1);
		$scope.notes.splice($scope.notes.indexOf(note), 1);

		if (NoteService.selectedNote == note) {
			console.log(2);
			$scope.selectNote($scope.notes[0]);
		}
	});

	$scope.selectNote = function(note) {
		NoteService.selectedNote = note;
		$rootScope.$broadcast('notes.select', note);
	}

	$scope.selectedNotebook = null;
	$scope.notes = NoteService.notes;

}]);

module.controller('NoteDetailController', ['$scope', 'NoteService', function($scope, NoteService) {

	$scope.$on('notebooks.select', function(event, book) {
		$scope.note = null;
		$scope.noteForm.$setPristine();
	});

	$scope.$on('notes.select', function(event, note) {
		note.$get(function() {
			$scope.note = note;
			// doesn't work. Why? Is note a future?
			$scope.noteForm.$setPristine();
		});
	});

	$scope.$on('notes.created', function(event, note) {
		$scope.note = note;
	});

	$scope.$on('notes.update', function(event) {
		$scope.noteForm.$setPristine();
	});

	$scope.saveNote = function(note) {
		NoteService.saveNote(note);
	}

	$scope.deleteNote = function(note) {
		NoteService.deleteNote(note);
	};

}]);<commit_msg>Removed comment<commit_after>var module = angular.module('BrainDumpApp', ['ngResource', 'textAngular', 'braindump.notebooks', 'braindump.notes']);

module.controller('AppController', [ '$scope', 'NotebookService', 'NoteService', function($scope, NotebookService, NoteService) {

	$scope.createNote = function() {
		if (NotebookService.selectedNotebook != null) {
			NoteService.createNote(NotebookService.selectedNotebook);
		}
	}

}]);

module.controller('NotebookListController', ['$scope', '$rootScope', 'NotebookService', function($scope, $rootScope, NotebookService) {

	$scope.$on('notebooks.load', function(event) {
		$scope.notebooks = NotebookService.notebooks;
		$scope.selectNotebook($scope.notebooks[0]);
	});

	$scope.$on('notebooks.create', function(event, book) {
		$scope.notebooks = NotebookService.notebooks;
		$scope.selectNotebook(book);
		$scope.newNotebook = {};
		$scope.notebookForm.$setPristine();
	});

	$scope.$on('notes.delete', function(event, book) {
		NotebookService.selectedNotebook.noteCount--;
	});

	$scope.init = function() {
		NotebookService.getList();
	}

	$scope.selectNotebook = function(book) {
		if (NotebookService.selectedNotebook) {
			NotebookService.selectedNotebook.class = '';
		}
		book.class = 'active';
		NotebookService.selectedNotebook = book;

		$rootScope.$broadcast('notebooks.select', book);
	}

	$scope.addNotebook = function() {
		NotebookService.addNotebook($scope.newNotebook);
	};

	$scope.deleteNotebook = function(book) {
		NotebookService.deleteNotebook(book);
	}

	$scope.notebooks = NotebookService.notebooks;
	$scope.newNotebook = {};

}]);

module.controller('NoteListController', ['$scope', '$rootScope', 'NoteService', function($scope, $rootScope, NoteService) {

	$scope.$on('notebooks.select', function(event, book) {
		$scope.selectedNotebook = book;
		NoteService.getList(book);
	});

	$scope.$on('notes.load', function(event) {
		$scope.notes = NoteService.notes;
		if ($scope.notes.length > 0) {
			$scope.selectNote($scope.notes[0]);
		}
	});

	$scope.$on('notes.delete', function(event, note) {
		$scope.notes.splice($scope.notes.indexOf(note), 1);

		if (NoteService.selectedNote == note) {
			$scope.selectNote($scope.notes[0]);
		}
	});

	$scope.selectNote = function(note) {

		if (NoteService.selectedNote) {
			NoteService.selectedNote.class = '';
		}
		note.class = 'active';
		NoteService.selectedNote = note;

		$rootScope.$broadcast('notes.select', note);
	}

	$scope.selectedNotebook = null;
	$scope.notes = NoteService.notes;

}]);

module.controller('NoteDetailController', ['$scope', 'NoteService', function($scope, NoteService) {

	$scope.$on('notebooks.select', function(event, book) {
		$scope.note = null;
		$scope.noteForm.$setPristine();
	});

	$scope.$on('notes.select', function(event, note) {
		note.$get(function() {
			$scope.note = note;
			// bad hack as active class is stored note object
			note.class = 'active';
			// doesn't work. Why? Is note a future?
			$scope.noteForm.$setPristine();
		});
	});

	$scope.$on('notes.created', function(event, note) {
		$scope.note = note;
	});

	$scope.$on('notes.update', function(event) {
		$scope.noteForm.$setPristine();
	});

	$scope.saveNote = function(note) {
		NoteService.saveNote(note);
	}

	$scope.deleteNote = function(note) {
		NoteService.deleteNote(note);
	};

}]);<|endoftext|>


<commit_before>import { MultiSelectStateless } from '@atlaskit/multi-select';
import AKInlineDialog from '@atlaskit/inline-dialog';
import _debounce from 'lodash/debounce';
import PropTypes from 'prop-types';
import React, { Component } from 'react';

import InlineDialogFailure from './InlineDialogFailure';

const logger = require('jitsi-meet-logger').getLogger(__filename);

/**
 * A MultiSelect that is also auto-completing.
 */
class MultiSelectAutocomplete extends Component {

    /**
     * {@code MultiSelectAutocomplete} component's property types.
     *
     * @static
     */
    static propTypes = {
        /**
         * The default value of the selected item.
         */
        defaultValue: PropTypes.array,

        /**
         * Indicates if the component is disabled.
         */
        isDisabled: PropTypes.bool,

        /**
         * Text to display while a query is executing.
         */
        loadingMessage: PropTypes.string,

        /**
         * The text to show when no matches are found.
         */
        noMatchesFound: PropTypes.string,

        /**
         * The function called immediately before a selection has been actually
         * selected. Provides an opportunity to do any formatting.
         */
        onItemSelected: PropTypes.func,

        /**
         * The function called when the selection changes.
         */
        onSelectionChange: PropTypes.func,

        /**
         * The placeholder text of the input component.
         */
        placeholder: PropTypes.string,

        /**
         * The service providing the search.
         */
        resourceClient: PropTypes.shape({
            makeQuery: PropTypes.func,
            parseResults: PropTypes.func
        }).isRequired,

        /**
         * Indicates if the component should fit the container.
         */
        shouldFitContainer: PropTypes.bool,

        /**
         * Indicates if we should focus.
         */
        shouldFocus: PropTypes.bool
    };

    /**
     * Initializes a new {@code MultiSelectAutocomplete} instance.
     *
     * @param {Object} props - The read-only properties with which the new
     * instance is to be initialized.
     */
    constructor(props) {
        super(props);

        const defaultValue = this.props.defaultValue || [];

        this.state = {
            /**
             * Indicates if the dropdown is open.
             */
            isOpen: false,

            /**
             * The text that filters the query result of the search.
             */
            filterValue: '',

            /**
             * Indicates if the component is currently loading results.
             */
            loading: false,

            /**
             * Indicates if there was an error.
             */
            error: false,

            /**
             * The list of result items.
             */
            items: [],

            /**
             * The list of selected items.
             */
            selectedItems: [ ...defaultValue ]
        };

        this._onFilterChange = this._onFilterChange.bind(this);
        this._onRetry = this._onRetry.bind(this);
        this._onSelectionChange = this._onSelectionChange.bind(this);
        this._sendQuery = _debounce(this._sendQuery.bind(this), 200);
    }

    /**
     * Sets the items to display as selected.
     *
     * @param {Array<Object>} selectedItems - The list of items to display as
     * having been selected.
     * @returns {void}
     */
    setSelectedItems(selectedItems = []) {
        this.setState({ selectedItems });
    }

    /**
     * Renders the content of this component.
     *
     * @returns {ReactElement}
     */
    render() {
        const shouldFitContainer = this.props.shouldFitContainer || false;
        const shouldFocus = this.props.shouldFocus || false;
        const isDisabled = this.props.isDisabled || false;
        const placeholder = this.props.placeholder || '';
        const noMatchesFound = this.props.noMatchesFound || '';

        return (

                <MultiSelectStateless
                    filterValue = { this.state.filterValue }
                    isDisabled = { isDisabled }
                    isLoading = { this.state.loading }
                    isOpen = { this.state.isOpen }
                    items = { this.state.items }
                    loadingMessage = { this.props.loadingMessage }
                    noMatchesFound = { noMatchesFound }
                    onFilterChange = { this._onFilterChange }
                    onRemoved = { this._onSelectionChange }
                    onSelected = { this._onSelectionChange }
                    placeholder = { placeholder }
                    selectedItems = { this.state.selectedItems }
                    shouldFitContainer = { shouldFitContainer }
                    shouldFocus = { shouldFocus } />
                { this._renderError() }

        );
    }

    /**
     * Sets the state and sends a query on filter change.
     *
     * @param {string} filterValue - The filter text value.
     * @private
     * @returns {void}
     */
    _onFilterChange(filterValue) {
        this.setState({
            // Clean the error if the filterValue is empty.
            error: this.state.error && Boolean(filterValue),
            filterValue,
            isOpen: Boolean(this.state.items.length) && Boolean(filterValue),
            items: filterValue ? this.state.items : [],
            loading: Boolean(filterValue)
        });
        if (filterValue) {
            this._sendQuery(filterValue);
        }
    }

    /**
     * Retries the query on retry.
     *
     * @private
     * @returns {void}
     */
    _onRetry() {
        this._sendQuery(this.state.filterValue);
    }

    /**
     * Updates the selected items when a selection event occurs.
     *
     * @param {Object} item - The selected item.
     * @private
     * @returns {void}
     */
    _onSelectionChange(item) {
        const existing
            = this.state.selectedItems.find(k => k.value === item.value);
        let selectedItems = this.state.selectedItems;

        if (existing) {
            selectedItems = selectedItems.filter(k => k !== existing);
        } else {
            selectedItems.push(this.props.onItemSelected(item));
        }
        this.setState({
            isOpen: false,
            selectedItems
        });

        if (this.props.onSelectionChange) {
            this.props.onSelectionChange(selectedItems);
        }
    }

    /**
     * Renders the error UI.
     *
     * @returns {ReactElement|null}
     */
    _renderError() {
        if (!this.state.error) {
            return null;
        }
        const content = ( // eslint-disable-line no-extra-parens

                <InlineDialogFailure
                    onRetry = { this._onRetry } />

        );

        return (
            <AKInlineDialog
                content = { content }
                isOpen = { true } />
        );
    }

    /**
     * Sends a query to the resourceClient.
     *
     * @param {string} filterValue - The string to use for the search.
     * @returns {void}
     */
    _sendQuery(filterValue) {
        if (!filterValue) {
            return;
        }

        this.setState({
            error: false
        });

        const resourceClient = this.props.resourceClient || {
            makeQuery: () => Promise.resolve([]),
            parseResults: results => results
        };

        resourceClient.makeQuery(filterValue)
            .then(results => {
                if (this.state.filterValue !== filterValue) {
                    this.setState({
                        error: false
                    });

                    return;
                }
                const itemGroups = [
                    {
                        items: resourceClient.parseResults(results)
                    }
                ];

                this.setState({
                    items: itemGroups,
                    isOpen: true,
                    loading: false,
                    error: false
                });
            })
            .catch(error => {
                logger.error('MultiSelectAutocomplete error in query', error);

                this.setState({
                    error: true,
                    loading: false,
                    isOpen: false
                });
            });
    }
}

export default MultiSelectAutocomplete;
<commit_msg>fix(invite): do not show caret in input (#2774)<commit_after>import { MultiSelectStateless } from '@atlaskit/multi-select';
import AKInlineDialog from '@atlaskit/inline-dialog';
import _debounce from 'lodash/debounce';
import PropTypes from 'prop-types';
import React, { Component } from 'react';

import InlineDialogFailure from './InlineDialogFailure';

const logger = require('jitsi-meet-logger').getLogger(__filename);

/**
 * A MultiSelect that is also auto-completing.
 */
class MultiSelectAutocomplete extends Component {

    /**
     * {@code MultiSelectAutocomplete} component's property types.
     *
     * @static
     */
    static propTypes = {
        /**
         * The default value of the selected item.
         */
        defaultValue: PropTypes.array,

        /**
         * Indicates if the component is disabled.
         */
        isDisabled: PropTypes.bool,

        /**
         * Text to display while a query is executing.
         */
        loadingMessage: PropTypes.string,

        /**
         * The text to show when no matches are found.
         */
        noMatchesFound: PropTypes.string,

        /**
         * The function called immediately before a selection has been actually
         * selected. Provides an opportunity to do any formatting.
         */
        onItemSelected: PropTypes.func,

        /**
         * The function called when the selection changes.
         */
        onSelectionChange: PropTypes.func,

        /**
         * The placeholder text of the input component.
         */
        placeholder: PropTypes.string,

        /**
         * The service providing the search.
         */
        resourceClient: PropTypes.shape({
            makeQuery: PropTypes.func,
            parseResults: PropTypes.func
        }).isRequired,

        /**
         * Indicates if the component should fit the container.
         */
        shouldFitContainer: PropTypes.bool,

        /**
         * Indicates if we should focus.
         */
        shouldFocus: PropTypes.bool
    };

    /**
     * Initializes a new {@code MultiSelectAutocomplete} instance.
     *
     * @param {Object} props - The read-only properties with which the new
     * instance is to be initialized.
     */
    constructor(props) {
        super(props);

        const defaultValue = this.props.defaultValue || [];

        this.state = {
            /**
             * Indicates if the dropdown is open.
             */
            isOpen: false,

            /**
             * The text that filters the query result of the search.
             */
            filterValue: '',

            /**
             * Indicates if the component is currently loading results.
             */
            loading: false,

            /**
             * Indicates if there was an error.
             */
            error: false,

            /**
             * The list of result items.
             */
            items: [],

            /**
             * The list of selected items.
             */
            selectedItems: [ ...defaultValue ]
        };

        this._onFilterChange = this._onFilterChange.bind(this);
        this._onRetry = this._onRetry.bind(this);
        this._onSelectionChange = this._onSelectionChange.bind(this);
        this._sendQuery = _debounce(this._sendQuery.bind(this), 200);
    }

    /**
     * Sets the items to display as selected.
     *
     * @param {Array<Object>} selectedItems - The list of items to display as
     * having been selected.
     * @returns {void}
     */
    setSelectedItems(selectedItems = []) {
        this.setState({ selectedItems });
    }

    /**
     * Renders the content of this component.
     *
     * @returns {ReactElement}
     */
    render() {
        const shouldFitContainer = this.props.shouldFitContainer || false;
        const shouldFocus = this.props.shouldFocus || false;
        const isDisabled = this.props.isDisabled || false;
        const placeholder = this.props.placeholder || '';
        const noMatchesFound = this.props.noMatchesFound || '';

        return (

                <MultiSelectStateless
                    filterValue = { this.state.filterValue }
                    icon = { null }
                    isDisabled = { isDisabled }
                    isLoading = { this.state.loading }
                    isOpen = { this.state.isOpen }
                    items = { this.state.items }
                    loadingMessage = { this.props.loadingMessage }
                    noMatchesFound = { noMatchesFound }
                    onFilterChange = { this._onFilterChange }
                    onRemoved = { this._onSelectionChange }
                    onSelected = { this._onSelectionChange }
                    placeholder = { placeholder }
                    selectedItems = { this.state.selectedItems }
                    shouldFitContainer = { shouldFitContainer }
                    shouldFocus = { shouldFocus } />
                { this._renderError() }

        );
    }

    /**
     * Sets the state and sends a query on filter change.
     *
     * @param {string} filterValue - The filter text value.
     * @private
     * @returns {void}
     */
    _onFilterChange(filterValue) {
        this.setState({
            // Clean the error if the filterValue is empty.
            error: this.state.error && Boolean(filterValue),
            filterValue,
            isOpen: Boolean(this.state.items.length) && Boolean(filterValue),
            items: filterValue ? this.state.items : [],
            loading: Boolean(filterValue)
        });
        if (filterValue) {
            this._sendQuery(filterValue);
        }
    }

    /**
     * Retries the query on retry.
     *
     * @private
     * @returns {void}
     */
    _onRetry() {
        this._sendQuery(this.state.filterValue);
    }

    /**
     * Updates the selected items when a selection event occurs.
     *
     * @param {Object} item - The selected item.
     * @private
     * @returns {void}
     */
    _onSelectionChange(item) {
        const existing
            = this.state.selectedItems.find(k => k.value === item.value);
        let selectedItems = this.state.selectedItems;

        if (existing) {
            selectedItems = selectedItems.filter(k => k !== existing);
        } else {
            selectedItems.push(this.props.onItemSelected(item));
        }
        this.setState({
            isOpen: false,
            selectedItems
        });

        if (this.props.onSelectionChange) {
            this.props.onSelectionChange(selectedItems);
        }
    }

    /**
     * Renders the error UI.
     *
     * @returns {ReactElement|null}
     */
    _renderError() {
        if (!this.state.error) {
            return null;
        }
        const content = ( // eslint-disable-line no-extra-parens

                <InlineDialogFailure
                    onRetry = { this._onRetry } />

        );

        return (
            <AKInlineDialog
                content = { content }
                isOpen = { true } />
        );
    }

    /**
     * Sends a query to the resourceClient.
     *
     * @param {string} filterValue - The string to use for the search.
     * @returns {void}
     */
    _sendQuery(filterValue) {
        if (!filterValue) {
            return;
        }

        this.setState({
            error: false
        });

        const resourceClient = this.props.resourceClient || {
            makeQuery: () => Promise.resolve([]),
            parseResults: results => results
        };

        resourceClient.makeQuery(filterValue)
            .then(results => {
                if (this.state.filterValue !== filterValue) {
                    this.setState({
                        error: false
                    });

                    return;
                }
                const itemGroups = [
                    {
                        items: resourceClient.parseResults(results)
                    }
                ];

                this.setState({
                    items: itemGroups,
                    isOpen: true,
                    loading: false,
                    error: false
                });
            })
            .catch(error => {
                logger.error('MultiSelectAutocomplete error in query', error);

                this.setState({
                    error: true,
                    loading: false,
                    isOpen: false
                });
            });
    }
}

export default MultiSelectAutocomplete;
<|endoftext|>


<commit_before>/**
 * @module src/GetTranslationDraft
 *
 * Component that display GetTranslationDraft
 * Accepts the following properties:
 *  - source language: Which language you want to convert from
 *  - version : Version of source language
 *  - target language: In which tokens have been translated too
 *  - token words: token words showul be entered in the form of xls
*/

import React, { Component } from 'react';
import './App.css';
import Header from './Header';
import Footer from './Footer';
import { FormControl } from 'react-bootstrap';
import SourceLanguages from './SourceLanguages';
import TargetLanguages from './TargetLanguages';
import $ from 'jquery';
import GlobalURL from './GlobalURL';
import saveAs from 'save-as'
import Checkbox from './Checkbox';
import booksName1 from './BookName';
var JSZip = require("jszip");
var zip = new JSZip();

var tabData = [
  { name: 'Select Books', isActive: true }
];

class Tabs extends Component {
  render() {
    return (

        {tabData.map(function(tab, i){
          return (
            <Tab key={i} data={tab} isActive={this.props.activeTab === tab} handleClick={this.props.changeTab.bind(this,tab)} />
          );
        }.bind(this))}

    );
  }
}

class Tab extends Component{
  render() {
    return (

        {this.props.data.name}

    );
  }
}

class GetTranslationDraft extends Component {
  constructor(props) {
    super(props);
    this.state = {
      sourcelang:'Tamil',
      targetlang:'Malayalam',
      version: '',
      revision: '',
      bookName: '',
      books: [],
      uploaded:'Uploading',
      activeTab: tabData[0],
      activeTabValue: '',
      dataDisplay: 'Select Books'
    }

      // Upload file specific callback handlers
      this.uploadFile = this.uploadFile.bind(this);
      this.onSelect = this.onSelect.bind(this);
      this.exportToUSFMFile = this.exportToUSFMFile.bind(this);
      this.handleClick = this.handleClick.bind(this);

  }

    handleClick(tab){
    this.setState({
      activeTab: tab,
      dataDisplay: tab.name
    });
  }

  componentWillMount = () => {
    this.selectedCheckboxes1 = new Set();
  }

  toggleCheckbox1 = label => {
    if (this.selectedCheckboxes1.has(label)) {
      this.selectedCheckboxes1.delete(label);
    } else {
      this.selectedCheckboxes1.add(label);
    }
  }

  createCheckboxes1 = (obj) => (
    Object.keys(booksName1[0]).map(function(v, i){

      return (<Checkbox
            label={booksName1[0][v]}
            handleCheckboxChange={obj.toggleCheckbox1}
            bookCode={v}
    />)
    })

  )

  onSelect(e) {
    this.setState({
      [e.target.name]: e.target.value });
  }

  uploadFile(e){
    e.preventDefault();
    global.books = [];

    // eslint-disable-next-line
    for (const books of this.selectedCheckboxes1) {
      global.books = Array.from(this.selectedCheckboxes1);
    }

    var _this = this
    var data = {
            "sourcelang": this.state.sourcelang, "version": this.state.version, "revision": this.state.revision,  "targetlang": this.state.targetlang, "books": global.books
    }

    let accessToken = JSON.parse(window.localStorage.getItem('access_token'))
    $.ajax({
      url: GlobalURL["hostURL"]+"/v1/translations",
      contentType: "application/json; charset=utf-8",
      data : JSON.stringify(data),
      method : "POST",
      headers: {
                "Authorization": "bearer " + JSON.stringify(accessToken['access_token']).slice(1,-1)},
      beforeSend: function () {
          $(".modal").show();
      },
      complete: function () {
          $(".modal").hide();
      },
      success: function (result) {
         if (result.success !== false) {
          _this.exportToUSFMFile(result)
          _this.setState({message: result.message, uploaded: 'success'})
        }else {
          _this.setState({message: result.message, uploaded: 'failure'})
          }
      },
      error: function (error) {
        _this.setState({uploaded: 'failure'})
      }
    });

  }

  exportToUSFMFile(jsonData) {
    var _this = this;
    jsonData = JSON.parse(jsonData)
    let exportFileDefaultName = [];
    $.each(jsonData, function(key, value) {
      zip.file(key + '.usfm', value)
      exportFileDefaultName.push(key + '.usfm');
    });
    zip.generateAsync({type:"blob"})
      .then(function(content) {
          saveAs(content, _this.state.targetlang + '.zip');
      }, function(err){
         _this.setState({uploaded: 'failure'})
      })
  }

  render() {
    return(

          <form className="col-md-12 uploader" encType="multipart/form-data">

Download Translation Draft

                Translation Done Successfully !!!

                Failed to Translate Sources !!!

                <lable className="control-label Concord2">  Source Language  </lable>
                    <FormControl value={this.state.sourcelang} onChange={this.onSelect} name="sourcelang" componentClass="select" placeholder="select">
                      {SourceLanguages.map((sourcelang, i) => <option  key={i} value={sourcelang.value}>{sourcelang.value}</option>)}
                    </FormControl>
                 <lable className="control-lable Concord2">  Version  </lable>
                    <input value={this.state.version} onChange={this.onSelect} name="version" type="text"  placeholder="version" className="form-control"/>
                <lable className="control-lable Concord2">  Revision  </lable>
                    <input value={this.state.revision} onChange={this.onSelect} name="revision" type="text" placeholder="revision" className="form-control"/>
                <lable className="control-label Concord2">  Target Language  </lable>
                    <FormControl value={this.state.targetlang} onChange={this.onSelect} name="targetlang" componentClass="select" placeholder="select">
                      {TargetLanguages.map((targetlang, i) => <option  key={i} value={targetlang.value}>{targetlang.value}</option>)}
                    </FormControl>

                <Tabs activeTab={this.state.activeTab}  changeTab={this.handleClick}/>

{this.createCheckboxes1(this)}

                  <button id="btnGet" type="button" className="btn btn-success ConcordButton" onClick={this.uploadFile}>  Download Drafts </button>

          </form>

      );
    }
}

export default GetTranslationDraft;
<commit_msg>Added message dynamically as per response<commit_after>/**
 * @module src/GetTranslationDraft
 *
 * Component that display GetTranslationDraft
 * Accepts the following properties:
 *  - source language: Which language you want to convert from
 *  - version : Version of source language
 *  - target language: In which tokens have been translated too
 *  - token words: token words showul be entered in the form of xls
*/

import React, { Component } from 'react';
import './App.css';
import Header from './Header';
import Footer from './Footer';
import { FormControl } from 'react-bootstrap';
import SourceLanguages from './SourceLanguages';
import TargetLanguages from './TargetLanguages';
import $ from 'jquery';
import GlobalURL from './GlobalURL';
import saveAs from 'save-as'
import Checkbox from './Checkbox';
import booksName1 from './BookName';
var JSZip = require("jszip");
var zip;

var tabData = [
  { name: 'Select Books', isActive: true }
];

class Tabs extends Component {
  render() {
    return (

        {tabData.map(function(tab, i){
          return (
            <Tab key={i} data={tab} isActive={this.props.activeTab === tab} handleClick={this.props.changeTab.bind(this,tab)} />
          );
        }.bind(this))}

    );
  }
}

class Tab extends Component{
  render() {
    return (

        {this.props.data.name}

    );
  }
}

class GetTranslationDraft extends Component {
  constructor(props) {
    super(props);
    this.state = {
      sourcelang:'Tamil',
      targetlang:'Malayalam',
      version: '',
      revision: '',
      bookName: '',
      books: [],
      uploaded:'Uploading',
      activeTab: tabData[0],
      activeTabValue: ''
    }

      // Upload file specific callback handlers
      this.uploadFile = this.uploadFile.bind(this);
      this.onSelect = this.onSelect.bind(this);
      this.exportToUSFMFile = this.exportToUSFMFile.bind(this);
      this.handleClick = this.handleClick.bind(this);

  }

    handleClick(tab){
    this.setState({
      activeTab: tab
    });
  }

  componentWillMount = () => {
    this.selectedCheckboxes1 = new Set();
  }

  toggleCheckbox1 = label => {
    if (this.selectedCheckboxes1.has(label)) {
      this.selectedCheckboxes1.delete(label);
    } else {
      this.selectedCheckboxes1.add(label);
    }
  }

  createCheckboxes1 = (obj) => (
    Object.keys(booksName1[0]).map(function(v, i){

      return (<Checkbox
            label={booksName1[0][v]}
            handleCheckboxChange={obj.toggleCheckbox1}
            bookCode={v}
    />)
    })

  )

  onSelect(e) {
    this.setState({
      [e.target.name]: e.target.value });
  }

  uploadFile(e){
    e.preventDefault();
    global.books = [];

    // eslint-disable-next-line
    for (const books of this.selectedCheckboxes1) {
      global.books = Array.from(this.selectedCheckboxes1);
    }

    var _this = this
    var data = {
            "sourcelang": this.state.sourcelang, "version": this.state.version, "revision": this.state.revision,  "targetlang": this.state.targetlang, "books": global.books
    }

    let accessToken = JSON.parse(window.localStorage.getItem('access_token'))
    $.ajax({
      url: GlobalURL["hostURL"]+"/v1/translations",
      contentType: "application/json; charset=utf-8",
      data : JSON.stringify(data),
      method : "POST",
      headers: {
                "Authorization": "bearer " + JSON.stringify(accessToken['access_token']).slice(1,-1)},
      beforeSend: function () {
          $(".modal").show();
      },
      complete: function () {
          $(".modal").hide();
      },
      success: function (result) {
        result = JSON.parse(result)
         if (result.success !== false) {
          _this.exportToUSFMFile(result)
          _this.setState({message: result.message, uploaded: 'success'})
        }else {
          _this.setState({message: result.message, uploaded: 'failure'})
          }
      },
      error: function (error) {
        _this.setState({uploaded: 'failure'})
      }
    });

  }

  exportToUSFMFile(jsonData) {
    var _this = this;
    zip = new JSZip();
    $.each(jsonData, function(key, value) {
      zip.file(key + '.usfm', value)
    });
    zip.generateAsync({type:"blob"})
      .then(function(content) {
          saveAs(content, _this.state.targetlang + '.zip');
      }, function(err){
         _this.setState({uploaded: 'failure'})
      })
  }

  render() {
    return(

          <form className="col-md-12 uploader" encType="multipart/form-data">

Download Translation Draft

                Translation Done Successfully !!!

                {this.state.message}

                <lable className="control-label Concord2">  Source Language  </lable>
                    <FormControl value={this.state.sourcelang} onChange={this.onSelect} name="sourcelang" componentClass="select" placeholder="select">
                      {SourceLanguages.map((sourcelang, i) => <option  key={i} value={sourcelang.value}>{sourcelang.value}</option>)}
                    </FormControl>
                 <lable className="control-lable Concord2">  Version  </lable>
                    <input value={this.state.version} onChange={this.onSelect} name="version" type="text"  placeholder="version" className="form-control"/>
                <lable className="control-lable Concord2">  Revision  </lable>
                    <input value={this.state.revision} onChange={this.onSelect} name="revision" type="text" placeholder="revision" className="form-control"/>
                <lable className="control-label Concord2">  Target Language  </lable>
                    <FormControl value={this.state.targetlang} onChange={this.onSelect} name="targetlang" componentClass="select" placeholder="select">
                      {TargetLanguages.map((targetlang, i) => <option  key={i} value={targetlang.value}>{targetlang.value}</option>)}
                    </FormControl>

                <Tabs activeTab={this.state.activeTab}  changeTab={this.handleClick}/>

{this.createCheckboxes1(this)}

                  <button id="btnGet" type="button" className="btn btn-success ConcordButton" onClick={this.uploadFile}>  Download Drafts </button>

          </form>

      );
    }
}

export default GetTranslationDraft;
<|endoftext|>


<commit_before>/*
 * An AudioProcessor object is used to calculate pitch and vibrato rate and width frame by frame.
 * When you get a new frame, call AudioProcessor.prototype.process().
 * You can then get all processed pitches, rates, and widths via getPitches, getVibratoRates, getVibratoWidths
 */

let recentPitch;//global access in case setInterval isn't good enough to use

const MIN_TONE_DURATION = 0.2;
const PITCH_FRAME_DURATION = 0.03; // 2 cycles of 100 Hz tone
const VIBRATO_FRAME_DURATION = 0.2; // 1 cycles of 2 Hz vibrato. See https://en.wikipedia.org/wiki/Vibrato#Typical_rate_and_extent_of_vibrato

// Bounds on pitch, rate, and width estimates
const MIN_PITCH = 75;
const MAX_PITCH = 3000;
const MIN_RATE = 0;
const MAX_RATE = 15;
const MIN_WIDTH = 0;
const MAX_WIDTH = 1; // semitones

function AudioProcessor(sampleRate) {
    this.sampleRate = sampleRate;
    this.frameSize = nextPow2(PITCH_FRAME_DURATION * sampleRate);
    this.frameRate = this.sampleRate / this.frameSize;
    this.vibratoFrameSize = nextPow2(VIBRATO_FRAME_DURATION * this.frameRate);

    this.timestamps = [];
    this.frames = [];
    this.pitches = [];
    this.vibratoRates = [];
    this.vibratoWidths = [];
}

AudioProcessor.prototype.getFrameSize = function() {
    return this.frameSize;
}

AudioProcessor.prototype.getTimestamps = function() {
    return this.timestamps;
}

AudioProcessor.prototype.getPitches = function() {
    return this.pitches;
}

AudioProcessor.prototype.getVibratoRates = function() {
    return this.vibratoRates;
}

AudioProcessor.prototype.getVibratoWidths = function() {
    return this.vibratoWidths;
}

AudioProcessor.prototype.currentPitch = function() {
	recentPitch = this.pitches[this.pitches.length - 1];
	return this.pitches[this.pitches.length - 1];
}

/*
 * Resets all historical frames, pitches, and vibrato results.
 */
AudioProcessor.prototype.clear = function() {
    this.timestamps = [];
    this.frames = [];
    this.pitches = [];
    this.vibratoRates = [];
    this.vibratoWidths = [];
}

/*
 * Processes a new frame, storing all info in frames, pitches, vibratoRates, and vibratoWidths.
 */
AudioProcessor.prototype.process = function(frame, timestamp) {
    this.timestamps.push(timestamp);
    this.frames.push(frame);
    this.pitchProcess();
    this.vibratoProcess();
}

/*
 * Finds pitch for the latest frame buffer and adds it to the pitch array.
 */
AudioProcessor.prototype.pitchProcess = function() {
    var result = detectPitch(this.frames[this.frames.length - 1]);
    if (result != null && result.freq != -1) {
        this.pitches.push(result.freq);
    }
    else {
        this.pitches.push(-1);
    }

//    this.smoothPitchContour();
}

/*
 * Smooths the latest frame of duration MIN_TONE_DURATION
 */
AudioProcessor.prototype.smoothPitchContour = function() {

    var toneFrameSize = Math.round(MIN_TONE_DURATION * this.frameRate);
    var end = this.pitches.length - 1;
    var start = end - toneFrameSize;

    if (start >= 0) {
        console.log("Smooth from " + start + " to " + end);
        // If the bookends of the tone frame are within a quarter tone, average out the intermediate pitch values
        var semitoneDiff = Math.abs(freq2Semitones(this.pitches[start]) - freq2Semitones(this.pitches[end]))
        if (semitoneDiff < 0.5) {
            var avePitch = (this.pitches[start] + this.pitches[end]) / 2;
            for (var i = start + 1; i < end; i++) {

                semitoneDiff = Math.abs(freq2Semitones(avePitch) - freq2Semitones(this.pitches[i]))
                if (semitoneDiff > 1) {
                    console.log("outlier, pitch = " + avePitch);

                    if (this.pitches[i] == -1) {
                        // Average of neighbors
                        this.pitches[i] = (this.pitches[i - 1] + this.pitches[i + 1]) / 2;
                    }
                    else if (this.pitches[i] > avePitch) {
                        var n = Math.round(this.pitches[i] / avePitch);
                        this.pitches[i] /= n;
                    }
                    else if (this.pitches[i] < avePitch) {
                        var n = Math.round(avePitch / this.pitches[i]);
                        this.pitches[i] *= n;
                    }
                }
            }

            for (var i = start + 1; i < end; i++) {
                // If its still not within a semitone, make it the average of its neighbors
                if (semitoneDiff > 1) {
                    this.pitches[i] = (this.pitches[i - 1] + this.pitches[i + 1]) / 2;
                }
            }
            for (var i = start + 1; i < end; i++) {
                // If still not within a semitone, make it the average of the bookends
                if (semitoneDiff > 1) {
                    this.pitches[i] = avePitch;
                }
            }
        }
    }
}

/*
 * Calculates vibrato parameters from the latest pitch buffer and adds them to their respective arrays.
 * Only call this after calling pitchProcess.
 */
AudioProcessor.prototype.vibratoProcess = function() {

    if (this.pitches.length < this.vibratoFrameSize) {
        this.vibratoRates.push(-1);
        this.vibratoWidths.push(-1);
    }
    else {
        var pitchFrame = this.pitches.slice(this.pitches.length - this.vibratoFrameSize, this.pitches.length);

        var width = Math.max(...pitchFrame) - Math.min(...pitchFrame);
        var semitoneWidth = freq2Semitones(Math.max(...pitchFrame)) - freq2Semitones(Math.min(...pitchFrame));
        if (MIN_WIDTH <= semitoneWidth && semitoneWidth <= MAX_WIDTH) {
            this.vibratoWidths.push(semitoneWidth);
        }
        else {
            this.vibratoWidths.push(0);
        }

        // Normalize pitches (zero out the DC offset)
        var normalizedPitchFrame = normalize(pitchFrame);

        // TODO: Fix weird bottoming out
//        // Detect whether vibrato is present (width is at least a quarter of a semitone)
//        if (semitoneWidth >= 1 / 4) {
//            console.log("Here");
//            // Find all instances of three nearly equal pitch samples and eliminate the middle one
//            for (var i = 0; i < this.pitches.length; i++) {
//
//            }
//        }

        // Peak-picking algorithm
        var peakIndices = [];
        for (var i = 1; i < normalizedPitchFrame.length - 1; i++) {
            if (normalizedPitchFrame[i] > normalizedPitchFrame[i - 1] &&
                    normalizedPitchFrame[i] > normalizedPitchFrame[i + 1]) {
                peakIndices.push(i);
            }
        }

        var frameStart = this.frames.length - this.vibratoFrameSize - 1;
        var start = frameStart + peakIndices[0];
        var end = frameStart + peakIndices[peakIndices.length - 1];
        var duration = this.timestamps[end] - this.timestamps[start];
        var rate = (peakIndices.length - 1) / duration;
        if (MIN_RATE <= rate && rate <= MAX_RATE) {
            this.vibratoRates.push(rate);
        }
        else {
            this.vibratoRates.push(0);
        }
    }
}
<commit_msg>Parameters are tuned to violin recording. Probably need to dynamically compute them at runtime.<commit_after>/*
 * An AudioProcessor object is used to calculate pitch and vibrato rate and width frame by frame.
 * When you get a new frame, call AudioProcessor.prototype.process().
 * You can then get all processed pitches, rates, and widths via getPitches, getVibratoRates, getVibratoWidths
 */

let recentPitch;//global access in case setInterval isn't good enough to use

const MIN_TONE_DURATION = 0.2;
const PITCH_FRAME_DURATION = 0.03; // 3 cycles of 100 Hz tone
const VIBRATO_FRAME_DURATION = 0.5; // 2.5 cycles of 5 Hz vibrato. See https://en.wikipedia.org/wiki/Vibrato#Typical_rate_and_extent_of_vibrato

// Bounds on pitch, rate, and width estimates
const MIN_PITCH = 75;
const MAX_PITCH = 3000;
const MIN_RATE = 0;
const MAX_RATE = 15;
const MIN_WIDTH = 0;
const MAX_WIDTH = 1; // semitones

function AudioProcessor(sampleRate) {
    this.sampleRate = sampleRate;
    this.frameSize = nextPow2(PITCH_FRAME_DURATION * sampleRate);
    this.frameRate = this.sampleRate / this.frameSize;
    this.vibratoFrameSize = nextPow2(VIBRATO_FRAME_DURATION * this.frameRate);

    this.timestamps = [];
    this.frames = [];
    this.pitches = [];
    this.vibratoRates = [];
    this.vibratoWidths = [];
}

AudioProcessor.prototype.getFrameSize = function() {
    return this.frameSize;
}

AudioProcessor.prototype.getTimestamps = function() {
    return this.timestamps;
}

AudioProcessor.prototype.getPitches = function() {
    return this.pitches;
}

AudioProcessor.prototype.getVibratoRates = function() {
    return this.vibratoRates;
}

AudioProcessor.prototype.getVibratoWidths = function() {
    return this.vibratoWidths;
}

AudioProcessor.prototype.currentPitch = function() {
	recentPitch = this.pitches[this.pitches.length - 1];
	return this.pitches[this.pitches.length - 1];
}

/*
 * Resets all historical frames, pitches, and vibrato results.
 */
AudioProcessor.prototype.clear = function() {
    this.timestamps = [];
    this.frames = [];
    this.pitches = [];
    this.vibratoRates = [];
    this.vibratoWidths = [];
}

/*
 * Processes a new frame, storing all info in frames, pitches, vibratoRates, and vibratoWidths.
 */
AudioProcessor.prototype.process = function(frame, timestamp) {
    this.timestamps.push(timestamp);
    this.frames.push(frame);
    this.pitchProcess();
    this.vibratoProcess();
}

/*
 * Finds pitch for the latest frame buffer and adds it to the pitch array.
 */
AudioProcessor.prototype.pitchProcess = function() {
    var result = detectPitch(this.frames[this.frames.length - 1]);
    if (result != null && result.freq != -1) {
        this.pitches.push(result.freq);
    }
    else {
        this.pitches.push(-1);
    }

//    this.smoothPitchContour();
}

/*
 * Smooths the latest frame of duration MIN_TONE_DURATION
 */
AudioProcessor.prototype.smoothPitchContour = function() {

    var toneFrameSize = Math.round(MIN_TONE_DURATION * this.frameRate);
    var end = this.pitches.length - 1;
    var start = end - toneFrameSize;

    if (start >= 0) {
        console.log("Smooth from " + start + " to " + end);
        // If the bookends of the tone frame are within a quarter tone, average out the intermediate pitch values
        var semitoneDiff = Math.abs(freq2Semitones(this.pitches[start]) - freq2Semitones(this.pitches[end]))
        if (semitoneDiff < 0.5) {
            var avePitch = (this.pitches[start] + this.pitches[end]) / 2;
            for (var i = start + 1; i < end; i++) {

                semitoneDiff = Math.abs(freq2Semitones(avePitch) - freq2Semitones(this.pitches[i]))
                if (semitoneDiff > 1) {
                    console.log("outlier, pitch = " + avePitch);

                    if (this.pitches[i] == -1) {
                        // Average of neighbors
                        this.pitches[i] = (this.pitches[i - 1] + this.pitches[i + 1]) / 2;
                    }
                    else if (this.pitches[i] > avePitch) {
                        var n = Math.round(this.pitches[i] / avePitch);
                        this.pitches[i] /= n;
                    }
                    else if (this.pitches[i] < avePitch) {
                        var n = Math.round(avePitch / this.pitches[i]);
                        this.pitches[i] *= n;
                    }
                }
            }

            for (var i = start + 1; i < end; i++) {
                // If its still not within a semitone, make it the average of its neighbors
                if (semitoneDiff > 1) {
                    this.pitches[i] = (this.pitches[i - 1] + this.pitches[i + 1]) / 2;
                }
            }
            for (var i = start + 1; i < end; i++) {
                // If still not within a semitone, make it the average of the bookends
                if (semitoneDiff > 1) {
                    this.pitches[i] = avePitch;
                }
            }
        }
    }
}

/*
 * Calculates vibrato parameters from the latest pitch buffer and adds them to their respective arrays.
 * Only call this after calling pitchProcess.
 */
AudioProcessor.prototype.vibratoProcess = function() {

    if (this.pitches.length < this.vibratoFrameSize) {
        this.vibratoRates.push(-1);
        this.vibratoWidths.push(-1);
    }
    else {
        var pitchFrame = this.pitches.slice(this.pitches.length - this.vibratoFrameSize, this.pitches.length);

        var width = Math.max(...pitchFrame) - Math.min(...pitchFrame);
        var semitoneWidth = freq2Semitones(Math.max(...pitchFrame)) - freq2Semitones(Math.min(...pitchFrame));
        if (MIN_WIDTH <= semitoneWidth && semitoneWidth <= MAX_WIDTH) {
            this.vibratoWidths.push(semitoneWidth);
        }
        else {
            this.vibratoWidths.push(0);
        }

        // Normalize pitches (zero out the DC offset)
        var normalizedPitchFrame = normalize(pitchFrame);

        // TODO: Fix weird bottoming out
//        // Detect whether vibrato is present (width is at least a quarter of a semitone)
//        if (semitoneWidth >= 1 / 4) {
//            console.log("Here");
//            // Find all instances of three nearly equal pitch samples and eliminate the middle one
//            for (var i = 0; i < this.pitches.length; i++) {
//
//            }
//        }

        // Peak-picking algorithm
        var peakIndices = [];
        for (var i = 1; i < normalizedPitchFrame.length - 1; i++) {
            if (normalizedPitchFrame[i] > normalizedPitchFrame[i - 1] &&
                    normalizedPitchFrame[i] > normalizedPitchFrame[i + 1]) {
                peakIndices.push(i);
            }
        }

        var frameStart = this.frames.length - this.vibratoFrameSize - 1;
        var start = frameStart + peakIndices[0];
        var end = frameStart + peakIndices[peakIndices.length - 1];
        var duration = this.timestamps[end] - this.timestamps[start];
        var rate = (peakIndices.length - 1) / duration;
        if (MIN_RATE <= rate && rate <= MAX_RATE) {
            this.vibratoRates.push(rate);
        }
        else {
            this.vibratoRates.push(0);
        }
    }
}
<|endoftext|>


<commit_before>// The core file for running JavaScript on the web or on a robot. It contains
// the basic models for interfacing with the Robot Operating System, including
// node, publisher, and subscriber.
//
// When run in the browser, ros.js manages the nodes, publishers, and
// subscribers the web page is interested in via REST calls to the robot. It
// also sends and receives messages to the robot using web sockets.
//
// When run on the robot using Node.js, ros.js' functionality is extended to
// interact with the Robot Operating System directly, using XML-RPC and ROS
// specific protocols like TCPROS.

(function() {

  // Initial setup
  // -------------

  // Creates a module compatible with Node.js and the web browser.
  var root     = this
    , server   = false
    , ros      = null

  if (typeof exports !== 'undefined') {
    server   = true
    ros      = exports
    Backbone = require('backbone')
  }
  else {
    ros = root.ros = {}
  }

  // The base URL to send REST requests to. The default is root.
  ros.baseUrl = ''

  // Message
  // -------

  // The Message object will be extended by all ROS messages. For example, the
  // std_msgs/String message will extend Message.
  ros.Message = Backbone.Model.extend({
    idAttribute: 'type'
  , defaults: {
      // The order of the fields, as listed in the message file definition.
      'fieldOrder' : []
      // The message type, e.g. "std_msgs/String".
    , 'type'       : ''
      // The MD5 sum of the message, as calculated by `rosmsg md5sum`.
    , 'md5sum'     : ''
    }
  })

  // Node
  // ----

  // Manages all nodes instantiated through this session. Mainly for updating or
  // removing a node.
  ros.Nodes = Backbone.Collection.extend({
    model: ros.Node
  })
  ros.nodes = new ros.Nodes()

  // Creates a node and returns the created node in the callback or an error if
  // the node creation failed.
  //
  // Node attributes include:
  //  * name - The node name.
  ros.createNode = function(attributes, callback) {
    var that = this

    var node = new ros.Node(attributes)

    // Makes a REST call to the server with the node attributes.
    node.save(null, {
      // Adds the node to the list and returns the created node.
      success: function(data) {
        that.nodes.add(node)
        callback(null, node)
      }
      // Returns the error encountered when saving the node.
    , error: function(jqXHR, textStatus, errorThrown) {
        callback(errorThrown)
      }
    })
  }

  // A node maintains a collection of publishers and subscribers for topics.
  ros.Node = Backbone.Model.extend({

    // Sets the node ID to its name.
    idAttribute: 'name'
    // Sets the REST end point for managing the node.
  , urlRoot    : ros.baseUrl + '/nodes'

  , initialize: function(attributes, options) {
      if (!this.publishers) {
        this.publishers = new this.Publishers()
      }
      if (!this.subscribers) {
        this.subscribers = new this.Subscribers()
      }
    }

  , Publishers: Backbone.Collection.extend({
      model: ros.Publisher
    })

  , Subscribers : Backbone.Collection.extend({
      model: ros.Subscriber
    })

    // Creates a publisher for a given topic. Returns the publisher in the
    // callback after successfully registering it or an error if registering the
    // publisher failed.
    //
    // Publisher attributes include:
    //  * topic   - The topic name.
    //  * Message - The message type being published. This is the uninitialized
    //    Message model, like std_msgs.Header or geometry_msgs.Twist.
  , createPublisher: function(attributes, callback) {
      var that = this
      attributes.nodeId = this.id

      // Makes a REST call to the robot with the publisher attributes.
      var publisher = new ros.Publisher(attributes)
      publisher.save(null, {
        // On success, adds the publisher to the node's list and returns the
        // publisher in the callback.
        success: function(data) {
          that.publishers.add(publisher)
          callback(null, publisher)
        }
        // Returns any error from registering the publisher.
      , error: function(jqXHR, textStatus, errorThrown) {
          callback(errorThrown)
        }
      })
    }

  , removePublisher: function(publisher) {
      this.publishers.remove(publisher)
      publisher.destroy()
    }

    // Creates a subscriber for a given topic. Returns the subscriber in the
    // callback after successfully registering it or an error if registering the
    // subscriber failed.
    //
    // Subscriber attributes include:
    //  * topic   - The topic name.
    //  * Message - The message type being subscribed to. This is the
    //    uninitialized Message model, like std_msgs.Header or
    //    geometry_msgs.Twist.
  , createSubscriber: function(attributes, callback) {
      var that = this
      attributes.nodeId = this.id

      // Makes a REST call to the robot with the subscriber attributes.
      var subscriber = new ros.Subscriber(attributes)
      subscriber.save(null, {
        // On success, adds the subscriber to the node's list and returns the
        // subscriber in the callback.
        success: function(data) {
          that.subscribers.add(subscriber)
          callback(null, subscriber)
        }
        // Returns any error from registering the subscriber.
      , error: function(jqXHR, textStatus, errorThrown) {
          callback(errorThrown)
        }
      })
    }

  , removeSubscriber: function(subscriber) {
      this.subscribers.remove(subscriber)
      subscriber.destroy()
    }
  })

  // Publisher
  // ---------

  // The publisher sends messages for a given topic.
  ros.Publisher = Backbone.Model.extend({

    defaults: {
      // The default ROS protocol for communicating with other nodes.
      protocol: 'TCPROS'
    }

  , initialize: function(attributes) {
      var that = this

      // The REST end point for managing the publisher.
      this.urlRoot = ros.baseUrl
        + '/nodes/'
        + this.get('nodeId')
        + '/publishers'

      // Creates the message type from the uninitialized Message model.
      var Message = this.get('Message')
      if (Message) {
        var message     = new Message()
          , messageType = message.get('type')
        this.set({ messageType: messageType })
      }

      var topic = this.get('topic')
      if (topic) {
        // Sets the publisher ID to the topic's name
        this.id = topic

        // Opens up a web socket using socket.io to publish messages on
        if (!server) {
          var namespacedTopic = '/' + topic
          var socket = ros.io.connect(namespacedTopic)
          socket.on('connect', function() {
            that.socket = socket
          })
        }
      }

    }

    // Publishes a message to the robot using web sockets
  , publish: function(message, callback) {
      if (this.socket === undefined) {
        var error = new Error('Socket not connected to server')
        callback(error)
      }
      else {
        this.socket.emit('message', message)
        callback()
      }
    }
  })

  // Subscriber
  // ---------

  // The subscriber receives messages for a given topic.
  ros.Subscriber = Backbone.Model.extend({

    defaults: {
      // The default ROS protocol for communicating with other nodes.
      protocol: 'TCPROS'
    }

  , initialize: function(attributes) {
      var that = this

      // The REST end point for managing the subscriber.
      this.urlRoot = ros.baseUrl
        + '/nodes/'
        + this.get('nodeId')
        + '/subscribers'

      // Creates the message type from the uninitialized Message model.
      var Message = this.get('Message')
      if (Message) {
        var message     = new Message()
          , messageType = message.get('type')
        this.set({ messageType: messageType })
      }

      var topic = this.get('topic')
      if (topic) {
        // Sets the subscriber ID to the topic's name.
        this.id = topic

        // Listens for messages published from the robot. Messages are received
        // over a web socket using socket.io.
        if (!server) {
          var namespacedTopic = '/' + topic
          var socket = ros.io.connect(namespacedTopic)
          socket.on('connect', function() {
            that.socket = socket

            // When a  message is received over the web socket, emits an event
            // with the message data for others to handle (like the subscribe
            // function).
            socket.on('message', function(message) {
              that.trigger('message', message)
            })
          })
        }
      }
    }

    // When a message is received from the server, calls back with the message
    // object. This can happen multiple times.
  , subscribe: function(callback) {
      // Knows a message is received by listening for the event.
      this.bind('message', function(message) {
        callback(null, message)
      })
    }
  })

}).call(this)

<commit_msg>Assigns socket.io to ros object automatically in browser.<commit_after>// The core file for running JavaScript on the web or on a robot. It contains
// the basic models for interfacing with the Robot Operating System, including
// node, publisher, and subscriber.
//
// When run in the browser, ros.js manages the nodes, publishers, and
// subscribers the web page is interested in via REST calls to the robot. It
// also sends and receives messages to the robot using web sockets.
//
// When run on the robot using Node.js, ros.js' functionality is extended to
// interact with the Robot Operating System directly, using XML-RPC and ROS
// specific protocols like TCPROS.

(function() {

  // Initial setup
  // -------------

  // Creates a module compatible with Node.js and the web browser.
  var root     = this
    , server   = false
    , ros      = null

  if (typeof exports !== 'undefined') {
    server   = true
    ros      = exports
    Backbone = require('backbone')
  }
  else {
    ros = root.ros = {}
    ros.io = root.io
  }

  // The base URL to send REST requests to. The default is root.
  ros.baseUrl = ''

  // Message
  // -------

  // The Message object will be extended by all ROS messages. For example, the
  // std_msgs/String message will extend Message.
  ros.Message = Backbone.Model.extend({
    idAttribute: 'type'
  , defaults: {
      // The order of the fields, as listed in the message file definition.
      'fieldOrder' : []
      // The message type, e.g. "std_msgs/String".
    , 'type'       : ''
      // The MD5 sum of the message, as calculated by `rosmsg md5sum`.
    , 'md5sum'     : ''
    }
  })

  // Node
  // ----

  // Manages all nodes instantiated through this session. Mainly for updating or
  // removing a node.
  ros.Nodes = Backbone.Collection.extend({
    model: ros.Node
  })
  ros.nodes = new ros.Nodes()

  // Creates a node and returns the created node in the callback or an error if
  // the node creation failed.
  //
  // Node attributes include:
  //  * name - The node name.
  ros.createNode = function(attributes, callback) {
    var that = this

    var node = new ros.Node(attributes)

    // Makes a REST call to the server with the node attributes.
    node.save(null, {
      // Adds the node to the list and returns the created node.
      success: function(data) {
        that.nodes.add(node)
        callback(null, node)
      }
      // Returns the error encountered when saving the node.
    , error: function(jqXHR, textStatus, errorThrown) {
        callback(errorThrown)
      }
    })
  }

  // A node maintains a collection of publishers and subscribers for topics.
  ros.Node = Backbone.Model.extend({

    // Sets the node ID to its name.
    idAttribute: 'name'
    // Sets the REST end point for managing the node.
  , urlRoot    : ros.baseUrl + '/nodes'

  , initialize: function(attributes, options) {
      if (!this.publishers) {
        this.publishers = new this.Publishers()
      }
      if (!this.subscribers) {
        this.subscribers = new this.Subscribers()
      }
    }

  , Publishers: Backbone.Collection.extend({
      model: ros.Publisher
    })

  , Subscribers : Backbone.Collection.extend({
      model: ros.Subscriber
    })

    // Creates a publisher for a given topic. Returns the publisher in the
    // callback after successfully registering it or an error if registering the
    // publisher failed.
    //
    // Publisher attributes include:
    //  * topic   - The topic name.
    //  * Message - The message type being published. This is the uninitialized
    //    Message model, like std_msgs.Header or geometry_msgs.Twist.
  , createPublisher: function(attributes, callback) {
      var that = this
      attributes.nodeId = this.id

      // Makes a REST call to the robot with the publisher attributes.
      var publisher = new ros.Publisher(attributes)
      publisher.save(null, {
        // On success, adds the publisher to the node's list and returns the
        // publisher in the callback.
        success: function(data) {
          that.publishers.add(publisher)
          callback(null, publisher)
        }
        // Returns any error from registering the publisher.
      , error: function(jqXHR, textStatus, errorThrown) {
          callback(errorThrown)
        }
      })
    }

  , removePublisher: function(publisher) {
      this.publishers.remove(publisher)
      publisher.destroy()
    }

    // Creates a subscriber for a given topic. Returns the subscriber in the
    // callback after successfully registering it or an error if registering the
    // subscriber failed.
    //
    // Subscriber attributes include:
    //  * topic   - The topic name.
    //  * Message - The message type being subscribed to. This is the
    //    uninitialized Message model, like std_msgs.Header or
    //    geometry_msgs.Twist.
  , createSubscriber: function(attributes, callback) {
      var that = this
      attributes.nodeId = this.id

      // Makes a REST call to the robot with the subscriber attributes.
      var subscriber = new ros.Subscriber(attributes)
      subscriber.save(null, {
        // On success, adds the subscriber to the node's list and returns the
        // subscriber in the callback.
        success: function(data) {
          that.subscribers.add(subscriber)
          callback(null, subscriber)
        }
        // Returns any error from registering the subscriber.
      , error: function(jqXHR, textStatus, errorThrown) {
          callback(errorThrown)
        }
      })
    }

  , removeSubscriber: function(subscriber) {
      this.subscribers.remove(subscriber)
      subscriber.destroy()
    }
  })

  // Publisher
  // ---------

  // The publisher sends messages for a given topic.
  ros.Publisher = Backbone.Model.extend({

    defaults: {
      // The default ROS protocol for communicating with other nodes.
      protocol: 'TCPROS'
    }

  , initialize: function(attributes) {
      var that = this

      // The REST end point for managing the publisher.
      this.urlRoot = ros.baseUrl
        + '/nodes/'
        + this.get('nodeId')
        + '/publishers'

      // Creates the message type from the uninitialized Message model.
      var Message = this.get('Message')
      if (Message) {
        var message     = new Message()
          , messageType = message.get('type')
        this.set({ messageType: messageType })
      }

      var topic = this.get('topic')
      if (topic) {
        // Sets the publisher ID to the topic's name
        this.id = topic

        // Opens up a web socket using socket.io to publish messages on
        if (!server) {
          var namespacedTopic = '/' + topic
          var socket = ros.io.connect(namespacedTopic)
          socket.on('connect', function() {
            that.socket = socket
          })
        }
      }

    }

    // Publishes a message to the robot using web sockets
  , publish: function(message, callback) {
      if (this.socket === undefined) {
        var error = new Error('Socket not connected to server')
        callback(error)
      }
      else {
        this.socket.emit('message', message)
        callback()
      }
    }
  })

  // Subscriber
  // ---------

  // The subscriber receives messages for a given topic.
  ros.Subscriber = Backbone.Model.extend({

    defaults: {
      // The default ROS protocol for communicating with other nodes.
      protocol: 'TCPROS'
    }

  , initialize: function(attributes) {
      var that = this

      // The REST end point for managing the subscriber.
      this.urlRoot = ros.baseUrl
        + '/nodes/'
        + this.get('nodeId')
        + '/subscribers'

      // Creates the message type from the uninitialized Message model.
      var Message = this.get('Message')
      if (Message) {
        var message     = new Message()
          , messageType = message.get('type')
        this.set({ messageType: messageType })
      }

      var topic = this.get('topic')
      if (topic) {
        // Sets the subscriber ID to the topic's name.
        this.id = topic

        // Listens for messages published from the robot. Messages are received
        // over a web socket using socket.io.
        if (!server) {
          var namespacedTopic = '/' + topic
          var socket = ros.io.connect(namespacedTopic)
          socket.on('connect', function() {
            that.socket = socket

            // When a  message is received over the web socket, emits an event
            // with the message data for others to handle (like the subscribe
            // function).
            socket.on('message', function(message) {
              that.trigger('message', message)
            })
          })
        }
      }
    }

    // When a message is received from the server, calls back with the message
    // object. This can happen multiple times.
  , subscribe: function(callback) {
      // Knows a message is received by listening for the event.
      this.bind('message', function(message) {
        callback(null, message)
      })
    }
  })

}).call(this)

<|endoftext|>


<commit_before>//@auth
//@req(name)

import com.hivext.api.core.utils.Transport;

var url = getParam('url'),
    description = "start-stop-scheduler",
    resp, tasks, envName = '${env.envName}', envAppid = '${env.appid}', version;

version = jelastic.system.service.GetVersion().version.split("-").shift();

if (url) {
    //reading script from URL
    var body = new Transport().get(url);

    //delete the script if it exists already
    jelastic.dev.scripting.DeleteScript({appid: appid, session: session, name:name});

    //create a new script
    resp = jelastic.dev.scripting.CreateScript({appid: appid, session: session, name: name, type: 'js', code: body});
    if (resp.result != 0) return buildErrorMessage(resp);
}

resp = jelastic.utils.scheduler.GetTasks({appid: appid, session: session});
if (resp.result != 0) return resp;

tasks = resp.objects;
for (var i = 0, l = tasks.length; i < l; i++)
if (tasks[i].script == name) jelastic.utils.scheduler.RemoveTask({appid: appid, session:session, id: tasks[i].id});

var startCron = getParam('start'),
    stopCron = getParam('stop');

if (startCron) {
    resp = addTask(startCron, 'start')
    if (resp.result != 0) return buildErrorMessage(resp);
}

if (stopCron) {
    resp = addTask(stopCron, 'stop');
}

if (getParam('action') && getParam('action') == 'update') {
    resp.type = 'info';
    return resp;
}

return resp

function addTask(cron, taskName) {
    var quartz = convert(cron);
    var params = toJSON({
        action: taskName,
        envName: envName
    });

    for (var i = 0, l = quartz.length; i < l; i++) {
        if (compareVersions(version, '5.3') >= 0 || version.indexOf('trunk') != -1) {
            var resp = jelastic.utils.scheduler.CreateEnvTask({appid: appid, envName: envName, session: session, script: name, trigger: "cron:" + quartz[i], description: description, params: params})
        } else {
            var resp = jelastic.utils.scheduler.AddTask({appid: appid, session: session, script: name, trigger: "cron:" + quartz[i], description: description, params: params})
        }
        if (resp.result != 0) return buildErrorMessage(resp)
    }

    return {result: 0}
}

function buildErrorMessage(resp) {
    resp.type = 'error';
    resp.message = resp.error;
    return resp;
}

function compareVersions(a, b) {
   a = a.split("."), b = b.split(".")
   for (var i = 0, l = Math.max(a.length, b.length); i < l; i++) {x = parseInt(a[i], 10) || 0; y = parseInt(b[i], 10) || 0; if (x != y) return x > y ? 1 : -1 }
   return 0;
 }

function convert(cron) {
    //conversion is based on https://github.com/lirantal/cron-to-quartz
    /**
     * Object declaration
     * C2Q - Cron 2 Quartz conversion library
     *
     */
    var C2Q = {};

    /**
     * Get a Quartz CRON notation from provided Unix CRON syntax
     * getQuartz
     *
     * Expects to get a Unix CRON syntax format, for example: 00 11,13 * * *
     *
     * @param {string} unix CRON format
     * @return {array} array of arrays
     *   for example:
     *    [
     *     ['0', '00', '11,13', '*', '*', '?', '*' ]
     *    ]
     *
     *
     */
    C2Q.getQuartz = function (crontab) {

        var data = [];
        var quartzEntry = [];

        // check for cron magic entries
        quartzEntry = parseCronMagics(crontab);

        if (quartzEntry) {
            data.push(quartzEntry);
        } else {

            // if cron magic entries not found, proceed to parsing normal cron format
            var crontabEntry = crontab.split(' ');
            quartzEntry = parseCronSyntax(crontabEntry);

            data.push(quartzEntry);

            // Quartz doesn't support both DOM and DOW definitions so if we find such ocurrence we'll need to
            // create 2 Quartz entries, one with DOM and one with DOW to create an OR expression
            if (crontabEntry[2] !== '*' && crontabEntry[4] !== '*') {

                // by default, parseCronSyntax() gives priority to parse the DOM first so we reset it now to * to
                // make sure we also have a variant of the CRON expression with DOW
                crontabEntry[2] = '*';

                quartzEntry = parseCronSyntax(crontabEntry);
                data.push(quartzEntry);
            }

        }

        return data;
    };

    function advanceNumber(str) {

        var quartzCompatibleStr = '';
        var num;
        str.split('').forEach(function (chr) {

            num = parseInt(chr);

            // char is an actual number
            if (!isNaN(num)) {
                // number is in allowed range
                if (num >= 0 && num <= 7) {
                    quartzCompatibleStr += num + 1;
                } else {
                    // otherwise default to 1, beginning of the week
                    quartzCompatibleStr = 1;
                }
            } else {
                quartzCompatibleStr += chr;
            }

        });

        return quartzCompatibleStr;
    }

    /**
     * parse cron
     * parseCronMagics
     *
     * @param {string} a string representation of a unix CRON entry
     * @return {array} an array representation of a Quartz CRON entry
     *
     */

    function parseCronSyntax(crontabEntry) {

        var quartzEntry = [];

        // first we initialize the seconds to 0 by default because linux CRON entries do not include a seconds definition
        quartzEntry.push('0');

        // quartz scheduler can't handle an OR definition, and so it doesn't support both DOM and DOW fields to be defined
        // for this reason we need to shift one of them to be the value or * and the other to be ?
        var toggleQuartzCompat = false;

        crontabEntry.forEach(function (item, index, array) {

            // index 0 = minutes
            // index 1 = hours
            // these cron definitions should be compatible with quartz so we push them as is
            if (index === 0 || index === 1) {
                quartzEntry.push(item);
            }

            // index 2 = DOM = Day of Month
            if (index === 2) {
                if (item !== '?') {
                    toggleQuartzCompat = true;
                }

                if (item === '*') {
                    toggleQuartzCompat = false;
                    item = '?';
                }

                quartzEntry.push(item);
            }

            // index 3 = Month
            if (index === 3) {
                quartzEntry.push(item);
            }

            // index 4 = DOW = Day of Week
            if (index === 4) {

                // day of week needs another adjustments - it is specified as 1-7 in quartz but 0-6 in crontab
                var itemAbbreviated = advanceNumber(item);

                if (toggleQuartzCompat === true) {
                    quartzEntry.push('?');
                } else {
                    quartzEntry.push(itemAbbreviated);
                }
            }

            // beyond index 4 we don't care and exit the loop
            if (index >= 5) {
                return true;
            }

        });

        // quartz expect a last 7th parameter for scheduling yearly recurrence so we pass * by default for all years
        quartzEntry.push('*');

        return quartzEntry;

    }

    /**
     * parse cron format specified with the shorthand magic @ entries, for example: @hourly
     * parseCronMagics
     *
     * @param {string} a string representation of a unix CRON entry
     * @return {array} an array representation of a Quartz CRON entry
     *
     */

    function parseCronMagics(crontab) {

        var quartzEntry = false;

        // @hourly
        if (crontab.indexOf('@hourly') === 0) {
            quartzEntry = ['0', '0', '*', '*', '*', '?', '*'];
        }

        // @daily and @midnight
        if (crontab.indexOf('@daily') === 0 || crontab.indexOf('@midnight') === 0) {
            quartzEntry = ['0', '0', '0', '*', '*', '?', '*'];
        }

        // @weekly
        if (crontab.indexOf('@weekly') === 0) {
            quartzEntry = ['0', '0', '0', '?', '*', '1', '*'];
        }

        // @monthly
        if (crontab.indexOf('@monthly') === 0) {
            quartzEntry = ['0', '0', '0', '1', '*', '?', '*'];
        }

        // @yearly and @annually
        if (crontab.indexOf('@yearly') === 0 || crontab.indexOf('@annually') === 0) {
            quartzEntry = ['0', '0', '0', '1', '1', '?', '*'];
        }

        return quartzEntry || false;
    }

    var arr = C2Q.getQuartz(cron);

    for (var i = 0, l = arr.length; i < l; i++) {
        arr[i] = arr[i].join(' ');
    }
    return arr;
}
<commit_msg>Update create-service.js<commit_after>//@auth
//@req(name)

import com.hivext.api.core.utils.Transport;

var url = getParam('url'),
    description = "start-stop-scheduler",
    resp, tasks, envName = '${env.envName}', envAppid = '${env.appid}', version;

version = jelastic.system.service.GetVersion().version.split("-").shift();

if (url) {
    //reading script from URL
    var body = new Transport().get(url);

    //delete the script if it exists already
    jelastic.dev.scripting.DeleteScript({appid: appid, session: session, name:name});

    //create a new script
    resp = jelastic.dev.scripting.CreateScript({appid: appid, session: session, name: name, type: 'js', code: body});
    if (resp.result != 0) return buildErrorMessage(resp);
}

resp = jelastic.utils.scheduler.GetTasks({appid: appid, session: session});
if (resp.result != 0) return resp;

tasks = resp.objects;
for (var i = 0, l = tasks.length; i < l; i++)
if (tasks[i].script == name) jelastic.utils.scheduler.RemoveTask({appid: appid, session:session, id: tasks[i].id});

var startCron = getParam('start'),
    stopCron = getParam('stop');

if (startCron) {
    resp = addTask(startCron, 'start')
    if (resp.result != 0) return buildErrorMessage(resp);
}

if (stopCron) {
    resp = addTask(stopCron, 'stop');
}

if (getParam('action') && getParam('action') == 'update') {
    resp.type = 'info';
    return resp;
}

return resp

function addTask(cron, taskName) {
    var quartz = convert(cron);
    var params = toJSON({
        action: taskName,
        envName: envName
    });

    for (var i = 0, l = quartz.length; i < l; i++) {
        if (compareVersions(version, '5.3') >= 0 || version.indexOf('trunk') != -1) {
            var resp = jelastic.utils.scheduler.CreateEnvTask({appid: 'dashboard', envName: envName, session: session, script: name, trigger: "cron:" + quartz[i], description: description, params: params})
        } else {
            var resp = jelastic.utils.scheduler.AddTask({appid: appid, session: session, script: name, trigger: "cron:" + quartz[i], description: description, params: params})
        }
        if (resp.result != 0) return buildErrorMessage(resp)
    }

    return {result: 0}
}

function buildErrorMessage(resp) {
    resp.type = 'error';
    resp.message = resp.error;
    return resp;
}

function compareVersions(a, b) {
   a = a.split("."), b = b.split(".")
   for (var i = 0, l = Math.max(a.length, b.length); i < l; i++) {x = parseInt(a[i], 10) || 0; y = parseInt(b[i], 10) || 0; if (x != y) return x > y ? 1 : -1 }
   return 0;
 }

function convert(cron) {
    //conversion is based on https://github.com/lirantal/cron-to-quartz
    /**
     * Object declaration
     * C2Q - Cron 2 Quartz conversion library
     *
     */
    var C2Q = {};

    /**
     * Get a Quartz CRON notation from provided Unix CRON syntax
     * getQuartz
     *
     * Expects to get a Unix CRON syntax format, for example: 00 11,13 * * *
     *
     * @param {string} unix CRON format
     * @return {array} array of arrays
     *   for example:
     *    [
     *     ['0', '00', '11,13', '*', '*', '?', '*' ]
     *    ]
     *
     *
     */
    C2Q.getQuartz = function (crontab) {

        var data = [];
        var quartzEntry = [];

        // check for cron magic entries
        quartzEntry = parseCronMagics(crontab);

        if (quartzEntry) {
            data.push(quartzEntry);
        } else {

            // if cron magic entries not found, proceed to parsing normal cron format
            var crontabEntry = crontab.split(' ');
            quartzEntry = parseCronSyntax(crontabEntry);

            data.push(quartzEntry);

            // Quartz doesn't support both DOM and DOW definitions so if we find such ocurrence we'll need to
            // create 2 Quartz entries, one with DOM and one with DOW to create an OR expression
            if (crontabEntry[2] !== '*' && crontabEntry[4] !== '*') {

                // by default, parseCronSyntax() gives priority to parse the DOM first so we reset it now to * to
                // make sure we also have a variant of the CRON expression with DOW
                crontabEntry[2] = '*';

                quartzEntry = parseCronSyntax(crontabEntry);
                data.push(quartzEntry);
            }

        }

        return data;
    };

    function advanceNumber(str) {

        var quartzCompatibleStr = '';
        var num;
        str.split('').forEach(function (chr) {

            num = parseInt(chr);

            // char is an actual number
            if (!isNaN(num)) {
                // number is in allowed range
                if (num >= 0 && num <= 7) {
                    quartzCompatibleStr += num + 1;
                } else {
                    // otherwise default to 1, beginning of the week
                    quartzCompatibleStr = 1;
                }
            } else {
                quartzCompatibleStr += chr;
            }

        });

        return quartzCompatibleStr;
    }

    /**
     * parse cron
     * parseCronMagics
     *
     * @param {string} a string representation of a unix CRON entry
     * @return {array} an array representation of a Quartz CRON entry
     *
     */

    function parseCronSyntax(crontabEntry) {

        var quartzEntry = [];

        // first we initialize the seconds to 0 by default because linux CRON entries do not include a seconds definition
        quartzEntry.push('0');

        // quartz scheduler can't handle an OR definition, and so it doesn't support both DOM and DOW fields to be defined
        // for this reason we need to shift one of them to be the value or * and the other to be ?
        var toggleQuartzCompat = false;

        crontabEntry.forEach(function (item, index, array) {

            // index 0 = minutes
            // index 1 = hours
            // these cron definitions should be compatible with quartz so we push them as is
            if (index === 0 || index === 1) {
                quartzEntry.push(item);
            }

            // index 2 = DOM = Day of Month
            if (index === 2) {
                if (item !== '?') {
                    toggleQuartzCompat = true;
                }

                if (item === '*') {
                    toggleQuartzCompat = false;
                    item = '?';
                }

                quartzEntry.push(item);
            }

            // index 3 = Month
            if (index === 3) {
                quartzEntry.push(item);
            }

            // index 4 = DOW = Day of Week
            if (index === 4) {

                // day of week needs another adjustments - it is specified as 1-7 in quartz but 0-6 in crontab
                var itemAbbreviated = advanceNumber(item);

                if (toggleQuartzCompat === true) {
                    quartzEntry.push('?');
                } else {
                    quartzEntry.push(itemAbbreviated);
                }
            }

            // beyond index 4 we don't care and exit the loop
            if (index >= 5) {
                return true;
            }

        });

        // quartz expect a last 7th parameter for scheduling yearly recurrence so we pass * by default for all years
        quartzEntry.push('*');

        return quartzEntry;

    }

    /**
     * parse cron format specified with the shorthand magic @ entries, for example: @hourly
     * parseCronMagics
     *
     * @param {string} a string representation of a unix CRON entry
     * @return {array} an array representation of a Quartz CRON entry
     *
     */

    function parseCronMagics(crontab) {

        var quartzEntry = false;

        // @hourly
        if (crontab.indexOf('@hourly') === 0) {
            quartzEntry = ['0', '0', '*', '*', '*', '?', '*'];
        }

        // @daily and @midnight
        if (crontab.indexOf('@daily') === 0 || crontab.indexOf('@midnight') === 0) {
            quartzEntry = ['0', '0', '0', '*', '*', '?', '*'];
        }

        // @weekly
        if (crontab.indexOf('@weekly') === 0) {
            quartzEntry = ['0', '0', '0', '?', '*', '1', '*'];
        }

        // @monthly
        if (crontab.indexOf('@monthly') === 0) {
            quartzEntry = ['0', '0', '0', '1', '*', '?', '*'];
        }

        // @yearly and @annually
        if (crontab.indexOf('@yearly') === 0 || crontab.indexOf('@annually') === 0) {
            quartzEntry = ['0', '0', '0', '1', '1', '?', '*'];
        }

        return quartzEntry || false;
    }

    var arr = C2Q.getQuartz(cron);

    for (var i = 0, l = arr.length; i < l; i++) {
        arr[i] = arr[i].join(' ');
    }
    return arr;
}
<|endoftext|>


<commit_before>$(function () {
    $('a').not('[href*="mailto:"]').each(function () {
        var a = new RegExp('/' + window.location.host + '/');
        var href = this.href;
        if ( ! a.test(href) ) {
            $(this).attr('target', '_blank');
        }
    });
});<commit_msg>Actually make the blog link internal, now it has internal navigation.<commit_after>$(function () {
    $('a').not('[href*="mailto:"]').each(function () {{
        var href = this.href;
        if ( href.indexOf(window.location.host) != -1 ) {
            $(this).attr('target', '_blank');
        }
    });
});
<|endoftext|>


<commit_before>const Promise = require('bluebird');

const server = require('./../../server.js');
const CollectionService = require('./../Collection/Service.js');

const Models = server.sequelize.models;
const SLocation = Models.Location;

const Service = {
  getLocationsList: () => {
    const processedLocations = [];
    return SLocation.findAll().then(rawLocations => new Promise((resolve) => {
      rawLocations.forEach((location) => {
        processedLocations.push({
          id: location.id,
          name: location.name,
          latitude: location.latitude,
          longitude: location.longitude,
          radius: location.radius,
        });
      });
      resolve(processedLocations);
    }));
  },
  createLocation: (location) => {
    const DEFAULT_LOCATION = {
      name: 'DEFAULT',
      latitude: 33.9698,
      longitude: -118.4169,
      radius: 0.003,
    };

    const data = DEFAULT_LOCATION;
    data.name = location.name || data.name;
    data.latitude = location.latitude || data.latitude;
    data.longitude = location.longitude || data.longitude;
    data.radius = location.radius || data.radius;

    return SLocation.create(data).then(rawLocation => new Promise((resolve) => {
      resolve({
        id: rawLocation.id,
        name: rawLocation.name,
        latitude: rawLocation.latitude,
        longitude: rawLocation.longitude,
        radius: rawLocation.radius,
      });
    }));
  },
  getLocation: id => SLocation.findById(id).then(rawLocation => new Promise((resolve) => {
    if (!rawLocation) resolve({});
    resolve({
      id: rawLocation.id,
      name: rawLocation.name,
      latitude: rawLocation.latitude,
      longitude: rawLocation.longitude,
      radius: rawLocation.radius,
    });
  })),
  getLocationCount: id => SLocation.findById(id)
  .then(location => CollectionService.getAddressesWithinRange({
    latitude: location.latitude,
    longitude: location.longitude,
    radius: location.radius,
  })),
};

module.exports = Service;
<commit_msg>Added Timeslice querying<commit_after>const Promise = require('bluebird');
const Moment = require('moment');

const server = require('./../../server.js');
const CollectionService = require('./../Collection/Service.js');

const Models = server.sequelize.models;
const SLocation = Models.Location;

const Service = {
  getLocationsList: () => {
    const processedLocations = [];
    return SLocation.findAll().then(rawLocations => new Promise((resolve) => {
      rawLocations.forEach((location) => {
        processedLocations.push({
          id: location.id,
          name: location.name,
          latitude: location.latitude,
          longitude: location.longitude,
          radius: location.radius,
        });
      });
      resolve(processedLocations);
    }));
  },
  createLocation: (location) => {
    const DEFAULT_LOCATION = {
      name: 'DEFAULT',
      latitude: 33.9698,
      longitude: -118.4169,
      radius: 0.003,
    };

    const data = DEFAULT_LOCATION;
    data.name = location.name || data.name;
    data.latitude = location.latitude || data.latitude;
    data.longitude = location.longitude || data.longitude;
    data.radius = location.radius || data.radius;

    return SLocation.create(data).then(rawLocation => new Promise((resolve) => {
      resolve({
        id: rawLocation.id,
        name: rawLocation.name,
        latitude: rawLocation.latitude,
        longitude: rawLocation.longitude,
        radius: rawLocation.radius,
      });
    }));
  },
  getLocation: id => SLocation.findById(id).then(rawLocation => new Promise((resolve, reject) => {
    if (!rawLocation) reject({ code: 404 });
    resolve({
      id: rawLocation.id,
      name: rawLocation.name,
      latitude: rawLocation.latitude,
      longitude: rawLocation.longitude,
      radius: rawLocation.radius,
    });
  })),
  getLocationCount: (id, query) => SLocation.findById(id)
  .then((location) => {
    if (!location) return Promise.reject({ code: 404 });
    const timeSlices = [];
    if (query.start && query.end && query.slice) {
      let previousTime = Moment(query.end);
      for (let time = Moment(query.end).subtract(query.slice, 'minutes');
      time.isSameOrAfter(Moment(query.start));
      time = time.subtract(query.slice, 'minutes')) {
        timeSlices.push({
          start: time.toISOString(),
          end: previousTime.toISOString(),
        });
        previousTime = Moment(time);
      }
    } else {
      timeSlices.push({
        start: Moment().subtract(1, 'hours'),
        end: Moment(),
      });
    }
    return Promise.map(timeSlices, (slice) => {
      console.log(slice);
      return CollectionService.getAddressesWithinRange({
        latitude: location.latitude,
        longitude: location.longitude,
        radius: location.radius,
        start: slice.start,
        end: slice.end,
      });
    });
  })
  .catch((error) => {
    console.log(error);
    return Promise.reject(error);
  }),
};

module.exports = Service;
<|endoftext|>