<commit_before>module.exports = function (grunt) {
    var
        project_folder = grunt.option('project') ? grunt.option('project') + '/' : './',
        path = require('path'),
        bower_dependencies = grunt.file.readJSON(project_folder + 'bower.json').dependencies,
        bower_comp = Object.keys(bower_dependencies);

    // Load all grunt tasks.
    require('load-grunt-tasks')(grunt, { config: project_folder + 'package.json' });

    // Show elapsed time at the end.
    require('time-grunt')(grunt);

    // Application configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON(project_folder + 'package.json'),

        banner: '/*!\n' +
            ' * <%%= pkg.name %> - <%%= grunt.template.today("yyyy-mm-dd") %>\n' +
            ' * <%%= pkg.homepage %>\n' +
            ' * @license <%%= pkg.license %>\n' +
            ' * v<%%= pkg.version %>\n */\n',

        'string-replace': {
            'material-design-iconic-font': {
                files: [{
                    expand: true,
                    cwd: 'bower_components/material-design-iconic-font/scss/',
                    src: '**/*',
                    dest: 'bower_components/material-design-iconic-font/scss/'
                }],
                options: {
                    replacements: [{
                        pattern: '$md-css-prefix: md;',
                        replacement: '$md-css-prefix: mdi;'
                    }]
                }
            },
            'default-tags': {
                files: [{
                    expand: true,
                    cwd: 'app/',
                    src: [
                        '**/*',
                        '!**/assets/fonts/**',
                        '!**/assets/images/**'
                    ],
                    dest: 'app/'
                }],
                options: {
                    replacements: [
                        {
                            pattern: 'fkjs_(name)',
                            replacement: '<%%= pkg.name %>'
                        },
                        {
                            pattern: 'fkjs_(title)',
                            replacement: '<%%= pkg.title %>'
                        },
                        {
                            pattern: 'fkjs_(description)',
                            replacement: '<%%= pkg.description %>'
                        },
                        {
                            pattern: 'fkjs_(version)',
                            replacement: '<%%= pkg.version %>'
                        }
                    ]
                }
            },
            'dist-tags': {
                files: [{
                    expand: true,
                    cwd: 'dist/',
                    src: [
                        '**/*',
                        '!**/assets/fonts/**',
                        '!**/assets/images/**'
                    ],
                    dest: 'dist/'
                }],
                options: {
                    replacements: [
                        {
                            pattern: 'fkjs_(name)',
                            replacement: '<%%= pkg.name %>'
                        },
                        {
                            pattern: 'fkjs_(title)',
                            replacement: '<%%= pkg.title %>'
                        },
                        {
                            pattern: 'fkjs_(description)',
                            replacement: '<%%= pkg.description %>'
                        },
                        {
                            pattern: 'fkjs_(version)',
                            replacement: '<%%= pkg.version %>'
                        }
                    ]
                }
            }
        },
        copy: {
            'bootstrap-fonts': {
                src: [
                    '**/*'
                ],
                expand: true,
                cwd: 'bower_components/bootstrap/fonts',
                dest: 'app/assets/fonts'
            },
            'material-design-iconic-font': {
                src: [
                    '**/*'
                ],
                expand: true,
                cwd: 'bower_components/material-design-iconic-font/fonts',
                dest: 'app/assets/fonts'
            },
            dist: {
                src: [
                    '**/*',
                    '!**/test/**',
                    '!**/docs/**',
                    '!**/assets/css/**',
                    '!**/assets/scss/**',
                    '!**/src/**/*.js'
                ],
                expand: true,
                cwd: 'app',
                dest: 'dist'
            }
        },
        wiredep: {
            build: {
                src: [
                    'app/index.html'
                ],
                options: {

                }
            }
        },
        sass: {
            'material-design-iconic-font': {
                options: {
                    style: 'expanded',
                    noCache: true
                },
                files: [{
                    expand: true,
                    cwd: 'bower_components/material-design-iconic-font/scss',
                    src: ['**/*.scss'],
                    dest: 'bower_components/material-design-iconic-font/css',
                    ext: '.css'
                }]
            },
            'compile-scss': {
                options: {
                    style: 'expanded',
                    lineNumbers: true,
                    cacheLocation: 'app/assets/scss/.sass-cache'
                },
                files: [{
                    expand: true,
                    cwd: 'app/assets/scss/',
                    src: ['**/*.scss'],
                    dest: 'app/assets/scss/.temp',
                    ext: '.css'
                }]
            }
        },
        bower_concat: {
            all: {
                dest: 'dist/_bower.js',
                cssDest: 'dist/_bower.css',
                exclude: [

                ],
                mainFiles: {
                    //'script.js': 'dist/script.js'
                },
                dependencies: {

                },
                bowerOptions: {
                    relative: false
                },
                callback: function (main_files, component) {
                    var component_dependencies,
                        dependencies = [];

                    if (grunt.file.exists(project_folder + 'bower_components/' + component + '/bower.json')) {
                        component_dependencies = grunt.file.readJSON(project_folder + 'bower_components/' + component + '/bower.json').dependencies,
                        dependencies = component_dependencies ? Object.keys(component_dependencies) : [];
                    }

                    return main_files.map(function (filepath) {
                        for (i = 0; i < bower_comp.length; i++) {
                            return ((bower_comp[i].indexOf(component) > -1 || dependencies.length > -1) && component != 'script.js') ? filepath : false;
                        }
                    });
                }
            }
        },
        ngAnnotate: {
            dist: {
                files: {
                    'dist/app.js.files.js': [
                        'app/src/**/*.js'
                    ]
                }
            }
        },
        concat: {
            options: {
                //separator: ';'
            },
            'compile-css-first': {
                src: [
                    'app/assets/scss/.temp/*.css',
                    'app/assets/css/**/*.css',
                    '!**/app/assets/css/app.css',
                    '!**/app/assets/css/**/custom.css'
                ],
                dest: 'app/assets/css/app.css',
            },
            'compile-css-last': {
                src: [
                    'app/assets/css/app.css',
                    'app/assets/css/custom.css'
                ],
                dest: 'app/assets/css/app.css'
            },
            'dist-libraries': {
                src: [
                    'dist/_bower.js'
                ],
                dest: 'dist/app.libraries.js'
            },
            'dist-js-files': {
                src: [
                    'dist/app.libraries.js',
                    'dist/app.js.files.js'
                ],
                dest: 'dist/app.js'
            },
            'dist-stylesheets': {
                src: [
                    'dist/_bower.css'
                ],
                dest: 'dist/assets/css/app.css',
            },
            'dist-css-first': {
                src: [
                    'dist/_bower.css',
                    'app/assets/scss/.temp/*.css',
                    'app/assets/css/**/*.css',
                    '!**/app/assets/css/app.css',
                    '!**/app/assets/css/**/custom.css'
                ],
                dest: 'dist/assets/css/app.css',
            },
            'dist-css-last': {
                src: [
                    'dist/assets/css/app.css',
                    'app/assets/css/custom.css'
                ],
                dest: 'dist/assets/css/app.css',
            }
        },
        uglify: {
            options: {
                compress: {
                    global_defs: {
                        "DEBUG": false
                    },
                    dead_code: true
                },
                banner: '<%%= banner %>'
            },
            libraries: {
                src: 'dist/app.js',
                dest: 'dist/app.min.js'
            }
        },
        cssmin: {
            css: {
                src: 'dist/assets/css/app.css',
                dest: 'dist/assets/css/app.min.css'
            }
        },
        processhtml: {
            options: {
                data: {
                    html_tag: '<html ng-app="<%%= pkg.name %>">'
                }
            },
            dist: {
                files: {
                    'dist/index.html': ['dist/index.html']
                }
            }
        },
        clean: {
            'dist-before': [
                'dist/'
            ],
            'dist-after': [
                'app/assets/scss/.temp',
                'dist/app.js',
                'dist/app.bootstrap.js',
                'dist/app.libraries.js',
                'dist/app.js.files.js',
                'dist/assets/css/app.css',
                'dist/_bower.js',
                'dist/_bower.css',
                'dist/src/services'
            ],
            'docs': [
                'dist/docs'
            ]
        },
        watch: {
            debug: {
                files: [
                    'app/**/*',
					'!app/assets/scss/.sass-cache',
					'!app/assets/scss/.temp'
                ],
                tasks: ['compile-scss'],
                options: {
                    // Start a live reload server on the default port 35729
                    livereload: true,
                    spawn: false
                }
            }
        },
        ngdocs: {
            options: {
                dest: 'app/docs',
                startPage: '/api/app',
                html5Mode: false,
                title: '<%%= pkg.title %> Docs',
                bestMatch: true
            },
            all: [
				'app/src/**/*.js',
                'app/app.bootstrap.js'
            ]
        },
        karma: {
            unit: {
                configFile: 'app/test/karma.conf.js'
            }
        }
    });

    /**
	 * @description
	 *   Now that we have loaded the package.json and the node_modules we set the base path
     *   for the actual execution of the tasks.
	 *
	 */
    grunt.file.setBase(project_folder);

    grunt.event.on('watch', function (action, filepath, target) {
        grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
    });

    /**
	 * @description
	 *   Running test task(s).
	 *
	 */
    grunt.registerTask('test', [
		'karma'
    ]);

    /**
	 * @description
	 *   Generate documentation (ngDocs) task(s).
	 *
	 */
    grunt.registerTask('docs', [
		'clean:docs',
        'ngdocs'
    ]);

    /**
	 * @description
	 *   Compile SCSS task(s).
	 *
	 */
    grunt.registerTask('compile-scss', [
        'sass:compile-scss',
        'concat:compile-css-first',
        'concat:compile-css-last'
    ]);

    /**
	 * @description
	 *   Dist task(s).
	 *
	 */
    grunt.registerTask('dist', [
        'clean:dist-before',
        'copy:dist',
        'string-replace:dist-tags',
        'processhtml',
        'bower_concat',
        'sass:compile-scss',
        'concat:dist-stylesheets',
        'concat:dist-css-first',
        'concat:dist-css-last',
        'cssmin',
        'ngAnnotate:dist',
        'concat:dist-libraries',
        'concat:dist-js-files',
        'uglify',
        'clean:dist-after'
    ]);

    /**
	 * @description
	 *   Default task(s).
	 *
	 */
    grunt.registerTask('default', [
        'copy:material-design-iconic-font',
        'string-replace:material-design-iconic-font',
        'sass:material-design-iconic-font',
        'string-replace:default-tags',
        'compile-scss',
        'wiredep:build'
    ]);
};<commit_msg>Update: app.bootstrap.js removed from dist folder<commit_after>module.exports = function (grunt) {
    var
        project_folder = grunt.option('project') ? grunt.option('project') + '/' : './',
        path = require('path'),
        bower_dependencies = grunt.file.readJSON(project_folder + 'bower.json').dependencies,
        bower_comp = Object.keys(bower_dependencies);

    // Load all grunt tasks.
    require('load-grunt-tasks')(grunt, { config: project_folder + 'package.json' });

    // Show elapsed time at the end.
    require('time-grunt')(grunt);

    // Application configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON(project_folder + 'package.json'),

        banner: '/*!\n' +
            ' * <%%= pkg.name %> - <%%= grunt.template.today("yyyy-mm-dd") %>\n' +
            ' * <%%= pkg.homepage %>\n' +
            ' * @license <%%= pkg.license %>\n' +
            ' * v<%%= pkg.version %>\n */\n',

        'string-replace': {
            'material-design-iconic-font': {
                files: [{
                    expand: true,
                    cwd: 'bower_components/material-design-iconic-font/scss/',
                    src: '**/*',
                    dest: 'bower_components/material-design-iconic-font/scss/'
                }],
                options: {
                    replacements: [{
                        pattern: '$md-css-prefix: md;',
                        replacement: '$md-css-prefix: mdi;'
                    }]
                }
            },
            'default-tags': {
                files: [{
                    expand: true,
                    cwd: 'app/',
                    src: [
                        '**/*',
                        '!**/assets/fonts/**',
                        '!**/assets/images/**'
                    ],
                    dest: 'app/'
                }],
                options: {
                    replacements: [
                        {
                            pattern: 'fkjs_(name)',
                            replacement: '<%%= pkg.name %>'
                        },
                        {
                            pattern: 'fkjs_(title)',
                            replacement: '<%%= pkg.title %>'
                        },
                        {
                            pattern: 'fkjs_(description)',
                            replacement: '<%%= pkg.description %>'
                        },
                        {
                            pattern: 'fkjs_(version)',
                            replacement: '<%%= pkg.version %>'
                        }
                    ]
                }
            },
            'dist-tags': {
                files: [{
                    expand: true,
                    cwd: 'dist/',
                    src: [
                        '**/*',
                        '!**/assets/fonts/**',
                        '!**/assets/images/**'
                    ],
                    dest: 'dist/'
                }],
                options: {
                    replacements: [
                        {
                            pattern: 'fkjs_(name)',
                            replacement: '<%%= pkg.name %>'
                        },
                        {
                            pattern: 'fkjs_(title)',
                            replacement: '<%%= pkg.title %>'
                        },
                        {
                            pattern: 'fkjs_(description)',
                            replacement: '<%%= pkg.description %>'
                        },
                        {
                            pattern: 'fkjs_(version)',
                            replacement: '<%%= pkg.version %>'
                        }
                    ]
                }
            }
        },
        copy: {
            'bootstrap-fonts': {
                src: [
                    '**/*'
                ],
                expand: true,
                cwd: 'bower_components/bootstrap/fonts',
                dest: 'app/assets/fonts'
            },
            'material-design-iconic-font': {
                src: [
                    '**/*'
                ],
                expand: true,
                cwd: 'bower_components/material-design-iconic-font/fonts',
                dest: 'app/assets/fonts'
            },
            dist: {
                src: [
                    '**/*',
                    '!**/app.bootstrap.js',
                    '!**/test/**',
                    '!**/docs/**',
                    '!**/assets/css/**',
                    '!**/assets/scss/**',
                    '!**/src/**/*.js'
                ],
                expand: true,
                cwd: 'app',
                dest: 'dist'
            }
        },
        wiredep: {
            build: {
                src: [
                    'app/index.html'
                ],
                options: {

                }
            }
        },
        sass: {
            'material-design-iconic-font': {
                options: {
                    style: 'expanded',
                    noCache: true
                },
                files: [{
                    expand: true,
                    cwd: 'bower_components/material-design-iconic-font/scss',
                    src: ['**/*.scss'],
                    dest: 'bower_components/material-design-iconic-font/css',
                    ext: '.css'
                }]
            },
            'compile-scss': {
                options: {
                    style: 'expanded',
                    lineNumbers: true,
                    cacheLocation: 'app/assets/scss/.sass-cache'
                },
                files: [{
                    expand: true,
                    cwd: 'app/assets/scss/',
                    src: ['**/*.scss'],
                    dest: 'app/assets/scss/.temp',
                    ext: '.css'
                }]
            }
        },
        bower_concat: {
            all: {
                dest: 'dist/_bower.js',
                cssDest: 'dist/_bower.css',
                exclude: [

                ],
                mainFiles: {
                    //'script.js': 'dist/script.js'
                },
                dependencies: {

                },
                bowerOptions: {
                    relative: false
                },
                callback: function (main_files, component) {
                    var component_dependencies,
                        dependencies = [];

                    if (grunt.file.exists(project_folder + 'bower_components/' + component + '/bower.json')) {
                        component_dependencies = grunt.file.readJSON(project_folder + 'bower_components/' + component + '/bower.json').dependencies,
                        dependencies = component_dependencies ? Object.keys(component_dependencies) : [];
                    }

                    return main_files.map(function (filepath) {
                        for (i = 0; i < bower_comp.length; i++) {
                            return ((bower_comp[i].indexOf(component) > -1 || dependencies.length > -1) && component != 'script.js') ? filepath : false;
                        }
                    });
                }
            }
        },
        ngAnnotate: {
            dist: {
                files: {
                    'dist/app.js.files.js': [
                        'app/src/**/*.js'
                    ]
                }
            }
        },
        concat: {
            options: {
                //separator: ';'
            },
            'compile-css-first': {
                src: [
                    'app/assets/scss/.temp/*.css',
                    'app/assets/css/**/*.css',
                    '!**/app/assets/css/app.css',
                    '!**/app/assets/css/**/custom.css'
                ],
                dest: 'app/assets/css/app.css',
            },
            'compile-css-last': {
                src: [
                    'app/assets/css/app.css',
                    'app/assets/css/custom.css'
                ],
                dest: 'app/assets/css/app.css'
            },
            'dist-libraries': {
                src: [
                    'dist/_bower.js'
                ],
                dest: 'dist/app.libraries.js'
            },
            'dist-js-files': {
                src: [
                    'dist/app.libraries.js',
                    'dist/app.js.files.js'
                ],
                dest: 'dist/app.js'
            },
            'dist-stylesheets': {
                src: [
                    'dist/_bower.css'
                ],
                dest: 'dist/assets/css/app.css',
            },
            'dist-css-first': {
                src: [
                    'dist/_bower.css',
                    'app/assets/scss/.temp/*.css',
                    'app/assets/css/**/*.css',
                    '!**/app/assets/css/app.css',
                    '!**/app/assets/css/**/custom.css'
                ],
                dest: 'dist/assets/css/app.css',
            },
            'dist-css-last': {
                src: [
                    'dist/assets/css/app.css',
                    'app/assets/css/custom.css'
                ],
                dest: 'dist/assets/css/app.css',
            }
        },
        uglify: {
            options: {
                compress: {
                    global_defs: {
                        "DEBUG": false
                    },
                    dead_code: true
                },
                banner: '<%%= banner %>'
            },
            libraries: {
                src: 'dist/app.js',
                dest: 'dist/app.min.js'
            }
        },
        cssmin: {
            css: {
                src: 'dist/assets/css/app.css',
                dest: 'dist/assets/css/app.min.css'
            }
        },
        processhtml: {
            options: {
                data: {
                    html_tag: '<html ng-app="<%%= pkg.name %>">'
                }
            },
            dist: {
                files: {
                    'dist/index.html': ['dist/index.html']
                }
            }
        },
        clean: {
            'dist-before': [
                'dist/'
            ],
            'dist-after': [
                'app/assets/scss/.temp',
                'dist/app.js',
                'dist/app.libraries.js',
                'dist/app.js.files.js',
                'dist/assets/css/app.css',
                'dist/_bower.js',
                'dist/_bower.css',
                'dist/src/services'
            ],
            'docs': [
                'dist/docs'
            ]
        },
        watch: {
            debug: {
                files: [
                    'app/**/*',
					'!app/assets/scss/.sass-cache',
					'!app/assets/scss/.temp'
                ],
                tasks: ['compile-scss'],
                options: {
                    // Start a live reload server on the default port 35729
                    livereload: true,
                    spawn: false
                }
            }
        },
        ngdocs: {
            options: {
                dest: 'app/docs',
                startPage: '/api/app',
                html5Mode: false,
                title: '<%%= pkg.title %> Docs',
                bestMatch: true
            },
            all: [
				'app/src/**/*.js',
                'app/app.bootstrap.js'
            ]
        },
        karma: {
            unit: {
                configFile: 'app/test/karma.conf.js'
            }
        }
    });

    /**
	 * @description
	 *   Now that we have loaded the package.json and the node_modules we set the base path
     *   for the actual execution of the tasks.
	 *
	 */
    grunt.file.setBase(project_folder);

    grunt.event.on('watch', function (action, filepath, target) {
        grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
    });

    /**
	 * @description
	 *   Running test task(s).
	 *
	 */
    grunt.registerTask('test', [
		'karma'
    ]);

    /**
	 * @description
	 *   Generate documentation (ngDocs) task(s).
	 *
	 */
    grunt.registerTask('docs', [
		'clean:docs',
        'ngdocs'
    ]);

    /**
	 * @description
	 *   Compile SCSS task(s).
	 *
	 */
    grunt.registerTask('compile-scss', [
        'sass:compile-scss',
        'concat:compile-css-first',
        'concat:compile-css-last'
    ]);

    /**
	 * @description
	 *   Dist task(s).
	 *
	 */
    grunt.registerTask('dist', [
        'clean:dist-before',
        'copy:dist',
        'string-replace:dist-tags',
        'processhtml',
        'bower_concat',
        'sass:compile-scss',
        'concat:dist-stylesheets',
        'concat:dist-css-first',
        'concat:dist-css-last',
        'cssmin',
        'ngAnnotate:dist',
        'concat:dist-libraries',
        'concat:dist-js-files',
        'uglify',
        'clean:dist-after'
    ]);

    /**
	 * @description
	 *   Default task(s).
	 *
	 */
    grunt.registerTask('default', [
        'copy:material-design-iconic-font',
        'string-replace:material-design-iconic-font',
        'sass:material-design-iconic-font',
        'string-replace:default-tags',
        'compile-scss',
        'wiredep:build'
    ]);
};<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import Paper from '@material-ui/core/Paper'
import IconButton from '@material-ui/core/IconButton'
import CloseIcon from '@material-ui/icons/Close'
import { setCampaignDismissTime } from 'js/utils/local-user-data-mgr'
import Typography from '@material-ui/core/Typography'

const styles = theme => ({
  root: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    width: '100%',
    height: '100%',
    boxSizing: 'border-box',
    pointerEvents: 'none',
  },
  paper: {
    position: 'relative',
    pointerEvents: 'all',
    minWidth: 400,
    width: '100%',
    margin: 0,
    padding: 0,
    background: '#FFF',
    border: 'none',
  },
  borderTop: {
    width: '100%',
    height: 3,
    borderTopLeftRadius: 2,
    borderTopRightRadius: 2,
    backgroundColor: theme.palette.secondary.main,
  },
  closeButton: {
    position: 'absolute',
    top: 5,
    right: 2,
  },
  campaignContent: {
    padding: 12,
  },
  campaignAddendum: {
    background: '#f5f5f5', // darker: '#eeeeee'
    padding: 12,
  },
  mainTextContainer: {},
  title: {
    textAlign: 'center',
  },
  description: {
    margin: 14,
    textAlign: 'left',
  },
})

const getCampaignContent = ({ currentDateString }) => {
  let title
  let mainContent
  let addendumContent

  switch (currentDateString) {
    case '2020-10-29': {
      title = <Typography variant="h6">Some title here</Typography>
      mainContent = (

          <Typography variant="body2">Some description here</Typography>

      )
      addendumContent = (

          <Typography variant="body2">Hi there!</Typography>

      )
      break
    }
    case '2020-10-30': {
      title = <Typography variant="h6">Another title!</Typography>
      mainContent = (

          <Typography variant="body2">Another description here</Typography>

      )
      addendumContent = (

          <Typography variant="body2">Hi there! :)</Typography>

      )
      break
    }
    default: {
      title = <Typography variant="h6">Some title here</Typography>
      mainContent = (

          <Typography variant="body2">Some description here</Typography>

      )
      addendumContent = (

          <Typography variant="body2">Hi there!</Typography>

      )
    }
  }

  return {
    title,
    mainContent,
    addendumContent,
  }
}

const MillionRaisedCampaign = ({ classes, currentDateString, onDismiss }) => {
  const { title, mainContent, addendumContent } = getCampaignContent({
    currentDateString,
  })
  return (

      <Paper elevation={1} className={classes.paper}>
        <Paper elevation={1} className={classes.paper}>

          <IconButton
            onClick={() => {
              setCampaignDismissTime()
              onDismiss()
            }}
            className={classes.closeButton}
          >
            <CloseIcon />
          </IconButton>

{title}

{mainContent}

        </Paper>

{addendumContent}

      </Paper>

  )
}

MillionRaisedCampaign.propTypes = {
  currentDateString: PropTypes.string.isRequired,
  onDismiss: PropTypes.func.isRequired,
}
MillionRaisedCampaign.defaultProps = {
  onDismiss: () => {},
}

export default withStyles(styles, { withTheme: true })(MillionRaisedCampaign)
<commit_msg>Add a default title<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import Paper from '@material-ui/core/Paper'
import IconButton from '@material-ui/core/IconButton'
import CloseIcon from '@material-ui/icons/Close'
import { setCampaignDismissTime } from 'js/utils/local-user-data-mgr'
import Typography from '@material-ui/core/Typography'

const styles = theme => ({
  root: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    width: '100%',
    height: '100%',
    boxSizing: 'border-box',
    pointerEvents: 'none',
  },
  paper: {
    position: 'relative',
    pointerEvents: 'all',
    minWidth: 400,
    width: '100%',
    margin: 0,
    padding: 0,
    background: '#FFF',
    border: 'none',
  },
  borderTop: {
    width: '100%',
    height: 3,
    borderTopLeftRadius: 2,
    borderTopRightRadius: 2,
    backgroundColor: theme.palette.secondary.main,
  },
  closeButton: {
    position: 'absolute',
    top: 5,
    right: 2,
  },
  campaignContent: {
    padding: 12,
  },
  campaignAddendum: {
    background: '#f5f5f5', // darker: '#eeeeee'
    padding: 12,
  },
  mainTextContainer: {},
  title: {
    textAlign: 'center',
  },
  description: {
    margin: 14,
    textAlign: 'left',
  },
})

const getCampaignContent = ({ currentDateString }) => {
  const defaultTitle = (
    <Typography variant="h6">
      $1,000,000: A tab you’ll want to keep open
    </Typography>
  )
  let title = defaultTitle
  let mainContent
  let addendumContent
  switch (currentDateString) {
    case '2020-10-29': {
      mainContent = (

          <Typography variant="body2">Some description here</Typography>

      )
      addendumContent = (

          <Typography variant="body2">Hi there!</Typography>

      )
      break
    }
    case '2020-10-30': {
      mainContent = (

          <Typography variant="body2">Another description here</Typography>

      )
      addendumContent = (

          <Typography variant="body2">Hi there! :)</Typography>

      )
      break
    }
    default: {
      mainContent = (

          <Typography variant="body2">Some description here</Typography>

      )
      addendumContent = (

          <Typography variant="body2">Hi there!</Typography>

      )
    }
  }

  return {
    title,
    mainContent,
    addendumContent,
  }
}

const MillionRaisedCampaign = ({ classes, currentDateString, onDismiss }) => {
  const { title, mainContent, addendumContent } = getCampaignContent({
    currentDateString,
  })
  return (

      <Paper elevation={1} className={classes.paper}>
        <Paper elevation={1} className={classes.paper}>

          <IconButton
            onClick={() => {
              setCampaignDismissTime()
              onDismiss()
            }}
            className={classes.closeButton}
          >
            <CloseIcon />
          </IconButton>

{title}

{mainContent}

        </Paper>

{addendumContent}

      </Paper>

  )
}

MillionRaisedCampaign.propTypes = {
  currentDateString: PropTypes.string.isRequired,
  onDismiss: PropTypes.func.isRequired,
}
MillionRaisedCampaign.defaultProps = {
  onDismiss: () => {},
}

export default withStyles(styles, { withTheme: true })(MillionRaisedCampaign)
<|endoftext|>


<commit_before>const $ = require('jquery');
const Point = require('./Point');

class Board {
	constructor(boardPaper) {
		this.boardPaper = boardPaper;
		boardPaper.attr({
			viewBox: [-3, -25, 206, 250]
		});
		boardPaper.rect(0, 0, 200, 200).addClass('board-edge');
		this.points = [];
		for (let y = 0; y < 9; y++) {
			const row = [];
			this.points.push(row);
			for (let x = 0; x < 9; x++) {
				row.push(new Point(this, x, y));
			}
		}
		this.goalCircleA = boardPaper.circle(100, 200, 5).addClass('board-goal player-a');
		this.goalCircleB = boardPaper.circle(100, 0, 5).addClass('board-goal player-b');
		this.traceLine = boardPaper.polyline(100, 100).addClass('trace-line');
		this.currentPointCircle = boardPaper.circle(100, 100, 7).addClass('current-point');
		this.arrowMap = new Map();

		this.trace = [[[4, 4]]];
		this.moves = [];
		this.activePlayer = 0;
		this.update();
	}

	get currentCoords() {
		const lastPath = this.trace[this.trace.length - 1];
		return lastPath[lastPath.length - 1];
	}

	getCurrentPoint() {
		const [x, y] = this.currentCoords;
		if (y === 9 || y === -1) {
			return null;
		}
		return this.points[y][x];
	}

	update() {
		const player = ['a', 'b'][this.activePlayer];
		const currentPoint = this.getCurrentPoint();
		this.traceLine.attr({
			points: this.trace.map((path) => path.map(([x, y]) => [20 + 20 * x, 20 + 20 * y]))
		});
		const [x, y] = this.currentCoords;
		this.currentPointCircle.attr({
			cx: 20 + 20 * x,
			cy: 20 + 20 * y
		});
		this.arrowMap.forEach((arrow) => arrow.remove());
		if (currentPoint !== null) {
			this.arrowMap = currentPoint.drawArrows();
			this.arrowMap.forEach((arrow, direction) => {
				arrow.click(() => {
					this.moveTo(direction);
					this.update();
				});
			});
			$('.active-player').removeClass('active-player');
			$('.player-' + player).addClass('active-player');
		} else {
			this.arrowMap = new Map();
		}
	}

	switchPlayer() {
		this.activePlayer = 1 - this.activePlayer;
	}

	moveTo(direction) {
		const dxdys = [
			[ 0, -1],
			[ 1, -1],
			[ 1,  0],
			[ 1,  1],
			[ 0,  1],
			[-1,  1],
			[-1,  0],
			[-1, -1]
		];

		const oldPoint = this.getCurrentPoint();
		const moves = oldPoint.getMoves(direction);

		let {x, y} = oldPoint;
		this.trace.push(moves.map((currentDirection) => {
			const [dx, dy] = dxdys[currentDirection];
			x += dx;
			y += dy;
			return [x, y];
		}));
		this.moves.push(moves);
		const newPoint = this.getCurrentPoint();

		oldPoint.availableDirections.delete(direction);

		if (newPoint !== null) {
			newPoint.availableDirections.delete((moves[moves.length - 1] + 4) % 8);
			let isTriangleFormed = false;
			if (moves.length === 1) {
				if (direction % 2 === 0) {
					isTriangleFormed = (
						!oldPoint.availableDirections.has((direction + 1) % 8) && !newPoint.availableDirections.has((direction + 2) % 8)
					) || (
						!oldPoint.availableDirections.has((direction + 7) % 8) && !newPoint.availableDirections.has((direction + 6) % 8)
					) || (
						!oldPoint.availableDirections.has((direction + 2) % 8) && !newPoint.availableDirections.has((direction + 3) % 8)
					) || (
						!oldPoint.availableDirections.has((direction + 6) % 8) && !newPoint.availableDirections.has((direction + 5) % 8)
					);
				} else {
					isTriangleFormed = (
						!oldPoint.availableDirections.has((direction + 1) % 8) && !newPoint.availableDirections.has((direction + 3) % 8)
					) || (
						!oldPoint.availableDirections.has((direction + 7) % 8) && !newPoint.availableDirections.has((direction + 5) % 8)
					);
				}
			}
			if (!isTriangleFormed) {
				// TODO: visualize triangle
				this.switchPlayer();
			}
		} else {
			// clear
		}
	}

	undo() {
		const newPoint = this.getCurrentPoint();
		this.trace.pop();
		const moves = this.moves.pop();
		const oldPoint = this.getCurrentPoint();

		if (!moves) {
			// Not moved yet
			return;
		}

		oldPoint.availableDirections.add(moves[0]);
		if (newPoint !== null) {
			newPoint.availableDirections.add((moves[moves.length - 1] + 4) % 8);
		}

		this.update();
	}
}

module.exports = Board;
<commit_msg>Refactoring<commit_after>const $ = require('jquery');
const Point = require('./Point');

class Board {
	constructor(boardPaper) {
		this.boardPaper = boardPaper;
		boardPaper.attr({
			viewBox: [-3, -25, 206, 250]
		});
		boardPaper.rect(0, 0, 200, 200).addClass('board-edge');
		this.points = [];
		for (let y = 0; y < 9; y++) {
			const row = [];
			this.points.push(row);
			for (let x = 0; x < 9; x++) {
				row.push(new Point(this, x, y));
			}
		}
		this.goalCircleA = boardPaper.circle(100, 200, 5).addClass('board-goal player-a');
		this.goalCircleB = boardPaper.circle(100, 0, 5).addClass('board-goal player-b');
		this.traceLine = boardPaper.polyline(100, 100).addClass('trace-line');
		this.currentPointCircle = boardPaper.circle(100, 100, 7).addClass('current-point');
		this.arrowMap = new Map();

		this.trace = [[[4, 4]]];
		this.moves = [];
		this.activePlayer = 0;
		this.update();
	}

	get currentCoords() {
		const lastPath = this.trace[this.trace.length - 1];
		return lastPath[lastPath.length - 1];
	}

	getCurrentPoint() {
		const [x, y] = this.currentCoords;
		if (y === 9 || y === -1) {
			return null;
		}
		return this.points[y][x];
	}

	update() {
		const player = ['a', 'b'][this.activePlayer];
		const currentPoint = this.getCurrentPoint();
		this.traceLine.attr({
			points: this.trace.map((path) => path.map(([x, y]) => [20 + 20 * x, 20 + 20 * y]))
		});
		const [x, y] = this.currentCoords;
		this.currentPointCircle.attr({
			cx: 20 + 20 * x,
			cy: 20 + 20 * y
		});
		this.arrowMap.forEach((arrow) => arrow.remove());
		if (currentPoint !== null) {
			this.arrowMap = currentPoint.drawArrows();
			this.arrowMap.forEach((arrow, direction) => {
				arrow.click(() => {
					this.moveTo(direction);
					this.update();
				});
			});
			$('.active-player').removeClass('active-player');
			$('.player-' + player).addClass('active-player');
		} else {
			this.arrowMap = new Map();
		}
	}

	switchPlayer() {
		this.activePlayer = 1 - this.activePlayer;
	}

	moveTo(direction) {
		const dxdys = [
			[ 0, -1],
			[ 1, -1],
			[ 1,  0],
			[ 1,  1],
			[ 0,  1],
			[-1,  1],
			[-1,  0],
			[-1, -1]
		];

		const oldPoint = this.getCurrentPoint();
		const moves = oldPoint.getMoves(direction);

		let {x, y} = oldPoint;
		this.trace.push(moves.map((currentDirection) => {
			const [dx, dy] = dxdys[currentDirection];
			x += dx;
			y += dy;
			return [x, y];
		}));
		this.moves.push(moves);
		const newPoint = this.getCurrentPoint();

		oldPoint.availableDirections.delete(direction);

		if (newPoint !== null) {
			newPoint.availableDirections.delete((moves[moves.length - 1] + 4) % 8);
			let otherSidesRelativeDirections = [];
			if (moves.length === 1) {
				if (direction % 2 === 0) {
					otherSidesRelativeDirections = [
						[1, 2],
						[7, 6],
						[2, 3],
						[6, 5]
					];
				} else {
					otherSidesRelativeDirections = [
						[1, 3],
						[7, 5]
					];
				}
			}
			let thirdPoint = null;
			for ([diff1, diff2] of otherSidesRelativeDirections) {
				const direction1 = (direction + diff1) % 8;
				const direction2 = (direction + diff2) % 8;
				if (!oldPoint.availableDirections.has(direction1) && !newPoint.availableDirections.has(direction2)) {
					const [dx, dy] = dxdys[direction1];
					thirdPoint = this.points[oldPoint.y + dy][oldPoint.x + dx];
					break;
				}
			}
			if (!thirdPoint) {
				// TODO: visualize triangle
				this.switchPlayer();
			}
		} else {
			// clear
		}
	}

	undo() {
		const newPoint = this.getCurrentPoint();
		this.trace.pop();
		const moves = this.moves.pop();
		const oldPoint = this.getCurrentPoint();

		if (!moves) {
			// Not moved yet
			return;
		}

		oldPoint.availableDirections.add(moves[0]);
		if (newPoint !== null) {
			newPoint.availableDirections.add((moves[moves.length - 1] + 4) % 8);
		}

		this.update();
	}
}

module.exports = Board;
<|endoftext|>


<commit_before>var esprima   = require('esprima'),
	fs        = require('fs'),
	escodegen = require('escodegen');

var getRenderer = function(ext, cwd){
	return "define(function() {\n"+
	"	var Rndrr = {},\n"+
	"		buildMap = {};\n"+
	"	Rndrr.load = function(name, parentRequire, load, config) {\n"+
	"		var path   = parentRequire.toUrl(name + '." + ext + "').replace(/\\.|\\//g, '_').replace(/^_+|_+$/g, '');\n"+
	"			fs     = require.nodeRequire('fs'),\n"+
	"			views  = JSON.parse(fs.readFileSync('" + cwd + "/.build/views.json')),\n"+
	"			output = views[path];\n"+
	"\n"+
	"		buildMap[name] = output;\n"+
	"		load(output);\n"+
	"	};\n"+
	"	Rndrr.write = function (pluginName, name, write) {\n"+
	"		if (buildMap.hasOwnProperty(name)) {\n"+
	"			var text = buildMap[name];\n"+
	"			write.asModule(pluginName + '!' + name, text);\n"+
	"		}\n"+
	"	};\n"+
	"	return Rndrr;\n"+
	"});\n";
}

/**
 * This Gruntfile provides a `build` task that enables you to combine your
 * EJS and mustache views in the production build.
 *
 * The problem is that r.js is completely synchronous and can-compile uses
 * JSDom library which is async. That's why this build system is complicated
 * and kinda brittle. It should be only a temporary solution.
 *
 * Build system works like this:
 *
 * 1. Create temp .build folder
 * 2. call can-compile and create .build/views.js file
 * 3. Use esprima and escodegen to parse .build/views.js and convert it to a JSON file
 * 4. Provide custom renderers for mustache and EJS that will get compiled view from the JSON file
 * 5. Call require compile task to create production.js file
 * 6. Remoce .build folder to cleanup
 */

module.exports = function(grunt) {

	grunt.initConfig({
		exec : {
			mkbuilddir : {
				cmd : 'mkdir .build'
			},
			rmbuilddir   : {
				cmd : 'rm -rf .build'
			},
			compileviews : {
				cmd: 'node_modules/can-compile/bin/can-compile -o .build/views.js'
			}
		},
		requirejs : {
			compile : {
				options : {
					paths: {
						can      : 'components/canjs/amd/can',
						jquery   : 'components/jquery/jquery',
						mustache : '.build/mustache',
						ejs      : '.build/ejs'
					},
					name : '<%= appName %>',
					out : 'production.js'
				}
			}
		}
	});

	grunt.registerTask('extractViews', function(){
		var file           = fs.readFileSync('.build/views.js'),
			ast            = esprima.parse(file),
			views          = ast.body[0].expression.callee.body.body,
			generatedViews = {};

		views.forEach(function(view){
			var filename = view.expression.arguments[0].value;
			generatedViews[filename] = escodegen.generate(view);

		})
		fs.writeFileSync('.build/views.json', JSON.stringify(generatedViews));
	})

	grunt.registerTask('createRenderers', function(){
		fs.writeFileSync('.build/mustache.js', getRenderer('mustache', process.cwd()));
		fs.writeFileSync('.build/ejs.js', getRenderer('ejs', process.cwd()));
	})

	grunt.registerTask('build', function(){
		grunt.task.run(
			'exec:rmbuilddir',
			'exec:mkbuilddir',
			'exec:compileviews',
			'extractViews',
			'createRenderers',
			'requirejs:compile',
			'exec:rmbuilddir'
		);
	});

	grunt.loadNpmTasks('grunt-contrib-requirejs');
	grunt.loadNpmTasks('grunt-exec');
	grunt.registerTask('default', 'build');

};<commit_msg>Fix renderer function generated in Gruntfile.js<commit_after>var esprima   = require('esprima'),
	fs        = require('fs'),
	escodegen = require('escodegen');

var getRenderer = function(ext, cwd){
	return "define(function() {\n"+
		"	var Rndrr = {},\n"+
		"		buildMap = {};\n"+
		"	Rndrr.load = function(name, parentRequire, load, config) {\n"+
		"		var path = parentRequire.toUrl(name + '." + ext + "'),\n"+
		"			fs, views, output;\n"+
		"		if(config.isBuild){\n"+
		"			path   = path.replace(/\\.|\\//g, '_').replace(/^_+|_+$/g, '');\n"+
		"			fs     = require.nodeRequire('fs'),\n"+
		"			views  = JSON.parse(fs.readFileSync('" + cwd + "/.build/views.json')),\n"+
		"			output = 'define([\\'can/view/" + ext + "\\'], function(can){ ' + views[path] + ' });'\n"+
		"			buildMap[name] = output;\n"+
		"			load(output);\n"+
		"		} else {\n"+
		"			parentRequire(['can/view/" + ext + "', 'can/observe'], function(can) {\n"+
		"				load(function(data){\n"+
		"					return can.view(path, data)\n"+
		"				});\n"+
		"			});\n"+
		"		}\n"+
		"	};\n"+
		"	Rndrr.write = function (pluginName, name, write) {\n"+
		"		if (buildMap.hasOwnProperty(name)) {\n"+
		"			var text = buildMap[name];\n"+
		"			write.asModule(pluginName + '!' + name, text);\n"+
		"		}\n"+
		"	};\n"+
		"	return Rndrr;\n"+
		"});";
}

/**
 * This Gruntfile provides a `build` task that enables you to combine your
 * EJS and mustache views in the production build.
 *
 * The problem is that r.js is completely synchronous and can-compile uses
 * JSDom library which is async. That's why this build system is complicated
 * and kinda brittle. It should be only a temporary solution.
 *
 * Build system works like this:
 *
 * 1. Create temp .build folder
 * 2. call can-compile and create .build/views.js file
 * 3. Use esprima and escodegen to parse .build/views.js and convert it to a JSON file
 * 4. Provide custom renderers for mustache and EJS that will get compiled view from the JSON file
 * 5. Call require compile task to create production.js file
 * 6. Remoce .build folder to cleanup
 */

module.exports = function(grunt) {

	grunt.initConfig({
		exec : {
			mkbuilddir : {
				cmd : 'mkdir .build'
			},
			rmbuilddir   : {
				cmd : 'rm -rf .build'
			},
			compileviews : {
				cmd: 'node_modules/can-compile/bin/can-compile -o .build/views.js'
			}
		},
		requirejs : {
			compile : {
				options : {
					paths: {
						can      : 'components/canjs/amd/can',
						jquery   : 'components/jquery/jquery',
						mustache : '.build/mustache',
						ejs      : '.build/ejs'
					},
					name : '<%= appName %>',
					out : 'production.js'
				}
			}
		}
	});

	grunt.registerTask('extractViews', function(){
		var file           = fs.readFileSync('.build/views.js'),
			ast            = esprima.parse(file),
			views          = ast.body[0].expression.callee.body.body,
			generatedViews = {};

		views.forEach(function(view){
			var filename = view.expression.arguments[0].value;
			generatedViews[filename] = escodegen.generate(view);

		})
		fs.writeFileSync('.build/views.json', JSON.stringify(generatedViews));
	})

	grunt.registerTask('createRenderers', function(){
		fs.writeFileSync('.build/mustache.js', getRenderer('mustache', process.cwd()));
		fs.writeFileSync('.build/ejs.js', getRenderer('ejs', process.cwd()));
	})

	grunt.registerTask('build', function(){
		grunt.task.run(
			'exec:rmbuilddir',
			'exec:mkbuilddir',
			'exec:compileviews',
			'extractViews',
			'createRenderers',
			'requirejs:compile',
			'exec:rmbuilddir'
		);
	});

	grunt.loadNpmTasks('grunt-contrib-requirejs');
	grunt.loadNpmTasks('grunt-exec');
	grunt.registerTask('default', 'build');

};<|endoftext|>


<commit_before>(function() {
	/**
	 * Load the list of files asynchronously. This uses recursion in
	 * order to create a queue of files that will be loaded serially.
	 * Each layer, starting at the bottom, loads a file and then loads
	 * the layer on top of it. The very top file on the stack will have
	 * zero files to load, so instead it will be the one to call the
	 * callback to notify the caller that all the content is loaded.
	 *
	 * @param {Object} context function to call this method in the context of
	 * @param {Array.<string>} paths array of strings containing relative paths for required locale data files
	 * @param {Array} results empty array in which to place the resulting json when it is loaded from a file
	 * @param {function(Array.<Object>)} callback callback to call when this function is finished attempting
	 * to load all the files that exist and can be loaded
	 */
	function loadFiles(context, paths, results, callback) {
		if (paths.length > 0) {
			var path = paths.shift();
			var file = "lib/enyo-ilib/ilib/locale/" + path;
			var ajax = new enyo.Ajax({url: file});
			var resultFunc = function(inSender, json) {
				results.push((typeof(json) === 'object') ? json : undefined);
				if (paths.length > 0) {
					loadFiles(context, paths, results, callback);
				} else {
					// only the bottom item on the stack will call
					// the callback
					callback.call(context, results);
				}
			};
			ajax.response(this, resultFunc);
			ajax.error(this, function(inSender, json) {
				// not there? Try the standard place instead
				var file = "resources/" + path;
				var ajax2 = new enyo.Ajax({url: file});

				ajax2.response(this, resultFunc);
				ajax2.error(this, resultFunc);
				ajax2.go();
			});
			ajax.go();
		}
	}

	ilib.setLoaderCallback(enyo.bind(this, function(paths, sync, callback) {
		if (sync) {
			var ret = [];
			// synchronous
			paths.forEach(function (path) {
				var ajax = new enyo.Ajax({
					url: "lib/enyo-ilib/ilib/locale/" + path,
					sync: true
				});

				var handler = function(inSender, json) {
					ret.push((typeof(json) === 'object') ? json : undefined);
				};
				ajax.response(this, handler);
				ajax.error(this, function(inSender, json) {
					var ajax2 = new enyo.Ajax({
						url: "resources/" + path,
						sync: true
					});
					ajax2.response(this, handler);
					ajax2.error(this, handler);
					ajax2.go();
				});
				ajax.go();
			});

			if (typeof(callback) === 'function') {
				callback.call(this, ret);
			}
			return ret;
		}

		// asynchronous
		var results = [];
		loadFiles(this, paths, results, callback);
	}));
})();

/*
 * Reset the $L function to use ilib instead of the dummy function that enyo
 * comes with by default.
 */
$L = (function() {
	if (typeof(window.UILocale) !== 'undefined') {
		// this is a hack until GF-1581 is fixed
		ilib.setLocale(window.UILocale);
	}
	var lfunc = function (string) {
		var str = $L.rb.getString(string);
		return str.toString();
	};
	lfunc.rb = new ilib.ResBundle({
		type: "html",
		name: "strings",
		lengthen: true		// if pseudo-localizing, this tells it to lengthen strings
	});
	return lfunc;
})();

/**
 * Set the locale for the strings that $L loads. This may reload the
 * string resources if necessary.
 */
$L.setLocale = function (spec) {
	if (spec !== $L.rb.getLocale().getSpec()) {
		$L.rb = new ilib.ResBundle({
			locale: spec,
			type: "html",
			name: "strings",
			lengthen: true		// if pseudo-localizing, this tells it to lengthen strings
		});
	}
};
<commit_msg>Get the glue code to work on webOS<commit_after>(function() {
	/**
	 * Load the list of files asynchronously. This uses recursion in
	 * order to create a queue of files that will be loaded serially.
	 * Each layer, starting at the bottom, loads a file and then loads
	 * the layer on top of it. The very top file on the stack will have
	 * zero files to load, so instead it will be the one to call the
	 * callback to notify the caller that all the content is loaded.
	 *
	 * @param {Object} context function to call this method in the context of
	 * @param {Array.<string>} paths array of strings containing relative paths for required locale data files
	 * @param {Array} results empty array in which to place the resulting json when it is loaded from a file
	 * @param {Object} params An object full of parameters that the caller is passing to this function to help load the files
	 * @param {function(Array.<Object>)} callback callback to call when this function is finished attempting
	 * to load all the files that exist and can be loaded
	 */
	function loadFiles(context, paths, results, params, callback) {
		if (paths.length > 0) {
			var path = paths.shift();
			var file = "lib/enyo-ilib/ilib/locale/" + path;
			var ajax = new enyo.Ajax({url: file});
			var resultFunc = function(inSender, json) {
				results.push((typeof(json) === 'object') ? json : undefined);
				if (paths.length > 0) {
					loadFiles(context, paths, results, params, callback);
				} else {
					// only the bottom item on the stack will call
					// the callback
					callback.call(context, results);
				}
			};
			ajax.response(this, resultFunc);
			ajax.error(this, function(inSender, json) {
				// not there? Try the standard place instead
				var file = "resources/" + path;
				var ajax2 = new enyo.Ajax({url: file});

				ajax2.response(this, resultFunc);
				ajax2.error(this, resultFunc);
				ajax2.go();
			});
			ajax.go();
		}
	}

	ilib.setLoaderCallback(enyo.bind(this, function(paths, sync, params, callback) {
		if (sync) {
			var ret = [];
			// synchronous
			if (ilib._getPlatform() === "webos") {
				// running on a webos device
				paths.forEach(function (path) {
					var json;
					try {
						jsonString = palmGetResource("/usr/palm/applications/com.palm.app.moondemo2/lib/enyo-ilib/ilib/locale/" + path, "const json");		// get the object from the shared cache
						json = (typeof(jsonString) === 'string') ? JSON.parse(jsonString) : jsonString;
					} catch ( e1 ) {
						json = undefined;
					}
					if (!json) {
						try {
							jsonString = palmGetResource("/usr/palm/applications/com.palm.app.moondemo2/resources/" + path, "const json");		// get the object from the shared cache
							json = (typeof(jsonString) === 'string') ? JSON.parse(jsonString) : jsonString;
						} catch ( e2 ) {
							json = undefined;
						}
					}
					ret.push(json);
				});
			} else {
				// running on the desktop build or the browser
				paths.forEach(function (path) {
					// console.log("browser/sync: attempting to load lib/enyo-ilib/ilib/locale/" + path);
					var ajax = new enyo.Ajax({
						url: "lib/enyo-ilib/ilib/locale/" + path,
						sync: true
					});

					var handler = function(inSender, json) {
						// console.log((json ? "success" : "failed"));
						ret.push((typeof(json) === 'object') ? json : undefined);
					};
					ajax.response(this, handler);
					ajax.error(this, function(inSender, json) {
						// console.log("browser/sync: Now attempting to load resources/" + path);
						var ajax2 = new enyo.Ajax({
							url: "resources/" + path,
							sync: true
						});
						ajax2.response(this, handler);
						ajax2.error(this, handler);
						ajax2.go();
					});
					ajax.go();
				});
			}

			if (typeof(callback) === 'function') {
				callback.call(this, ret);
			}
			return ret;
		}

		// asynchronous
		var results = [];
		loadFiles(this, paths, results, params, callback);
	}));
})();

/*
 * Reset the $L function to use ilib instead of the dummy function that enyo
 * comes with by default.
 */
$L = (function() {
	if (typeof(window.UILocale) !== 'undefined') {
		// this is a hack until GF-1581 is fixed
		ilib.setLocale(window.UILocale);
	}
	var lfunc = function (string) {
		var str = $L.rb.getString(string);
		return str.toString();
	};
	lfunc.rb = new ilib.ResBundle({
		type: "html",
		name: "strings",
		lengthen: true		// if pseudo-localizing, this tells it to lengthen strings
	});
	return lfunc;
})();

/**
 * Set the locale for the strings that $L loads. This may reload the
 * string resources if necessary.
 */
$L.setLocale = function (spec) {
	if (spec !== $L.rb.getLocale().getSpec()) {
		$L.rb = new ilib.ResBundle({
			locale: spec,
			type: "html",
			name: "strings",
			lengthen: true		// if pseudo-localizing, this tells it to lengthen strings
		});
	}
};
<|endoftext|>


<commit_before>"use strict";

require("setimmediate"); // polyfill for env != IE10+

/* global requestIdleCallback */
if (global.window) { // eslint-disable-line no-undef
	require("requestidlecallback"); // polyfill for env != Chrome46+
} else {
	global.requestIdleCallback = fn => {
		return setTimeout(() => {
			let deadline = Date.now() + 50;
			fn({
				timeRemaining: () => Math.max(0, deadline - Date.now()),
				didTimeout: false
			});
		}, 0);
	};
	global.cancelIdleCallback = handle => clearTimeout(handle);
}

let jsonop = require("jsonop"),
	OrderedArray = require("./OrderedArray"),
	RangeArray = require("./RangeArray"),
	keySlice  = require("./keyslice"),
	keyToSlice = keySlice.keyToSlice,
	sliceToKey = keySlice.sliceToKey;

module.exports = class Cache {
	constructor(options) {
		options = jsonop({
			id: (entity) => { return entity.id; },
			is: (entity, type) => { return entity.type === type; }
		}, options || {});

		this.entities = {};
		this.indexes = {};
		this.queries = {};
		this.knowledge = {};
		this.app = {};
		this.keyToSlice = keyToSlice;
		this.sliceToKey = sliceToKey;

		/*
			map of types to index keys to index slices for fast lookup
			{
				items: {
					"items:createTime(tag:hidden)": { type: items, order: createTime, filters: { tag: hidden } }
				}
			}
		*/
		this._types = {};
		this._changeListeners = [];
		this._queryCallbacks = {};
		this._recentQueries = { entities: {}};
		this._querySeqNum = 0;
		this._id = options.id;
		this._is = options.is;
		this._options = options;
	}

	/*
		Get index keys and corresponding values that must include this entity,
		taking into account knowledge for the same key.
		@param entity
		@returns { key: value }
	*/
	getKeyValues(entity) {
		let keyValues = {};

		for (let type in this._types) {
			if (!this._is(entity, type)) { continue; }

			keyloop:
			for (let key in this._types[type].base) {
				let slice = this._types[type].base[key],
					value = entity[slice.order];

				if (typeof value === "undefined") { continue; }

				for (let prop in slice.filters) {
					if (entity[prop] !== slice.filters[prop]) {
						continue keyloop;
					}
				}
				if (this.knowledge[key].contains(value)) {
					keyValues[key] = { value, item: (slice.link || slice.join) ?
						{ [type]: entity } : entity };
				}
			}

			keyloop:
			for (let key in this._types[type].join) {
				let slice = this._types[type].join[key],
					base = this.entities[entity[slice.join[type]]],
					value = base[slice.order];

				if (typeof value === "undefined") { continue; }

				for (let prop in slice.filters) {
					if (entity[prop] !== slice.filters[prop]) {
						continue keyloop;
					}
				}
				if (this.knowledge[key].contains(value)) {
					keyValues[key] = { value, item: { [type]: entity } };
				}
			}

			// TODO: Implement link types. This is not currently
			// required in HeyNeighbor, so not targeted for first
			// release.
		}

		return keyValues;
	}

	/*
		Adds or updates an entity and updates indexes if necessary.
	*/
	putEntity(entity, excludeKeys) {
		let id = this._id(entity),
			oldKeyValues,
			newKeyValues;

		if (this.entities[id]) {
			oldKeyValues = this.getKeyValues(this.entities[id]);
			entity = jsonop(this.entities[id], entity);
		}
		this.entities[id] = entity;
		newKeyValues = this.getKeyValues(entity);

		if (oldKeyValues) {
			for (let key in oldKeyValues) {
				if (oldKeyValues[key].value !== newKeyValues[key].value) {
					this.indexes[key].delete(oldKeyValues[key].value);
				} else {
					delete newKeyValues[key];
				}
			}
		}

		if (excludeKeys) { for (let key of excludeKeys) {
			delete newKeyValues[key];
		}}

		for (let key in newKeyValues) {
			this.indexes[key].add(newKeyValues[key].item);
		}

		return entity;
	}

	deleteEntity(id) {
		let keyValues = this.getKeyValues(this.entities[id]);
		for (let key in keyValues) {
			if (
				keyValues[key].item === this.entities[id] ||
				keyValues[key].item[keyToSlice(key).type] === this.entities[id]
			) {
				this.indexes[key].delete(keyValues[key].value);
			} else {
				for (let type in keyValues[key].item) {
					if (keyValues[key].item[type] === this.entities[id]) {
						this.indexes[key].put({ [type]: null });
					}
				}
			}
		}
		delete this.entities[id];
	}

	putIndex(key, knowledge, items) {
		let slice = keyToSlice(key),
			addType = (comp, type) => {
				this._types[type] = this._types[type] || {
					base: {}, link: {}, join: {}
				};
				this._types[type][comp][key] = slice;
			};
		if (!this.knowledge[key]) {
			addType("base", slice.type);
			if (slice.link) { for (let type in slice.link) {
				addType("link", type);
			}}
			if (slice.join) { for (let type in slice.join) {
				addType("join", type);
			}}

			this.knowledge[key] = knowledge;
			this.indexes[key] = items;
			this.indexEntities(key);
		} else {
			for (let range of knowledge) {
				let rangeItems = items.slice(...range);
				this.indexes[key].splice(...range, rangeItems);
				this.knowledge[key].add(range);
			}
		}
		// insert all the items into entities, updating all indexes
		// except this one.
		if (slice.join || slice.link) {
			for (let item of items) {
				for (let name in item) {
					this.putEntity(item[name], [ key ]);
				}
			}
		} else {
			for (let item of items) {
				this.putEntity(item, [ key ]);
			}
		}

		if (this._queryCallbacks[key]) {
			for (let i in this._queryCallbacks[key]) {
				let { ranges, callback } = this._queryCallbacks[key][i];
				if (ranges.subtract(this.knowledge[key]).length === 0) {
					// No gaps in knowledge; query is satisfied.
					this.query(key, ranges[0], callback);
				}
			}
		}
	}

	/*
		Checks every entity for inclusion in a particular index. Called when a
		new index is created.
	*/
	indexEntities(key) {
		let slice = keyToSlice(key);
		for (let id in this.entities) {
			let entity = this.entities[id],
				value = entity[slice.order];
			if (typeof value !== "undefined") {
				this.indexes[key].add(entity);
			}
		}
		/* TODO: Rewrite for perf: use push() then sort() */
	}

	pruneEntities(/* deadline */) {
		/* TODO: Implement in a nonblocking fashion */
	}

	/*
		Make changes to this cache (setState).
	*/
	put(changes) {
		/* handle the addition of ranges of results */
		if (changes.knowledge) { for (let key in changes.knowledge) {
			let items = changes.indexes && changes.indexes[key] || [];

			if (!(changes.knowledge[key] instanceof RangeArray)) {
				changes.knowledge[key] =
					new RangeArray(changes.knowledge[key]);
			}
			if (!items) {
				items = new OrderedArray(keyToSlice(key).order, []);
			} else if (!(items instanceof OrderedArray)) {
				changes.indexes[key] = items =
					new OrderedArray(keyToSlice(key).order, changes.indexes[key]);
			}

			this.putIndex(key, changes.knowledge[key], items);
		}}

		/* handle the addition of individual entities */
		if (changes.entities) { for (let id in changes.entities) {
			if (changes.entities[id] === null) this.deleteEntity(id);
			else this.putEntity(changes.entities[id]);
		}}

		if (changes.app) { this.app = jsonop(this.app, changes.app); }

		/* handle the addition of a query */
		if (changes.queries) { for (let key in changes.queries) {
			if (!this.queries[key]) {
				this.queries[key] = changes.queries[key];
			} else {
				for (let range in changes.queries[key]) {
					this.queries[key].add(range);
				}
			}
		}}

		/* if there are too many entities, clean up */
		if (Object.keys(this.entities).length > this._options.maxEntities) {
			requestIdleCallback(this.pruneEntities.bind(this));
		}
		this._changeListeners.forEach(fn => fn(changes));
	}

	query(key, range, callback) {
		let items, gaps, ranges = new RangeArray([ range ]);
		range.seqNum = this._querySeqNum++;

		/* Extract items and calculate gaps in knowledge */
		if (!this.knowledge[key]) {
			let { order } = keyToSlice(key);
			items = new OrderedArray(order, []);
			gaps = ranges;
		} else {
			items = this.indexes[key].slice(...range);
			gaps = (range.length === 3 ? items.getRange() : ranges)
				.difference(this.knowledge[key]);

			// If it is a before/after range, gaps will not show missing data at
			// start and end; we need to detect and correct this.

			if (range.length === 3 && items.length < range[1] + range[2]) {
				let pos = items.indexOf(range[0]);
				if (
					pos < range[1] &&
					!this.knowledge[key].hasStart()
				) { gaps.add([
					items.get(0)[items.order], range[1] - pos, 0
				]); }
				if (
					items.length - pos < range[2] &&
					!this.knowledge[key].hasEnd()
				) { gaps.add([
					items.get(items.length - 1)[items.order], 0,
					range[2] + pos - items.length
				]); }
			}
		}

		/* Insert “loading” placeholders corresponding to the gaps. */
		for (let gap of gaps) {
			if (gap.length === 2) {
				items.put({
					type: "loading", start: gap[0], end: gap[1],
					[items.order]: gap[1] === Infinity ? gap[1] : gap[0]
				});
			} else {
				items.put({
					type: "loading", start: gap[0], before: gap[1], after: gap[2],
					[items.order]: gap[0]
				}, !!items.after);
			}
		}

		/* Make queries corresponding to the gaps. */
		if (gaps.length) {
			this.put({ queries: { [key]: gaps }});
			if (callback) {
				this._queryCallbacks[key] = this._queryCallbacks[key] || [];
				this._queryCallbacks[key].push({ ranges, callback });
			}
		} else {
			if (callback) {
				setImmediate(() => callback(null, items));
			}
		}

		/* Update the most recently accessed map */
		if (!this._recentQueries[key]) {
			this._recentQueries[key] = items.getRange();
		} else {
			this._recentQueries[key].put(items.getRange());
		}

		return items;
	}

	onChange(fn) {
		this._changeListeners.push(fn);
	}

	get() {
		let args = Array.prototype.slice.call(arguments),
			pointer = this; // eslint-disable-line consistent-this
		console.log("args: ",args);
		while (typeof pointer === "object" && pointer !== null && args.length) {
			pointer = pointer[args.shift()];
		}

		return pointer;
	}

	getEntity(id) {
		this._recentQueries.entities[id] = this._querySeqNum++;
		return this.get(...([ "entities" ].concat([id])));
	}

	with(changes) {
		var cache = new Cache();
		cache.put({ app: jsonop(this.app, changes.app) });
		return cache;
	}
};
<commit_msg>Adding callback to getEntity.<commit_after>"use strict";

require("setimmediate"); // polyfill for env != IE10+

/* global requestIdleCallback */
if (global.window) { // eslint-disable-line no-undef
	require("requestidlecallback"); // polyfill for env != Chrome46+
} else {
	global.requestIdleCallback = fn => {
		return setTimeout(() => {
			let deadline = Date.now() + 50;
			fn({
				timeRemaining: () => Math.max(0, deadline - Date.now()),
				didTimeout: false
			});
		}, 0);
	};
	global.cancelIdleCallback = handle => clearTimeout(handle);
}

let jsonop = require("jsonop"),
	OrderedArray = require("./OrderedArray"),
	RangeArray = require("./RangeArray"),
	keySlice  = require("./keyslice"),
	keyToSlice = keySlice.keyToSlice,
	sliceToKey = keySlice.sliceToKey;

module.exports = class Cache {
	constructor(options) {
		options = jsonop({
			id: (entity) => { return entity.id; },
			is: (entity, type) => { return entity.type === type; }
		}, options || {});

		this.entities = {};
		this.indexes = {};
		this.queries = {};
		this.knowledge = {};
		this.app = {};
		this.keyToSlice = keyToSlice;
		this.sliceToKey = sliceToKey;

		/*
			map of types to index keys to index slices for fast lookup
			{
				items: {
					"items:createTime(tag:hidden)": { type: items, order: createTime, filters: { tag: hidden } }
				}
			}
		*/
		this._types = {};
		this._changeListeners = [];
		this._queryCallbacks = {};
		this._recentQueries = { entities: {}};
		this._querySeqNum = 0;
		this._id = options.id;
		this._is = options.is;
		this._options = options;
	}

	/*
		Get index keys and corresponding values that must include this entity,
		taking into account knowledge for the same key.
		@param entity
		@returns { key: value }
	*/
	getKeyValues(entity) {
		let keyValues = {};

		for (let type in this._types) {
			if (!this._is(entity, type)) { continue; }

			keyloop:
			for (let key in this._types[type].base) {
				let slice = this._types[type].base[key],
					value = entity[slice.order];

				if (typeof value === "undefined") { continue; }

				for (let prop in slice.filters) {
					if (entity[prop] !== slice.filters[prop]) {
						continue keyloop;
					}
				}
				if (this.knowledge[key].contains(value)) {
					keyValues[key] = { value, item: (slice.link || slice.join) ?
						{ [type]: entity } : entity };
				}
			}

			keyloop:
			for (let key in this._types[type].join) {
				let slice = this._types[type].join[key],
					base = this.entities[entity[slice.join[type]]],
					value = base[slice.order];

				if (typeof value === "undefined") { continue; }

				for (let prop in slice.filters) {
					if (entity[prop] !== slice.filters[prop]) {
						continue keyloop;
					}
				}
				if (this.knowledge[key].contains(value)) {
					keyValues[key] = { value, item: { [type]: entity } };
				}
			}

			// TODO: Implement link types. This is not currently
			// required in HeyNeighbor, so not targeted for first
			// release.
		}

		return keyValues;
	}

	/*
		Adds or updates an entity and updates indexes if necessary.
	*/
	putEntity(entity, excludeKeys) {
		let id = this._id(entity),
			oldKeyValues,
			newKeyValues;

		if (this.entities[id]) {
			oldKeyValues = this.getKeyValues(this.entities[id]);
			entity = jsonop(this.entities[id], entity);
		}
		this.entities[id] = entity;
		newKeyValues = this.getKeyValues(entity);

		if (oldKeyValues) {
			for (let key in oldKeyValues) {
				if (oldKeyValues[key].value !== newKeyValues[key].value) {
					this.indexes[key].delete(oldKeyValues[key].value);
				} else {
					delete newKeyValues[key];
				}
			}
		}

		if (excludeKeys) { for (let key of excludeKeys) {
			delete newKeyValues[key];
		}}

		for (let key in newKeyValues) {
			this.indexes[key].add(newKeyValues[key].item);
		}

		return entity;
	}

	deleteEntity(id) {
		let keyValues = this.getKeyValues(this.entities[id]);
		for (let key in keyValues) {
			if (
				keyValues[key].item === this.entities[id] ||
				keyValues[key].item[keyToSlice(key).type] === this.entities[id]
			) {
				this.indexes[key].delete(keyValues[key].value);
			} else {
				for (let type in keyValues[key].item) {
					if (keyValues[key].item[type] === this.entities[id]) {
						this.indexes[key].put({ [type]: null });
					}
				}
			}
		}
		delete this.entities[id];
	}

	putIndex(key, knowledge, items) {
		let slice = keyToSlice(key),
			addType = (comp, type) => {
				this._types[type] = this._types[type] || {
					base: {}, link: {}, join: {}
				};
				this._types[type][comp][key] = slice;
			};
		if (!this.knowledge[key]) {
			addType("base", slice.type);
			if (slice.link) { for (let type in slice.link) {
				addType("link", type);
			}}
			if (slice.join) { for (let type in slice.join) {
				addType("join", type);
			}}

			this.knowledge[key] = knowledge;
			this.indexes[key] = items;
			this.indexEntities(key);
		} else {
			for (let range of knowledge) {
				let rangeItems = items.slice(...range);
				this.indexes[key].splice(...range, rangeItems);
				this.knowledge[key].add(range);
			}
		}
		// insert all the items into entities, updating all indexes
		// except this one.
		if (slice.join || slice.link) {
			for (let item of items) {
				for (let name in item) {
					this.putEntity(item[name], [ key ]);
				}
			}
		} else {
			for (let item of items) {
				this.putEntity(item, [ key ]);
			}
		}

		if (this._queryCallbacks[key]) {
			for (let i in this._queryCallbacks[key]) {
				let { ranges, callback } = this._queryCallbacks[key][i];
				if (ranges.subtract(this.knowledge[key]).length === 0) {
					// No gaps in knowledge; query is satisfied.
					this.query(key, ranges[0], callback);
				}
			}
		}
	}

	/*
		Checks every entity for inclusion in a particular index. Called when a
		new index is created.
	*/
	indexEntities(key) {
		let slice = keyToSlice(key);
		for (let id in this.entities) {
			let entity = this.entities[id],
				value = entity[slice.order];
			if (typeof value !== "undefined") {
				this.indexes[key].add(entity);
			}
		}
		/* TODO: Rewrite for perf: use push() then sort() */
	}

	pruneEntities(/* deadline */) {
		/* TODO: Implement in a nonblocking fashion */
	}

	/*
		Make changes to this cache (setState).
	*/
	put(changes) {
		/* handle the addition of ranges of results */
		if (changes.knowledge) { for (let key in changes.knowledge) {
			let items = changes.indexes && changes.indexes[key] || [];

			if (!(changes.knowledge[key] instanceof RangeArray)) {
				changes.knowledge[key] =
					new RangeArray(changes.knowledge[key]);
			}
			if (!items) {
				items = new OrderedArray(keyToSlice(key).order, []);
			} else if (!(items instanceof OrderedArray)) {
				changes.indexes[key] = items =
					new OrderedArray(keyToSlice(key).order, changes.indexes[key]);
			}

			this.putIndex(key, changes.knowledge[key], items);
		}}

		/* handle the addition of individual entities */
		if (changes.entities) { for (let id in changes.entities) {
			if (changes.entities[id] === null) this.deleteEntity(id);
			else this.putEntity(changes.entities[id]);
		}}

		if (changes.app) { this.app = jsonop(this.app, changes.app); }

		/* handle the addition of a query */
		if (changes.queries) { for (let key in changes.queries) {
			if (!this.queries[key]) {
				this.queries[key] = changes.queries[key];
			} else {
				for (let range in changes.queries[key]) {
					this.queries[key].add(range);
				}
			}
		}}

		/* if there are too many entities, clean up */
		if (Object.keys(this.entities).length > this._options.maxEntities) {
			requestIdleCallback(this.pruneEntities.bind(this));
		}
		this._changeListeners.forEach(fn => fn(changes));
	}

	query(key, range, callback) {
		let items, gaps, ranges = new RangeArray([ range ]);
		range.seqNum = this._querySeqNum++;

		/* Extract items and calculate gaps in knowledge */
		if (!this.knowledge[key]) {
			let { order } = keyToSlice(key);
			items = new OrderedArray(order, []);
			gaps = ranges;
		} else {
			items = this.indexes[key].slice(...range);
			gaps = (range.length === 3 ? items.getRange() : ranges)
				.difference(this.knowledge[key]);

			// If it is a before/after range, gaps will not show missing data at
			// start and end; we need to detect and correct this.

			if (range.length === 3 && items.length < range[1] + range[2]) {
				let pos = items.indexOf(range[0]);
				if (
					pos < range[1] &&
					!this.knowledge[key].hasStart()
				) { gaps.add([
					items.get(0)[items.order], range[1] - pos, 0
				]); }
				if (
					items.length - pos < range[2] &&
					!this.knowledge[key].hasEnd()
				) { gaps.add([
					items.get(items.length - 1)[items.order], 0,
					range[2] + pos - items.length
				]); }
			}
		}

		/* Insert “loading” placeholders corresponding to the gaps. */
		for (let gap of gaps) {
			if (gap.length === 2) {
				items.put({
					type: "loading", start: gap[0], end: gap[1],
					[items.order]: gap[1] === Infinity ? gap[1] : gap[0]
				});
			} else {
				items.put({
					type: "loading", start: gap[0], before: gap[1], after: gap[2],
					[items.order]: gap[0]
				}, !!items.after);
			}
		}

		/* Make queries corresponding to the gaps. */
		if (gaps.length) {
			this.put({ queries: { [key]: gaps }});
			if (callback) {
				this._queryCallbacks[key] = this._queryCallbacks[key] || [];
				this._queryCallbacks[key].push({ ranges, callback });
			}
		} else {
			if (callback) {
				setImmediate(() => callback(null, items));
			}
		}

		/* Update the most recently accessed map */
		if (!this._recentQueries[key]) {
			this._recentQueries[key] = items.getRange();
		} else {
			this._recentQueries[key].put(items.getRange());
		}

		return items;
	}

	onChange(fn) {
		this._changeListeners.push(fn);
	}

	get() {
		let args = Array.prototype.slice.call(arguments),
			pointer = this; // eslint-disable-line consistent-this
		while (typeof pointer === "object" && pointer !== null && args.length) {
			pointer = pointer[args.shift()];
		}

		return pointer;
	}

	getEntity(id, callback) {
		var result;
		this._recentQueries.entities[id] = this._querySeqNum++;
		if (this.entities && this.entities[id]) result = this.entities[id];

		if (result) {
			if (callback) callback(null, result);
			return result;
		} else {
			this.put({
				queries: {
					entities: {
						id: true
					}
				}
			});

			if (callback) {
				this._queryCallback.entities = this._queryCallback.entities || {};
				(this._queryCallback.entities = this._queryCallback.entities || []).push(callback);
			}

			return {type: "loading"};
		}
	}

	with(changes) {
		var cache = new Cache();
		cache.put({ app: jsonop(this.app, changes.app) });
		return cache;
	}
};
<|endoftext|>


<commit_before>class Clan {
    removePlayer(player) {
        for (var i = 0; i < this.members.length; ++i) {
            if (this.members[i].player.sid === player.player.sid) {
                this.members[i].player.team = null;
                this.members.splice(i, 1);
                return true;
            }
        }
        return false;
    }
    addPlayer(player) {
        player.player.team = this.name;
        this.members.push(player);
    }
    constructor(name) {
        if (name) {
            this.name = name;
        } else {
            this.name = null;
        }
        this.members = [];
    }
}
module.exports = Clan;<commit_msg>Add clan serialization<commit_after>class Clan {
    removePlayer(player) {
        for (var i = 0; i < this.members.length; ++i) {
            if (this.members[i].player.sid === player.player.sid) {
                this.members[i].player.team = null;
                this.members.splice(i, 1);
                return true;
            }
        }
        return false;
    }
    addPlayer(player) {
        player.player.team = this.name;
        this.members.push(player);
    }
    serialize() {
        var me = this;
        // Turn the Clan object into a structure the client can use
        return {
            sid: me.name
        }
    }
    constructor(name) {
        if (name) {
            this.name = name;
        } else {
            this.name = null;
        }
        this.members = [];
    }
}
module.exports = Clan;<|endoftext|>


<commit_before>'use babel';

import { join } from 'path';
// eslint-disable-next-line no-unused-vars
import { it, fit, wait, beforeEach, afterEach } from 'jasmine-fix';

const { lint } = require('../lib/main.js').provideLinter();

const fixturePath = join(__dirname, 'fixtures');
const fixtureWithConfigPath = join(__dirname, 'fixtures', 'with-config-file');
const goodPath = join(fixturePath, 'good.py');
const badPath = join(fixturePath, 'bad.py');
const badIgnoredPath = join(fixtureWithConfigPath, 'bad-ignored.py');
const badSubdirIgnoredPath = join(fixtureWithConfigPath, 'subdir', 'bad-ignored.py');
const errwarnPath = join(fixturePath, 'errwarn.py');
const builtinsPath = join(fixturePath, 'builtins.py');

describe('The flake8 provider for Linter', () => {
  beforeEach(async () => {
    // Info about this beforeEach() implementation:
    // https://github.com/AtomLinter/Meta/issues/15
    const activationPromise = atom.packages.activatePackage('linter-flake8');

    await atom.packages.activatePackage('language-python');
    await atom.workspace.open(goodPath);

    atom.packages.triggerDeferredActivationHooks();
    await activationPromise;
  });

  it('should be in the packages list', () =>
    expect(atom.packages.isPackageLoaded('linter-flake8')).toBe(true));

  it('should be an active package', () =>
    expect(atom.packages.isPackageActive('linter-flake8')).toBe(true));

  describe('checks bad.py and', () => {
    let editor = null;
    beforeEach(async () => {
      editor = await atom.workspace.open(badPath);
    });

    it('finds at least one message', async () => {
      const messages = await lint(editor);
      expect(messages.length).toBeGreaterThan(0);
    });

    it('verifies that message', async () => {
      const messages = await lint(editor);
      expect(messages[0].type).toBe('Warning');
      expect(messages[0].html).not.toBeDefined();
      expect(messages[0].text).toBe('F821 — undefined name \'asfd\'');
      expect(messages[0].filePath).toBe(badPath);
      expect(messages[0].range).toEqual([[0, 0], [0, 4]]);
    });

    it('checks that the message is an error if flakeErrors is set', async () => {
      atom.config.set('linter-flake8.flakeErrors', true);
      const messages = await lint(editor);
      expect(messages[0].type).toBe('Error');
    });
  });

  describe('checks errwarn.py and', () => {
    let editor = null;

    beforeEach(async () => {
      editor = await atom.workspace.open(errwarnPath);
    });

    it('finds at least one message', async () => {
      const messages = await lint(editor);
      expect(messages.length).toBeGreaterThan(0);
    });

    it('finds the message is a warning if pycodestyleErrorsToWarnings is set', async () => {
      atom.config.set('linter-flake8.pycodestyleErrorsToWarnings', true);
      const messages = await lint(editor);
      expect(messages[0].type).toBe('Warning');
    });

    it("finds the message is an error if pycodestyleErrorsToWarnings isn't set", async () => {
      atom.config.set('linter-flake8.pycodestyleErrorsToWarnings', false);
      const messages = await lint(editor);
      expect(messages[0].type).toBe('Error');
    });
  });

  describe('use configuration file and', () => {
    let editor = null;

    beforeEach(async () => {
      atom.project.addPath(fixtureWithConfigPath);
      editor = await atom.workspace.open(badIgnoredPath);
    });

    it('ignores file excluded in configuration file', async () => {
      const messages = await lint(editor);
      expect(messages.length).toBe(0);
    });

    it('ignores file excluded in configuration file using relative path', async () => {
      editor = await atom.workspace.open(badSubdirIgnoredPath);
      const messages = await lint(editor);
      expect(messages.length).toBe(0);
    });
  });

  it('finds nothing wrong with a valid file', async () => {
    const editor = await atom.workspace.open(goodPath);
    const messages = await lint(editor);
    expect(messages.length).toBe(0);
  });

  describe('executable path', () => {
    const helpers = require('atom-linter');

    let editor = null;
    const realExec = helpers.exec;
    const execParams = [];
    function fakeExec(...parameters) {
      execParams.push(parameters);
      return Promise.resolve('');
    }

    beforeEach(async () => {
      atom.project.addPath(fixturePath);

      Object.defineProperty(helpers, 'exec', {
        enumerable: true,
        value: fakeExec,
      });

      editor = await atom.workspace.open(badPath);
    });

    afterEach(() => {
      Object.defineProperty(helpers, 'exec', {
        enumerable: true,
        value: realExec,
      });
    });

    it('finds executable relative to project', async () => {
      atom.config.set('linter-flake8.executablePath', join('$PROJECT', 'flake8'));
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join(fixturePath, 'flake8'));
    });

    it('finds executable relative to projects', async () => {
      const paths = [
        join('$project', 'null'),
        join('$pRoJeCt', 'flake1'),
        join('$PrOjEcT', 'flake2'),
        join('$PROJECT', 'flake8'),
      ].join(';');
      atom.config.set('linter-flake8.executablePath', paths);
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join(fixturePath, 'flake8'));
    });

    it('finds executable using project name', async () => {
      atom.config.set('linter-flake8.executablePath', join('$PROJECT_NAME', 'flake8'));
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join('fixtures', 'flake8'));
    });

    it('finds executable using project names', async () => {
      const paths = [
        join('$project_name', 'null'),
        join('$pRoJeCt_NaMe', 'flake1'),
        join('$PrOjEcT_nAmE', 'flake2'),
        join('$PROJECT_NAME', 'flake8'),
      ].join(';');
      const correct = [
        join('fixtures', 'null'),
        join('fixtures', 'flake1'),
        join('fixtures', 'flake2'),
        join('fixtures', 'flake8'),
      ].join(';');
      atom.config.set('linter-flake8.executablePath', paths);
      await lint(editor);
      expect(execParams.pop()[0]).toBe(correct);
    });

    it('normalizes executable path', async () => {
      atom.config.set(
        'linter-flake8.executablePath',
        join(fixturePath, '..', 'fixtures', 'flake8'),
      );
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join(fixturePath, 'flake8'));
    });

    it('finds backup executable', async () => {
      const flakeNotFound = join('$PROJECT', 'flake8_notfound');
      const flakeBackup = join(fixturePath, 'flake8_backup');
      atom.config.set(
        'linter-flake8.executablePath',
        `${flakeNotFound};${flakeBackup}`,
      );
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join(fixturePath, 'flake8_backup'));
    });
  });

  describe('works with defining builtins', () => {
    let editor;

    beforeEach(async () => {
      editor = await atom.workspace.open(builtinsPath);
    });

    it('shows all warnings when the setting is blank', async () => {
      const messages = await lint(editor);
      expect(messages.length).toBe(2);

      expect(messages[0].type).toBe('Warning');
      expect(messages[0].html).not.toBeDefined();
      expect(messages[0].text).toBe('F821 — undefined name \'bar\'');
      expect(messages[0].filePath).toBe(builtinsPath);
      expect(messages[0].range).toEqual([[0, 6], [0, 9]]);

      expect(messages[1].type).toBe('Warning');
      expect(messages[1].html).not.toBeDefined();
      expect(messages[1].text).toBe('F821 — undefined name \'foo_bar\'');
      expect(messages[1].filePath).toBe(builtinsPath);
      expect(messages[1].range).toEqual([[1, 9], [1, 16]]);
    });

    it('works with a single builtin', async () => {
      atom.config.set('linter-flake8.builtins', ['bar']);
      const messages = await lint(editor);
      expect(messages.length).toBe(1);

      expect(messages[0].type).toBe('Warning');
      expect(messages[0].html).not.toBeDefined();
      expect(messages[0].text).toBe('F821 — undefined name \'foo_bar\'');
      expect(messages[0].filePath).toBe(builtinsPath);
      expect(messages[0].range).toEqual([[1, 9], [1, 16]]);
    });

    it('works with multiple builtins', async () => {
      atom.config.set('linter-flake8.builtins', ['bar', 'foo_bar']);
      const messages = await lint(editor);
      expect(messages.length).toBe(0);
    });
  });
});
<commit_msg>linter v2: fix spec<commit_after>'use babel';

import { join } from 'path';
// eslint-disable-next-line no-unused-vars
import { it, fit, wait, beforeEach, afterEach } from 'jasmine-fix';

const { lint } = require('../lib/main.js').provideLinter();

const fixturePath = join(__dirname, 'fixtures');
const fixtureWithConfigPath = join(__dirname, 'fixtures', 'with-config-file');
const goodPath = join(fixturePath, 'good.py');
const badPath = join(fixturePath, 'bad.py');
const badIgnoredPath = join(fixtureWithConfigPath, 'bad-ignored.py');
const badSubdirIgnoredPath = join(fixtureWithConfigPath, 'subdir', 'bad-ignored.py');
const errwarnPath = join(fixturePath, 'errwarn.py');
const builtinsPath = join(fixturePath, 'builtins.py');

describe('The flake8 provider for Linter', () => {
  beforeEach(async () => {
    // Info about this beforeEach() implementation:
    // https://github.com/AtomLinter/Meta/issues/15
    const activationPromise = atom.packages.activatePackage('linter-flake8');

    await atom.packages.activatePackage('language-python');
    await atom.workspace.open(goodPath);

    atom.packages.triggerDeferredActivationHooks();
    await activationPromise;
  });

  it('should be in the packages list', () =>
    expect(atom.packages.isPackageLoaded('linter-flake8')).toBe(true));

  it('should be an active package', () =>
    expect(atom.packages.isPackageActive('linter-flake8')).toBe(true));

  describe('checks bad.py and', () => {
    let editor = null;
    beforeEach(async () => {
      editor = await atom.workspace.open(badPath);
    });

    it('finds at least one message', async () => {
      const messages = await lint(editor);
      expect(messages.length).toBeGreaterThan(0);
    });

    it('verifies that message', async () => {
      const messages = await lint(editor);
      expect(messages[0].severity).toBe('warning');
      expect(messages[0].description).not.toBeDefined();
      expect(messages[0].excerpt).toBe('F821 — undefined name \'asfd\'');
      expect(messages[0].location.file).toBe(badPath);
      expect(messages[0].location.position).toEqual([[0, 0], [0, 4]]);
    });

    it('checks that the message is an error if flakeErrors is set', async () => {
      atom.config.set('linter-flake8.flakeErrors', true);
      const messages = await lint(editor);
      expect(messages[0].severity).toBe('error');
    });
  });

  describe('checks errwarn.py and', () => {
    let editor = null;

    beforeEach(async () => {
      editor = await atom.workspace.open(errwarnPath);
    });

    it('finds at least one message', async () => {
      const messages = await lint(editor);
      expect(messages.length).toBeGreaterThan(0);
    });

    it('finds the message is a warning if pycodestyleErrorsToWarnings is set', async () => {
      atom.config.set('linter-flake8.pycodestyleErrorsToWarnings', true);
      const messages = await lint(editor);
      expect(messages[0].severity).toBe('warning');
    });

    it("finds the message is an error if pycodestyleErrorsToWarnings isn't set", async () => {
      atom.config.set('linter-flake8.pycodestyleErrorsToWarnings', false);
      const messages = await lint(editor);
      expect(messages[0].severity).toBe('error');
    });
  });

  describe('use configuration file and', () => {
    let editor = null;

    beforeEach(async () => {
      atom.project.addPath(fixtureWithConfigPath);
      editor = await atom.workspace.open(badIgnoredPath);
    });

    it('ignores file excluded in configuration file', async () => {
      const messages = await lint(editor);
      expect(messages.length).toBe(0);
    });

    it('ignores file excluded in configuration file using relative path', async () => {
      editor = await atom.workspace.open(badSubdirIgnoredPath);
      const messages = await lint(editor);
      expect(messages.length).toBe(0);
    });
  });

  it('finds nothing wrong with a valid file', async () => {
    const editor = await atom.workspace.open(goodPath);
    const messages = await lint(editor);
    expect(messages.length).toBe(0);
  });

  describe('executable path', () => {
    const helpers = require('atom-linter');

    let editor = null;
    const realExec = helpers.exec;
    const execParams = [];
    function fakeExec(...parameters) {
      execParams.push(parameters);
      return Promise.resolve('');
    }

    beforeEach(async () => {
      atom.project.addPath(fixturePath);

      Object.defineProperty(helpers, 'exec', {
        enumerable: true,
        value: fakeExec,
      });

      editor = await atom.workspace.open(badPath);
    });

    afterEach(() => {
      Object.defineProperty(helpers, 'exec', {
        enumerable: true,
        value: realExec,
      });
    });

    it('finds executable relative to project', async () => {
      atom.config.set('linter-flake8.executablePath', join('$PROJECT', 'flake8'));
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join(fixturePath, 'flake8'));
    });

    it('finds executable relative to projects', async () => {
      const paths = [
        join('$project', 'null'),
        join('$pRoJeCt', 'flake1'),
        join('$PrOjEcT', 'flake2'),
        join('$PROJECT', 'flake8'),
      ].join(';');
      atom.config.set('linter-flake8.executablePath', paths);
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join(fixturePath, 'flake8'));
    });

    it('finds executable using project name', async () => {
      atom.config.set('linter-flake8.executablePath', join('$PROJECT_NAME', 'flake8'));
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join('fixtures', 'flake8'));
    });

    it('finds executable using project names', async () => {
      const paths = [
        join('$project_name', 'null'),
        join('$pRoJeCt_NaMe', 'flake1'),
        join('$PrOjEcT_nAmE', 'flake2'),
        join('$PROJECT_NAME', 'flake8'),
      ].join(';');
      const correct = [
        join('fixtures', 'null'),
        join('fixtures', 'flake1'),
        join('fixtures', 'flake2'),
        join('fixtures', 'flake8'),
      ].join(';');
      atom.config.set('linter-flake8.executablePath', paths);
      await lint(editor);
      expect(execParams.pop()[0]).toBe(correct);
    });

    it('normalizes executable path', async () => {
      atom.config.set(
        'linter-flake8.executablePath',
        join(fixturePath, '..', 'fixtures', 'flake8'),
      );
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join(fixturePath, 'flake8'));
    });

    it('finds backup executable', async () => {
      const flakeNotFound = join('$PROJECT', 'flake8_notfound');
      const flakeBackup = join(fixturePath, 'flake8_backup');
      atom.config.set(
        'linter-flake8.executablePath',
        `${flakeNotFound};${flakeBackup}`,
      );
      await lint(editor);
      expect(execParams.pop()[0]).toBe(join(fixturePath, 'flake8_backup'));
    });
  });

  describe('works with defining builtins', () => {
    let editor;

    beforeEach(async () => {
      editor = await atom.workspace.open(builtinsPath);
    });

    it('shows all warnings when the setting is blank', async () => {
      const messages = await lint(editor);
      expect(messages.length).toBe(2);

      expect(messages[0].severity).toBe('warning');
      expect(messages[0].description).not.toBeDefined();
      expect(messages[0].excerpt).toBe('F821 — undefined name \'bar\'');
      expect(messages[0].location.file).toBe(builtinsPath);
      expect(messages[0].location.position).toEqual([[0, 6], [0, 9]]);

      expect(messages[1].severity).toBe('warning');
      expect(messages[1].description).not.toBeDefined();
      expect(messages[1].excerpt).toBe('F821 — undefined name \'foo_bar\'');
      expect(messages[1].location.file).toBe(builtinsPath);
      expect(messages[1].location.position).toEqual([[1, 9], [1, 16]]);
    });

    it('works with a single builtin', async () => {
      atom.config.set('linter-flake8.builtins', ['bar']);
      const messages = await lint(editor);
      expect(messages.length).toBe(1);

      expect(messages[0].severity).toBe('warning');
      expect(messages[0].description).not.toBeDefined();
      expect(messages[0].excerpt).toBe('F821 — undefined name \'foo_bar\'');
      expect(messages[0].location.file).toBe(builtinsPath);
      expect(messages[0].location.position).toEqual([[1, 9], [1, 16]]);
    });

    it('works with multiple builtins', async () => {
      atom.config.set('linter-flake8.builtins', ['bar', 'foo_bar']);
      const messages = await lint(editor);
      expect(messages.length).toBe(0);
    });
  });
});
<|endoftext|>