<commit_before>/*ngInject*/
export function setupRoutes($stateProvider, $urlRouterProvider) {
    $stateProvider
        .state('login', {
            url: '/login',
            template: '<mc-login></mc-login>'
        })
        .state('join', {
            url: '/join',
            template: '<mc-join></mc-join>'
        })
        .state('validate', {
            url: '/validate/:validation_uuid',
            template: '<mc-join-validate></mc-join-validate>'
        })
        .state('reset', {
            url: '/reset',
            template: '<mc-reset-password></mc-reset-password>'
        })
        .state('rvalidate', {
            url: '/rvalidate/:validation_uuid',
            template: '<mc-reset-validate></mc-reset-validate>'
        })
        .state('projects', {
            url: '/projects',
            abstract: true,
            template: '

',
        })
        .state('projects.list', {
            url: '/list',
            template: '<mc-projects-list-view-container flex layout="column"></mc-projects-list-view-container>'
        })
        .state('globus', {
            url: '/globus',
            abstract: true,
            template: '

'
        })
        .state('globus.auth', {
            url: '/auth',
            abstract: true,
            template: '

'
        })
        .state('globus.auth.testing', {
            url: '/testing',
            template: '<mc-globus-auth-testing></mc-globus-auth-testing>'
        })
        .state('account', {
            url: '/account',
            abstract: true,
            template: '

'
        })
        .state('account.settings', {
            url: '/settings',
            template: '<md-content><mc-account-settings></mc-account-settings></md-content>'
        })
        .state('account.settings.profile', {
            url: '/profile',
            template: '<mc-account-settings-profile></mc-account-settings-profile>'
        })
        .state('account.settings.projects', {
            url: '/projects',
            template: '<mc-account-settings-projects></mc-account-settings-projects>'
        })
        .state('templates', {
            url: '/templates',
            abstract: true,
            template: '<md-content ui-view layout="column" flex></md-content>'
        })
        .state('templates.builder', {
            url: '/builder',
            template: '<mc-template-builder layout="column" layout-fill class="height-100"></mc-template-builder>'
        })
        .state('admin', {
            url: '/admin',
            abstract: true,
            template: '

'
        })
        .state('admin.info', {
            url: '/info',
            template: '<mc-admin-info></mc-admin-info>'
        })
        .state('admin.info.users', {
            url: '/users',
            template: '<mc-admin-info-users></mc-admin-info-users>'
        })
        .state('admin.info.projects', {
            url: '/users',
            template: '<mc-admin-info-projects></mc-admin-info-projects>'
        })
        .state('admin.info.globus', {
            url: '/globus',
            template: '<mc-admin-info-globus></mc-admin-info-globus>'
        })
        .state('public', {
            url: '/public',
            abstract: true,
            template: '

'
        })
        .state('public.templates', {
            url: '/templates',
            template: '<mc-public-templates layout="column" layout-fill class="height-100"></mc-public-templates>'
        })
        .state('project', {
            url: '/project/:project_id',
            template: '<mc-project-view-container class="height-100" flex="100" layout="column"></mc-project-view-container>',
            resolve: {
                _project: ['projectsAPI', '$stateParams', 'mcStateStore', function(projectsAPI, $stateParams, mcStateStore) {
                    return projectsAPI.getProjectOverview($stateParams.project_id).then(p => {
                        mcStateStore.updateState('project', p);
                        return p;
                    });
                }]
            }
        })
        .state('project.home', {
            url: '/home',
            template: '<md-content layout="column" className="height-100"><mc-project-home project="$resolve._project" class="height-100"></mc-project-home></md-content>'
        })
        .state('project.details', {
            url: '/details',
            template: '<md-content layout="column" class="height-100"><mc-project-details class="height-100"></mc-project-details></md-content>'
        })
        .state('project.search', {
            url: '/search/:query',
            template: '<mc-project-search></mc-project-search>'
        })
        .state('project.notes', {
            url: '/notes',
            template: '<md-content layout="column" class="height-100"><mc-project-notes class="height-100"></mc-project-notes></md-content>'
        })
        .state('project.create', {
            url: '/create',
            abstract: true,
            template: '<ui-view flex layout="column"></ui-view>'
        })
        .state('project.experiment', {
            url: '/experiment/:experiment_id',
            template: `<mc-experiment experiment="$resolve.experiment" class="height-100"></mc-experiment>`,
            resolve: {
                experiment: ['$stateParams', 'experimentsAPI', 'mcStateStore',
                    ($stateParams, experimentsAPI, mcStateStore) => {
                        let e = mcStateStore.getState(`experiment:${$stateParams.experiment_id}`);
                        if (e !== null) {
                            return e;
                        }

                        return experimentsAPI.getExperimentForProject($stateParams.project_id, $stateParams.experiment_id).then((e) => e);
                    }
                ]
            }
        })
        .state('project.experiment.details', {
            url: '/details',
            template: '<md-content layout="column" class="height-100"><mc-experiment-details experiment="$resolve.experiment" show-note="true"></mc-experiment-details></md-content>'
        })
        .state('project.experiment.workflow', {
            url: '/workflow',
            template: '<mc-experiment-workflow-view-container experiment="$resolve.experiment"></mc-experiment-workflow-view-container>'
            // template: '<mc-processes-workflow processes="$resolve.processes"></mc-processes-workflow>',
            // resolve: {
            //     processes: ['experiment', (experiment) => _.values(experiment.processes)]
            // }
        })
        .state('project.experiment.samples', {
            url: '/samples',
            template: '<md-content layout="column" class="height-100"><mc-project-samples samples="$resolve.samples"></mc-project-samples></md-content>',
            resolve: {
                samples: ['experimentsAPI', 'mcprojstore',
                    (experimentsAPI, mcprojstore) => {
                        const e = mcprojstore.currentExperiment;
                        const p = mcprojstore.currentProject;
                        return experimentsAPI.getSamplesForExperiment(p.id, e.id);
                    }
                ]
            }
        })
        .state('project.experiment.files', {
            url: '/files',
            template: '<md-content layout="column" class="height-100"><mc-experiment-files files="$resolve.files"></mc-experiment-files></md-content>',
            resolve: {
                files: ['experimentsAPI', '$stateParams',
                    (experimentsAPI, $stateParams) =>
                        experimentsAPI.getFilesForExperiment($stateParams.project_id, $stateParams.experiment_id)
                ]
            }
        })
        .state('project.experiment.tbuilder', {
            url: '/tbuilder',
            template: '<md-content layout="column" class="height-100"><mc-template-builder layout="column" layout-fill></mc-template-builder></md-content>'
        })
        .state('project.experiment.publish', {
            url: '/publish',
            template: '<mc-experiment-publish></mc-experiment-publish>'
        })
        .state('project.experiment.datasets', {
            url: '/datasets',
            template: '<md-content layout="column" class="height-100">

</md-content>',
            abstract: true
        })
        .state('project.experiment.datasets.list', {
            url: '/list',
            template: '<mc-experiment-datasets layout="column" flex></mc-experiment-datasets>'
        })
        .state('project.experiment.datasets.dataset', {
            url: '/dataset/:dataset_id',
            template: '<mc-experiment-dataset layout="column" flex layout-fill></mc-experiment-dataset>'
        })
        .state('project.experiment.sample', {
            url: '/sample/:sample_id',
            template: '<mc-show-sample sample-id="ctrl.sampleId"></mc-show-sample>',
            controllerAs: 'ctrl',
            controller: ['$stateParams', function($stateParams) {
                this.sampleId = $stateParams.sample_id;
            }]
        })
        .state('project.experiments', {
            url: '/experiments',
            template: '<mc-project-experiments experiments="$resolve.experiments"></mc-project-experiments>',
            resolve: {
                experiments: ['experimentsAPI', '$stateParams',
                    (experimentsAPI, $stateParams) =>
                        experimentsAPI.getAllForProject($stateParams.project_id)
                ]
            }
        })
        .state('project.processes', {
            url: '/processes',
            template: '<mc-project-processes processes="$resolve.processes"></mc-project-processes>',
            resolve: {
                processes: ['projectsAPI', '$stateParams',
                    (projectsAPI, $stateParams) =>
                        projectsAPI.getProjectProcesses($stateParams.project_id)
                ]
            }
        })
        .state('project.samples', {
            url: '/samples',
            template: '<md-content layout="column" class="height-100"><mc-project-samples samples="$resolve.samples" class="height-100"></mc-project-samples></md-content>',
            resolve: {
                samples: ['samplesAPI', '$stateParams',
                    (samplesAPI, $stateParams) =>
                        samplesAPI.getProjectSamples($stateParams.project_id)
                ]
            }
        })
        .state('project.samples.sample', {
            url: '/sample/:sample_id',
            template: '<mc-sample></mc-sample>'
        })
        .state('project.files', {
            url: '/files',
            // template: '<mc-file-tree flex layout-fill></mc-file-tree>'
            template: '<mc-project-files-view-container flex layout-fill></mc-project-files-view-container>'
        })
        .state('project.files.uploads2', {
            url: '/uploads2/:directory_id',
            template: '<mc-file-tree-uploader-container></mc-file-tree-uploader-container>'
        })
        .state('project.files.uploads', {
            url: '/uploads',
            template: '<mc-file-uploads reset-files="true"></mc-file-uploads>'
        })
        .state('project.files.file', {
            url: '/file/:file_id',
            template: '<mc-file-container></mc-file-container>'
        })
        .state('project.files.dir', {
            url: '/dir/:dir_id',
            template: '<mc-dir-container></mc-dir-container>'
        })
        .state('project.file', {
            url: '/file/:file_id',
            template: '<mc-file></mc-file>'
        })
        .state('project.sample', {
            url: '/sample/:sample_id',
            template: '<mc-sample></mc-sample>'
        })
        .state('project.datasets', {
            url: '/datasets',
            abstract: true,
            template: '<md-content>

</md-content>',
        })
        .state('project.datasets.list', {
            url: '/list',
            template: '<mc-project-datasets-view-container layout-fill flex></mc-project-datasets-view-container>'
        })
        .state('project.datasets.dataset', {
            url: '/dataset/:dataset_id',
            // template: '<md-content layout-fill flex layout="column" style="background-color:brown"><mc-project-dataset-view-container></mc-project-dataset-view-container></md-content>'
            template: '<mc-project-dataset-view-container></mc-project-dataset-view-container>'
        })
        .state('project.settings', {
            url: '/settings',
            template: '<mc-project-settings></mc-project-settings>'
        })
        .state('project.collaborators', {
            url: '/collaborators',
            template: '<mc-project-collaborators class="height-100"></mc-project-collaborators>'
        })
        .state('data', {
            url: '/data',
            abstract: true,
            // template: '<md-content ui-view flex></md-content>'
            template: '

'
        })
        .state('data.dataset', {
            url: '/dataset/:dataset_id',
            template: '<mc-dataset-overview-container layout="column" flex></mc-dataset-overview-container>'
        })
        .state('data.home', {
            url: '/home',
            template: '<md-content flex><mc-data-home tags="$resolve.tags"></mc-data-home></md-content>',
            resolve: {
                tags: ['publicTagsAPI',
                    (publicTagsAPI) => publicTagsAPI.getPopularTags().then(
                        (tags) => tags.map(t => t.tag)
                    )
                ]
            }
        })
        .state('data.tag', {
            url: '/tag/:tag',
            template: '<mc-dataset-list datasets="$resolve.datasets" details-route="data.dataset" layout-margin></mc-dataset-list>',
            resolve: {
                datasets: ['publicDatasetsAPI', '$stateParams',
                    (publicDatasetsAPI, $stateParams) => publicDatasetsAPI.getDatasetsForTag($stateParams.tag)
                ]
            }
        })
        .state('data.home.recent', {
            url: '/recent',
            template: '<mc-dataset-list datasets="$resolve.datasets" details-route="data.dataset"></mc-dataset-list>',
            resolve: {
                datasets: ['publicDatasetsAPI',
                    (publicDatasetsAPI) => publicDatasetsAPI.getRecent()
                ]
            }
        })
        .state('data.home.top', {
            url: '/top',
            template: '<mc-dataset-list datasets="$resolve.datasets" details-route="data.dataset"></mc-dataset-list>',
            resolve: {
                datasets: ['publicDatasetsAPI',
                    (publicDatasetsAPI) => publicDatasetsAPI.getTopViewed()
                ]
            }
        });

    // $urlRouterProvider.otherwise('/login');
    $urlRouterProvider.otherwise('/data/home/top');
}
<commit_msg>Change to mcStateStore for samples<commit_after>/*ngInject*/
export function setupRoutes($stateProvider, $urlRouterProvider) {
    $stateProvider
        .state('login', {
            url: '/login',
            template: '<mc-login></mc-login>'
        })
        .state('join', {
            url: '/join',
            template: '<mc-join></mc-join>'
        })
        .state('validate', {
            url: '/validate/:validation_uuid',
            template: '<mc-join-validate></mc-join-validate>'
        })
        .state('reset', {
            url: '/reset',
            template: '<mc-reset-password></mc-reset-password>'
        })
        .state('rvalidate', {
            url: '/rvalidate/:validation_uuid',
            template: '<mc-reset-validate></mc-reset-validate>'
        })
        .state('projects', {
            url: '/projects',
            abstract: true,
            template: '

',
        })
        .state('projects.list', {
            url: '/list',
            template: '<mc-projects-list-view-container flex layout="column"></mc-projects-list-view-container>'
        })
        .state('globus', {
            url: '/globus',
            abstract: true,
            template: '

'
        })
        .state('globus.auth', {
            url: '/auth',
            abstract: true,
            template: '

'
        })
        .state('globus.auth.testing', {
            url: '/testing',
            template: '<mc-globus-auth-testing></mc-globus-auth-testing>'
        })
        .state('account', {
            url: '/account',
            abstract: true,
            template: '

'
        })
        .state('account.settings', {
            url: '/settings',
            template: '<md-content><mc-account-settings></mc-account-settings></md-content>'
        })
        .state('account.settings.profile', {
            url: '/profile',
            template: '<mc-account-settings-profile></mc-account-settings-profile>'
        })
        .state('account.settings.projects', {
            url: '/projects',
            template: '<mc-account-settings-projects></mc-account-settings-projects>'
        })
        .state('templates', {
            url: '/templates',
            abstract: true,
            template: '<md-content ui-view layout="column" flex></md-content>'
        })
        .state('templates.builder', {
            url: '/builder',
            template: '<mc-template-builder layout="column" layout-fill class="height-100"></mc-template-builder>'
        })
        .state('admin', {
            url: '/admin',
            abstract: true,
            template: '

'
        })
        .state('admin.info', {
            url: '/info',
            template: '<mc-admin-info></mc-admin-info>'
        })
        .state('admin.info.users', {
            url: '/users',
            template: '<mc-admin-info-users></mc-admin-info-users>'
        })
        .state('admin.info.projects', {
            url: '/users',
            template: '<mc-admin-info-projects></mc-admin-info-projects>'
        })
        .state('admin.info.globus', {
            url: '/globus',
            template: '<mc-admin-info-globus></mc-admin-info-globus>'
        })
        .state('public', {
            url: '/public',
            abstract: true,
            template: '

'
        })
        .state('public.templates', {
            url: '/templates',
            template: '<mc-public-templates layout="column" layout-fill class="height-100"></mc-public-templates>'
        })
        .state('project', {
            url: '/project/:project_id',
            template: '<mc-project-view-container class="height-100" flex="100" layout="column"></mc-project-view-container>',
            resolve: {
                _project: ['projectsAPI', '$stateParams', 'mcStateStore', function(projectsAPI, $stateParams, mcStateStore) {
                    return projectsAPI.getProjectOverview($stateParams.project_id).then(p => {
                        mcStateStore.updateState('project', p);
                        return p;
                    });
                }]
            }
        })
        .state('project.home', {
            url: '/home',
            template: '<md-content layout="column" className="height-100"><mc-project-home project="$resolve._project" class="height-100"></mc-project-home></md-content>'
        })
        .state('project.details', {
            url: '/details',
            template: '<md-content layout="column" class="height-100"><mc-project-details class="height-100"></mc-project-details></md-content>'
        })
        .state('project.search', {
            url: '/search/:query',
            template: '<mc-project-search></mc-project-search>'
        })
        .state('project.notes', {
            url: '/notes',
            template: '<md-content layout="column" class="height-100"><mc-project-notes class="height-100"></mc-project-notes></md-content>'
        })
        .state('project.create', {
            url: '/create',
            abstract: true,
            template: '<ui-view flex layout="column"></ui-view>'
        })
        .state('project.experiment', {
            url: '/experiment/:experiment_id',
            template: `<mc-experiment experiment="$resolve.experiment" class="height-100"></mc-experiment>`,
            resolve: {
                experiment: ['$stateParams', 'experimentsAPI', 'mcStateStore',
                    ($stateParams, experimentsAPI, mcStateStore) => {
                        let e = mcStateStore.getState(`experiment:${$stateParams.experiment_id}`);
                        if (e !== null) {
                            return e;
                        }

                        return experimentsAPI.getExperimentForProject($stateParams.project_id, $stateParams.experiment_id).then((e) => e);
                    }
                ]
            }
        })
        .state('project.experiment.details', {
            url: '/details',
            template: '<md-content layout="column" class="height-100"><mc-experiment-details experiment="$resolve.experiment" show-note="true"></mc-experiment-details></md-content>'
        })
        .state('project.experiment.workflow', {
            url: '/workflow',
            template: '<mc-experiment-workflow-view-container experiment="$resolve.experiment"></mc-experiment-workflow-view-container>'
            // template: '<mc-processes-workflow processes="$resolve.processes"></mc-processes-workflow>',
            // resolve: {
            //     processes: ['experiment', (experiment) => _.values(experiment.processes)]
            // }
        })
        .state('project.experiment.samples', {
            url: '/samples',
            template: '<md-content layout="column" class="height-100"><mc-project-samples samples="$resolve.samples"></mc-project-samples></md-content>',
            resolve: {
                samples: ['experimentsAPI', 'mcStateStore',
                    (experimentsAPI, mcStateStore) => {
                        const e = mcStateStore.getState('experiment');
                        const p = mcStateStore.getState('project');
                        return experimentsAPI.getSamplesForExperiment(p.id, e.id);
                    }
                ]
            }
        })
        .state('project.experiment.files', {
            url: '/files',
            template: '<md-content layout="column" class="height-100"><mc-experiment-files files="$resolve.files"></mc-experiment-files></md-content>',
            resolve: {
                files: ['experimentsAPI', '$stateParams',
                    (experimentsAPI, $stateParams) =>
                        experimentsAPI.getFilesForExperiment($stateParams.project_id, $stateParams.experiment_id)
                ]
            }
        })
        .state('project.experiment.tbuilder', {
            url: '/tbuilder',
            template: '<md-content layout="column" class="height-100"><mc-template-builder layout="column" layout-fill></mc-template-builder></md-content>'
        })
        .state('project.experiment.publish', {
            url: '/publish',
            template: '<mc-experiment-publish></mc-experiment-publish>'
        })
        .state('project.experiment.datasets', {
            url: '/datasets',
            template: '<md-content layout="column" class="height-100">

</md-content>',
            abstract: true
        })
        .state('project.experiment.datasets.list', {
            url: '/list',
            template: '<mc-experiment-datasets layout="column" flex></mc-experiment-datasets>'
        })
        .state('project.experiment.datasets.dataset', {
            url: '/dataset/:dataset_id',
            template: '<mc-experiment-dataset layout="column" flex layout-fill></mc-experiment-dataset>'
        })
        .state('project.experiment.sample', {
            url: '/sample/:sample_id',
            template: '<mc-show-sample sample-id="ctrl.sampleId"></mc-show-sample>',
            controllerAs: 'ctrl',
            controller: ['$stateParams', function($stateParams) {
                this.sampleId = $stateParams.sample_id;
            }]
        })
        .state('project.experiments', {
            url: '/experiments',
            template: '<mc-project-experiments experiments="$resolve.experiments"></mc-project-experiments>',
            resolve: {
                experiments: ['experimentsAPI', '$stateParams',
                    (experimentsAPI, $stateParams) =>
                        experimentsAPI.getAllForProject($stateParams.project_id)
                ]
            }
        })
        .state('project.processes', {
            url: '/processes',
            template: '<mc-project-processes processes="$resolve.processes"></mc-project-processes>',
            resolve: {
                processes: ['projectsAPI', '$stateParams',
                    (projectsAPI, $stateParams) =>
                        projectsAPI.getProjectProcesses($stateParams.project_id)
                ]
            }
        })
        .state('project.samples', {
            url: '/samples',
            template: '<md-content layout="column" class="height-100"><mc-project-samples samples="$resolve.samples" class="height-100"></mc-project-samples></md-content>',
            resolve: {
                samples: ['samplesAPI', '$stateParams',
                    (samplesAPI, $stateParams) =>
                        samplesAPI.getProjectSamples($stateParams.project_id)
                ]
            }
        })
        .state('project.samples.sample', {
            url: '/sample/:sample_id',
            template: '<mc-sample></mc-sample>'
        })
        .state('project.files', {
            url: '/files',
            // template: '<mc-file-tree flex layout-fill></mc-file-tree>'
            template: '<mc-project-files-view-container flex layout-fill></mc-project-files-view-container>'
        })
        .state('project.files.uploads2', {
            url: '/uploads2/:directory_id',
            template: '<mc-file-tree-uploader-container></mc-file-tree-uploader-container>'
        })
        .state('project.files.uploads', {
            url: '/uploads',
            template: '<mc-file-uploads reset-files="true"></mc-file-uploads>'
        })
        .state('project.files.file', {
            url: '/file/:file_id',
            template: '<mc-file-container></mc-file-container>'
        })
        .state('project.files.dir', {
            url: '/dir/:dir_id',
            template: '<mc-dir-container></mc-dir-container>'
        })
        .state('project.file', {
            url: '/file/:file_id',
            template: '<mc-file></mc-file>'
        })
        .state('project.sample', {
            url: '/sample/:sample_id',
            template: '<mc-sample></mc-sample>'
        })
        .state('project.datasets', {
            url: '/datasets',
            abstract: true,
            template: '<md-content>

</md-content>',
        })
        .state('project.datasets.list', {
            url: '/list',
            template: '<mc-project-datasets-view-container layout-fill flex></mc-project-datasets-view-container>'
        })
        .state('project.datasets.dataset', {
            url: '/dataset/:dataset_id',
            // template: '<md-content layout-fill flex layout="column" style="background-color:brown"><mc-project-dataset-view-container></mc-project-dataset-view-container></md-content>'
            template: '<mc-project-dataset-view-container></mc-project-dataset-view-container>'
        })
        .state('project.settings', {
            url: '/settings',
            template: '<mc-project-settings></mc-project-settings>'
        })
        .state('project.collaborators', {
            url: '/collaborators',
            template: '<mc-project-collaborators class="height-100"></mc-project-collaborators>'
        })
        .state('data', {
            url: '/data',
            abstract: true,
            // template: '<md-content ui-view flex></md-content>'
            template: '

'
        })
        .state('data.dataset', {
            url: '/dataset/:dataset_id',
            template: '<mc-dataset-overview-container layout="column" flex></mc-dataset-overview-container>'
        })
        .state('data.home', {
            url: '/home',
            template: '<md-content flex><mc-data-home tags="$resolve.tags"></mc-data-home></md-content>',
            resolve: {
                tags: ['publicTagsAPI',
                    (publicTagsAPI) => publicTagsAPI.getPopularTags().then(
                        (tags) => tags.map(t => t.tag)
                    )
                ]
            }
        })
        .state('data.tag', {
            url: '/tag/:tag',
            template: '<mc-dataset-list datasets="$resolve.datasets" details-route="data.dataset" layout-margin></mc-dataset-list>',
            resolve: {
                datasets: ['publicDatasetsAPI', '$stateParams',
                    (publicDatasetsAPI, $stateParams) => publicDatasetsAPI.getDatasetsForTag($stateParams.tag)
                ]
            }
        })
        .state('data.home.recent', {
            url: '/recent',
            template: '<mc-dataset-list datasets="$resolve.datasets" details-route="data.dataset"></mc-dataset-list>',
            resolve: {
                datasets: ['publicDatasetsAPI',
                    (publicDatasetsAPI) => publicDatasetsAPI.getRecent()
                ]
            }
        })
        .state('data.home.top', {
            url: '/top',
            template: '<mc-dataset-list datasets="$resolve.datasets" details-route="data.dataset"></mc-dataset-list>',
            resolve: {
                datasets: ['publicDatasetsAPI',
                    (publicDatasetsAPI) => publicDatasetsAPI.getTopViewed()
                ]
            }
        });

    // $urlRouterProvider.otherwise('/login');
    $urlRouterProvider.otherwise('/data/home/top');
}
<|endoftext|>


<commit_before>/*globals define, _*/

/**
 * @author brollb / https://github.com/brollb
 */

define(['js/Decorators/DecoratorWithPorts.Base',
        'js/Widgets/DiagramDesigner/DiagramDesignerWidget.Constants',
        './SVGPort'], function (DecoratorWithPortsBase,
                                DiagramDesignerWidgetConstants,
                                SVGPort) {

    "use strict";

    var SVGDecoratorPorts,
        ABSTRACT_CLASS = 'abstract',
        PORT_HEIGHT = 13,   //must be same as SVGDecorator.scss 's $port-height
        DEFAULT_SVG_DEFAULT_HEIGHT = 50;

    SVGDecoratorPorts = function(){
        DecoratorWithPortsBase.apply(this, []);
    };

    _.extend( SVGDecoratorPorts.prototype, DecoratorWithPortsBase.prototype);

    SVGDecoratorPorts.prototype._initializePortVariables = function (params) {
        this._PORT_HEIGHT = PORT_HEIGHT;
    };

    SVGDecoratorPorts.prototype._updatePorts = function () {
        var svg = this.$svgElement,
            svgWidth = parseInt(svg.attr('width'), 10),
            halfW = svgWidth / 2;

        this._portContainerWidth = halfW;

        if (!this.$leftPorts) {
            this.$leftPorts = $('<div/>', {'class': 'ports ports-l'});
            this.$leftPorts.insertAfter(this.$svgContent);
        }
        this.$leftPorts.css({'width': halfW});

        if (!this.$rightPorts) {
            this.$rightPorts = $('<div/>', {'class': 'ports ports-r'});
            this.$rightPorts.insertAfter(this.$svgContent);
        }
        this.$rightPorts.css({'width': halfW,
                              'left': halfW});

        this.updatePortIDList();

        for (var i = 0; i < this.portIDs.length; i += 1) {
            this.ports[this.portIDs[i]].update();
        }

        this._updatePortPositions();
    };

    SVGDecoratorPorts.prototype._fixPortContainerPosition = function (xShift) {
        this._portContainerXShift = xShift;
        this.$leftPorts.css('transform', 'translateX(' + xShift + 'px)');
        this.$rightPorts.css('transform', 'translateX(' + xShift + 'px)');
    };

    SVGDecoratorPorts.prototype.renderPort = function (portId) {
        return new SVGPort({'id': portId,
            'logger': this.logger,
            'client': this._control._client,
            'decorator': this});
    };

    SVGDecoratorPorts.prototype._updatePortPositions = function () {
        var leftPorts = [],
            rightPorts = [],
            i,
            RIGHT_POS_X = 300,
            TITLE_PADDING = 2,
            PORT_TOP_PADDING = 1,
            ports = this.ports,
            portSorter,
            portInstance;

        for (i = 0; i < this.portIDs.length; i += 1) {
            if (this.ports[this.portIDs[i]].positionX > RIGHT_POS_X) {
                rightPorts.push(this.portIDs[i]);
            } else {
                leftPorts.push(this.portIDs[i]);
            }
        }

        portSorter = function (a, b) {
            var portAY = ports[a].positionY,
                portBY = ports[b].positionY;

            return portAY - portBY;
        };

        //sort the left and right ports based on their Y position
        leftPorts.sort(portSorter);
        rightPorts.sort(portSorter);

        for (i = 0; i < leftPorts.length; i += 1) {
            portInstance = ports[leftPorts[i]];
            this.$leftPorts.append(portInstance.$el);
            portInstance.updateOrientation(true);
            portInstance.updateTop(PORT_TOP_PADDING + i * PORT_HEIGHT);
        }
        this.$leftPorts.css('height', leftPorts.length * PORT_HEIGHT);
        this.$leftPorts.find('.port > .title').css('left', TITLE_PADDING);
        this.$leftPorts.find('.port > .title').css('width', this._portContainerWidth - TITLE_PADDING);
        this.$leftPorts.find('.port > .icon').css('left', -PORT_HEIGHT);
        this.$leftPorts.find('.port > .' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS).css('left', -PORT_HEIGHT + 1);

        for (i = 0; i < rightPorts.length; i += 1) {
            portInstance = ports[rightPorts[i]];
            this.$rightPorts.append(portInstance.$el);
            portInstance.updateOrientation(false);
            portInstance.updateTop(PORT_TOP_PADDING + i * PORT_HEIGHT);
        }
        this.$rightPorts.css('height', rightPorts.length * PORT_HEIGHT);
        this.$rightPorts.find('.port > .title').css('right', -this._portContainerWidth + TITLE_PADDING);
        this.$rightPorts.find('.port > .title').css('width', this._portContainerWidth - TITLE_PADDING);
        this.$rightPorts.find('.port > .icon').css('left', this._portContainerWidth);
        this.$rightPorts.find('.port > .' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS).css('left', this._portContainerWidth);

        //store if we have ports on the left/right
        this._leftPorts = leftPorts.length > 0;
        this._rightPorts = rightPorts.length > 0;

        //fix default SVG's dimensions to sorround the ports
        //defaultSVG only, nothing else
        if (this._defaultSVGUsed === true) {
            var svg = this.$svgElement;
            var svgRect = svg.find('rect');
            var height = Math.max(leftPorts.length * PORT_HEIGHT, rightPorts.length * PORT_HEIGHT, DEFAULT_SVG_DEFAULT_HEIGHT);
            svg.attr('height', height);
            svgRect.attr('height', height - 1);

            var connectorSouth = this.$el.find('.' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS + '.cs');
            connectorSouth.css('top', height);
        }

        //remove left side connector if there is port there
        if (this._leftPorts) {
            var connectorWest = this.$el.find('.' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS + '.cw');
            connectorWest.css('top', height / 2);
            connectorWest.remove();
        }

        //remove right side connector if there is port there
        if (this._rightPorts) {
            var connectorEast = this.$el.find('.' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS + '.ce');
            connectorEast.css('top', height / 2);
            connectorEast.remove();
        }
    };

    SVGDecoratorPorts.prototype._updatePort = function (portId) {
        var isPort = this.isPort(portId);

        if (this.ports[portId]) {
            //port already, should it stay?
            if (isPort === true) {
                this.ports[portId].update();
            } else {
                this.removePort(portId);
            }
        } else {
            this.addPort(portId);
            //if it became a port, update it
            if (this.ports[portId]) {
                this.ports[portId].update();
            }
        }

        this._updatePortPositions();
    };

    return SVGDecoratorPorts;
});

<commit_msg>fixing up var declaration<commit_after>/*globals define, _*/

/**
 * @author brollb / https://github.com/brollb
 */

define(['js/Decorators/DecoratorWithPorts.Base',
        'js/Widgets/DiagramDesigner/DiagramDesignerWidget.Constants',
        './SVGPort'], function (DecoratorWithPortsBase,
                                DiagramDesignerWidgetConstants,
                                SVGPort) {

    "use strict";

    var SVGDecoratorPorts,
        ABSTRACT_CLASS = 'abstract',
        PORT_HEIGHT = 13,   //must be same as SVGDecorator.scss 's $port-height
        DEFAULT_SVG_DEFAULT_HEIGHT = 50;

    SVGDecoratorPorts = function(){
        DecoratorWithPortsBase.apply(this, []);
    };

    _.extend( SVGDecoratorPorts.prototype, DecoratorWithPortsBase.prototype);

    SVGDecoratorPorts.prototype._initializePortVariables = function (params) {
        this._PORT_HEIGHT = PORT_HEIGHT;
    };

    SVGDecoratorPorts.prototype._updatePorts = function () {
        var svg = this.$svgElement,
            svgWidth = parseInt(svg.attr('width'), 10),
            halfW = svgWidth / 2;

        this._portContainerWidth = halfW;

        if (!this.$leftPorts) {
            this.$leftPorts = $('<div/>', {'class': 'ports ports-l'});
            this.$leftPorts.insertAfter(this.$svgContent);
        }
        this.$leftPorts.css({'width': halfW});

        if (!this.$rightPorts) {
            this.$rightPorts = $('<div/>', {'class': 'ports ports-r'});
            this.$rightPorts.insertAfter(this.$svgContent);
        }
        this.$rightPorts.css({'width': halfW,
                              'left': halfW});

        this.updatePortIDList();

        for (var i = 0; i < this.portIDs.length; i += 1) {
            this.ports[this.portIDs[i]].update();
        }

        this._updatePortPositions();
    };

    SVGDecoratorPorts.prototype._fixPortContainerPosition = function (xShift) {
        this._portContainerXShift = xShift;
        this.$leftPorts.css('transform', 'translateX(' + xShift + 'px)');
        this.$rightPorts.css('transform', 'translateX(' + xShift + 'px)');
    };

    SVGDecoratorPorts.prototype.renderPort = function (portId) {
        return new SVGPort({'id': portId,
            'logger': this.logger,
            'client': this._control._client,
            'decorator': this});
    };

    SVGDecoratorPorts.prototype._updatePortPositions = function () {
        var leftPorts = [],
            rightPorts = [],
            i,
            RIGHT_POS_X = 300,
            TITLE_PADDING = 2,
            PORT_TOP_PADDING = 1,
            ports = this.ports,
            portSorter,
            portInstance,

            svg,
            svgRect,
            height,

            connectorSouth,
            connectorWest,
            connectorEast;

        for (i = 0; i < this.portIDs.length; i += 1) {
            if (this.ports[this.portIDs[i]].positionX > RIGHT_POS_X) {
                rightPorts.push(this.portIDs[i]);
            } else {
                leftPorts.push(this.portIDs[i]);
            }
        }

        portSorter = function (a, b) {
            var portAY = ports[a].positionY,
                portBY = ports[b].positionY;

            return portAY - portBY;
        };

        //sort the left and right ports based on their Y position
        leftPorts.sort(portSorter);
        rightPorts.sort(portSorter);

        for (i = 0; i < leftPorts.length; i += 1) {
            portInstance = ports[leftPorts[i]];
            this.$leftPorts.append(portInstance.$el);
            portInstance.updateOrientation(true);
            portInstance.updateTop(PORT_TOP_PADDING + i * PORT_HEIGHT);
        }
        this.$leftPorts.css('height', leftPorts.length * PORT_HEIGHT);
        this.$leftPorts.find('.port > .title').css('left', TITLE_PADDING);
        this.$leftPorts.find('.port > .title').css('width', this._portContainerWidth - TITLE_PADDING);
        this.$leftPorts.find('.port > .icon').css('left', -PORT_HEIGHT);
        this.$leftPorts.find('.port > .' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS).css('left', -PORT_HEIGHT + 1);

        for (i = 0; i < rightPorts.length; i += 1) {
            portInstance = ports[rightPorts[i]];
            this.$rightPorts.append(portInstance.$el);
            portInstance.updateOrientation(false);
            portInstance.updateTop(PORT_TOP_PADDING + i * PORT_HEIGHT);
        }
        this.$rightPorts.css('height', rightPorts.length * PORT_HEIGHT);
        this.$rightPorts.find('.port > .title').css('right', -this._portContainerWidth + TITLE_PADDING);
        this.$rightPorts.find('.port > .title').css('width', this._portContainerWidth - TITLE_PADDING);
        this.$rightPorts.find('.port > .icon').css('left', this._portContainerWidth);
        this.$rightPorts.find('.port > .' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS).css('left', this._portContainerWidth);

        //store if we have ports on the left/right
        this._leftPorts = leftPorts.length > 0;
        this._rightPorts = rightPorts.length > 0;

        height = Math.max(leftPorts.length * PORT_HEIGHT, rightPorts.length * PORT_HEIGHT, DEFAULT_SVG_DEFAULT_HEIGHT);

        //fix default SVG's dimensions to sorround the ports
        //defaultSVG only, nothing else
        if (this._defaultSVGUsed === true) {
            svg = this.$svgElement;
            svgRect = svg.find('rect');

            svg.attr('height', height);
            svgRect.attr('height', height - 1);

            connectorSouth = this.$el.find('.' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS + '.cs');
            connectorSouth.css('top', height);
        }

        //remove left side connector if there is port there
        if (this._leftPorts) {
            connectorWest = this.$el.find('.' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS + '.cw');
            connectorWest.css('top', height / 2);
            connectorWest.remove();
        }

        //remove right side connector if there is port there
        if (this._rightPorts) {
            connectorEast = this.$el.find('.' + DiagramDesignerWidgetConstants.CONNECTOR_CLASS + '.ce');
            connectorEast.css('top', height / 2);
            connectorEast.remove();
        }
    };

    SVGDecoratorPorts.prototype._updatePort = function (portId) {
        var isPort = this.isPort(portId);

        if (this.ports[portId]) {
            //port already, should it stay?
            if (isPort === true) {
                this.ports[portId].update();
            } else {
                this.removePort(portId);
            }
        } else {
            this.addPort(portId);
            //if it became a port, update it
            if (this.ports[portId]) {
                this.ports[portId].update();
            }
        }

        this._updatePortPositions();
    };

    return SVGDecoratorPorts;
});

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */

'use strict';

const startButton = document.getElementById('startButton');
const callButton = document.getElementById('callButton');
const restartButton = document.getElementById('restartButton');
const hangupButton = document.getElementById('hangupButton');
callButton.disabled = true;
hangupButton.disabled = true;
restartButton.disabled = true;
startButton.onclick = start;
callButton.onclick = call;
hangupButton.onclick = hangup;
restartButton.onclick = restart;

let startTime;
const localVideo = document.getElementById('localVideo');
const remoteVideo = document.getElementById('remoteVideo');

localVideo.addEventListener('loadedmetadata', function() {
  trace(`Local video videoWidth: ${this.videoWidth}px,  videoHeight: ${this.videoHeight}px`);
});

remoteVideo.addEventListener('loadedmetadata', function() {
  trace(`Remote video videoWidth: ${this.videoWidth}px,  videoHeight: ${this.videoHeight}px`);
});

remoteVideo.onresize = () => {
  trace(`Remote video size changed to ${remoteVideo.videoWidth}x${remoteVideo.videoHeight}`);
  // We'll use the first onsize callback as an indication that video has started
  // playing out.
  if (startTime) {
    const elapsedTime = window.performance.now() - startTime;
    trace('Setup time: ' + elapsedTime.toFixed(3) + 'ms');
    startTime = null;
    // Have run these functions again in order to get the getStats() reports
    // with type candidatePair and populate the candidate id
    // elements.
    checkStats(pc1);
    checkStats(pc2);
  }
};

let localStream;
let pc1;
let pc2;
const offerOptions = {
  offerToReceiveAudio: 1,
  offerToReceiveVideo: 1
};

function getName(pc) {
  return (pc === pc1) ? 'pc1' : 'pc2';
}

function getOtherPc(pc) {
  return (pc === pc1) ? pc2 : pc1;
}

function gotStream(stream) {
  trace('Received local stream');
  localVideo.srcObject = stream;
  localStream = stream;
  callButton.disabled = false;
}

function start() {
  trace('Requesting local stream');
  startButton.disabled = true;
  navigator.mediaDevices
    .getUserMedia({
      audio: true,
      video: true
    })
    .then(gotStream)
    .catch(e => alert(`getUserMedia() error: ${e.name}`));
}

// Simulate an ice restart.
function restart() {
  restartButton.disabled = true;
  offerOptions.iceRestart = true;
  trace('pc1 createOffer restart');
  pc1.createOffer(offerOptions).then(onCreateOfferSuccess, onCreateSessionDescriptionError);
}

function call() {
  callButton.disabled = true;
  hangupButton.disabled = false;
  trace('Starting call');
  startTime = window.performance.now();
  const videoTracks = localStream.getVideoTracks();
  const audioTracks = localStream.getAudioTracks();
  if (videoTracks.length > 0) {
    trace(`Using video device: ${videoTracks[0].label}`);
  }
  if (audioTracks.length > 0) {
    trace(`Using audio device: ${audioTracks[0].label}`);
  }
  const servers = null;
  pc1 = new RTCPeerConnection(servers);
  trace('Created local peer connection object pc1');
  pc1.onicecandidate = e => onIceCandidate(pc1, e);
  pc2 = new RTCPeerConnection(servers);
  trace('Created remote peer connection object pc2');
  pc2.onicecandidate = e => onIceCandidate(pc2, e);
  pc1.oniceconnectionstatechange = e => {
    onIceStateChange(pc1, e);
    if (pc1 && pc1.iceConnectionState === 'completed') {
      restartButton.disabled = false;
    }
  };
  pc2.oniceconnectionstatechange = e => onIceStateChange(pc2, e);
  pc2.ontrack = gotRemoteStream;

  localStream.getTracks().forEach(track => pc1.addTrack(track, localStream)
  );
  trace('Added local stream to pc1');

  trace('pc1 createOffer start');
  pc1.createOffer(offerOptions).then(onCreateOfferSuccess, onCreateSessionDescriptionError);
}

function onCreateSessionDescriptionError(error) {
  trace(`Failed to create session description: ${error.toString()}`);
}

function onCreateOfferSuccess(desc) {
  trace(`Offer from pc1\n${desc.sdp}`);
  trace('pc1 setLocalDescription start');
  pc1.setLocalDescription(desc).then(() => onSetLocalSuccess(pc1), onSetSessionDescriptionError);
  trace('pc2 setRemoteDescription start');
  pc2.setRemoteDescription(desc).then(() => onSetRemoteSuccess(pc2), onSetSessionDescriptionError);
  trace('pc2 createAnswer start');
  // Since the 'remote' side has no media stream we need
  // to pass in the right constraints in order for it to
  // accept the incoming offer of audio and video.
  pc2.createAnswer().then(onCreateAnswerSuccess, onCreateSessionDescriptionError);
}

function onSetLocalSuccess(pc) {
  trace(`${getName(pc)} setLocalDescription complete`);
}

function onSetRemoteSuccess(pc) {
  trace(`${getName(pc)} setRemoteDescription complete`);
}

function onSetSessionDescriptionError(error) {
  trace(`Failed to set session description: ${error.toString()}`);
}

function gotRemoteStream(e) {
  if (remoteVideo.srcObject !== e.streams[0]) {
    remoteVideo.srcObject = e.streams[0];
    trace('pc2 received remote stream');
  }
}

function onCreateAnswerSuccess(desc) {
  trace(`Answer from pc2:\n${desc.sdp}`);
  trace('pc2 setLocalDescription start');
  pc2.setLocalDescription(desc).then(() => onSetLocalSuccess(pc2), onSetSessionDescriptionError);
  trace('pc1 setRemoteDescription start');
  pc1.setRemoteDescription(desc).then(() => onSetRemoteSuccess(pc1), onSetSessionDescriptionError);
}

function onIceCandidate(pc, event) {
  getOtherPc(pc)
    .addIceCandidate(event.candidate)
    .then(() => onAddIceCandidateSuccess(pc), err => onAddIceCandidateError(pc, err));
  trace(`${getName(pc)} ICE candidate:\n${event.candidate ? event.candidate.candidate : '(null)'}`);
}

function onAddIceCandidateSuccess(pc) {
  trace(`${getName(pc)} addIceCandidate success`);
}

function onAddIceCandidateError(pc, error) {
  trace(`${getName(pc)} failed to add ICE Candidate: ${error.toString()}`);
}

function onIceStateChange(pc, event) {
  if (pc) {
    console.log(`${getName(pc)} ICE state: ${pc.iceConnectionState}`);
    console.log('ICE state change event: ', event);
    // TODO: get rid of this in favor of http://w3c.github.io/webrtc-pc/#widl-RTCIceTransport-onselectedcandidatepairchange
    if (pc.iceConnectionState === 'connected' ||
      pc.iceConnectionState === 'completed') {
      checkStats(pc);
    }
  }
}

function checkStats(pc) {
  pc.getStats(null).then(results => {
    // figure out the peer's ip
    let activeCandidatePair = null;
    let remoteCandidate = null;

    // Search for the candidate pair, spec-way first.
    results.forEach(report => {
      if (report.type === 'transport') {
        activeCandidatePair = results.get(report.selectedCandidatePairId);
      }
    });
    // Fallback for Firefox.
    if (!activeCandidatePair) {
      results.forEach(report => {
        if (report.type === 'candidate-pair' && report.state === 'succeeded' && report.selected) {
          activeCandidatePair = report;
        }
      });
    }
    if (activeCandidatePair && activeCandidatePair.remoteCandidateId) {
      results.forEach(report => {
        if (report.type === 'remote-candidate' && report.id === activeCandidatePair.remoteCandidateId) {
          remoteCandidate = report;
        }
      });
    }
    console.log(remoteCandidate);
    if (remoteCandidate && remoteCandidate.id) {
      // TODO: update a div showing the remote ip/port?
      document.getElementById(pc === pc1 ? 'localCandidateId' : 'remoteCandidateId').textContent = remoteCandidate.id;
    }
  });
}

function hangup() {
  trace('Ending call');
  pc1.close();
  pc2.close();
  pc1 = null;
  pc2 = null;
  hangupButton.disabled = true;
  restartButton.disabled = true;
  callButton.disabled = false;
}
<commit_msg>Revert "Fix button state change on quickly clicking restart button" (#1078)<commit_after>/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */

'use strict';

const startButton = document.getElementById('startButton');
const callButton = document.getElementById('callButton');
const restartButton = document.getElementById('restartButton');
const hangupButton = document.getElementById('hangupButton');
callButton.disabled = true;
hangupButton.disabled = true;
restartButton.disabled = true;
startButton.onclick = start;
callButton.onclick = call;
hangupButton.onclick = hangup;
restartButton.onclick = restart;

let startTime;
const localVideo = document.getElementById('localVideo');
const remoteVideo = document.getElementById('remoteVideo');

localVideo.addEventListener('loadedmetadata', function() {
  trace(`Local video videoWidth: ${this.videoWidth}px,  videoHeight: ${this.videoHeight}px`);
});

remoteVideo.addEventListener('loadedmetadata', function() {
  trace(`Remote video videoWidth: ${this.videoWidth}px,  videoHeight: ${this.videoHeight}px`);
});

remoteVideo.onresize = () => {
  trace(`Remote video size changed to ${remoteVideo.videoWidth}x${remoteVideo.videoHeight}`);
  // We'll use the first onsize callback as an indication that video has started
  // playing out.
  if (startTime) {
    const elapsedTime = window.performance.now() - startTime;
    trace('Setup time: ' + elapsedTime.toFixed(3) + 'ms');
    startTime = null;
    // Have run these functions again in order to get the getStats() reports
    // with type candidatePair and populate the candidate id
    // elements.
    checkStats(pc1);
    checkStats(pc2);
  }
};

let localStream;
let pc1;
let pc2;
const offerOptions = {
  offerToReceiveAudio: 1,
  offerToReceiveVideo: 1
};

function getName(pc) {
  return (pc === pc1) ? 'pc1' : 'pc2';
}

function getOtherPc(pc) {
  return (pc === pc1) ? pc2 : pc1;
}

function gotStream(stream) {
  trace('Received local stream');
  localVideo.srcObject = stream;
  localStream = stream;
  callButton.disabled = false;
}

function start() {
  trace('Requesting local stream');
  startButton.disabled = true;
  navigator.mediaDevices
    .getUserMedia({
      audio: true,
      video: true
    })
    .then(gotStream)
    .catch(e => alert(`getUserMedia() error: ${e.name}`));
}

// Simulate an ice restart.
function restart() {
  restartButton.disabled = true;
  offerOptions.iceRestart = true;
  trace('pc1 createOffer restart');
  pc1.createOffer(offerOptions).then(onCreateOfferSuccess, onCreateSessionDescriptionError);
}

function call() {
  callButton.disabled = true;
  hangupButton.disabled = false;
  trace('Starting call');
  startTime = window.performance.now();
  const videoTracks = localStream.getVideoTracks();
  const audioTracks = localStream.getAudioTracks();
  if (videoTracks.length > 0) {
    trace(`Using video device: ${videoTracks[0].label}`);
  }
  if (audioTracks.length > 0) {
    trace(`Using audio device: ${audioTracks[0].label}`);
  }
  const servers = null;
  pc1 = new RTCPeerConnection(servers);
  trace('Created local peer connection object pc1');
  pc1.onicecandidate = e => onIceCandidate(pc1, e);
  pc2 = new RTCPeerConnection(servers);
  trace('Created remote peer connection object pc2');
  pc2.onicecandidate = e => onIceCandidate(pc2, e);
  pc1.oniceconnectionstatechange = e => {
    onIceStateChange(pc1, e);
    if (pc1 && pc1.iceConnectionState === 'connected') {
      restartButton.disabled = false;
    }
  };
  pc2.oniceconnectionstatechange = e => onIceStateChange(pc2, e);
  pc2.ontrack = gotRemoteStream;

  localStream.getTracks().forEach(track => pc1.addTrack(track, localStream)
  );
  trace('Added local stream to pc1');

  trace('pc1 createOffer start');
  pc1.createOffer(offerOptions).then(onCreateOfferSuccess, onCreateSessionDescriptionError);
}

function onCreateSessionDescriptionError(error) {
  trace(`Failed to create session description: ${error.toString()}`);
}

function onCreateOfferSuccess(desc) {
  trace(`Offer from pc1\n${desc.sdp}`);
  trace('pc1 setLocalDescription start');
  pc1.setLocalDescription(desc).then(() => onSetLocalSuccess(pc1), onSetSessionDescriptionError);
  trace('pc2 setRemoteDescription start');
  pc2.setRemoteDescription(desc).then(() => onSetRemoteSuccess(pc2), onSetSessionDescriptionError);
  trace('pc2 createAnswer start');
  // Since the 'remote' side has no media stream we need
  // to pass in the right constraints in order for it to
  // accept the incoming offer of audio and video.
  pc2.createAnswer().then(onCreateAnswerSuccess, onCreateSessionDescriptionError);
}

function onSetLocalSuccess(pc) {
  trace(`${getName(pc)} setLocalDescription complete`);
}

function onSetRemoteSuccess(pc) {
  trace(`${getName(pc)} setRemoteDescription complete`);
}

function onSetSessionDescriptionError(error) {
  trace(`Failed to set session description: ${error.toString()}`);
}

function gotRemoteStream(e) {
  if (remoteVideo.srcObject !== e.streams[0]) {
    remoteVideo.srcObject = e.streams[0];
    trace('pc2 received remote stream');
  }
}

function onCreateAnswerSuccess(desc) {
  trace(`Answer from pc2:\n${desc.sdp}`);
  trace('pc2 setLocalDescription start');
  pc2.setLocalDescription(desc).then(() => onSetLocalSuccess(pc2), onSetSessionDescriptionError);
  trace('pc1 setRemoteDescription start');
  pc1.setRemoteDescription(desc).then(() => onSetRemoteSuccess(pc1), onSetSessionDescriptionError);
}

function onIceCandidate(pc, event) {
  getOtherPc(pc)
    .addIceCandidate(event.candidate)
    .then(() => onAddIceCandidateSuccess(pc), err => onAddIceCandidateError(pc, err));
  trace(`${getName(pc)} ICE candidate:\n${event.candidate ? event.candidate.candidate : '(null)'}`);
}

function onAddIceCandidateSuccess(pc) {
  trace(`${getName(pc)} addIceCandidate success`);
}

function onAddIceCandidateError(pc, error) {
  trace(`${getName(pc)} failed to add ICE Candidate: ${error.toString()}`);
}

function onIceStateChange(pc, event) {
  if (pc) {
    trace(`${getName(pc)} ICE state: ${pc.iceConnectionState}`);
    console.log('ICE state change event: ', event);
    // TODO: get rid of this in favor of http://w3c.github.io/webrtc-pc/#widl-RTCIceTransport-onselectedcandidatepairchange
    if (pc.iceConnectionState === 'connected' ||
      pc.iceConnectionState === 'completed') {
      checkStats(pc);
    }
  }
}

function checkStats(pc) {
  pc.getStats(null).then(results => {
    // figure out the peer's ip
    let activeCandidatePair = null;
    let remoteCandidate = null;

    // Search for the candidate pair, spec-way first.
    results.forEach(report => {
      if (report.type === 'transport') {
        activeCandidatePair = results.get(report.selectedCandidatePairId);
      }
    });
    // Fallback for Firefox.
    if (!activeCandidatePair) {
      results.forEach(report => {
        if (report.type === 'candidate-pair' && report.state === 'succeeded' && report.selected) {
          activeCandidatePair = report;
        }
      });
    }
    if (activeCandidatePair && activeCandidatePair.remoteCandidateId) {
      results.forEach(report => {
        if (report.type === 'remote-candidate' && report.id === activeCandidatePair.remoteCandidateId) {
          remoteCandidate = report;
        }
      });
    }
    console.log(remoteCandidate);
    if (remoteCandidate && remoteCandidate.id) {
      // TODO: update a div showing the remote ip/port?
      document.getElementById(pc === pc1 ? 'localCandidateId' : 'remoteCandidateId').textContent = remoteCandidate.id;
    }
  });
}

function hangup() {
  trace('Ending call');
  pc1.close();
  pc2.close();
  pc1 = null;
  pc2 = null;
  hangupButton.disabled = true;
  restartButton.disabled = true;
  callButton.disabled = false;
}
<|endoftext|>


<commit_before>exports.version=1397136941
<commit_msg>update the version number<commit_after>exports.version=1397517314
<|endoftext|>


<commit_before>var stateProvider = require("./stateProvider");
module.exports = (function(){
	//TODO:

	this.getBetAmount = function() {
		var bet = 500;
		//get bet amount
		//calculation and some calculation logic goes here
		return bet;
	};

	this.getCheckAmount = function() {
		//TODO:
		//return stateProvider.getCheckAmount()
		return 10;
	};

	return this;
})();

function toNum(c) {
    switch (c) {
        case 'J':
            return 11;
        case 'Q':
            return 12;
        case 'K':
            return 13;
        case 'A':
            return 14;

        default:
            return c;
    }
}

function lameCards(cards) {
    if (
        (toNum(cards[0].rank) < 4 || toNum(cards[1].rank) < 4) &&
        cards[0].rank != cards[1].rank
       ) {
        return true
    } else {
        return false
    }
}
<commit_msg>toNum returns ints with praseInt()<commit_after>var stateProvider = require("./stateProvider");
module.exports = (function(){
	//TODO:

	this.getBetAmount = function() {
		var bet = 500;
		//get bet amount
		//calculation and some calculation logic goes here
		return bet;
	};

	this.getCheckAmount = function() {
		//TODO:
		//return stateProvider.getCheckAmount()
		return 10;
	};

	return this;
})();

function toNum(c) {
    switch (c) {
        case 'J':
            return 11;
        case 'Q':
            return 12;
        case 'K':
            return 13;
        case 'A':
            return 14;

        default:
            return parseInt(c);
    }
}

function lameCards(cards) {
    if (
        (toNum(cards[0].rank) < 4 || toNum(cards[1].rank) < 4) &&
        cards[0].rank != cards[1].rank
       ) {
        return true
    } else {
        return false
    }
}
<|endoftext|>


<commit_before>var http = require('http');
var cfg = require('./dummyserver-config');

var bigslowHello = function(res) {
    var entity = 'This School Is Not Falling Apart.\n';
    var n = 100;
    res.writeHead(200, {
        'Content-Type': 'text/plain; charset=UTF-8',
        'Content-Length': entity.length * n * 100
    });

    var i = 0;
    var interval = setInterval(function() {
        if(i < n) {
            for(var j = 0; j < 100; j+=1) {
                res.write(entity);
            }
            i += 1;
        } else {
            clearInterval(interval);
            res.end();
        }
    }, 1000);
};

var endsWith = function(str, substr) {
    return str.substr(str.length - substr.length) === substr;
};

http.createServer(function (req, res) {
    res.useChunkedEncodingByDefault = false;

    var output = function(status, body, head, mimeType) {
        // on some Android devices CORS implementations are buggy
        // that is why there needs to be two workarounds:
        // 1. custom header with origin has to be passed, because they do not send Origin header on the actual request
        // 2. caching must be disabled on serverside, because of unknown reasons, and when developing, you should clear cache on device, after disabling the cache on serverside
        // read more: http://www.kinvey.com/blog/107/how-to-build-a-service-that-supports-every-android-browser

        var headers = {
            'Access-Control-Allow-Credentials': 'true',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'OPTIONS, POST, HEAD, PUT, DELETE, GET',
            // workaround for #1: the server-side part: need X-Httpinvoke-Origin header
            // workaround for Safari 4.0: need Content-Type header
            'Access-Control-Allow-Headers': 'Content-Type, X-Httpinvoke-Origin',
            // workaround for #2: avoiding cache
            'Pragma': 'no-cache',
            'Expires': 'Thu, 01 Jan 1970 00:00:00 GMT',
            'Last-Modified': new Date().toGMTString(),
            'Cache-Control': 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
        };
        if(body !== null) {
            headers['Content-Type'] = mimeType;
            headers['Content-Length'] = String(body.length);
        }
        if(typeof req.headers.origin !== 'undefined') {
            headers['Access-Control-Allow-Origin'] = req.headers.origin;
        } else if(typeof req.headers['x-httpinvoke-origin'] !== 'undefined') {
            // workaround for #1: the server-side part
            headers['Access-Control-Allow-Origin'] = req.headers['x-httpinvoke-origin'];
        }
        res.writeHead(status, headers);
        if(body === null || head) {
            res.end();
        } else {
            res.end(body);
        }
    };
    var hello = 'Hello World\n';

    if(req.method === 'OPTIONS') {
        output(200, new Buffer([]), false, 'text/plain; charset=UTF-8');
    } else if(req.method === 'POST') {
        if(endsWith(req.url, '/noentity')) {
            output(200, null, false);
        } else {
            output(200, hello, false, 'text/plain; charset=UTF-8');
        }
    } else if(req.method === 'HEAD') {
        output(200, hello, true, 'text/plain; charset=UTF-8');
    } else if(req.method === 'PUT') {
        output(200, hello, false, 'text/plain; charset=UTF-8');
    } else if(req.method === 'DELETE') {
        output(200, hello, false, 'text/plain; charset=UTF-8');
    } else if(req.method === 'GET') {
        if(endsWith(req.url, '/bigslow')) {
            bigslowHello(res);
        } else if(endsWith(req.url, '/text/utf8')) {
            output(200, new Buffer(cfg.textTest(), 'utf8'), false, 'text/plain; charset=UTF-8');
        } else if(endsWith(req.url, '/text/utf8/empty')) {
            output(200, new Buffer('', 'utf8'), false, 'text/plain; charset=UTF-8');
        } else if(endsWith(req.url, '/json')) {
            output(200, new Buffer(JSON.stringify(cfg.jsonTest()), 'utf8'), false, 'application/json');
        } else if(endsWith(req.url, '/json/null')) {
            output(200, new Buffer('null', 'utf8'), false, 'application/json');
        } else if(endsWith(req.url, '/bytearray')) {
            output(200, new Buffer(cfg.bytearrayTest()), false, 'application/octet-stream');
        } else if(endsWith(req.url, '/bytearray/empty')) {
            output(200, new Buffer([]), false, 'application/octet-stream');
        } else if(endsWith(req.url, '/error')) {
            res.end();
        } else {
            output(200, hello, false, 'text/plain; charset=UTF-8');
        }
    } else {
        output(406, hello, false, 'text/plain; charset=UTF-8');
    }
}).listen(cfg.port, cfg.host);
<commit_msg>dummyserver.js: POST /noentity now returns HTTP Status 204<commit_after>var http = require('http');
var cfg = require('./dummyserver-config');

var bigslowHello = function(res) {
    var entity = 'This School Is Not Falling Apart.\n';
    var n = 100;
    res.writeHead(200, {
        'Content-Type': 'text/plain; charset=UTF-8',
        'Content-Length': entity.length * n * 100
    });

    var i = 0;
    var interval = setInterval(function() {
        if(i < n) {
            for(var j = 0; j < 100; j+=1) {
                res.write(entity);
            }
            i += 1;
        } else {
            clearInterval(interval);
            res.end();
        }
    }, 1000);
};

var endsWith = function(str, substr) {
    return str.substr(str.length - substr.length) === substr;
};

http.createServer(function (req, res) {
    res.useChunkedEncodingByDefault = false;

    var output = function(status, body, head, mimeType) {
        // on some Android devices CORS implementations are buggy
        // that is why there needs to be two workarounds:
        // 1. custom header with origin has to be passed, because they do not send Origin header on the actual request
        // 2. caching must be disabled on serverside, because of unknown reasons, and when developing, you should clear cache on device, after disabling the cache on serverside
        // read more: http://www.kinvey.com/blog/107/how-to-build-a-service-that-supports-every-android-browser

        var headers = {
            'Access-Control-Allow-Credentials': 'true',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'OPTIONS, POST, HEAD, PUT, DELETE, GET',
            // workaround for #1: the server-side part: need X-Httpinvoke-Origin header
            // workaround for Safari 4.0: need Content-Type header
            'Access-Control-Allow-Headers': 'Content-Type, X-Httpinvoke-Origin',
            // workaround for #2: avoiding cache
            'Pragma': 'no-cache',
            'Expires': 'Thu, 01 Jan 1970 00:00:00 GMT',
            'Last-Modified': new Date().toGMTString(),
            'Cache-Control': 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
        };
        if(body !== null) {
            headers['Content-Type'] = mimeType;
            headers['Content-Length'] = String(body.length);
        }
        if(typeof req.headers.origin !== 'undefined') {
            headers['Access-Control-Allow-Origin'] = req.headers.origin;
        } else if(typeof req.headers['x-httpinvoke-origin'] !== 'undefined') {
            // workaround for #1: the server-side part
            headers['Access-Control-Allow-Origin'] = req.headers['x-httpinvoke-origin'];
        }
        res.writeHead(status, headers);
        if(body === null || head) {
            res.end();
        } else {
            res.end(body);
        }
    };
    var hello = 'Hello World\n';

    if(req.method === 'OPTIONS') {
        output(200, new Buffer([]), false, 'text/plain; charset=UTF-8');
    } else if(req.method === 'POST') {
        if(endsWith(req.url, '/noentity')) {
            output(204, null, false);
        } else {
            output(200, hello, false, 'text/plain; charset=UTF-8');
        }
    } else if(req.method === 'HEAD') {
        output(200, hello, true, 'text/plain; charset=UTF-8');
    } else if(req.method === 'PUT') {
        output(200, hello, false, 'text/plain; charset=UTF-8');
    } else if(req.method === 'DELETE') {
        output(200, hello, false, 'text/plain; charset=UTF-8');
    } else if(req.method === 'GET') {
        if(endsWith(req.url, '/bigslow')) {
            bigslowHello(res);
        } else if(endsWith(req.url, '/text/utf8')) {
            output(200, new Buffer(cfg.textTest(), 'utf8'), false, 'text/plain; charset=UTF-8');
        } else if(endsWith(req.url, '/text/utf8/empty')) {
            output(200, new Buffer('', 'utf8'), false, 'text/plain; charset=UTF-8');
        } else if(endsWith(req.url, '/json')) {
            output(200, new Buffer(JSON.stringify(cfg.jsonTest()), 'utf8'), false, 'application/json');
        } else if(endsWith(req.url, '/json/null')) {
            output(200, new Buffer('null', 'utf8'), false, 'application/json');
        } else if(endsWith(req.url, '/bytearray')) {
            output(200, new Buffer(cfg.bytearrayTest()), false, 'application/octet-stream');
        } else if(endsWith(req.url, '/bytearray/empty')) {
            output(200, new Buffer([]), false, 'application/octet-stream');
        } else if(endsWith(req.url, '/error')) {
            res.end();
        } else {
            output(200, hello, false, 'text/plain; charset=UTF-8');
        }
    } else {
        output(406, hello, false, 'text/plain; charset=UTF-8');
    }
}).listen(cfg.port, cfg.host);
<|endoftext|>


<commit_before>'use strict';

var async = require('async');
var _ = require('lodash');
var moment = require('moment');
var fs = require('fs');
var path = require('path');
var DEFAULT_LANG = 'en_US';

function updateApplication(args, callback) {
  var seneca = this;
  var plugin = args.role;
  var ENTITY_NS = 'cd/applications';
  var ATTENDANCE_ENTITY_NS = 'cd/attendance';
  var applications = seneca.make$(ENTITY_NS);
  var so = seneca.options();
  var application = args.application;
  var emailSubject = application.emailSubject;
  delete application.emailSubject;

  async.waterfall([
    updateApplication,
    sendEmail
  ], callback);

  function updateApplication(done) {
    applications.save$(application, function(err, application) {
      if (err) return done(err);
      done(null, application);
    });
  }

  function sendEmail(application, done) {
    if(application.status !== 'approved') return done(null, application);
    //Only send an email if the application is approved.
    async.waterfall([
      loadUser,
      loadEvent,
      saveAttendanceRecord,
      sendEmail
    ], function (err, res) {
      if(err) return done(null, {error: err});
      return done(null, application);
    });

    function loadUser(cb) {
      seneca.act({role:'cd-users', cmd:'load', id:application.userId || application.user_id}, function (err, response) {
        if(err) return cb(err);
        return cb(null, response);
      });
    }

    function loadEvent(user, cb) {
      seneca.act({role:plugin, cmd:'getEvent', id:application.eventId || application.event_id}, function (err, response) {
        if(err) return cb(err);
        return cb(null, user, response);
      });
    }

    function saveAttendanceRecord(user, event, cb) {
      if(event.type === 'recurring') {
        //Save attendance record for each event date
        var eventDates = event.dates;
        async.each(eventDates, function (eventDate, cb) {
          var attendance = {
            user_id: user.id,
            event_id: event.id,
            event_date: eventDate,
            attended: false
          };
          seneca.act({role: plugin, cmd:'saveAttendance', attendance: attendance}, cb);
        }, function (err) {
          if(err) return cb(err);
          return cb(null, user, event);
        });
      } else {
        //One-off event
        var eventDate = _.first(event.dates);
        var attendance = {
          user_id: user.id,
          event_id: event.id,
          event_date: eventDate,
          attended: false
        };
        seneca.act({role: plugin, cmd: 'saveAttendance', attendance: attendance}, function (err, response) {
          if(err) return cb(err);
          return cb(null, user, event);
        });
      }
    }

    function sendEmail(user, event, sendEmailCb) {
      var recipients = [];
      if(!user.email) { //Approving attendee-u13, retrieve parent email addresses.
        seneca.act({role: 'cd-profiles', cmd: 'list', query: {userId:user.id}}, function (err, userProfiles) {
          if(err) return cb(err);
          var youth = userProfiles[0];
          async.each(youth.parents, function (parentUserId, cb) {
            seneca.act({role: 'cd-profiles', cmd: 'list', query: {userId: parentUserId}}, function (err, response) {
              if(err) return cb(err);
              var parentEmail = youth.email;
              recipients.push(parentEmail);
              cb();
            });
          }, prepareEmails)
        });
      } else {
        recipients.push(user.email);
        prepareEmails();
      }

      function prepareEmails() {
        //Send approval email to all recipients
        if(event.type === 'recurring') {
          //Recurring event
          var locality = args.locality || 'en_US';
          var code = 'recurring-event-application-approved-';

          var firstDate = _.first(event.dates);
          var eventStartDate = moment(firstDate).format('MMMM Do YYYY, HH:mm');
          var eventEndDate = moment(_.last(event.dates)).format('MMMM Do YYYY, HH:mm');
          //TODO: Translate weekdays.
          var weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
          var eventDay = weekdays[moment(firstDate).weekday()];
          var content = {
            userName: user.name,
            eventName: event.name,
            eventStartDate: eventStartDate,
            eventEndDate: eventEndDate,
            eventDay: eventDay,
            year: moment(new Date()).format('YYYY')
          };
          send(code, locality, content);
        } else {
          //One-off event
          var locality = args.locality || 'en_US';
          var code = 'one-off-event-application-approved-';

          var eventDate = moment(_.first(event.dates)).format('MMMM Do YYYY, HH:mm');
          var content = {
            userName: user.name,
            eventName: event.name,
            eventDate: eventDate,
            year: moment(new Date()).format('YYYY')
          };
          send(code, locality, content);
        }

        function send(code, locality, content) {
          async.each(recipients, function (recipient, cb) {
            var payload = {
              to: recipient,
              code: code,
              locality: locality,
              content: content,
              subject: emailSubject
            };
            seneca.act({role:'cd-dojos', cmd:'send_email', payload:payload}, cb);
          }, sendEmailCb);
        }
      }
    }

  }
}

module.exports = updateApplication;
<commit_msg>checking for existing invitees when re-saving event<commit_after>'use strict';

var async = require('async');
var _ = require('lodash');
var moment = require('moment');
var fs = require('fs');
var path = require('path');
var DEFAULT_LANG = 'en_US';

function updateApplication(args, callback) {
  var seneca = this;
  var plugin = args.role;
  var ENTITY_NS = 'cd/applications';
  var ATTENDANCE_ENTITY_NS = 'cd/attendance';
  var applications = seneca.make$(ENTITY_NS);
  var so = seneca.options();
  var application = args.application;
  var emailSubject = application.emailSubject;
  delete application.emailSubject;

  async.waterfall([
    updateApplication,
    sendEmail
  ], callback);

  function updateApplication(done) {
    applications.list$({event_id: application.event_id, user_id: application.user_id}, function(err, list){
      if(err) return done(err);

      if(list.length > 0) return done(null, {error: "username already exists"});

      applications.save$(application, function(err, application) {
        if (err) return done(err);
        return done(null, application);
      });
    })
  }

  function sendEmail(application, done) {
    if(application.error) return done(null, application);
    if(application.status !== 'approved') return done(null, application);
    //Only send an email if the application is approved.
    async.waterfall([
      loadUser,
      loadEvent,
      saveAttendanceRecord,
      sendEmail
    ], function (err, res) {
      if(err) return done(null, {error: err});
      return done(null, application);
    });

    function loadUser(cb) {
      seneca.act({role:'cd-users', cmd:'load', id:application.userId || application.user_id}, function (err, response) {
        if(err) return cb(err);
        return cb(null, response);
      });
    }

    function loadEvent(user, cb) {
      seneca.act({role:plugin, cmd:'getEvent', id:application.eventId || application.event_id}, function (err, response) {
        if(err) return cb(err);
        return cb(null, user, response);
      });
    }

    function saveAttendanceRecord(user, event, cb) {
      if(event.type === 'recurring') {
        //Save attendance record for each event date
        var eventDates = event.dates;
        async.each(eventDates, function (eventDate, cb) {
          var attendance = {
            user_id: user.id,
            event_id: event.id,
            event_date: eventDate,
            attended: false
          };
          seneca.act({role: plugin, cmd:'saveAttendance', attendance: attendance}, cb);
        }, function (err) {
          if(err) return cb(err);
          return cb(null, user, event);
        });
      } else {
        //One-off event
        var eventDate = _.first(event.dates);
        var attendance = {
          user_id: user.id,
          event_id: event.id,
          event_date: eventDate,
          attended: false
        };
        seneca.act({role: plugin, cmd: 'saveAttendance', attendance: attendance}, function (err, response) {
          if(err) return cb(err);
          return cb(null, user, event);
        });
      }
    }

    function sendEmail(user, event, sendEmailCb) {
      var recipients = [];
      if(!user.email) { //Approving attendee-u13, retrieve parent email addresses.
        seneca.act({role: 'cd-profiles', cmd: 'list', query: {userId:user.id}}, function (err, userProfiles) {
          if(err) return cb(err);
          var youth = userProfiles[0];
          async.each(youth.parents, function (parentUserId, cb) {
            seneca.act({role: 'cd-profiles', cmd: 'list', query: {userId: parentUserId}}, function (err, response) {
              if(err) return cb(err);
              var parentEmail = youth.email;
              recipients.push(parentEmail);
              cb();
            });
          }, prepareEmails)
        });
      } else {
        recipients.push(user.email);
        prepareEmails();
      }

      function prepareEmails() {
        //Send approval email to all recipients
        if(event.type === 'recurring') {
          //Recurring event
          var locality = args.locality || 'en_US';
          var code = 'recurring-event-application-approved-';

          var firstDate = _.first(event.dates);
          var eventStartDate = moment(firstDate).format('MMMM Do YYYY, HH:mm');
          var eventEndDate = moment(_.last(event.dates)).format('MMMM Do YYYY, HH:mm');
          //TODO: Translate weekdays.
          var weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
          var eventDay = weekdays[moment(firstDate).weekday()];
          var content = {
            userName: user.name,
            eventName: event.name,
            eventStartDate: eventStartDate,
            eventEndDate: eventEndDate,
            eventDay: eventDay,
            year: moment(new Date()).format('YYYY')
          };
          send(code, locality, content);
        } else {
          //One-off event
          var locality = args.locality || 'en_US';
          var code = 'one-off-event-application-approved-';

          var eventDate = moment(_.first(event.dates)).format('MMMM Do YYYY, HH:mm');
          var content = {
            userName: user.name,
            eventName: event.name,
            eventDate: eventDate,
            year: moment(new Date()).format('YYYY')
          };
          send(code, locality, content);
        }

        function send(code, locality, content) {
          async.each(recipients, function (recipient, cb) {
            var payload = {
              to: recipient,
              code: code,
              locality: locality,
              content: content,
              subject: emailSubject
            };
            seneca.act({role:'cd-dojos', cmd:'send_email', payload:payload}, cb);
          }, sendEmailCb);
        }
      }
    }

  }
}

module.exports = updateApplication;
<|endoftext|>


<commit_before>(function () {
	'use strict';

	var MongoClient = require('mongodb').MongoClient;
	exports.generate = function (appid, valuemgr, converter, url, n, collection, callback) {
		console.log('--GENERATE USER--');
		generateDB(appid, converter, url, n, collection, valuemgr, callback);
	};

	function generateDB(appid, converter, url, n, collection, valuemgr,  callback) {
		MongoClient.connect(url).then(function (db) {
			var count = 0;
			converter.toIDs(['_isUser', 'name', 'age', "_os", 'iq', "_device", "_browser", "_lang", "_city", 'gender', 'height', '_segments', '_campaign', '_lastcampaign', '_firstcampaign'], function (ids) {
				for (var i = 0; i < n; i++) {
					count++;
					var user = generateUsers(ids);
					valuemgr.cineObject(appid, 'user', user);

					db.collection(collection).insertOne(user, function (err, results) {
						if (err) throw err;
						var newuser = results.ops[0];
						newuser._mtid = newuser._id;
						db.collection(collection).updateOne({_id: newuser._id}, newuser, function () {
							count--;
							if (count % 1000 === 0)
								console.log((n - count) + ' records');

							if (count === 0) {
								db.close();
								console.log('Done');
								callback();
							}
						});
					});

				}
			});

			// Listen for some events
			db.on('reconnect', function (data) {
				console.log('[MongoDB] reconnect success');
			});
			db.on('error', function (err) {
				console.log('[MongoDB] error', err.message);
			});
			db.on('close', function (err) {
				console.log('[MongoDB] disconnected');
			});
		}).catch(function (err) {
			console.error("[MongoDB]", err.message);
			setTimeout(function () {
				generateDB(url);
			}, 2000);
		});
	}

	var campaigns = ["black_friday", "spring_sale", "justdoit", "thinkdifference", "newyear", "valentine", "chrismas"];

	function generateUsers(ids) {
		var users = {};
		users[ids._isUser] = true;
		//users[ids.userid] = generateNumber(1, 1000000);
		users[ids.name] = generateName();
		users[ids.height] = generateNumber(150, 180);
		users[ids.iq] = generateNumber(30, 40);
		users[ids._segments] = [];
		users[ids.age] = generateNumber(20, 60);
		users[ids._os] = os[generateNumber(0, 6)];
		users[ids._device] = devices[generateNumber(0, 6)];
		users[ids.gender] = ['male' ,'female', ''][generateNumber(0, 2)];
		users[ids._lang] = generateNumber(1, 2) === 1 ? 'en' : 'vn';
		users[ids._city] = generateNumber(1, 2) === 1 ? 'Hồ Chí Minh' : 'Hà Nội';
		users[ids._browser] = browsers[generateNumber(0, 6)];
		users[ids._firstcampaign] = campaigns[generateNumber(0, 6)];
		users[ids._campaign] = [campaigns[generateNumber(0, 6)], campaigns[generateNumber(0,6)]];
		users[ids._lastcampaign] = campaigns[generateNumber(0, 6)];
		return users;
	}

//function generateNumber(min, max) {
//	var range = max - min;
//	return Math.floor(Math.random() * (range + 1)) + min;
//}

	function generateName() {
		var ho = ['An', 'Ánh', 'Ân', 'Âu', 'Ấu', 'Bá', 'Bạc', 'Bạch', 'Bàng', 'Bành', 'Bảo', 'Bế', 'Bì', 'Biện', 'Bình', 'Bồ', 'Ca', 'Cái', 'Cam', 'Cao', 'Cát', 'Cầm', 'Cấn', 'Chế', 'Chiêm', 'Chu', 'Chung', 'Chương', 'Chử', 'Cổ', 'Cù', 'Cung', 'Cự', 'Dã', 'Danh', 'Diêm', 'Doãn', 'Diệp', 'Đàm', 'Đan', 'Đào', 'Đậu', 'Điền', 'Đinh', 'Đoàn', 'Đôn', 'Đồng', 'Đổng', 'Đới', 'Đường', 'Giả', 'Giao', 'Giang', 'Giáp', 'Hà', 'Hạ', 'Hàn', 'Hán', 'Hy', 'Hình', 'Hoa', 'Hồng', 'Hùng', 'Hứa', 'Kha', 'Khương', 'Khâu', 'Khoa', 'Khổng', 'Khu', 'Khuất', 'Khúc', 'Kiều', 'Kim', 'La', 'Lạc', 'Lại', 'Lâm', 'Lều', 'Liễu', 'Lò', 'Lục', 'Lư', 'Lã', 'Lương', 'Lưu', 'Ma', 'Mã', 'Mạc', 'Mạch', 'Mai', 'Mang', 'Mâu', 'Mẫn', 'Mộc', 'Ninh', 'Nhâm', 'Ngân', 'Nghiêm', 'Nghị', 'Ngụy', 'Nhữ', 'Nông', 'Ong', 'Ông', 'Phi', 'Phí', 'Phó', 'Phùng', 'Phương', 'Quản', 'Quách', 'Sầm', 'Sơn', 'Sử', 'Tạ', 'Tào', 'Tăng', 'Thạch', 'Thái', 'Thành', 'Thào', 'Thân', 'Thập', 'Thi', 'Thiều', 'Thịnh', 'Thôi', 'Tiêu', 'Tiếp', 'Tòng', 'Tô', 'Tôn', 'Tông', 'Tống', 'Trang', 'Trà', 'Trác', 'Triệu', 'Trịnh', 'Trình', 'Trưng', 'Trương', 'Từ', 'Ty', 'Uông', 'Văn', 'Vi', 'Viên', 'Vương', 'Xa', 'Yên', 'Ngọc', 'Liêu', 'Lỗ'];

		var ten = ['Mỹ', 'Duệ', 'Tăng', 'Cường', 'Tráng', 'Liên', 'Huy', 'Phát', 'Bội', 'Hương', 'Linh', 'Nghi', 'Hàm', 'Tốn', 'Thuận', 'Vĩ', 'Vọng', 'Biểu', 'Khôn', 'Quang', 'Lương', 'Kiến', 'Ninh', 'Hòa', 'Thuật', 'Du', 'Hành', 'Suất', 'Nghĩa', 'Phương', 'Dưỡng', 'Di', 'Tương', 'Thực', 'Hảo', 'Cao', 'Túc', 'Thể', 'Vi', 'Tường', 'Tịnh', 'Hoài', 'Chiêm', 'Viễn', 'Ái', 'Cảnh', 'Ngưỡng', 'Mậu', 'Thanh', 'Kha', 'Nghiễm', 'Khác', 'Do', 'Trung', 'Ðạt', 'Liên', 'Trung', 'Tập', 'Cát', 'Ða', 'Diên', 'Hội', 'Phong', 'Hanh', 'Hiệp', 'Trùng', 'Phùng', 'Tuấn', 'Lãng', 'Nghi', 'Hậu', 'Lưu', 'Thành', 'Tú', 'Diệu', 'Diễn', 'Khánh', 'Thích', 'Phương', 'Huy', 'Từ', 'Thể', 'Dương', 'Quỳnh', 'Cẩm', 'Phu', 'Văn', 'Ái', 'Diệu', 'Dương', 'Bách', 'Chi', 'Quân', 'Phụ', 'Dực', 'Vạn', 'Diệp', 'Hiệu', 'Khuông', 'Tương'];
		return ho[Math.floor(Math.random() * 100) % ho.length] + ' ' + ten[Math.floor(Math.random() * 100) % ten.length];
	}

	function randomNumber(a, b) {
		if (b === undefined) {
			b = a;
			a = 0;
		}
		var delta = b - a + 1;
		return Math.floor(Math.random() * delta) + a
	}

	var h = [];

	function generateNumber(a, b) {
		var delta = b - a + 1;
		if (h.length == 0 || h.length < delta) {
			//init hash

			for (var i = 0; i < delta; i++) {
				if (i === 0) h[i] = randomNumber(0, 20);
				else h[i] = h[i - 1] + randomNumber(0, 20);
			}
		}
		var r = randomNumber(0, h[delta - 1]);

		for (var i = 0; i < delta; i++)
			if (h[i] >= r) return i + a;
		return 'fuck'
	}

	var os = [["window"], ["ubuntu"], ["mac"], ["ubuntu", "window"], ["mac", "ubuntu"], ["mac", "window"], ["mac", "ubuntu", "window"]];
	var devices = [["phone"], ["desktop"], ["tablet"], ["phone", "desktop"], ["tablet", "phone"], ["tablet", "desktop"], ["tablet", "phone", "desktop"]];
	var browsers = [["chrome"], ["firefox"], ["ie"], ["chrome", "firefox"], ["ie", "chrome"], ["ie", "firefox"], ["chrome", "ie", "firefox"]];
//generateDB();

})();<commit_msg>add ctime to user<commit_after>(function () {
	'use strict';

	var MongoClient = require('mongodb').MongoClient;
	exports.generate = function (appid, valuemgr, converter, url, n, collection, callback) {
		console.log('--GENERATE USER--');
		generateDB(appid, converter, url, n, collection, valuemgr, callback);
	};

	function generateDB(appid, converter, url, n, collection, valuemgr,  callback) {
		MongoClient.connect(url).then(function (db) {
			var count = 0;
			converter.toIDs(['_isUser', 'name', 'age', "_os", 'iq', "_device", "_browser", "_lang", "_city", 'gender', 'height', '_segments', '_campaign', '_lastcampaign', '_firstcampaign'], function (ids) {
				for (var i = 0; i < n; i++) {
					count++;
					var user = generateUsers(ids);
					valuemgr.cineObject(appid, 'user', user);

					db.collection(collection).insertOne(user, function (err, results) {
						if (err) throw err;
						var newuser = results.ops[0];
						newuser._mtid = newuser._id;
						db.collection(collection).updateOne({_id: newuser._id}, newuser, function () {
							count--;
							if (count % 1000 === 0)
								console.log((n - count) + ' records');

							if (count === 0) {
								db.close();
								console.log('Done');
								callback();
							}
						});
					});

				}
			});

			// Listen for some events
			db.on('reconnect', function (data) {
				console.log('[MongoDB] reconnect success');
			});
			db.on('error', function (err) {
				console.log('[MongoDB] error', err.message);
			});
			db.on('close', function (err) {
				console.log('[MongoDB] disconnected');
			});
		}).catch(function (err) {
			console.error("[MongoDB]", err.message);
			setTimeout(function () {
				generateDB(url);
			}, 2000);
		});
	}

	var campaigns = ["black_friday", "spring_sale", "justdoit", "thinkdifference", "newyear", "valentine", "chrismas"];

	function generateUsers(ids) {
		var users = {};
		users[ids._isUser] = true;
		//users[ids.userid] = generateNumber(1, 1000000);
		users[ids.name] = generateName();
		users[ids.height] = generateNumber(150, 180);
		users[ids.iq] = generateNumber(30, 40);
		users[ids._segments] = [];
		users[ids.age] = generateNumber(20, 60);
		users[ids._os] = os[generateNumber(0, 6)];
		users[ids._devicetype] = devices[generateNumber(0, 6)];
		users[ids.gender] = ['male' ,'female', ''][generateNumber(0, 2)];
		users[ids._lang] = generateNumber(1, 2) === 1 ? 'en' : 'vn';
		users[ids._city] = generateNumber(1, 2) === 1 ? 'Hồ Chí Minh' : 'Hà Nội';
		users[ids._browser] = browsers[generateNumber(0, 6)];
		users[ids._firstcampaign] = campaigns[generateNumber(0, 6)];
		users[ids._campaign] = [campaigns[generateNumber(0, 6)], campaigns[generateNumber(0,6)]];
		users[ids._lastcampaign] = campaigns[generateNumber(0, 6)];
		user[ids._ctime] = Math.floor(new Date().getTime() / 1000 - generateNumber(0, 2592000));
		return users;
	}

//function generateNumber(min, max) {
//	var range = max - min;
//	return Math.floor(Math.random() * (range + 1)) + min;
//}

	function generateName() {
		var ho = ['An', 'Ánh', 'Ân', 'Âu', 'Ấu', 'Bá', 'Bạc', 'Bạch', 'Bàng', 'Bành', 'Bảo', 'Bế', 'Bì', 'Biện', 'Bình', 'Bồ', 'Ca', 'Cái', 'Cam', 'Cao', 'Cát', 'Cầm', 'Cấn', 'Chế', 'Chiêm', 'Chu', 'Chung', 'Chương', 'Chử', 'Cổ', 'Cù', 'Cung', 'Cự', 'Dã', 'Danh', 'Diêm', 'Doãn', 'Diệp', 'Đàm', 'Đan', 'Đào', 'Đậu', 'Điền', 'Đinh', 'Đoàn', 'Đôn', 'Đồng', 'Đổng', 'Đới', 'Đường', 'Giả', 'Giao', 'Giang', 'Giáp', 'Hà', 'Hạ', 'Hàn', 'Hán', 'Hy', 'Hình', 'Hoa', 'Hồng', 'Hùng', 'Hứa', 'Kha', 'Khương', 'Khâu', 'Khoa', 'Khổng', 'Khu', 'Khuất', 'Khúc', 'Kiều', 'Kim', 'La', 'Lạc', 'Lại', 'Lâm', 'Lều', 'Liễu', 'Lò', 'Lục', 'Lư', 'Lã', 'Lương', 'Lưu', 'Ma', 'Mã', 'Mạc', 'Mạch', 'Mai', 'Mang', 'Mâu', 'Mẫn', 'Mộc', 'Ninh', 'Nhâm', 'Ngân', 'Nghiêm', 'Nghị', 'Ngụy', 'Nhữ', 'Nông', 'Ong', 'Ông', 'Phi', 'Phí', 'Phó', 'Phùng', 'Phương', 'Quản', 'Quách', 'Sầm', 'Sơn', 'Sử', 'Tạ', 'Tào', 'Tăng', 'Thạch', 'Thái', 'Thành', 'Thào', 'Thân', 'Thập', 'Thi', 'Thiều', 'Thịnh', 'Thôi', 'Tiêu', 'Tiếp', 'Tòng', 'Tô', 'Tôn', 'Tông', 'Tống', 'Trang', 'Trà', 'Trác', 'Triệu', 'Trịnh', 'Trình', 'Trưng', 'Trương', 'Từ', 'Ty', 'Uông', 'Văn', 'Vi', 'Viên', 'Vương', 'Xa', 'Yên', 'Ngọc', 'Liêu', 'Lỗ'];

		var ten = ['Mỹ', 'Duệ', 'Tăng', 'Cường', 'Tráng', 'Liên', 'Huy', 'Phát', 'Bội', 'Hương', 'Linh', 'Nghi', 'Hàm', 'Tốn', 'Thuận', 'Vĩ', 'Vọng', 'Biểu', 'Khôn', 'Quang', 'Lương', 'Kiến', 'Ninh', 'Hòa', 'Thuật', 'Du', 'Hành', 'Suất', 'Nghĩa', 'Phương', 'Dưỡng', 'Di', 'Tương', 'Thực', 'Hảo', 'Cao', 'Túc', 'Thể', 'Vi', 'Tường', 'Tịnh', 'Hoài', 'Chiêm', 'Viễn', 'Ái', 'Cảnh', 'Ngưỡng', 'Mậu', 'Thanh', 'Kha', 'Nghiễm', 'Khác', 'Do', 'Trung', 'Ðạt', 'Liên', 'Trung', 'Tập', 'Cát', 'Ða', 'Diên', 'Hội', 'Phong', 'Hanh', 'Hiệp', 'Trùng', 'Phùng', 'Tuấn', 'Lãng', 'Nghi', 'Hậu', 'Lưu', 'Thành', 'Tú', 'Diệu', 'Diễn', 'Khánh', 'Thích', 'Phương', 'Huy', 'Từ', 'Thể', 'Dương', 'Quỳnh', 'Cẩm', 'Phu', 'Văn', 'Ái', 'Diệu', 'Dương', 'Bách', 'Chi', 'Quân', 'Phụ', 'Dực', 'Vạn', 'Diệp', 'Hiệu', 'Khuông', 'Tương'];
		return ho[Math.floor(Math.random() * 100) % ho.length] + ' ' + ten[Math.floor(Math.random() * 100) % ten.length];
	}

	function randomNumber(a, b) {
		if (b === undefined) {
			b = a;
			a = 0;
		}
		var delta = b - a + 1;
		return Math.floor(Math.random() * delta) + a
	}

	var h = [];

	function generateNumber(a, b) {
		var delta = b - a + 1;
		if (h.length == 0 || h.length < delta) {
			//init hash

			for (var i = 0; i < delta; i++) {
				if (i === 0) h[i] = randomNumber(0, 20);
				else h[i] = h[i - 1] + randomNumber(0, 20);
			}
		}
		var r = randomNumber(0, h[delta - 1]);

		for (var i = 0; i < delta; i++)
			if (h[i] >= r) return i + a;
		return 'fuck'
	}

	var os = [["window"], ["ubuntu"], ["mac"], ["ubuntu", "window"], ["mac", "ubuntu"], ["mac", "window"], ["mac", "ubuntu", "window"]];
	var devices = [["phone"], ["desktop"], ["tablet"], ["phone", "desktop"], ["tablet", "phone"], ["tablet", "desktop"], ["tablet", "phone", "desktop"]];
	var browsers = [["chrome"], ["firefox"], ["ie"], ["chrome", "firefox"], ["ie", "chrome"], ["ie", "firefox"], ["chrome", "ie", "firefox"]];
//generateDB();

})();<|endoftext|>