<commit_before>// Generated on 2014-01-03 using generator-webapp 0.4.6
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

    // Load grunt tasks automatically
    require('load-grunt-tasks')(grunt);

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    var modRewrite = require('connect-modrewrite');

    // Define the configuration for all the tasks
    grunt.initConfig({

        // Project settings
        yeoman: {
            // Configurable paths
            app: 'app',
            dist: 'dist'
        },

        // Watches files for changes and runs tasks based on the changed files
        watch: {
            jstest: {
                files: ['test/spec/{,*/}*.js'],
                tasks: ['test:watch']
            },
            gruntfile: {
                files: ['Gruntfile.js']
            },
            compass: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
                tasks: ['compass:server', 'autoprefixer']
            },
            styles: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
                tasks: ['newer:copy:styles', 'autoprefixer']
            },
            livereload: {
                options: {
                    livereload: '<%= connect.options.livereload %>'
                },
                files: [
                    '<%= yeoman.app %>/{,*/}*.html',
                    '.tmp/scripts/main.js',
                    '.tmp/styles/{,*/}*.css',
                    '<%= yeoman.app %>/images/{,*/}*.{gif,jpeg,jpg,png,svg,webp}'
                ]
            },
            packagejson: {
                files: ['package.json'],
                tasks: ['browserify']
            }
        },

        // The actual grunt server settings
        connect: {
            options: {
                port: 9000,
                livereload: 35729,
                // Change this to '0.0.0.0' to access the server from outside
                hostname: '0.0.0.0',
                middleware: function(connect, options, middlewares) {
                    // Rewrite everything that does not contain a '.' to
                    // support pushState
                    middlewares.unshift(modRewrite(['^[^\\.]*$ /index.html [L]']));
                    return middlewares;
                }
            },
            livereload: {
                options: {
                    open: true,
                    base: [
                        '.tmp',
                        '<%= yeoman.app %>',
                        '.',
                        'api/app'
                    ]
                }
            },
            test: {
                options: {
                    port: 9001,
                    base: [
                        '.tmp',
                        'test',
                        '<%= yeoman.app %>',
                        'api/app'
                    ]
                }
            },
            dist: {
                options: {
                    open: true,
                    base: [
                        '<%= yeoman.dist %>',
                        'api/app'
                    ],
                    livereload: false
                }
            }
        },

        // Empties folders to start fresh
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        '<%= yeoman.dist %>/*',
                        '!<%= yeoman.dist %>/.git*'
                    ]
                }]
            },
            server: '.tmp'
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish')
            },
            all: [
                'Gruntfile.js',
                '<%= yeoman.app %>/scripts/**/*.js',
                '!<%= yeoman.app %>/scripts/vendor/*',
                'test/spec/{,*/}*.js'
            ]
        },

        // Mocha testing framework configuration options
        mocha: {
            all: {
                options: {
                    run: true,
                    urls: ['http://<%= connect.test.options.hostname %>:<%= connect.test.options.port %>/index.html']
                }
            }
        },

        // Compiles Sass to CSS and generates necessary files if requested
        compass: {
            options: {
                sassDir: '<%= yeoman.app %>/styles',
                cssDir: '.tmp/styles',
                generatedImagesDir: '.tmp/images/generated',
                imagesDir: '<%= yeoman.app %>/images',
                javascriptsDir: '<%= yeoman.app %>/scripts',
                fontsDir: '<%= yeoman.app %>/styles/fonts',
                importPath: '<%= yeoman.app %>/bower_components',
                httpImagesPath: '/images',
                httpGeneratedImagesPath: '/images/generated',
                httpFontsPath: '/styles/fonts',
                sourcemap: true,
                bundleExec: true,
                relativeAssets: false,
                assetCacheBuster: false
            },
            dist: {
                options: {
                    generatedImagesDir: '<%= yeoman.dist %>/images/generated'
                }
            },
            server: {
                options: {
                    debugInfo: false
                }
            }
        },

        // Add vendor prefixed styles
        autoprefixer: {
            options: {
                // Commented out to use more extensive autoprefixer defaults
                // browsers: ['last 1 version']
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: '.tmp/styles/',
                    src: '{,*/}*.css',
                    dest: '.tmp/styles/'
                }]
            }
        },

        browserify: {
            all: {
                files: {
                    '.tmp/scripts/main.js': '<%= yeoman.app %>/scripts/main.js'
                },
                options: {
                    browserifyOptions: {
                        debug: true
                    },
                    watch: true
                }
            }
        },

        // Renames files for browser caching purposes
        rev: {
            dist: {
                files: {
                    src: [
                        '<%= yeoman.dist %>/scripts/{,*/}*.js',
                        '<%= yeoman.dist %>/styles/{,*/}*.css',
                        '!<%= yeoman.dist %>/styles/slate.min.css',
                        '<%= yeoman.dist %>/images/{,*/}*.{gif,jpeg,jpg,png,webp}',
//                        '<%= yeoman.dist %>/styles/fonts/{,*/}*.*'
                    ]
                }
            }
        },

        // Reads HTML for usemin blocks to enable smart builds that automatically
        // concat, minify and revision files. Creates configurations in memory so
        // additional tasks can operate on them
        useminPrepare: {
            options: {
                dest: '<%= yeoman.dist %>'
            },
            html: '.tmp/index.html'
        },

        // Performs rewrites based on rev and the useminPrepare configuration
        usemin: {
            options: {
                assetsDirs: ['<%= yeoman.dist %>']
            },
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
        },

        // The following *-min tasks produce minified files in the dist folder
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/images',
                    src: '{,*/}*.{gif,jpeg,jpg,png}',
                    dest: '<%= yeoman.dist %>/images'
                }, {
                  expand: true,
                  cwd: '<%= yeoman.app %>/bower_components/select2',
                  src: '*.{gif,png}',
                  dest: '<%= yeoman.dist %>/styles'
                }]
            }
        },
        svgmin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/images',
                    src: '{,*/}*.svg',
                    dest: '<%= yeoman.dist %>/images'
                }]
            }
        },
        htmlmin: {
            dist: {
                options: {
                    collapseBooleanAttributes: true,
                    collapseWhitespace: true,
                    removeAttributeQuotes: true,
                    removeCommentsFromCDATA: true,
                    removeEmptyAttributes: true,
                    removeOptionalTags: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.dist %>',
                    src: '{,*/}*.html',
                    dest: '<%= yeoman.dist %>'
                }]
            }
        },

        // By default, your `index.html`'s <!-- Usemin block --> will take care of
        // minification. These next options are pre-configured if you do not wish
        // to use the Usemin blocks.
        cssmin: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/styles/exports.css': [
                        '.tmp/styles/exports.css'
                    ]
                }
            }
        },
        // uglify: {
        //     dist: {
        //         files: {
        //             '<%= yeoman.dist %>/scripts/scripts.js': [
        //                 '<%= yeoman.dist %>/scripts/scripts.js'
        //             ]
        //         }
        //     }
        // },
        // concat: {
        //     dist: {}
        // },

        // Copies remaining files to places other tasks can use
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.app %>',
                    dest: '<%= yeoman.dist %>',
                    src: [
                        '*.{config,php}',
                        '*.{ico,png,txt}',
                        '.htaccess',
                        'bower_components/zeroclipboard/dist/ZeroClipboard.swf',
                        'images/{,*/}*.webp',
                        '{,*/}*.html',
                        'scripts/disqus-count.js',
                        'styles/slate.min.css',
                        'styles/*.{gif,png}',
                        'styles/fonts/{,*/}*.*',
                        'vendor/knplabs/knp-snappy/src/**/*.php',
                        'bower_components/font-awesome/fonts/*.*',
                        'bower_components/jquery/dist/jquery.min.*',
                        'bower_components/raven-js/dist/raven.min.*'
                    ]
                }, {
                    expand: true,
                    cwd: '.tmp',
                    dest: '<%= yeoman.dist %>',
                    src: 'index.html'
                }]
            },
            styles: {
                expand: true,
                dot: true,
                cwd: '<%= yeoman.app %>/styles',
                dest: '.tmp/styles/',
                src: '{,*/}*.css'
            },
            tmp: {
                expand: true,
                cwd: '<%= yeoman.app %>',
                dest: '.tmp',
                src: [
                    'bower_components/qtip2/jquery.qtip.css',
                    'bower_components/select2/select2.css',
                    'bower_components/animate.css/animate.min.css',
                    'index.html'
                ]
            }
        },

        // Run some tasks in parallel to speed up build process
        concurrent: {
            server: [
                'compass:server',
                'copy:styles'
            ],
            test: [
                'copy:styles'
            ],
            dist: [
                'compass',
                'copy:styles',
                'imagemin',
                'svgmin'
            ]
        },
        rsync: {
            options: {
                args: ['-cruv']
            },
            'nusmods.com': {
                options: {
                    src: '<%= yeoman.dist %>/*',
                    dest: '~/nusmods.com'
                }
            }
        }
    });

    grunt.registerTask('serve', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'concurrent:server',
            'autoprefixer',
            'browserify',
            'connect:livereload',
            'watch'
        ]);
    });

    grunt.registerTask('server', function () {
        grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
        grunt.task.run(['serve']);
    });

    grunt.registerTask('test', function(target) {
        if (target !== 'watch') {
            grunt.task.run([
                'clean:server',
                'concurrent:test',
                'autoprefixer'
            ]);
        }

        grunt.task.run([
            'connect:test',
            'mocha'
        ]);
    });

    grunt.registerTask('build', [
        'clean:dist',
        'copy:tmp',
        'useminPrepare',
        'concurrent:dist',
        'autoprefixer',
        'browserify',
        'concat',
        'cssmin',
        'uglify',
        'copy:dist',
        'rev',
        'usemin',
        'htmlmin'
    ]);

    grunt.registerTask('default', [
        'newer:jshint',
        // 'test',
        'build'
    ]);
};
<commit_msg>Do not copy fallback JS since not using CDN<commit_after>// Generated on 2014-01-03 using generator-webapp 0.4.6
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

    // Load grunt tasks automatically
    require('load-grunt-tasks')(grunt);

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    var modRewrite = require('connect-modrewrite');

    // Define the configuration for all the tasks
    grunt.initConfig({

        // Project settings
        yeoman: {
            // Configurable paths
            app: 'app',
            dist: 'dist'
        },

        // Watches files for changes and runs tasks based on the changed files
        watch: {
            jstest: {
                files: ['test/spec/{,*/}*.js'],
                tasks: ['test:watch']
            },
            gruntfile: {
                files: ['Gruntfile.js']
            },
            compass: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
                tasks: ['compass:server', 'autoprefixer']
            },
            styles: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
                tasks: ['newer:copy:styles', 'autoprefixer']
            },
            livereload: {
                options: {
                    livereload: '<%= connect.options.livereload %>'
                },
                files: [
                    '<%= yeoman.app %>/{,*/}*.html',
                    '.tmp/scripts/main.js',
                    '.tmp/styles/{,*/}*.css',
                    '<%= yeoman.app %>/images/{,*/}*.{gif,jpeg,jpg,png,svg,webp}'
                ]
            },
            packagejson: {
                files: ['package.json'],
                tasks: ['browserify']
            }
        },

        // The actual grunt server settings
        connect: {
            options: {
                port: 9000,
                livereload: 35729,
                // Change this to '0.0.0.0' to access the server from outside
                hostname: '0.0.0.0',
                middleware: function(connect, options, middlewares) {
                    // Rewrite everything that does not contain a '.' to
                    // support pushState
                    middlewares.unshift(modRewrite(['^[^\\.]*$ /index.html [L]']));
                    return middlewares;
                }
            },
            livereload: {
                options: {
                    open: true,
                    base: [
                        '.tmp',
                        '<%= yeoman.app %>',
                        '.',
                        'api/app'
                    ]
                }
            },
            test: {
                options: {
                    port: 9001,
                    base: [
                        '.tmp',
                        'test',
                        '<%= yeoman.app %>',
                        'api/app'
                    ]
                }
            },
            dist: {
                options: {
                    open: true,
                    base: [
                        '<%= yeoman.dist %>',
                        'api/app'
                    ],
                    livereload: false
                }
            }
        },

        // Empties folders to start fresh
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        '<%= yeoman.dist %>/*',
                        '!<%= yeoman.dist %>/.git*'
                    ]
                }]
            },
            server: '.tmp'
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish')
            },
            all: [
                'Gruntfile.js',
                '<%= yeoman.app %>/scripts/**/*.js',
                '!<%= yeoman.app %>/scripts/vendor/*',
                'test/spec/{,*/}*.js'
            ]
        },

        // Mocha testing framework configuration options
        mocha: {
            all: {
                options: {
                    run: true,
                    urls: ['http://<%= connect.test.options.hostname %>:<%= connect.test.options.port %>/index.html']
                }
            }
        },

        // Compiles Sass to CSS and generates necessary files if requested
        compass: {
            options: {
                sassDir: '<%= yeoman.app %>/styles',
                cssDir: '.tmp/styles',
                generatedImagesDir: '.tmp/images/generated',
                imagesDir: '<%= yeoman.app %>/images',
                javascriptsDir: '<%= yeoman.app %>/scripts',
                fontsDir: '<%= yeoman.app %>/styles/fonts',
                importPath: '<%= yeoman.app %>/bower_components',
                httpImagesPath: '/images',
                httpGeneratedImagesPath: '/images/generated',
                httpFontsPath: '/styles/fonts',
                sourcemap: true,
                bundleExec: true,
                relativeAssets: false,
                assetCacheBuster: false
            },
            dist: {
                options: {
                    generatedImagesDir: '<%= yeoman.dist %>/images/generated'
                }
            },
            server: {
                options: {
                    debugInfo: false
                }
            }
        },

        // Add vendor prefixed styles
        autoprefixer: {
            options: {
                // Commented out to use more extensive autoprefixer defaults
                // browsers: ['last 1 version']
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: '.tmp/styles/',
                    src: '{,*/}*.css',
                    dest: '.tmp/styles/'
                }]
            }
        },

        browserify: {
            all: {
                files: {
                    '.tmp/scripts/main.js': '<%= yeoman.app %>/scripts/main.js'
                },
                options: {
                    browserifyOptions: {
                        debug: true
                    },
                    watch: true
                }
            }
        },

        // Renames files for browser caching purposes
        rev: {
            dist: {
                files: {
                    src: [
                        '<%= yeoman.dist %>/scripts/{,*/}*.js',
                        '<%= yeoman.dist %>/styles/{,*/}*.css',
                        '!<%= yeoman.dist %>/styles/slate.min.css',
                        '<%= yeoman.dist %>/images/{,*/}*.{gif,jpeg,jpg,png,webp}',
//                        '<%= yeoman.dist %>/styles/fonts/{,*/}*.*'
                    ]
                }
            }
        },

        // Reads HTML for usemin blocks to enable smart builds that automatically
        // concat, minify and revision files. Creates configurations in memory so
        // additional tasks can operate on them
        useminPrepare: {
            options: {
                dest: '<%= yeoman.dist %>'
            },
            html: '.tmp/index.html'
        },

        // Performs rewrites based on rev and the useminPrepare configuration
        usemin: {
            options: {
                assetsDirs: ['<%= yeoman.dist %>']
            },
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
        },

        // The following *-min tasks produce minified files in the dist folder
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/images',
                    src: '{,*/}*.{gif,jpeg,jpg,png}',
                    dest: '<%= yeoman.dist %>/images'
                }, {
                  expand: true,
                  cwd: '<%= yeoman.app %>/bower_components/select2',
                  src: '*.{gif,png}',
                  dest: '<%= yeoman.dist %>/styles'
                }]
            }
        },
        svgmin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/images',
                    src: '{,*/}*.svg',
                    dest: '<%= yeoman.dist %>/images'
                }]
            }
        },
        htmlmin: {
            dist: {
                options: {
                    collapseBooleanAttributes: true,
                    collapseWhitespace: true,
                    removeAttributeQuotes: true,
                    removeCommentsFromCDATA: true,
                    removeEmptyAttributes: true,
                    removeOptionalTags: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.dist %>',
                    src: '{,*/}*.html',
                    dest: '<%= yeoman.dist %>'
                }]
            }
        },

        // By default, your `index.html`'s <!-- Usemin block --> will take care of
        // minification. These next options are pre-configured if you do not wish
        // to use the Usemin blocks.
        cssmin: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/styles/exports.css': [
                        '.tmp/styles/exports.css'
                    ]
                }
            }
        },
        // uglify: {
        //     dist: {
        //         files: {
        //             '<%= yeoman.dist %>/scripts/scripts.js': [
        //                 '<%= yeoman.dist %>/scripts/scripts.js'
        //             ]
        //         }
        //     }
        // },
        // concat: {
        //     dist: {}
        // },

        // Copies remaining files to places other tasks can use
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.app %>',
                    dest: '<%= yeoman.dist %>',
                    src: [
                        '*.{config,php}',
                        '*.{ico,png,txt}',
                        '.htaccess',
                        'bower_components/zeroclipboard/dist/ZeroClipboard.swf',
                        'images/{,*/}*.webp',
                        '{,*/}*.html',
                        'scripts/disqus-count.js',
                        'styles/slate.min.css',
                        'styles/*.{gif,png}',
                        'styles/fonts/{,*/}*.*',
                        'vendor/knplabs/knp-snappy/src/**/*.php',
                        'bower_components/font-awesome/fonts/*.*'
                    ]
                }, {
                    expand: true,
                    cwd: '.tmp',
                    dest: '<%= yeoman.dist %>',
                    src: 'index.html'
                }]
            },
            styles: {
                expand: true,
                dot: true,
                cwd: '<%= yeoman.app %>/styles',
                dest: '.tmp/styles/',
                src: '{,*/}*.css'
            },
            tmp: {
                expand: true,
                cwd: '<%= yeoman.app %>',
                dest: '.tmp',
                src: [
                    'bower_components/qtip2/jquery.qtip.css',
                    'bower_components/select2/select2.css',
                    'bower_components/animate.css/animate.min.css',
                    'index.html'
                ]
            }
        },

        // Run some tasks in parallel to speed up build process
        concurrent: {
            server: [
                'compass:server',
                'copy:styles'
            ],
            test: [
                'copy:styles'
            ],
            dist: [
                'compass',
                'copy:styles',
                'imagemin',
                'svgmin'
            ]
        },
        rsync: {
            options: {
                args: ['-cruv']
            },
            'nusmods.com': {
                options: {
                    src: '<%= yeoman.dist %>/*',
                    dest: '~/nusmods.com'
                }
            }
        }
    });

    grunt.registerTask('serve', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'concurrent:server',
            'autoprefixer',
            'browserify',
            'connect:livereload',
            'watch'
        ]);
    });

    grunt.registerTask('server', function () {
        grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
        grunt.task.run(['serve']);
    });

    grunt.registerTask('test', function(target) {
        if (target !== 'watch') {
            grunt.task.run([
                'clean:server',
                'concurrent:test',
                'autoprefixer'
            ]);
        }

        grunt.task.run([
            'connect:test',
            'mocha'
        ]);
    });

    grunt.registerTask('build', [
        'clean:dist',
        'copy:tmp',
        'useminPrepare',
        'concurrent:dist',
        'autoprefixer',
        'browserify',
        'concat',
        'cssmin',
        'uglify',
        'copy:dist',
        'rev',
        'usemin',
        'htmlmin'
    ]);

    grunt.registerTask('default', [
        'newer:jshint',
        // 'test',
        'build'
    ]);
};
<|endoftext|>


<commit_before>const nedb = require("nedb");

class nedbAdapter {
  constructor(options) {
    this._nedb = new nedb(
      Object.assign({
        filename: '.bundle-cache.json',
        autoload: true
      }, options)
    )
  }

  getItem(id) {
    return new Promise((resolve, reject) => this._nedb.findOne({ id }, { _id: 0 }, resultHandler(resolve, reject)))
      .then(([result]) => result);
  }

  setItem(id, data) {
    return new Promise((resolve, reject) => this._nedb.update({ id }, data, { upsert: true }, resultHandler(resolve, reject)))
      .then(() => this.getItem(id));
  }

  deleteItem(id) {
    return Promise.resolve(this._nedb.remove({ id }));
  }
}

function resultHandler(resolve, reject) {
  return function(err, ...args) {
    if (err) {
      reject(err);
    }
    else {
      resolve(args);
    }
  }
}

module.exports = nedbAdapter;
<commit_msg>renamed output cache file<commit_after>const nedb = require("nedb");

class nedbAdapter {
  constructor(options) {
    this._nedb = new nedb(
      Object.assign({
        filename: '.bundler-cache',
        autoload: true
      }, options)
    )
  }

  getItem(id) {
    return new Promise((resolve, reject) => this._nedb.findOne({ id }, { _id: 0 }, resultHandler(resolve, reject)))
      .then(([result]) => result);
  }

  setItem(id, data) {
    return new Promise((resolve, reject) => this._nedb.update({ id }, data, { upsert: true }, resultHandler(resolve, reject)))
      .then(() => this.getItem(id));
  }

  deleteItem(id) {
    return Promise.resolve(this._nedb.remove({ id }));
  }
}

function resultHandler(resolve, reject) {
  return function(err, ...args) {
    if (err) {
      reject(err);
    }
    else {
      resolve(args);
    }
  }
}

module.exports = nedbAdapter;
<|endoftext|>


<commit_before>define([
	"dojo/Evented",
	"dojo/on",
	"dojo/domReady",
	"dojo/sniff",	// has("ie"), has("ios")
	"dojo/window" // getBox()
], function(Evented, on, domReady, has, winUtils){

	// module:
	//		dijit/Viewport

	/*=====
	return {
		// summary:
		//		Utility singleton to watch for viewport resizes, avoiding duplicate notifications
		//		which can lead to infinite loops.
		// description:
		//		Usage: Viewport.on("resize", myCallback).
		//
		//		myCallback() is called without arguments in case it's _WidgetBase.resize(),
		//		which would interpret the argument as the size to make the widget.
	};
	=====*/

	var Viewport = new Evented();

	var focusedNode;

	domReady(function(){
		var oldBox = winUtils.getBox();
		Viewport._rlh = on(window, "resize", function(){
			var newBox = winUtils.getBox();
			if(oldBox.h == newBox.h && oldBox.w == newBox.w){ return; }
			oldBox = newBox;
			Viewport.emit("resize");
		});

		// Also catch zoom changes on IE8, since they don't naturally generate resize events
		if(has("ie") == 8){
			var deviceXDPI = screen.deviceXDPI;
			setInterval(function(){
				if(screen.deviceXDPI != deviceXDPI){
					deviceXDPI = screen.deviceXDPI;
					Viewport.emit("resize");
				}
			}, 500);
		}

		// On iOS, keep track of the focused node so we can guess when the keyboard is/isn't being displayed.
		if(true || has("ios")){
			on(document, "focusin", function(evt){
				focusedNode = evt.target;
			});
			on(document, "focusout", function(evt){
				focusedNode = null;
			});
		}
	});

	Viewport.getEffectiveBox = function(/*Document*/ doc){
		// summary:
		//		Get the size of the viewport, or on mobile devices, the part of the viewport not obscured by the
		//		virtual keyboard.

		var box = winUtils.getBox(doc);

		// Account for iOS virtual keyboard, if it's being shown.  Unfortunately no direct way to check or measure.
		var tag = focusedNode && focusedNode.tagName && focusedNode.tagName.toLowerCase();
		if(has("ios") && !focusedNode.readOnly && (tag == "textarea" || (tag == "input" &&
			/^(color|email|number|password|search|tel|text|url)$/.test(focusedNode.type)))){
			box.h *= (box.h > box.w ? 0.66 : 0.40);
		}

		return box;
	};

	return Viewport;
});
<commit_msg>Account for when viewport ends before the bottom of the screen, and thus keyboard is not obscuring as much of the viewport as we thought it was.   Fixes #16989, refs #16730 !strict.<commit_after>define([
	"dojo/Evented",
	"dojo/on",
	"dojo/domReady",
	"dojo/sniff",	// has("ie"), has("ios")
	"dojo/window" // getBox()
], function(Evented, on, domReady, has, winUtils){

	// module:
	//		dijit/Viewport

	/*=====
	return {
		// summary:
		//		Utility singleton to watch for viewport resizes, avoiding duplicate notifications
		//		which can lead to infinite loops.
		// description:
		//		Usage: Viewport.on("resize", myCallback).
		//
		//		myCallback() is called without arguments in case it's _WidgetBase.resize(),
		//		which would interpret the argument as the size to make the widget.
	};
	=====*/

	var Viewport = new Evented();

	var focusedNode;

	domReady(function(){
		var oldBox = winUtils.getBox();
		Viewport._rlh = on(window, "resize", function(){
			var newBox = winUtils.getBox();
			if(oldBox.h == newBox.h && oldBox.w == newBox.w){ return; }
			oldBox = newBox;
			Viewport.emit("resize");
		});

		// Also catch zoom changes on IE8, since they don't naturally generate resize events
		if(has("ie") == 8){
			var deviceXDPI = screen.deviceXDPI;
			setInterval(function(){
				if(screen.deviceXDPI != deviceXDPI){
					deviceXDPI = screen.deviceXDPI;
					Viewport.emit("resize");
				}
			}, 500);
		}

		// On iOS, keep track of the focused node so we can guess when the keyboard is/isn't being displayed.
		if(has("ios")){
			on(document, "focusin", function(evt){
				focusedNode = evt.target;
			});
			on(document, "focusout", function(evt){
				focusedNode = null;
			});
		}
	});

	Viewport.getEffectiveBox = function(/*Document*/ doc){
		// summary:
		//		Get the size of the viewport, or on mobile devices, the part of the viewport not obscured by the
		//		virtual keyboard.

		var box = winUtils.getBox(doc);

		// Account for iOS virtual keyboard, if it's being shown.  Unfortunately no direct way to check or measure.
		var tag = focusedNode && focusedNode.tagName && focusedNode.tagName.toLowerCase();
		if(has("ios") && !focusedNode.readOnly && (tag == "textarea" || (tag == "input" &&
			/^(color|email|number|password|search|tel|text|url)$/.test(focusedNode.type)))){

			// Box represents the size of the viewport.  Some of the viewport is likely covered by the keyboard.
			// Estimate height of visible viewport assuming viewport goes to bottom of screen, but is covered by keyboard.
			box.h *= (orientation == 0 || orientation == 180 ? 0.66 : 0.40);

			// Above measurement will be inaccurate if viewport was scrolled up so far that it ends before the bottom
			// of the screen.   In this case, keyboard isn't covering as much of the viewport as we thought.
			// We know the visible size is at least the distance from the top of the viewport to the focused node.
			var rect = focusedNode.getBoundingClientRect();
			box.h = Math.max(box.h, rect.top + rect.height);
		}

		return box;
	};

	return Viewport;
});
<|endoftext|>


<commit_before>// @flow
import React from 'react';

import ImageListManageItem from './ImageListManageItem';

import {
  generateImageList,
  SPECIFY_IMAGE_PROPERTY,
  SPECIFY_ACTIVE_IMAGE,
  ADD_NEW_IMAGE,
  DELETE_IMAGE,
  MOVE_UP_IMAGE_ORDER,
} from '../../state/generateImageList';

import type {Image} from '../../image';

export default function ImageListManage({
  imageList,
  updateImageList,
  display,
}: {
  imageList: Image[],
  updateImageList: (Image[]) => void,
  display: {width: number, height: number},
}) {
  return (

        <button
          className="add-new-image fa fa-plus"
          onClick={() => {
            updateImageList(
              generateImageList({
                type: ADD_NEW_IMAGE,
                currentState: imageList,
                data: display,
              })
            );
          }}
        />

      {imageList.map((image, index) => (
        <ImageListManageItem
          key={image.id}
          deleteImage={
            imageList.length === 1 ? null : (
              () => {
                updateImageList(
                  generateImageList({
                    type: DELETE_IMAGE,
                    currentState: imageList,
                    target: image.id,
                  })
                );
              }
            )
          }
          label={image.label}
          isActive={image.isActive}
          isShow={image.isShow}
          activate={() => {
            updateImageList(
              generateImageList({
                type: SPECIFY_ACTIVE_IMAGE,
                currentState: imageList,
                target: image.id,
              })
            );
          }}
          moveUpImageOrder={
            index === 0 ? null : (
              () => {
                updateImageList(
                  generateImageList({
                    type: MOVE_UP_IMAGE_ORDER,
                    currentState: imageList,
                    target: image.id,
                  })
                );
              }
            )
          }
          moveDownImageOrder={
            index === imageList.length - 1 ? null : (
              () => {
                updateImageList(
                  generateImageList({
                    type: MOVE_UP_IMAGE_ORDER,
                    currentState: imageList,
                    target: imageList[index + 1].id,
                  })
                );
              }
            )
          }
          toggleShowOrHide={() => {
            updateImageList(
              generateImageList({
                type: SPECIFY_IMAGE_PROPERTY,
                data: {isShow: !image.isShow},
                currentState: imageList,
                target: image.id,
              })
            );
          }}
        />
      ))}

  );
}
<commit_msg>fix Flow<commit_after>// @flow
import React from 'react';

import ImageListManageItem from './ImageListManageItem';

import {
  generateImageList,
  SPECIFY_IMAGE_PROPERTY,
  SPECIFY_ACTIVE_IMAGE,
  ADD_NEW_IMAGE,
  DELETE_IMAGE,
  MOVE_UP_IMAGE_ORDER,
} from '../../state/generateImageList';

import type {Image} from '../../image';

export default function ImageListManage({
  imageList,
  updateImageList,
  display,
}: {
  imageList: Image[],
  updateImageList: (Image[]) => void,
  display: {width: number, height: number},
}) {
  return (

        <button
          className="add-new-image fa fa-plus"
          onClick={() => {
            updateImageList(
              generateImageList({
                type: ADD_NEW_IMAGE,
                currentState: imageList,
                data: {width: display.width, height: display.height},
              })
            );
          }}
        />

      {imageList.map((image, index) => (
        <ImageListManageItem
          key={image.id}
          deleteImage={
            imageList.length === 1 ? null : (
              () => {
                updateImageList(
                  generateImageList({
                    type: DELETE_IMAGE,
                    currentState: imageList,
                    target: image.id,
                  })
                );
              }
            )
          }
          label={image.label}
          isActive={image.isActive}
          isShow={image.isShow}
          activate={() => {
            updateImageList(
              generateImageList({
                type: SPECIFY_ACTIVE_IMAGE,
                currentState: imageList,
                target: image.id,
              })
            );
          }}
          moveUpImageOrder={
            index === 0 ? null : (
              () => {
                updateImageList(
                  generateImageList({
                    type: MOVE_UP_IMAGE_ORDER,
                    currentState: imageList,
                    target: image.id,
                  })
                );
              }
            )
          }
          moveDownImageOrder={
            index === imageList.length - 1 ? null : (
              () => {
                updateImageList(
                  generateImageList({
                    type: MOVE_UP_IMAGE_ORDER,
                    currentState: imageList,
                    target: imageList[index + 1].id,
                  })
                );
              }
            )
          }
          toggleShowOrHide={() => {
            updateImageList(
              generateImageList({
                type: SPECIFY_IMAGE_PROPERTY,
                data: {isShow: !image.isShow},
                currentState: imageList,
                target: image.id,
              })
            );
          }}
        />
      ))}

  );
}
<|endoftext|>


<commit_before>'use strict'

require('es6-object-assign').polyfill()
import 'es6-promise/auto'
import Vue from 'vue'
import { app, router<%= (store ? ', store' : '') %> } from './index'
import { getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promisify, getLocation, compile } from './utils'
const noopData = () => { return {} }
const noopFetch = () => {}
let _lastPaths = []
let _lastComponentsFiles = []

function mapTransitions(Components, to, from) {
  return Components.map((Component) => {
    let transition = Component.options.transition
    if (typeof transition === 'function') {
      return transition(to, from)
    }
    return transition
  })
}

function loadAsyncComponents (to, ___, next) {
  const resolveComponents = flatMapComponents(to, (Component, _, match, key) => {
    if (typeof Component === 'function' && !Component.options) {
      return new Promise(function (resolve, reject) {
        const _resolve = (Component) => {
          if (!Component.options) {
            Component = Vue.extend(Component) // fix issue #6
            Component._Ctor = Component
          } else {
           Component._Ctor = Component
           Component.extendOptions = Component.options
          }
          match.components[key] = Component
          resolve(Component)
        }
        Component().then(_resolve).catch(reject)
      })
    }
    if (typeof Component === 'object' && !Component.options) {
      // Updated via vue-router resolveAsyncComponents()
      Component = Vue.extend(Component)
      Component._Ctor = Component
      match.components[key] = Component
    }
    return Component
  })
  <%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %>
  Promise.all(resolveComponents)
  .then(() => next())
  .catch((err) => {
    this.error({ statusCode: 500, message: err.message })
    next(false)
  })
}

function render (to, from, next) {
  let Components = getMatchedComponents(to)
  if (!Components.length) {
    // Default layout
    this.setLayout()
    .then(() => {
      this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
      return next()
    })
    return
  }
  // Update ._data and other properties if hot reloaded
  Components.forEach(function (Component) {
    if (!Component._data) {
      Component._data = Component.options.data || noopData
    }
    if (Component._Ctor && Component._Ctor.options) {
      Component.options.fetch = Component._Ctor.options.fetch
      if (Component._dataFn) {
        const originalDataFn = Component._data.toString().replace(/\s/g, '')
        const dataFn = Component._dataFn
        const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '')
        // If component data method changed
        if (newDataFn !== originalDataFn && newDataFn !== dataFn) {
          Component._data = Component._Ctor.options.data || noopData
        }
      }
    }
  })
  this.setTransitions(mapTransitions(Components, to, from))
  this.error()
  let nextCalled = false
  // Set layout
  this.setLayout(Components[0].options.layout)
  .then(() => {
    // Pass validation?
    let isValid = true
    Components.forEach((Component) => {
      if (!isValid) return
      if (typeof Component.options.validate !== 'function') return
      isValid = Component.options.validate({
        params: to.params || {},
        query: to.query || {}
      })
    })
    if (!isValid) {
      this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
      return next()
    }
    return Promise.all(Components.map((Component, i) => {
      // Check if only children route changed
      Component._path = compile(to.matched[i].path)(to.params)
      if (Component._path === _lastPaths[i] && (i + 1) !== Components.length) {
        return Promise.resolve()
      }
      let promises = []
      const _next = function (path) {
        <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
        nextCalled = true
        next(path)
      }
      const context = getContext({ to<%= (store ? ', store' : '') %>, isClient: true, next: _next.bind(this), error: this.error.bind(this) })
      // Validate method
      if (Component._data && typeof Component._data === 'function') {
        var promise = promisify(Component._data, context)
        promise.then((data) => {
          Component._cData = () => data || {}
          Component.options.data = Component._cData
          Component._dataFn = Component.options.data.toString().replace(/\s/g, '')
          if (Component._Ctor && Component._Ctor.options) {
            Component._Ctor.options.data = Component.options.data
          }
          <%= (loading ? 'this.$loading.increase && this.$loading.increase(30)' : '') %>
        })
        promises.push(promise)
      }
      if (Component.options.fetch) {
        var p = Component.options.fetch(context)
        if (!(p instanceof Promise)) { p = Promise.resolve(p) }
        <%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
        promises.push(p)
      }
      return Promise.all(promises)
    }))
  })
  .then(() => {
    _lastPaths = Components.map((Component, i) => compile(to.matched[i].path)(to.params))
    <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
    // If not redirected
    if (!nextCalled) {
      next()
    }
  })
  .catch((error) => {
    _lastPaths = []
    this.error(error)
    next(false)
  })
}

// When navigating on a different route but the same component is used, Vue.js
// will not update the instance data, so we have to update $data ourselves
function fixPrepatch (to, ___) {
  Vue.nextTick(() => {
    let instances = getMatchedComponentsInstances(to)
    _lastComponentsFiles = instances.map((instance, i) => {
      if (!instance) return '';
      if (_lastPaths[i] === instance.constructor._path && typeof instance.constructor.options.data === 'function') {
        let newData = instance.constructor.options.data()
        for (let key in newData) {
          Vue.set(instance.$data, key, newData[key])
        }
      }
      return instance.constructor.options.__file
    })
    hotReloadAPI(this)
  })
}

// Special hot reload with data(context)
function hotReloadAPI (_app) {
  if (!module.hot) return
  const $nuxt = _app.$nuxt
  var _forceUpdate = $nuxt.$forceUpdate.bind($nuxt)
  $nuxt.$forceUpdate = function () {
    let Component = getMatchedComponents(router.currentRoute)[0]
    if (!Component) return _forceUpdate()
    if (typeof Component === 'object' && !Component.options) {
      // Updated via vue-router resolveAsyncComponents()
      Component = Vue.extend(Component)
      Component._Ctor = Component
    }
    let promises = []
    // If layout changed
    if (_app.layoutName !== Component.options.layout) {
      let promise = _app.setLayout(Component.options.layout)
      promise.then(() => {
        hotReloadAPI(_app)
      })
      promises.push(promise)
    }
    const next = function (path) {
      <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
      router.push(path)
    }
    const context = getContext({ route: router.currentRoute<%= (store ? ', store' : '') %>, isClient: true, next: next.bind(this), error: _app.error })
    // Check if data has been updated
    const originalDataFn = (Component._data || noopData).toString().replace(/\s/g, '')
    const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '')
    if (originalDataFn !== newDataFn) {
      Component._data = Component._Ctor.options.data || noopData
      let p = promisify(Component._data, context)
      p.then((data) => {
        Component._cData = () => data || {}
        Component.options.data = Component._cData
        Component._dataFn = Component.options.data.toString().replace(/\s/g, '')
        Component._Ctor.options.data = Component.options.data
        <%= (loading ? 'this.$loading.increase && this.$loading.increase(30)' : '') %>
      })
      promises.push(p)
    } else if (Component._cData) {
      Component.options.data = Component._cData
      Component._Ctor.options.data = Component.options.data
    }
    // Check if fetch has been updated
    const originalFetchFn = (Component.options.fetch || noopFetch).toString().replace(/\s/g, '')
    const newFetchFn = (Component._Ctor.options.fetch || noopFetch).toString().replace(/\s/g, '')
    // Fetch has been updated, we call it to update the store
    if (originalFetchFn !== newFetchFn) {
      Component.options.fetch = Component._Ctor.options.fetch || noopFetch
      let p = Component.options.fetch(context)
      if (!(p instanceof Promise)) { p = Promise.resolve(p) }
      <%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
      promises.push(p)
    }
    if (!promises.length) return;
    <%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %>
    return Promise.all(promises).then(() => {
      <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
      _forceUpdate()
    })
  }
}

// Load vue app
const NUXT = window.__NUXT__ || {}
if (!NUXT) {
  throw new Error('[nuxt.js] cannot find the global variable __NUXT__, make sure the server is working.')
}
// Get matched components
const path = getLocation(router.options.base)
const resolveComponents = flatMapComponents(router.match(path), (Component, _, match, key, index) => {
  if (typeof Component === 'function' && !Component.options) {
    return new Promise(function (resolve, reject) {
      const _resolve = (Component) => {
        if (!Component.options) {
          Component = Vue.extend(Component) // fix issue #6
          Component._Ctor = Component
        } else {
          Component._Ctor = Component
          Component.extendOptions = Component.options
        }
        if (Component.options.data && typeof Component.options.data === 'function') {
          Component._data = Component.options.data
          if (NUXT.serverRendered) {
            Component._cData = () => NUXT.data[index] || {}
            Component.options.data = Component._cData
            Component._dataFn = Component.options.data.toString().replace(/\s/g, '')
          }
          if (Component._Ctor && Component._Ctor.options) {
            Component._Ctor.options.data = Component.options.data
          }
        }
        match.components[key] = Component
        resolve(Component)
      }
      Component().then(_resolve).catch(reject)
    })
  }
  return Component
})

function nuxtReady (app) {
  window._nuxtReadyCbs.forEach((cb) => {
    if (typeof cb === 'function') {
      cb(app)
    }
  })
  // Add router hooks
  router.afterEach(function (to, from) {
    app.$nuxt.$emit('routeChanged', to, from)
  })
}

Promise.all(resolveComponents)
.then((Components) => {
  const _app = new Vue(app)

  return _app.setLayout(Components.length ? Components[0].options.layout : '')
  .then(() => {
    return { _app, Components }
  })
})
.then(({ _app, Components }) => {
  const mountApp = () => {
    _app.$mount('#__nuxt')
    <% if (loading) { %>
    // Special loading bar
    _app.$loading = _app.$nuxt.$loading
    <% } %>
    // Hot reloading
    hotReloadAPI(_app)
    // Call window.onNuxtReady callbacks
    Vue.nextTick(() => nuxtReady(_app))
  }
  <% if (store) { %>
  // Replace store state
  if (NUXT.state) {
    store.replaceState(NUXT.state)
  }
  <% } %>
  _app.setTransitions = _app.$options._nuxt.setTransitions.bind(_app)
  if (Components.length) {
    _app.setTransitions(mapTransitions(Components, router.currentRoute))
    _lastPaths = router.currentRoute.matched.map((route) => compile(route.path)(router.currentRoute.params))
    _lastComponentsFiles = Components.map((Component) => Component.options.__file)
  }
  _app.error = _app.$options._nuxt.error.bind(_app)
  _app.$loading = {} // to avoid error while _app.$nuxt does not exist
  if (NUXT.error) _app.error(NUXT.error)
  // Add router hooks
  router.beforeEach(loadAsyncComponents.bind(_app))
  router.beforeEach(render.bind(_app))
  router.afterEach(fixPrepatch.bind(_app))
  if (NUXT.serverRendered) {
    mountApp()
    return
  }
  render.call(_app, router.currentRoute, router.currentRoute, function (path) {
    if (path) {
      let mounted = false
      router.afterEach(function () {
        if (mounted) return
        mounted = true
        mountApp()
      })
      router.push(path)
      return
    }
    mountApp()
  })
})
.catch((err) => {
  console.error('[nuxt.js] Cannot load components', err) // eslint-disable-line no-console
})
<commit_msg>Fix hot-reload on data<commit_after>'use strict'

require('es6-object-assign').polyfill()
import 'es6-promise/auto'
import Vue from 'vue'
import { app, router<%= (store ? ', store' : '') %> } from './index'
import { getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promisify, getLocation, compile } from './utils'
const noopData = () => { return {} }
const noopFetch = () => {}
let _lastPaths = []
let _lastComponentsFiles = []

function mapTransitions(Components, to, from) {
  return Components.map((Component) => {
    let transition = Component.options.transition
    if (typeof transition === 'function') {
      return transition(to, from)
    }
    return transition
  })
}

function loadAsyncComponents (to, ___, next) {
  const resolveComponents = flatMapComponents(to, (Component, _, match, key) => {
    if (typeof Component === 'function' && !Component.options) {
      return new Promise(function (resolve, reject) {
        const _resolve = (Component) => {
          if (!Component.options) {
            Component = Vue.extend(Component) // fix issue #6
            Component._Ctor = Component
          } else {
           Component._Ctor = Component
           Component.extendOptions = Component.options
          }
          match.components[key] = Component
          resolve(Component)
        }
        Component().then(_resolve).catch(reject)
      })
    }
    if (typeof Component === 'object' && !Component.options) {
      // Updated via vue-router resolveAsyncComponents()
      Component = Vue.extend(Component)
      Component._Ctor = Component
      match.components[key] = Component
    }
    return Component
  })
  <%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %>
  Promise.all(resolveComponents)
  .then(() => next())
  .catch((err) => {
    this.error({ statusCode: 500, message: err.message })
    next(false)
  })
}

function render (to, from, next) {
  let Components = getMatchedComponents(to)
  if (!Components.length) {
    // Default layout
    this.setLayout()
    .then(() => {
      this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
      return next()
    })
    return
  }
  // Update ._data and other properties if hot reloaded
  Components.forEach(function (Component) {
    if (!Component._data) {
      Component._data = Component.options.data || noopData
    }
    if (Component._Ctor && Component._Ctor.options) {
      Component.options.fetch = Component._Ctor.options.fetch
      if (Component._dataFn) {
        const originalDataFn = Component._data.toString().replace(/\s/g, '')
        const dataFn = Component._dataFn
        const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '')
        // If component data method changed
        if (newDataFn !== originalDataFn && newDataFn !== dataFn) {
          Component._data = Component._Ctor.options.data || noopData
        }
      }
    }
  })
  this.setTransitions(mapTransitions(Components, to, from))
  this.error()
  let nextCalled = false
  // Set layout
  this.setLayout(Components[0].options.layout)
  .then(() => {
    // Pass validation?
    let isValid = true
    Components.forEach((Component) => {
      if (!isValid) return
      if (typeof Component.options.validate !== 'function') return
      isValid = Component.options.validate({
        params: to.params || {},
        query: to.query || {}
      })
    })
    if (!isValid) {
      this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
      return next()
    }
    return Promise.all(Components.map((Component, i) => {
      // Check if only children route changed
      Component._path = compile(to.matched[i].path)(to.params)
      if (Component._path === _lastPaths[i] && (i + 1) !== Components.length) {
        return Promise.resolve()
      }
      let promises = []
      const _next = function (path) {
        <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
        nextCalled = true
        next(path)
      }
      const context = getContext({ to<%= (store ? ', store' : '') %>, isClient: true, next: _next.bind(this), error: this.error.bind(this) })
      // Validate method
      if (Component._data && typeof Component._data === 'function') {
        var promise = promisify(Component._data, context)
        promise.then((data) => {
          Component._cData = () => data || {}
          Component.options.data = Component._cData
          Component._dataFn = Component.options.data.toString().replace(/\s/g, '')
          if (Component._Ctor && Component._Ctor.options) {
            Component._Ctor.options.data = Component.options.data
          }
          <%= (loading ? 'this.$loading.increase && this.$loading.increase(30)' : '') %>
        })
        promises.push(promise)
      }
      if (Component.options.fetch) {
        var p = Component.options.fetch(context)
        if (!(p instanceof Promise)) { p = Promise.resolve(p) }
        <%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
        promises.push(p)
      }
      return Promise.all(promises)
    }))
  })
  .then(() => {
    _lastPaths = Components.map((Component, i) => compile(to.matched[i].path)(to.params))
    <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
    // If not redirected
    if (!nextCalled) {
      next()
    }
  })
  .catch((error) => {
    _lastPaths = []
    this.error(error)
    next(false)
  })
}

// When navigating on a different route but the same component is used, Vue.js
// will not update the instance data, so we have to update $data ourselves
function fixPrepatch (to, ___) {
  Vue.nextTick(() => {
    let instances = getMatchedComponentsInstances(to)
    _lastComponentsFiles = instances.map((instance, i) => {
      if (!instance) return '';
      if (_lastPaths[i] === instance.constructor._path && typeof instance.constructor.options.data === 'function') {
        let newData = instance.constructor.options.data()
        for (let key in newData) {
          Vue.set(instance.$data, key, newData[key])
        }
      }
      return instance.constructor.options.__file
    })
    hotReloadAPI(this)
  })
}

// Special hot reload with data(context)
function hotReloadAPI (_app) {
  if (!module.hot) return
  const $nuxt = _app.$nuxt
  var _forceUpdate = $nuxt.$forceUpdate.bind($nuxt)
  $nuxt.$forceUpdate = function () {
    let Component = getMatchedComponents(router.currentRoute)[0]
    if (!Component) return _forceUpdate()
    if (typeof Component === 'object' && !Component.options) {
      // Updated via vue-router resolveAsyncComponents()
      Component = Vue.extend(Component)
      Component._Ctor = Component
    }
    let promises = []
    // If layout changed
    if (_app.layoutName !== Component.options.layout) {
      let promise = _app.setLayout(Component.options.layout)
      promise.then(() => {
        hotReloadAPI(_app)
      })
      promises.push(promise)
    }
    const next = function (path) {
      <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
      router.push(path)
    }
    const context = getContext({ route: router.currentRoute<%= (store ? ', store' : '') %>, isClient: true, next: next.bind(this), error: _app.error })
    // Check if data has been updated
    const originalDataFn = (Component._data || noopData).toString().replace(/\s/g, '')
    const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '')
    if (originalDataFn !== newDataFn) {
      Component._data = Component._Ctor.options.data || noopData
      let p = promisify(Component._data, context)
      p.then((data) => {
        Component._cData = () => data || {}
        Component.options.data = Component._cData
        Component._dataFn = Component.options.data.toString().replace(/\s/g, '')
        Component._Ctor.options.data = Component.options.data
        <%= (loading ? 'this.$loading.increase && this.$loading.increase(30)' : '') %>
      })
      promises.push(p)
    } else if (Component._cData) {
      Component._data = Component.options.data
      Component.options.data = Component._cData
      Component._Ctor.options.data = Component.options.data
    }
    // Check if fetch has been updated
    const originalFetchFn = (Component.options.fetch || noopFetch).toString().replace(/\s/g, '')
    const newFetchFn = (Component._Ctor.options.fetch || noopFetch).toString().replace(/\s/g, '')
    // Fetch has been updated, we call it to update the store
    if (originalFetchFn !== newFetchFn) {
      Component.options.fetch = Component._Ctor.options.fetch || noopFetch
      let p = Component.options.fetch(context)
      if (!(p instanceof Promise)) { p = Promise.resolve(p) }
      <%= (loading ? 'p.then(() => this.$loading.increase && this.$loading.increase(30))' : '') %>
      promises.push(p)
    }
    if (!promises.length) return;
    <%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %>
    return Promise.all(promises).then(() => {
      <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
      _forceUpdate()
    })
  }
}

// Load vue app
const NUXT = window.__NUXT__ || {}
if (!NUXT) {
  throw new Error('[nuxt.js] cannot find the global variable __NUXT__, make sure the server is working.')
}
// Get matched components
const path = getLocation(router.options.base)
const resolveComponents = flatMapComponents(router.match(path), (Component, _, match, key, index) => {
  if (typeof Component === 'function' && !Component.options) {
    return new Promise(function (resolve, reject) {
      const _resolve = (Component) => {
        if (!Component.options) {
          Component = Vue.extend(Component) // fix issue #6
          Component._Ctor = Component
        } else {
          Component._Ctor = Component
          Component.extendOptions = Component.options
        }
        if (Component.options.data && typeof Component.options.data === 'function') {
          Component._data = Component.options.data
          if (NUXT.serverRendered) {
            Component._cData = () => NUXT.data[index] || {}
            Component.options.data = Component._cData
            Component._dataFn = Component.options.data.toString().replace(/\s/g, '')
          }
          if (Component._Ctor && Component._Ctor.options) {
            Component._Ctor.options.data = Component.options.data
          }
        }
        match.components[key] = Component
        resolve(Component)
      }
      Component().then(_resolve).catch(reject)
    })
  }
  return Component
})

function nuxtReady (app) {
  window._nuxtReadyCbs.forEach((cb) => {
    if (typeof cb === 'function') {
      cb(app)
    }
  })
  // Add router hooks
  router.afterEach(function (to, from) {
    app.$nuxt.$emit('routeChanged', to, from)
  })
}

Promise.all(resolveComponents)
.then((Components) => {
  const _app = new Vue(app)

  return _app.setLayout(Components.length ? Components[0].options.layout : '')
  .then(() => {
    return { _app, Components }
  })
})
.then(({ _app, Components }) => {
  const mountApp = () => {
    _app.$mount('#__nuxt')
    <% if (loading) { %>
    // Special loading bar
    _app.$loading = _app.$nuxt.$loading
    <% } %>
    // Hot reloading
    hotReloadAPI(_app)
    // Call window.onNuxtReady callbacks
    Vue.nextTick(() => nuxtReady(_app))
  }
  <% if (store) { %>
  // Replace store state
  if (NUXT.state) {
    store.replaceState(NUXT.state)
  }
  <% } %>
  _app.setTransitions = _app.$options._nuxt.setTransitions.bind(_app)
  if (Components.length) {
    _app.setTransitions(mapTransitions(Components, router.currentRoute))
    _lastPaths = router.currentRoute.matched.map((route) => compile(route.path)(router.currentRoute.params))
    _lastComponentsFiles = Components.map((Component) => Component.options.__file)
  }
  _app.error = _app.$options._nuxt.error.bind(_app)
  _app.$loading = {} // to avoid error while _app.$nuxt does not exist
  if (NUXT.error) _app.error(NUXT.error)
  // Add router hooks
  router.beforeEach(loadAsyncComponents.bind(_app))
  router.beforeEach(render.bind(_app))
  router.afterEach(fixPrepatch.bind(_app))
  if (NUXT.serverRendered) {
    mountApp()
    return
  }
  render.call(_app, router.currentRoute, router.currentRoute, function (path) {
    if (path) {
      let mounted = false
      router.afterEach(function () {
        if (mounted) return
        mounted = true
        mountApp()
      })
      router.push(path)
      return
    }
    mountApp()
  })
})
.catch((err) => {
  console.error('[nuxt.js] Cannot load components', err) // eslint-disable-line no-console
})
<|endoftext|>


<commit_before>/* global describe it */

var request = require('request')
var assert = require('assert')
var base_url = (process.env.API_ADDRESS ? process.env.API_ADDRESS : 'http://localhost:3000')

describe('Test Resources responses', function () {
  var sampleResources = [{uri: 101164830, type: 'nypl:Component'}, {uri: 100037340, type: 'nypl:Item'}]
  // var sampleResources = [{uri: 101164830, type: 'resourcetypes:col'}, {uri: 100037340, type: 'resourcetypes:txt'}]

  describe('GET sample resources', function () {
    sampleResources.forEach(function (spec) {
      it(`Resource ${spec.uri} returns status code 200`, function (done) {
        request.get(`${base_url}/api/v1/resources/${spec.uri}`, function (err, response, body) {
          if (err) throw err
          assert.equal(200, response.statusCode)
          done()
        })
      })

      it(`Resource ${spec.uri} has correct type ${spec.type}`, function (done) {
        request.get(`${base_url}/api/v1/resources/${spec.uri}`, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)
          assert.equal(spec.type, doc.type) // ['rdf:type'][0]['objectUri'])
          done()
        })
      })
    })
  })

  describe('GET resources random', function () {
    var randomUrl = `${base_url}/api/v1/resources?action=random`
    it('Resource random has requested page size', function (done) {
      request.get(`${randomUrl}&per_page=13`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        assert.equal(13, doc.itemListElement.length)
        done()
      })
    })
  })

  describe('GET resources search', function () {
    var searchAllUrl = `${base_url}/api/v1/resources?action=search`

    it('Resource search all returns status code 200', function (done) {
      request.get(searchAllUrl, function (err, response, body) {
        if (err) throw err
        assert.equal(200, response.statusCode)
        done()
      })
    })

    it(`Resource search all (${searchAllUrl}) returns > 10mil results`, function (done) {
      request.get(searchAllUrl, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        assert(doc.totalResults > 10000000)
        done()
      })
    })

    it('Resource search all page 1 has default page size', function (done) {
      request.get(searchAllUrl, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        assert.equal(50, doc.itemListElement.length)
        done()
      })
    })

    it('Resource search all page 1 has requested page size', function (done) {
      request.get(`${searchAllUrl}&per_page=42`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        assert.equal(42, doc.itemListElement.length)
        done()
      })
    })

    it('Resource search pagination is consistent', function (done) {
      request.get(`${searchAllUrl}&page=101&per_page=1`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        var item101 = doc.itemListElement[0].result

        // Now fetch same item in different way:
        request.get(`${searchAllUrl}&page=2&per_page=100`, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)
          assert.equal(doc.itemListElement[0].result.uri, item101.uri)
          done()
        })
      })
    })

    it('Resource search filter on agents', function (done) {
      // Filter on these agents:
      var agents = ['agents:10955903', 'agents:10334529']

      // First just filter on the first agent
      request.get(`${searchAllUrl}&filters[contributor]=${agents[0]}]`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        // At writing, this returns 14 items
        assert(doc.totalResults < 100)

        var prevTotal = doc.totalResults

        // Now filter on both agents (matching either)
        var agentsFilter = agents.map((a) => `filters[contributor][]=${a}`).join('&')
        request.get(`${searchAllUrl}&${agentsFilter}`, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)
          assert(doc.totalResults > prevTotal)

          done()
        })
      })
    })

    it('Resource search date range', function (done) {
      var dates = [1984, 1985]

      // First just filter on the first date (objects whose start/end date range include 1984)
      request.get(`${searchAllUrl}&filters[date]=${dates[0]}`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)

        // Obj date range encompases queried date:
        assert(doc.itemListElement[0].result.dateStartYear <= dates[0])
        assert(doc.itemListElement[0].result.dateEndYear >= dates[0])

        // At writing, this returns 42,209 docs
        assert(doc.totalResults < 50000)

        var prevTotal = doc.totalResults

        // Now filter on both dates (adding objects whose date range includes 1985)
        var yearFilter = dates.map((a) => `filters[date][]=${a}`).join('&')
        request.get(`${searchAllUrl}&${yearFilter}`, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)
          assert(doc.totalResults > prevTotal)

          done()
        })
      })
    })

    var parents = [101669044]
    parents.forEach((parentId) => {
      var url = `${searchAllUrl}&filters[parent]=${parentId}`
      it('Resources by parent (' + url + ')', function (done) {
        // First just filter on the first date (objects whose start/end date range include 1984)
        request.get(url, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)

          var firstItem = doc.itemListElement[0].result
          if (firstItem.memberOf) {
            var rootParent = firstItem.memberOf[firstItem.memberOf.length - 1]
            assert(parseInt(rootParent['@id']) === parentId)
          }
          assert(parseInt(firstItem.parentUri) === parentId)

          done()
        })
      })
    })
  })
})
<commit_msg>increase resources search timeout<commit_after>/* global describe it */

var request = require('request')
var assert = require('assert')
var base_url = (process.env.API_ADDRESS ? process.env.API_ADDRESS : 'http://localhost:3000')

describe('Test Resources responses', function () {
  var sampleResources = [{uri: 101164830, type: 'nypl:Component'}, {uri: 100037340, type: 'nypl:Item'}]
  // var sampleResources = [{uri: 101164830, type: 'resourcetypes:col'}, {uri: 100037340, type: 'resourcetypes:txt'}]

  describe('GET sample resources', function () {
    sampleResources.forEach(function (spec) {
      it(`Resource ${spec.uri} returns status code 200`, function (done) {
        request.get(`${base_url}/api/v1/resources/${spec.uri}`, function (err, response, body) {
          if (err) throw err
          assert.equal(200, response.statusCode)
          done()
        })
      })

      it(`Resource ${spec.uri} has correct type ${spec.type}`, function (done) {
        request.get(`${base_url}/api/v1/resources/${spec.uri}`, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)
          assert.equal(spec.type, doc.type) // ['rdf:type'][0]['objectUri'])
          done()
        })
      })
    })
  })

  describe('GET resources random', function () {
    var randomUrl = `${base_url}/api/v1/resources?action=random`
    it('Resource random has requested page size', function (done) {
      request.get(`${randomUrl}&per_page=13`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        assert.equal(13, doc.itemListElement.length)
        done()
      })
    })
  })

  describe('GET resources search', function () {
    this.timeout(6000)

    var searchAllUrl = `${base_url}/api/v1/resources?action=search`

    it('Resource search all returns status code 200', function (done) {
      request.get(searchAllUrl, function (err, response, body) {
        if (err) throw err
        assert.equal(200, response.statusCode)
        done()
      })
    })

    it(`Resource search all (${searchAllUrl}) returns > 10mil results`, function (done) {
      request.get(searchAllUrl, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        assert(doc.totalResults > 10000000)
        done()
      })
    })

    it('Resource search all page 1 has default page size', function (done) {
      request.get(searchAllUrl, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        assert.equal(50, doc.itemListElement.length)
        done()
      })
    })

    it('Resource search all page 1 has requested page size', function (done) {
      request.get(`${searchAllUrl}&per_page=42`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        assert.equal(42, doc.itemListElement.length)
        done()
      })
    })

    it('Resource search pagination is consistent', function (done) {
      request.get(`${searchAllUrl}&page=101&per_page=1`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        var item101 = doc.itemListElement[0].result

        // Now fetch same item in different way:
        request.get(`${searchAllUrl}&page=2&per_page=100`, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)
          assert.equal(doc.itemListElement[0].result.uri, item101.uri)
          done()
        })
      })
    })

    it('Resource search filter on agents', function (done) {
      // Filter on these agents:
      var agents = ['agents:10955903', 'agents:10334529']

      // First just filter on the first agent
      request.get(`${searchAllUrl}&filters[contributor]=${agents[0]}]`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)
        // At writing, this returns 14 items
        assert(doc.totalResults < 100)

        var prevTotal = doc.totalResults

        // Now filter on both agents (matching either)
        var agentsFilter = agents.map((a) => `filters[contributor][]=${a}`).join('&')
        request.get(`${searchAllUrl}&${agentsFilter}`, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)
          assert(doc.totalResults > prevTotal)

          done()
        })
      })
    })

    it('Resource search date range', function (done) {
      var dates = [1984, 1985]

      // First just filter on the first date (objects whose start/end date range include 1984)
      request.get(`${searchAllUrl}&filters[date]=${dates[0]}`, function (err, response, body) {
        if (err) throw err
        var doc = JSON.parse(body)

        // Obj date range encompases queried date:
        assert(doc.itemListElement[0].result.dateStartYear <= dates[0])
        assert(doc.itemListElement[0].result.dateEndYear >= dates[0])

        // At writing, this returns 42,209 docs
        assert(doc.totalResults < 50000)

        var prevTotal = doc.totalResults

        // Now filter on both dates (adding objects whose date range includes 1985)
        var yearFilter = dates.map((a) => `filters[date][]=${a}`).join('&')
        request.get(`${searchAllUrl}&${yearFilter}`, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)
          assert(doc.totalResults > prevTotal)

          done()
        })
      })
    })

    var parents = [101669044]
    parents.forEach((parentId) => {
      var url = `${searchAllUrl}&filters[parent]=${parentId}`
      it('Resources by parent (' + url + ')', function (done) {
        // First just filter on the first date (objects whose start/end date range include 1984)
        request.get(url, function (err, response, body) {
          if (err) throw err
          var doc = JSON.parse(body)

          var firstItem = doc.itemListElement[0].result
          if (firstItem.memberOf) {
            var rootParent = firstItem.memberOf[firstItem.memberOf.length - 1]
            assert(parseInt(rootParent['@id']) === parentId)
          }
          assert(parseInt(firstItem.parentUri) === parentId)

          done()
        })
      })
    })
  })
})
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import {
  Text,
  View,
  StyleSheet,
  ActivityIndicator,
  ListView,
  LayoutAnimation,
  Platform,
  UIManager,
} from 'react-native'
import _ from 'lodash'
import moment from 'moment'
import { observer,inject } from 'mobx-react/native'
import { getColor } from '../config'
import Icon from 'react-native-vector-icons/Ionicons'
import { firebaseApp } from '../../firebase'
import Post from './post'
import { Card, ListItem, Button } from 'react-native-elements'

@inject("appStore") @observer
export default class Expos extends Component {
  constructor(props) {
    super(props)
    if (Platform.OS === 'android') {
      UIManager.setLayoutAnimationEnabledExperimental(true)
    }
    this.state = {
      counter: 3,
      isLoading: true,
      isEmpty: false,
      isFinished: false,
    }
  }

  componentDidMount() {
    firebaseApp.database().ref('exhibitions').on('value',
    (snapshot) => {
      if (snapshot.val()) {
        this.setState({ isEmpty: false })
        this.setState({ exhibits: snapshot.val()})
      }
      else {
        this.setState({ isEmpty: true })
      }
      this.setState({ isLoading: false })
    })
  }

  componentDidUpdate() {
    //LayoutAnimation.configureNext(LayoutAnimation.Presets.spring)
  }

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.card}>
          {this._renderCard(this.state.exhibits)}
        </View>
        <View style={styles.newExpo}>
          <Button
            backgroundColor='#03A9F4'
            raised
            icon={{name: 'plus', type: 'octicon', buttonStyle: styles.newExpo }}
            title='Nouvelle exposition'
            onPress={this._writeExpoData} />
        </View>
      </View>
    )
  }

  _renderCard = (data) => {
    console.log(data)
    if (data){
      const postExpo = []
      Object.keys(data).map((key, index) => {
        postExpo.push(
          <Card
            title={data[key].name}
            key={index}
            >
            <Text style={{marginBottom: 10}}>
              {data[key].description}
            </Text>
            <Button
              backgroundColor='#03A9F4'
              buttonStyle={{borderRadius: 0, marginLeft: 0, marginRight: 0, marginBottom: 0}}
              title='Voir exposition'
              onPress={this._writeExpoData} />
          </Card>
        )
      })
      return postExpo
    }
    else if(this.state.isEmpty) {
      return null
    }
    else {
      return (
        <ActivityIndicator size='large' style={{paddingTop: 20}}/>
      )
    }
  }

  _writeExpoData = () => {
    firebaseApp.database().ref('exhibitions/').push({
      description: "test2",
      end_date: "yo",
      name: "Icônes de moi",
      start_date: "Date2"
    });
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  card: {
    flex: .5
  },
  newExpo: {
    flex: 1,
    justifyContent: 'flex-end',
    marginBottom: 10
  }
})
<commit_msg>added css<commit_after>import React, { Component } from 'react'
import {
	Text,
	View,
	ScrollView,
	StyleSheet,
	ActivityIndicator,
	ListView,
	LayoutAnimation,
	Platform,
	UIManager,
} from 'react-native'
import _ from 'lodash'
import moment from 'moment'
import { observer,inject } from 'mobx-react/native'
import { getColor } from '../config'
import Icon from 'react-native-vector-icons/Ionicons'
import { firebaseApp } from '../../firebase'
import Post from './post'
import { Card, ListItem, Button } from 'react-native-elements'

@inject("appStore") @observer
export default class Expos extends Component {
	constructor(props) {
		super(props)
		if (Platform.OS === 'android') {
			UIManager.setLayoutAnimationEnabledExperimental(true)
		}
		this.state = {
			counter: 3,
			isLoading: true,
			isEmpty: false,
			isFinished: false,
		}
	}

	componentDidMount() {
		firebaseApp.database().ref('exhibitions').on('value',
		(snapshot) => {
			if (snapshot.val()) {
				this.setState({ isEmpty: false })
				this.setState({ exhibits: snapshot.val()})
			}
			else {
				this.setState({ isEmpty: true })
			}
			this.setState({ isLoading: false })
		})
	}

	componentDidUpdate() {
		//LayoutAnimation.configureNext(LayoutAnimation.Presets.spring)
	}

	render() {
		return (
			<View style={styles.container}>
					<ScrollView style={styles.card}>
						{this._renderCard(this.state.exhibits)}
					</ScrollView>
				<View style={styles.newExpo}>
					<Button
						backgroundColor='#03A9F4'
						raised
						icon={{name: 'plus', type: 'octicon', buttonStyle: styles.newExpo }}
						title='Nouvelle exposition'
						onPress={this._writeExpoData} />
				</View>
			</View>
		)
	}

	_renderCard = (data) => {
		if (data){
			const postExpo = []
			Object.keys(data).map((key, index) => {
				postExpo.push(
					<Card
						title={data[key].name}
						key={index}
						>
						<Text style={{marginBottom: 10}}>
							{data[key].description}
						</Text>
						<Button
							backgroundColor='#03A9F4'
							buttonStyle={{borderRadius: 0, marginLeft: 0, marginRight: 0, marginBottom: 0}}
							title='Voir exposition'
							onPress={this._writeExpoData} />
					</Card>
				)
			})
			return postExpo
		}
		else if(this.state.isEmpty) {
			return null
		}
		else {
			return (
				<ActivityIndicator size='large' style={{paddingTop: 20}}/>
			)
		}
	}

	_writeExpoData = () => {
		firebaseApp.database().ref('exhibitions/').push({
			description: "test2",
			end_date: "yo",
			name: "Icônes de moi",
			start_date: "Date2"
		});
	}
}

const styles = StyleSheet.create({
	container: {
		flex: 1
	},
	card: {
		flex: 1,
		marginBottom: 10
	},
	newExpo: {
		justifyContent: 'flex-end',
		paddingTop: 10,
		paddingBottom: 10,
		backgroundColor: getColor('#ffffff'),
	}
})
<|endoftext|>


<commit_before>var espower = require('espower'),
    CoffeeScript = require('coffee-script-redux'),
    _ = require('lodash'),
    fs = require('fs');

module.exports = function(grunt) {
    'use strict';

    var pkg = grunt.file.readJSON('package.json');

    (function () {
        var taskName;
        for(taskName in pkg.devDependencies) {
            if(taskName.substring(0, 6) === 'grunt-') {
                grunt.loadNpmTasks(taskName);
            }
        }
    })();

    grunt.initConfig({
        destDir: 'espowered_tests',
        clean: {
            power_assert: ['<%= destDir %>/'],
            power_coffee: ['<%= destDir %>/']
        },
        espower: {
            power_assert: {
                files: [
                    {
                        expand: true,     // Enable dynamic expansion.
                        cwd: 'test/',      // Src matches are relative to this path.
                        src: ['power_assert/**/*.js'], // Actual pattern(s) to match.
                        dest: '<%= destDir %>/',   // Destination path prefix.
                        ext: '.js'   // Dest filepaths will have this extension.
                    },
                ]
            }
        },
        espower_csredux: {
            power_coffee: {
                files: [
                    {
                        expand: true,     // Enable dynamic expansion.
                        cwd: 'test/',      // Src matches are relative to this path.
                        src: ['power_coffee/**/*.coffee'], // Actual pattern(s) to match.
                        dest: '<%= destDir %>/',   // Destination path prefix.
                        ext: '.js'   // Dest filepaths will have this extension.
                    },
                ]
            }
        },
        mochaTest: {
            espower_loader: {
                options: {
                    ui: 'tdd',
                    require: './enable-power-assert'
                },
                src: ['test/power_assert/*.js']
            },
            normal_assert: {
                options: { ui: 'tdd' },
                src: ['test/normal_assert/*.js']
            },
            mocha_expect: {
                options: { ui: 'bdd' },
                src: ['test/mocha_expect/*.js']
            },
            power_assert: {
                options: { ui: 'tdd' },
                src: ['<%= destDir %>/**/*.js']
            },
            power_coffee: {
                options: { ui: 'bdd' },
                src: ['<%= destDir %>/**/*.js']
            }
        },
        watch: {
            normal_assert: {
                files: ['test/normal_assert/*.js'],
                tasks: ['normal_assert']
            },
            mocha_expect: {
                files: ['test/mocha_expect/*.js'],
                tasks: ['mocha_expect']
            },
            power_assert: {
                files: ['test/power_assert/*.js'],
                tasks: ['power_assert']
            },
            power_coffee: {
                files: ['test/power_coffee/*.coffee'],
                tasks: ['power_coffee']
            },
        },
    });

    grunt.registerMultiTask('espower_csredux', 'instrument power assert into the coffee.', function() {
        // Merge task-specific and/or target-specific options with these defaults.
        var options = this.options({
                destructive: false,
                powerAssertVariableName: 'assert'
            });

        // Iterate over all specified file groups.
        this.files.forEach(function(f) {
            var src = f.src.filter(function(filepath) {
                // Warn on and remove invalid source files (if nonull was set).
                if (!grunt.file.exists(filepath)) {
                    grunt.log.warn('Source file "' + filepath + '" not found.');
                    return false;
                } else {
                    return true;
                }
            }).forEach(function(filepath) {
                grunt.verbose.writeln('espower src: ' + f.src);
                var absPath = fs.realpathSync(filepath),
                    csCode = fs.readFileSync(filepath, 'utf-8'),
                    parseOptions = {raw: true},
                    compileOptions = {bare: true},
                    jsGenerateOptions = {compact: false},
                    espowerOptions = _.merge(options, {
                        path: absPath,
                        source: csCode
                    });
                var csAST = CoffeeScript.parse(csCode, parseOptions);
                var jsAST = CoffeeScript.compile(csAST, compileOptions);
                var espoweredAst = espower(jsAST, espowerOptions);
                var jsCode = CoffeeScript.js(espoweredAst, jsGenerateOptions);
                grunt.verbose.writeln('espower dest: ' + f.dest);
                grunt.file.write(f.dest, jsCode);
            });
        });
    });

    grunt.registerTask('espower_loader', ['mochaTest:espower_loader']);

    grunt.registerTask('normal_assert', ['mochaTest:normal_assert']);
    grunt.registerTask('mocha_expect', ['mochaTest:mocha_expect']);
    grunt.registerTask('power_assert', ['clean:power_assert', 'espower:power_assert', 'mochaTest:power_assert']);
    grunt.registerTask('power_coffee', ['clean:power_coffee', 'espower_csredux:power_coffee', 'mochaTest:power_coffee']);

    grunt.registerTask('default', ['power_assert']);
};
<commit_msg>Only use merge function from lodash.<commit_after>var espower = require('espower'),
    CoffeeScript = require('coffee-script-redux'),
    merge = require('lodash.merge'),
    fs = require('fs');

module.exports = function(grunt) {
    'use strict';

    var pkg = grunt.file.readJSON('package.json');

    (function () {
        var taskName;
        for(taskName in pkg.devDependencies) {
            if(taskName.substring(0, 6) === 'grunt-') {
                grunt.loadNpmTasks(taskName);
            }
        }
    })();

    grunt.initConfig({
        destDir: 'espowered_tests',
        clean: {
            power_assert: ['<%= destDir %>/'],
            power_coffee: ['<%= destDir %>/']
        },
        espower: {
            power_assert: {
                files: [
                    {
                        expand: true,     // Enable dynamic expansion.
                        cwd: 'test/',      // Src matches are relative to this path.
                        src: ['power_assert/**/*.js'], // Actual pattern(s) to match.
                        dest: '<%= destDir %>/',   // Destination path prefix.
                        ext: '.js'   // Dest filepaths will have this extension.
                    },
                ]
            }
        },
        espower_csredux: {
            power_coffee: {
                files: [
                    {
                        expand: true,     // Enable dynamic expansion.
                        cwd: 'test/',      // Src matches are relative to this path.
                        src: ['power_coffee/**/*.coffee'], // Actual pattern(s) to match.
                        dest: '<%= destDir %>/',   // Destination path prefix.
                        ext: '.js'   // Dest filepaths will have this extension.
                    },
                ]
            }
        },
        mochaTest: {
            espower_loader: {
                options: {
                    ui: 'tdd',
                    require: './enable-power-assert'
                },
                src: ['test/power_assert/*.js']
            },
            normal_assert: {
                options: { ui: 'tdd' },
                src: ['test/normal_assert/*.js']
            },
            mocha_expect: {
                options: { ui: 'bdd' },
                src: ['test/mocha_expect/*.js']
            },
            power_assert: {
                options: { ui: 'tdd' },
                src: ['<%= destDir %>/**/*.js']
            },
            power_coffee: {
                options: { ui: 'bdd' },
                src: ['<%= destDir %>/**/*.js']
            }
        },
        watch: {
            normal_assert: {
                files: ['test/normal_assert/*.js'],
                tasks: ['normal_assert']
            },
            mocha_expect: {
                files: ['test/mocha_expect/*.js'],
                tasks: ['mocha_expect']
            },
            power_assert: {
                files: ['test/power_assert/*.js'],
                tasks: ['power_assert']
            },
            power_coffee: {
                files: ['test/power_coffee/*.coffee'],
                tasks: ['power_coffee']
            },
        },
    });

    grunt.registerMultiTask('espower_csredux', 'instrument power assert into the coffee.', function() {
        // Merge task-specific and/or target-specific options with these defaults.
        var options = this.options(espower.defaultOptions());

        // Iterate over all specified file groups.
        this.files.forEach(function(f) {
            var src = f.src.filter(function(filepath) {
                // Warn on and remove invalid source files (if nonull was set).
                if (!grunt.file.exists(filepath)) {
                    grunt.log.warn('Source file "' + filepath + '" not found.');
                    return false;
                } else {
                    return true;
                }
            }).forEach(function(filepath) {
                grunt.verbose.writeln('espower src: ' + f.src);
                var absPath = fs.realpathSync(filepath),
                    csCode = fs.readFileSync(filepath, 'utf-8'),
                    parseOptions = {raw: true},
                    compileOptions = {bare: true},
                    jsGenerateOptions = {compact: false},
                    espowerOptions = merge(options, {
                        path: absPath,
                        source: csCode
                    });
                var csAST = CoffeeScript.parse(csCode, parseOptions);
                var jsAST = CoffeeScript.compile(csAST, compileOptions);
                var espoweredAst = espower(jsAST, espowerOptions);
                var jsCode = CoffeeScript.js(espoweredAst, jsGenerateOptions);
                grunt.verbose.writeln('espower dest: ' + f.dest);
                grunt.file.write(f.dest, jsCode);
            });
        });
    });

    grunt.registerTask('espower_loader', ['mochaTest:espower_loader']);

    grunt.registerTask('normal_assert', ['mochaTest:normal_assert']);
    grunt.registerTask('mocha_expect', ['mochaTest:mocha_expect']);
    grunt.registerTask('power_assert', ['clean:power_assert', 'espower:power_assert', 'mochaTest:power_assert']);
    grunt.registerTask('power_coffee', ['clean:power_coffee', 'espower_csredux:power_coffee', 'mochaTest:power_coffee']);

    grunt.registerTask('default', ['power_assert']);
};
<|endoftext|>