<commit_before>module.exports = function( grunt ) {
	"use strict";

	var path = require( "path" ),
		httpPort =  Math.floor( 9000 + Math.random()*1000 ),
		name = "jquery.mobile",
		dist = "dist",
		distpaths = [
			path.join( dist, name ) + ".js",
			path.join( dist, name ) + ".min.map",
			path.join( dist, name ) + ".min.js"
		],
		banner = {
			normal: [
				"/*",
				"* jQuery Mobile <%= version %>",
				"* http://jquerymobile.com",
				"*",
				"* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors",
				"* Released under the MIT license.",
				"* http://jquery.org/license",
				"*",
				"*/",
				"",
				"",
				"" ].join( grunt.util.linefeed ),
			minified: "/*! jQuery Mobile <%= version %> | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */"
		};

	// grunt plugins
	grunt.loadNpmTasks( "grunt-contrib-jshint" );
	grunt.loadNpmTasks( "grunt-contrib-copy" );
	grunt.loadNpmTasks( "grunt-contrib-compress" );
	grunt.loadNpmTasks( "grunt-contrib-concat" );
	grunt.loadNpmTasks( "grunt-contrib-connect" );
	grunt.loadNpmTasks( "grunt-contrib-qunit" );
	grunt.loadNpmTasks( "grunt-contrib-requirejs" );
	grunt.loadNpmTasks( "grunt-contrib-uglify" );
	grunt.loadNpmTasks( "grunt-css" );
	grunt.loadNpmTasks( "grunt-git-authors" );
	grunt.loadNpmTasks( "grunt-qunit-junit" );

	// load the project's default tasks
	grunt.loadTasks( 'build/tasks');

	// Project configuration.
	grunt.config.init({
		pkg: grunt.file.readJSON( "package.json" ),

		version: "<%= pkg.version %>",

		jshint: {
			js: {
				options: {
					jshintrc: "js/.jshintrc"
				},
				files: {
					src: [
						"js/**/*.js",
						"!js/jquery.hashchange.js",
						"!js/jquery.js",
						"!js/jquery.ui.widget.js"
					]
				}
			},
			grunt: {
				options: {
					jshintrc: ".jshintrc"
				},
				files: {
					src: [ "Gruntfile.js" ]
				}
			}
		},

		requirejs: {
			js: {
				options: {
					baseUrl: "js",

					optimize: "none",

					//Finds require() dependencies inside a require() or define call.
					findNestedDependencies: true,

					//If skipModuleInsertion is false, then files that do not use define()
					//to define modules will get a define() placeholder inserted for them.
					//Also, require.pause/resume calls will be inserted.
					//Set it to true to avoid this. This is useful if you are building code that
					//does not use require() in the built project or in the JS files, but you
					//still want to use the optimization tool from RequireJS to concatenate modules
					//together.
					skipModuleInsertion: true,

					mainConfigFile: "js/requirejs.config.js",

					name: name,

					exclude: [
						"jquery",
						"depend",
						"json",
						"json!../package.json"
					],

					out: path.join( dist, name ) + ".js",

					pragmasOnSave: {
						jqmBuildExclude: true
					},

					//File paths are relative to the build file, or if running a commmand
					//line build, the current directory.
					wrap: {
						startFile: "build/wrap.start",
						endFile: "build/wrap.end"
					},

					onBuildWrite: function (moduleName, path, contents) {
						return contents.replace(/__version__/g, grunt.config.process( "\"<%= version %>\"" ) );
					}
				}
			}
		},

		concat: {
			js: {
				options: {
					banner: banner.normal
				},

				src: [ path.join( dist, name ) + ".js" ],
				dest: path.join( dist, name ) + ".js"
			},
			demos: {
				src: [ "docs/demos/_assets/js/*.js" ],
				dest: path.join( dist, "demos/_assets/js/demos.js" )
			}
		},

		uglify: {
			all: {
				options: {
					cwd: dist,
					banner: banner.minified,
					sourceMapPrefix: 1,
					sourceMap: path.join( dist, name ) + ".min.map",
					beautify: {
						ascii_only: true
					}
				},
				files: {
					"dist/jquery.mobile.min.js": path.join( dist, name ) + ".js",
				}
			}
		},

		cssbuild: {
			options: {
				banner: banner.normal,

				//Allow CSS optimizations. Allowed values:
				//- "standard": @import inlining, comment removal and line returns.
				//Removing line returns may have problems in IE, depending on the type
				//of CSS.
				//- "standard.keepLines": like "standard" but keeps line returns.
				//- "none": skip CSS optimizations.
				//- "standard.keepComments": keeps the file comments, but removes line
				//returns.  (r.js 1.0.8+)
				//- "standard.keepComments.keepLines": keeps the file comments and line
				//returns. (r.js 1.0.8+)
				optimizeCss: "standard.keepComments.keepLines",

				//If optimizeCss is in use, a list of of files to ignore for the @import
				//inlining. The value of this option should be a string of comma separated
				//CSS file names to ignore (like 'a.css,b.css'. The file names should match
				//whatever strings are used in the @import calls.
				cssImportIgnore: null,
			},
			all: {
				files: {
					"dist/jquery.mobile.structure.css": "css/structure/jquery.mobile.structure.css",
					"dist/jquery.mobile.theme.css": "css/themes/default/jquery.mobile.theme.css",
					"dist/jquery.mobile.css": "css/themes/default/jquery.mobile.css"
				}
			}
		},

		cssmin: {
			options: {
				banner: banner.minified
			},
			structure: {
				files: {
					"dist/jquery.mobile.structure.min.css": "dist/jquery.mobile.structure.css"
				}
			},
			theme: {
				files: {
					"dist/jquery.mobile.theme.min.css": "dist/jquery.mobile.theme.css"
				}
			},
			bundle: {
				files: {
					"dist/jquery.mobile.min.css": "dist/jquery.mobile.css"
				}
			}
		},

		copy: {
			images: {
				expand: true,
				cwd: "css/themes/default/images",
				src: "*",
				dest: path.join( dist, "images/" ),
			},
			"demos.processed": {
				options: {
					processContentExclude: [ "**/*.png", "**/*.gif" ],
					processContent: function( content, srcPath ) {
						if ( srcPath === "docs/demos/nav.html" ) {
							return false;
						}
						content = content.replace( /_assets\/js\/">/gi, "_assets/js/demos.js\">" );
						content = content.replace( /\.\.\/\.\.\/js\/">/gi, "js/" + name + ".min.js\">" );
						content = content.replace( /\.\.\/\.\.\/css\//gi, "css/" );
						content = content.replace( /^\s*<\?php include\(\s*['"]([^'"]+)['"].*$/gmi,
							function( match, includePath, offset, string ) {
								var fileToInclude = path.resolve( path.join( path.dirname( srcPath ), includePath ) );
								return grunt.file.read( fileToInclude );
							}
						);
						return content;
					}
				},
				files: [
					{
						expand: true,
						cwd: "docs/demos",
						src: [ "**" ],
						dest: path.join( dist, "demos/" )
					}
				]
			},
			"demos.unprocessed": {
				files: [
					{
						expand: true,
						cwd: dist,
						src: [ "*.js", "*.map" ],
						dest: path.join( dist, "demos/js/" )
					},
					{
						expand: true,
						cwd: dist,
						src: [ name + ".css", "images/*" ],
						dest: path.join( dist, "demos/css/themes/default/" )
					},
					{
						expand: true,
						cwd: dist,
						src: "images/*",
						dest: path.join( dist, "demos/" )
					},
				]
			}
		},

		compress: {
			dist: {
				options: {
					archive: path.join( dist, name ) + ".zip"
				},
				files: [
					{ expand: true, cwd: dist, src: [ "**", "!" + name + ".zip" ] }
				]
			}
		},

		connect: {
			server: {
				options: {
					port: httpPort,
					base: '.',
					middleware: function(connect, options) {
						return [
							function(req, res, next){
								var bundle = grunt.config.process( "<%= requirejs.js.options.out %>" );
								if (req.url === "/js/") {
									grunt.log.debug( req.url + " requested, serving: " + bundle );
									res.end( grunt.file.read( bundle ) );
								} else {
									next();
								}
							},

							// Serve static files.
							connect.static(options.base),
							// Make empty directories browsable.
							connect.directory(options.base)
						];
					}
				}
			}
		},

		qunit_junit: {
			options: {
				dest: "build/test-results",
				namer: function (url) {
					var match = url.match(/tests\/([^\/]*)\/(.*)$/);
					return match[2].replace(/\//g, '.').replace(/\.html/, '' ).replace(/\?/, "-");
				}
			}
		},

		qunit: {
			options: {
				timeout: 30000
			},

			files: {},

			http: {
				options: {
					urls: (function() {
						// Find the test files
						var suites = grunt.util._.without( ( grunt.option( "suites" ) || "" ).split( "," ), "" ),
							patterns, paths,
							versionedPaths = [],
							jQueries = grunt.util._.without( ( grunt.option( "jqueries" ) || "" ).split( "," ), "" );

						if ( suites.length ) {
							patterns = [];
							suites.forEach( function( unit ) {
								patterns = patterns.concat( [ "tests/unit/" + unit + "/index.html", "tests/unit/" + unit + "/*/index.html", "tests/unit/" + unit + "/**/*-tests.html" ] );
							});
						} else {
							patterns = [ "tests/unit/*/*/index.html", "tests/unit/**/*-tests.html" ];
						}

						paths = grunt.file.expand( patterns ).sort();

						if ( jQueries.length ) {
							paths.forEach( function( path ) {
								versionedPaths = versionedPaths.concat( jQueries.map( function( jQVersion ) {
									return path + "?jquery=" + jQVersion;
								}) );
							})
						}

						if ( versionedPaths.length ) {
							paths = versionedPaths;
						}

						return paths.map( function( path ) {
							return "http://localhost:<%= connect.server.options.port %>/" + path
						});
					}())
				}
			}
		},

		rsync: {
			options: {
				user: "ghislain.seguin",
				host: "localhost",
//				user: "jqadmin",
//				host: "code.origin.jquery.com",
				remoteBase: "/var/www/html/code.jquery.com/mobile/",
				cwd: "dist" //removes the dist directory from the destination
			},
			release: {
				files: {
					"jquery.mobile-<%= pkg.version %>.js": path.join( dist, "jquery.mobile.js" ),
					"jquery.mobile-<%= pkg.version %>.min.js": path.join( dist, "jquery.mobile.min.js" ),
					"jquery.mobile-<%= pkg.version %>.min.map": path.join( dist, "jquery.mobile.min.map" ),
					"jquery.mobile-<%= pkg.version %>.css": path.join( dist, "jquery.mobile.css" ),
					"jquery.mobile-<%= pkg.version %>.min.css": path.join( dist, "jquery.mobile.min.css" ),
					"jquery.mobile.structure-<%= pkg.version %>.css": path.join( dist, "jquery.mobile.structure.css" ),
					"jquery.mobile.structure-<%= pkg.version %>.min.css": path.join( dist, "jquery.mobile.structure.min.css" ),
					"jquery.mobile.structure-<%= pkg.version %>.zip": path.join( dist, "jquery.mobile.structure.min.css" )
		}
			},
			latest: {
				files: {
					"latest/": path.join( dist, "jquery.mobile.*" )
				}
			}
		},

		curl: {
			options: {
				baseUrl: "http://code.origin.jquery.com/mobile/",
				cwd: dist
			},
			latest: {
				files: {
					"latest/": path.join( dist, "jquery.mobile.*" )
				}
			}
		},

		release: {
			options: {
				versionRegExp: /^(\d)\.(\d+)\.(\d)(-(?:alpha|beta|rc)\.\d|pre)?$/
			}
		}

	});

	grunt.registerTask( "js:release",  [ "requirejs", "concat:js", "uglify" ] );
	grunt.registerTask( "js", [ "config:dev", "js:release" ] );

	grunt.registerTask( "css:release", [ "cssbuild", "cssmin" ] );
	grunt.registerTask( "css", [ "config:dev", "css:release" ] );

	grunt.registerTask( "demos", [ "concat:demos", "copy:demos.processed", "copy:demos.unprocessed" ] );

	grunt.registerTask( "dist:release", [ "js:release", "css:release", "copy:images", "demos", "compress:dist" ] );
	grunt.registerTask( "dist", [ "config:dev", "dist:release" ] );

	grunt.registerTask( "test", [ "config:dev", "requirejs", "connect", "qunit:http" ] );
	grunt.registerTask( "test:ci", [ "qunit_junit", "connect", "qunit:http" ] );

	grunt.registerTask( "deploy:latest", [ "release:init", "release:git:status", "dist:release", "rsync:latest", "curl:latest" ] );
	grunt.registerTask( "deploy:release", ["release:init", "release:git:status", "release:set-version", "recurse:_deploy", "release:set-next-version" ] );
	grunt.registerTask( "_deploy", [ "release:init", "release:fail-if-pre", "dist:release", "rsync:release" ] );

	// Default grunt
	grunt.registerTask( "default", [ "dist" ] );

};<commit_msg>Build: New demos + clean target<commit_after>module.exports = function( grunt ) {
	"use strict";

	var path = require( "path" ),
		httpPort =  Math.floor( 9000 + Math.random()*1000 ),
		name = "jquery.mobile",
		dist = "dist",
		distpaths = [
			path.join( dist, name ) + ".js",
			path.join( dist, name ) + ".min.map",
			path.join( dist, name ) + ".min.js"
		],
		banner = {
			normal: [
				"/*",
				"* jQuery Mobile <%= version %>",
				"* http://jquerymobile.com",
				"*",
				"* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors",
				"* Released under the MIT license.",
				"* http://jquery.org/license",
				"*",
				"*/",
				"",
				"",
				"" ].join( grunt.util.linefeed ),
			minified: "/*! jQuery Mobile <%= version %> | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */"
		};

	// grunt plugins
	grunt.loadNpmTasks( "grunt-contrib-jshint" );
	grunt.loadNpmTasks( "grunt-contrib-clean" );
	grunt.loadNpmTasks( "grunt-contrib-copy" );
	grunt.loadNpmTasks( "grunt-contrib-compress" );
	grunt.loadNpmTasks( "grunt-contrib-concat" );
	grunt.loadNpmTasks( "grunt-contrib-connect" );
	grunt.loadNpmTasks( "grunt-contrib-qunit" );
	grunt.loadNpmTasks( "grunt-contrib-requirejs" );
	grunt.loadNpmTasks( "grunt-contrib-uglify" );
	grunt.loadNpmTasks( "grunt-css" );
	grunt.loadNpmTasks( "grunt-git-authors" );
	grunt.loadNpmTasks( "grunt-qunit-junit" );

	// load the project's default tasks
	grunt.loadTasks( 'build/tasks');

	// Project configuration.
	grunt.config.init({
		pkg: grunt.file.readJSON( "package.json" ),

		version: "<%= pkg.version %>",

		jshint: {
			js: {
				options: {
					jshintrc: "js/.jshintrc"
				},
				files: {
					src: [
						"js/**/*.js",
						"!js/jquery.hashchange.js",
						"!js/jquery.js",
						"!js/jquery.ui.widget.js"
					]
				}
			},
			grunt: {
				options: {
					jshintrc: ".jshintrc"
				},
				files: {
					src: [ "Gruntfile.js" ]
				}
			}
		},

		requirejs: {
			js: {
				options: {
					baseUrl: "js",

					optimize: "none",

					//Finds require() dependencies inside a require() or define call.
					findNestedDependencies: true,

					//If skipModuleInsertion is false, then files that do not use define()
					//to define modules will get a define() placeholder inserted for them.
					//Also, require.pause/resume calls will be inserted.
					//Set it to true to avoid this. This is useful if you are building code that
					//does not use require() in the built project or in the JS files, but you
					//still want to use the optimization tool from RequireJS to concatenate modules
					//together.
					skipModuleInsertion: true,

					mainConfigFile: "js/requirejs.config.js",

					name: name,

					exclude: [
						"jquery",
						"depend",
						"json",
						"json!../package.json"
					],

					out: path.join( dist, name ) + ".js",

					pragmasOnSave: {
						jqmBuildExclude: true
					},

					//File paths are relative to the build file, or if running a commmand
					//line build, the current directory.
					wrap: {
						startFile: "build/wrap.start",
						endFile: "build/wrap.end"
					},

					onBuildWrite: function (moduleName, path, contents) {
						return contents.replace(/__version__/g, grunt.config.process( "\"<%= version %>\"" ) );
					}
				}
			}
		},

		concat: {
			js: {
				options: {
					banner: banner.normal
				},

				src: [ path.join( dist, name ) + ".js" ],
				dest: path.join( dist, name ) + ".js"
			},
			demos: {
				src: [ "demos/_assets/js/*.js" ],
				dest: path.join( dist, "demos/_assets/js/index.js" )
			}
		},

		uglify: {
			all: {
				options: {
					banner: banner.minified,
					sourceMap: path.join( dist, name ) + ".min.map",
					sourceMappingURL: "./" + name + ".min.map",
					beautify: {
						ascii_only: true
					}
				},
				files: {
					"dist/jquery.mobile.min.js": path.join( dist, name ) + ".js",
				}
			}
		},

		cssbuild: {
			options: {
				banner: banner.normal,

				//Allow CSS optimizations. Allowed values:
				//- "standard": @import inlining, comment removal and line returns.
				//Removing line returns may have problems in IE, depending on the type
				//of CSS.
				//- "standard.keepLines": like "standard" but keeps line returns.
				//- "none": skip CSS optimizations.
				//- "standard.keepComments": keeps the file comments, but removes line
				//returns.  (r.js 1.0.8+)
				//- "standard.keepComments.keepLines": keeps the file comments and line
				//returns. (r.js 1.0.8+)
				optimizeCss: "standard.keepComments.keepLines",

				//If optimizeCss is in use, a list of of files to ignore for the @import
				//inlining. The value of this option should be a string of comma separated
				//CSS file names to ignore (like 'a.css,b.css'. The file names should match
				//whatever strings are used in the @import calls.
				cssImportIgnore: null,
			},
			all: {
				files: {
					"dist/jquery.mobile.structure.css": "css/structure/jquery.mobile.structure.css",
					"dist/jquery.mobile.theme.css": "css/themes/default/jquery.mobile.theme.css",
					"dist/jquery.mobile.css": "css/themes/default/jquery.mobile.css"
				}
			}
		},

		cssmin: {
			options: {
				banner: banner.minified
			},
			structure: {
				files: {
					"dist/jquery.mobile.structure.min.css": "dist/jquery.mobile.structure.css"
				}
			},
			theme: {
				files: {
					"dist/jquery.mobile.theme.min.css": "dist/jquery.mobile.theme.css"
				}
			},
			bundle: {
				files: {
					"dist/jquery.mobile.min.css": "dist/jquery.mobile.css"
				}
			}
		},

		copy: {
			images: {
				expand: true,
				cwd: "css/themes/default/images",
				src: "*",
				dest: path.join( dist, "images/" ),
			},
			"demos.firstpass": {
				options: {
					processContent: function( content, srcPath ) {
						content = content.replace( /_assets\/js\/">/gi, "_assets/js/index.js\">" );
						content = content.replace( /\.\.\/js\//gi, "js/" );
						content = content.replace( /js\/"/gi, "js/" + name + ".min.js\"" );
						content = content.replace( /\.\.\/css\//gi, "css/" );
						content = content.replace( /^\s*<\?php include\(\s*['"]([^'"]+)['"].*$/gmi,
							function( match, includePath, offset, string ) {
								var fileToInclude = path.resolve( path.join( path.dirname( srcPath ), includePath ) );
								return grunt.file.read( fileToInclude );
							}
						);
						content = content.replace( /\.php/gi, ".html" );
						return content;
					}
				},
				files: [
					{
						expand: true,
						src: [ "*.php", "demos/**/*.php" ],
						dest: dist,
						ext: ".html"
					}
				]
			},
			"demos.secondpass": {
				options: {
					processContentExclude: [ "**/*.png", "**/*.gif" ],
					processContent: function( content, srcPath ) {
						content = content.replace( /\.php/gi, ".html" );
						return content;
					}
				},
				files: [
					{
						expand: true,
						src: [ "demos/**", "!**/*.php" ],
						dest: dist
					}
				]
			},
			"demos.unprocessed": {
				files: [
					{
						expand: true,
						cwd: "js",
						src: [ "jquery.js" ],
						dest: path.join( dist, "demos/js/" )
					},
					{
						expand: true,
						cwd: dist,
						src: [ "*.js", "*.map" ],
						dest: path.join( dist, "demos/js/" )
					},
					{
						expand: true,
						cwd: dist,
						src: [ name + ".css", "images/*" ],
						dest: path.join( dist, "demos/css/themes/default/" )
					},
					{
						expand: true,
						cwd: dist,
						src: "images/*",
						dest: path.join( dist, "demos/" )
					},
				]
			}
		},

		compress: {
			dist: {
				options: {
					archive: path.join( dist, name ) + ".zip"
				},
				files: [
					{ expand: true, cwd: dist, src: [ "**", "!" + name + ".zip" ] }
				]
			}
		},

		connect: {
			server: {
				options: {
					port: httpPort,
					base: '.',
					middleware: function(connect, options) {
						return [
							function(req, res, next){
								var bundle = grunt.config.process( "<%= requirejs.js.options.out %>" );
								if (req.url === "/js/") {
									grunt.log.debug( req.url + " requested, serving: " + bundle );
									res.end( grunt.file.read( bundle ) );
								} else {
									next();
								}
							},

							// Serve static files.
							connect.static(options.base),
							// Make empty directories browsable.
							connect.directory(options.base)
						];
					}
				}
			}
		},

		qunit_junit: {
			options: {
				dest: "build/test-results",
				namer: function (url) {
					var match = url.match(/tests\/([^\/]*)\/(.*)$/);
					return match[2].replace(/\//g, '.').replace(/\.html/, '' ).replace(/\?/, "-");
				}
			}
		},

		qunit: {
			options: {
				timeout: 30000
			},

			files: {},

			http: {
				options: {
					urls: (function() {
						// Find the test files
						var suites = grunt.util._.without( ( grunt.option( "suites" ) || "" ).split( "," ), "" ),
							patterns, paths,
							versionedPaths = [],
							jQueries = grunt.util._.without( ( grunt.option( "jqueries" ) || "" ).split( "," ), "" );

						if ( suites.length ) {
							patterns = [];
							suites.forEach( function( unit ) {
								patterns = patterns.concat( [ "tests/unit/" + unit + "/index.html", "tests/unit/" + unit + "/*/index.html", "tests/unit/" + unit + "/**/*-tests.html" ] );
							});
						} else {
							patterns = [ "tests/unit/*/*/index.html", "tests/unit/**/*-tests.html" ];
						}

						paths = grunt.file.expand( patterns ).sort();

						if ( jQueries.length ) {
							paths.forEach( function( path ) {
								versionedPaths = versionedPaths.concat( jQueries.map( function( jQVersion ) {
									return path + "?jquery=" + jQVersion;
								}) );
							})
						}

						if ( versionedPaths.length ) {
							paths = versionedPaths;
						}

						return paths.map( function( path ) {
							return "http://localhost:<%= connect.server.options.port %>/" + path
						});
					}())
				}
			}
		},

		rsync: {
			options: {
				user: "ghislain.seguin",
				host: "localhost",
//				user: "jqadmin",
//				host: "code.origin.jquery.com",
				remoteBase: "/var/www/html/code.jquery.com/mobile/",
				cwd: "dist" //removes the dist directory from the destination
			},
			release: {
				files: {
					"jquery.mobile-<%= pkg.version %>.js": path.join( dist, "jquery.mobile.js" ),
					"jquery.mobile-<%= pkg.version %>.min.js": path.join( dist, "jquery.mobile.min.js" ),
					"jquery.mobile-<%= pkg.version %>.min.map": path.join( dist, "jquery.mobile.min.map" ),
					"jquery.mobile-<%= pkg.version %>.css": path.join( dist, "jquery.mobile.css" ),
					"jquery.mobile-<%= pkg.version %>.min.css": path.join( dist, "jquery.mobile.min.css" ),
					"jquery.mobile.structure-<%= pkg.version %>.css": path.join( dist, "jquery.mobile.structure.css" ),
					"jquery.mobile.structure-<%= pkg.version %>.min.css": path.join( dist, "jquery.mobile.structure.min.css" ),
					"jquery.mobile.structure-<%= pkg.version %>.zip": path.join( dist, "jquery.mobile.structure.min.css" )
		}
			},
			latest: {
				files: {
					"latest/": path.join( dist, "jquery.mobile.*" )
				}
			}
		},

		curl: {
			options: {
				baseUrl: "http://code.origin.jquery.com/mobile/",
				cwd: dist
			},
			latest: {
				files: {
					"latest/": path.join( dist, "jquery.mobile.*" )
				}
			}
		},

		release: {
			options: {
				versionRegExp: /^(\d)\.(\d+)\.(\d)(-(?:alpha|beta|rc)\.\d|pre)?$/
			}
		},

		clean: [ dist ]
	});

	grunt.registerTask( "js:release",  [ "requirejs", "concat:js", "uglify" ] );
	grunt.registerTask( "js", [ "config:dev", "js:release" ] );

	grunt.registerTask( "css:release", [ "cssbuild", "cssmin" ] );
	grunt.registerTask( "css", [ "config:dev", "css:release" ] );

	grunt.registerTask( "demos", [ "concat:demos", "copy:demos.firstpass", "copy:demos.secondpass", "copy:demos.unprocessed" ] );

	grunt.registerTask( "dist:release", [ "js:release", "css:release", "copy:images", "demos", "compress:dist" ] );
	grunt.registerTask( "dist", [ "config:dev", "dist:release" ] );

	grunt.registerTask( "test", [ "config:dev", "requirejs", "connect", "qunit:http" ] );
	grunt.registerTask( "test:ci", [ "qunit_junit", "connect", "qunit:http" ] );

	grunt.registerTask( "deploy:latest", [ "release:init", "release:git:status", "dist:release", "rsync:latest", "curl:latest" ] );
	grunt.registerTask( "deploy:release", [ "release:init", "release:git:status", "release:set-version", "recurse:_deploy", "release:set-next-version" ] );
	grunt.registerTask( "_deploy", [ "release:init", "release:fail-if-pre", "dist:release", "rsync:release" ] );

	// Default grunt
	grunt.registerTask( "default", [ "dist" ] );

};<|endoftext|>


<commit_before>module.exports = function(grunt) {
    grunt.loadNpmTasks('grunt-screeps');

    grunt.initConfig({
        screeps: {
            options: {
                email: '<EMAIL>',
                password: '<PASSWORD>',
                branch: 'default'
            },
            dist: {
                src: ['dist/*.js']
            }
        }
    });
}<commit_msg>Switch default branch to survival<commit_after>module.exports = function(grunt) {
    grunt.loadNpmTasks('grunt-screeps');

    grunt.initConfig({
        screeps: {
            options: {
                email: '<EMAIL>',
                password: '<PASSWORD>',
                branch: 'Survival'
            },
            dist: {
                src: ['dist/*.js']
            }
        }
    });
}
<|endoftext|>


<commit_before>module.exports = function(grunt) {
  // configuraiton for requirejs build
  var buildOptionsFile = grunt.file.read( 'build/app.build.js' );
  var buildOptions = eval( buildOptionsFile );

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    watch: {
      files: ['index.html', '**/*.css'],
      options: {
        livereload: true
      },

      scripts: {
        files: '**/*.js'
      },

      css: {
        files: '**/*.less',
        tasks: ['less']
      }
    },

    less: {
      development: {
        options: {
          paths: 'css/',
          compress: "true"
        },

        files: {
          'css/modules.css': 'css/modules.less'
        }
      }
    },

    requirejs: {
      compile: {
        options: buildOptions
      }
    },

    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: './tmp',
          dest: '../',
          src: [
          '**/*'
          // '*.{ico,png,txt,html,map}',
          // 'bower_components/bootstrap/dist/**/*',
          // 'mocks/**/*',
          // 'common/**/*',
          // 'scripts/**/*',
          // 'vendors/**/*',
          // 'styles/**/*.css',
          // 'images/{,*/}*.{webp}',
          // '**/*.less'
          ]
        }]
      }
    },

    gitcheckout: {
      dist: {
        options: {
          branch: 'gh-pages'
        }
      }
    },
    // grunt-express will serve the files from the folders listed in `bases`
    // on specified `port` and `hostname`
    express: {
      all: {
        options: {
          port: 9001,
          hostname: "0.0.0.0",
          // Replace with the directory you want the files served from
          bases: [__dirname],
          livereload: true
        }
      }
    },

    // grunt-open will open your browser at the project's URL
    open: {
      all: {
        // Gets the port from the connect configuration
        path: 'http://localhost:<%= express.all.options.port %>'
      }
    }

});

  // grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-express');
  grunt.loadNpmTasks('grunt-open');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-git');

  // grunt.registerTask('test', ['jshint', 'qunit']);
  grunt.registerTask('gitc', ['copy:dist']);

  // grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
  grunt.registerTask('build', [
    // build project
    'less',
    'requirejs',
    // checkout the branch of production
    'gitcheckout',
    // copy the build project
    'copy:dist'
    // add, commit and push
  ]);
  grunt.registerTask('serve', ['express', 'open', 'watch']);

};<commit_msg>updating dest<commit_after>module.exports = function(grunt) {
  // configuraiton for requirejs build
  var buildOptionsFile = grunt.file.read( 'build/app.build.js' );
  var buildOptions = eval( buildOptionsFile );

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    watch: {
      files: ['index.html', '**/*.css'],
      options: {
        livereload: true
      },

      scripts: {
        files: '**/*.js'
      },

      css: {
        files: '**/*.less',
        tasks: ['less']
      }
    },

    less: {
      development: {
        options: {
          paths: 'css/',
          compress: "true"
        },

        files: {
          'css/modules.css': 'css/modules.less'
        }
      }
    },

    requirejs: {
      compile: {
        options: buildOptions
      }
    },

    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '.tmp/',
          dest: './',
          src: [
          '**/*'
          // '*.{ico,png,txt,html,map}',
          // 'bower_components/bootstrap/dist/**/*',
          // 'mocks/**/*',
          // 'common/**/*',
          // 'scripts/**/*',
          // 'vendors/**/*',
          // 'styles/**/*.css',
          // 'images/{,*/}*.{webp}',
          // '**/*.less'
          ]
        }]
      }
    },

    gitcheckout: {
      dist: {
        options: {
          branch: 'gh-pages'
        }
      }
    },
    // grunt-express will serve the files from the folders listed in `bases`
    // on specified `port` and `hostname`
    express: {
      all: {
        options: {
          port: 9001,
          hostname: "0.0.0.0",
          // Replace with the directory you want the files served from
          bases: [__dirname],
          livereload: true
        }
      }
    },

    // grunt-open will open your browser at the project's URL
    open: {
      all: {
        // Gets the port from the connect configuration
        path: 'http://localhost:<%= express.all.options.port %>'
      }
    }

});

  // grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-express');
  grunt.loadNpmTasks('grunt-open');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-git');

  // grunt.registerTask('test', ['jshint', 'qunit']);
  grunt.registerTask('gitc', ['copy:dist']);

  // grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
  grunt.registerTask('build', [
    // build project
    'less',
    'requirejs',
    // checkout the branch of production
    'gitcheckout',
    // copy the build project
    'copy:dist'
    // add, commit and push
  ]);
  grunt.registerTask('serve', ['express', 'open', 'watch']);

};<|endoftext|>


<commit_before>module.exports = function (grunt) {
    grunt.initConfig({
        sass: {
            dist: {
                options: {
                    includePaths: ['bower_components/foundation/scss']
                },
                files: {
                    'public/style.css': 'src/sass/style.scss'
                }
            }
        },

        concat: {
            dist: {
                src: ['bower_components/modernizr/modernizr.js', 'bower_components/yepnope/dist/yepnope-2.0.0.js'],
                dest: 'public/head.js'
            }
        },

        copy: {
            dist: {
                files: [
                    {expand: true, cwd: 'src/font/', src: ['**'], dest: 'public/font/'},
                    {expand: true, cwd: 'src/img/', src: ['**'], dest: 'public/img/'},
                    {expand: true, cwd: 'src/static/', src: ['**'], dest: 'public/'},
                    {src: 'src/js/body.js', dest: 'public/body.js'},
                    {src: 'src/js/call-for-papers.js', dest: 'public/call-for-papers.js'},
                    {src: 'bower_components/jquery/dist/jquery.min.js', dest: 'public/jquery.js'},
                    {src: 'src/js/google-analytics.js', dest: 'public/google-analytics.js'}
                ]
            }
        },

        'imagemagick-resize': {
            people: {
                from: 'src/img/people/',
                to: 'public/img/people/',
                files: '*.jpg',
                props: {
                    width: 300,
                    quality: 0.6
                }
            },
            sponsors: {
                from: 'src/img/logo/',
                to: 'public/img/logo/',
                files: '*.png',
                props: {
                    width: 300
                }
            }
        },

        cssmin: {
            dist: {
                files: {
                    'public/style.css': ['public/style.css']
                }
            }
        },

        uglify: {
            dist: {
                files: {
                    'public/head.js': ['public/head.js'],
                    'public/body.js': ['public/body.js'],
                    'public/google-analytics.js': ['public/google-analytics.js']
                }
            }
        },

        watch: {
            sass: {
                files: '**/*.scss',
                tasks: ['sass']
            }
        }
    });

    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-imagemagick');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    grunt.registerTask('default', ['sass', 'concat', 'copy']);
    grunt.registerTask('dist', ['sass:dist', 'concat:dist', 'copy:dist', 'cssmin:dist', 'uglify:dist', 'imagemagick-resize']);
};<commit_msg>Improved gruntfile. Now jquery is added to body.js and all stuff is updated on changes (while watching).<commit_after>module.exports = function (grunt) {
    grunt.initConfig({
        sass: {
            dist: {
                options: {
                    includePaths: ['bower_components/foundation/scss']
                },
                files: {
                    'public/style.css': 'src/sass/style.scss'
                }
            }
        },

        concat: {
            dist: {
                files: {
                    'public/head.js': [
                        'bower_components/modernizr/modernizr.js',
                        'bower_components/yepnope/dist/yepnope-2.0.0.js'
                    ],
                    'public/body.js': [
                        'bower_components/jquery/dist/jquery.js',
                        'bower_components/foundation/js/foundation/foundation.topbar.js',
                        'src/js/body.js'
                    ]
                }
            }
        },

        copy: {
            dist: {
                files: [
                    {expand: true, cwd: 'src/font/', src: ['**'], dest: 'public/font/'},
                    {expand: true, cwd: 'src/img/', src: ['**'], dest: 'public/img/'},
                    {expand: true, cwd: 'src/static/', src: ['**'], dest: 'public/'},
                    {src: 'src/js/call-for-papers.js', dest: 'public/call-for-papers.js'},
                    {src: 'src/js/google-analytics.js', dest: 'public/google-analytics.js'}
                ]
            }
        },

        'imagemagick-resize': {
            people: {
                from: 'src/img/people/',
                to: 'public/img/people/',
                files: '*.jpg',
                props: {
                    width: 300,
                    quality: 0.6
                }
            },
            sponsors: {
                from: 'src/img/logo/',
                to: 'public/img/logo/',
                files: '*.png',
                props: {
                    width: 300
                }
            }
        },

        cssmin: {
            dist: {
                files: {
                    'public/style.css': ['public/style.css']
                }
            }
        },

        uglify: {
            dist: {
                files: {
                    'public/head.js': ['public/head.js'],
                    'public/body.js': ['public/body.js'],
                    'public/google-analytics.js': ['public/google-analytics.js']
                }
            }
        },

        watch: {
            sass: {
                files: '**/*.scss',
                tasks: ['sass']
            },
            concat: {
                files: 'src/js/**.*',
                tasks:['concat']
            }
        }
    });

    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-imagemagick');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    grunt.registerTask('default', ['sass', 'concat', 'copy']);
    grunt.registerTask('dist', ['sass:dist', 'concat:dist', 'copy:dist', 'cssmin:dist', 'uglify:dist', 'imagemagick-resize']);
};<|endoftext|>


<commit_before>// (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP

import React, { Component } from 'react';
import Anchor from 'grommet/components/Anchor';
import Box from 'grommet/components/Box';
import Heading from 'grommet/components/Heading';
import Paragraph from 'grommet/components/Paragraph';
import Section from 'grommet/components/Section';
import DocsTemplate from '../../components/DocsTemplate';
import { DESC as BoxDesc } from '../components/box/BoxDoc';
import { DESC as CardDesc } from '../components/card/CardDoc';
import { DESC as FooterDesc } from '../components/footer/FooterDoc';
import { DESC as HeroDesc } from '../components/hero/HeroDoc';
import { DESC as HeaderDesc } from '../components/header/HeaderDoc';
import { DESC as SectionDesc } from '../components/SectionDoc';

const COMPONENTS = [
  {
    title: 'Box',
    desc: BoxDesc
  },{
    title: 'Card',
    desc: CardDesc
  },{
    title: 'Footer',
    desc: FooterDesc
  },{
    title: 'Header',
    desc: HeaderDesc
  },{
    title: 'Hero',
    desc: HeroDesc
  },{
    title: 'Section',
    desc: SectionDesc
  }
];

export default class PrimaryPageDoc extends Component {
  render () {
    const componentsList = COMPONENTS.map(({title, desc}, index) =>
      <Box pad={{vertical:'small'}} key={`component-${index}`}>
        <Anchor label={title} path={`/docs/${title.toLowerCase()}`} />
        <Paragraph margin="small">{desc}</Paragraph>
      </Box>
    );

    return (
      <DocsTemplate title="Primary Page" exampleUrl='grommet-primary-page'
        githubUrl="https://github.com/grommet/grommet-primary-page">

          <Paragraph size="large">
            The Primary Page template is bold and impactful with a large
            Marquee, intro, and social feed. It is most effective as
            a home page or landing page and can be customized with
            components for any purpose that fits your needs.
          </Paragraph>

          <Box direction="row" pad={{between: 'small'}}>
            <Box>
              <Paragraph margin="small">
                Desktop
              </Paragraph>

            </Box>
            <Box>
              <Paragraph margin="small">
                Tablet
              </Paragraph>

            </Box>
            <Box>
              <Paragraph margin="small">
                Palm
              </Paragraph>

            </Box>
          </Box>

          <Heading tag="h3">
            Components
          </Heading>
          {componentsList}

      </DocsTemplate>
    );
  }
};
<commit_msg>Update Primary Page wireframes.<commit_after>// (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP

import React, { Component } from 'react';
import Anchor from 'grommet/components/Anchor';
import Box from 'grommet/components/Box';
import Header from 'grommet/components/Header';
import Heading from 'grommet/components/Heading';
import Label from 'grommet/components/Label';
import Paragraph from 'grommet/components/Paragraph';
import Section from 'grommet/components/Section';
import DocsTemplate from '../../components/DocsTemplate';
import { DESC as BoxDesc } from '../components/box/BoxDoc';
import { DESC as CardDesc } from '../components/card/CardDoc';
import { DESC as FooterDesc } from '../components/footer/FooterDoc';
import { DESC as HeroDesc } from '../components/hero/HeroDoc';
import { DESC as HeaderDesc } from '../components/header/HeaderDoc';
import { DESC as SectionDesc } from '../components/SectionDoc';

const COMPONENTS = [
  {
    title: 'Box',
    desc: BoxDesc
  },{
    title: 'Card',
    desc: CardDesc
  },{
    title: 'Footer',
    desc: FooterDesc
  },{
    title: 'Header',
    desc: HeaderDesc
  },{
    title: 'Hero',
    desc: HeroDesc
  },{
    title: 'Section',
    desc: SectionDesc
  }
];

export default class PrimaryPageDoc extends Component {
  render () {
    const componentsList = COMPONENTS.map(({title, desc}, index) =>
      <Box pad={{vertical:'small'}} key={`component-${index}`}>
        <Anchor label={title} path={`/docs/${title.toLowerCase()}`} />
        <Paragraph margin="small">{desc}</Paragraph>
      </Box>
    );

    return (
      <DocsTemplate title="Primary Page" exampleUrl='grommet-primary-page'
        githubUrl="https://github.com/grommet/grommet-primary-page">

          <Paragraph size="large">
            The Primary Page template is bold and impactful with a large
            Marquee, intro, and social feed. It is most effective as
            a home page or landing page and can be customized with
            components for any purpose that fits your needs.
          </Paragraph>

          <Box direction="row" pad={{between: 'small'}} wrap={true}
            responsive={false}>
            <Box>
              Desktop
              <Box separator="all">

                <Box pad="large" separator="bottom" />
                <Box colorIndex="light-2"
                  pad={{ horizontal: 'medium', vertical: 'medium',
                    between: 'medium' }}>
                  <Box colorIndex="light-1" pad="large" separator="all" />
                  <Box direction="row" pad={{ between: 'medium' }}
                    responsive={false}>
                    <Box colorIndex="light-1" basis="1/3" pad="large"
                      separator="all" />
                    <Box colorIndex="light-1" basis="1/3" pad="large"
                      separator="all" />
                    <Box colorIndex="light-1" basis="1/3" pad="large"
                      separator="all" />
                  </Box>
                </Box>
              </Box>
            </Box>
            <Box>
              Tablet
              <Box separator="all">

                <Box pad="large" separator="bottom" />
                <Box colorIndex="light-2"
                  pad={{ horizontal: 'medium', vertical: 'medium',
                    between: 'medium' }}>
                  <Box colorIndex="light-1" pad="large" separator="all" />
                  <Box direction="row" pad={{ between: 'medium' }}
                    responsive={false}>
                    <Box colorIndex="light-1" basis="1/2" pad="large"
                      separator="all" />
                    <Box colorIndex="light-1" basis="1/2" pad="large"
                      separator="all" />
                  </Box>
                </Box>
              </Box>
            </Box>
            <Box>
              <Box>
              Palm
              <Box separator="all">

                <Box pad="large" separator="bottom" />
                <Box colorIndex="light-2"
                  pad={{ horizontal: 'medium', vertical: 'medium',
                    between: 'medium' }}>
                  <Box colorIndex="light-1" pad="large" separator="all" />
                  <Box pad={{ between: 'medium' }}>
                    <Box colorIndex="light-1" pad="large"
                      separator="all" />
                    <Box colorIndex="light-1" pad="large"
                      separator="all" />
                  </Box>
                </Box>
              </Box>
            </Box>
            </Box>
          </Box>

          <Heading tag="h3">
            Components
          </Heading>
          {componentsList}

      </DocsTemplate>
    );
  }
};
<|endoftext|>


<commit_before>/* eslint-env node */
/* eslint-disable camelcase, no-console, no-param-reassign */

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

	grunt.initConfig( {

		pkg: grunt.file.readJSON( 'package.json' ),

		// Clean up the build.
		clean: {
			compiled: {
				src: [ 'assets/js/*-compiled.js' ],
			},
			build: {
				src: [ 'build' ],
			},
		},

		// Shell actions.
		shell: {
			options: {
				stdout: true,
				stderr: true,
			},
			readme: {
				command: './vendor/xwp/wp-dev-lib/scripts/generate-markdown-readme', // Generate the readme.md.
			},
			phpunit: {
				command: 'phpunit',
			},
			verify_matching_versions: {
				command: 'php bin/verify-version-consistency.php',
			},
			create_build_zip: {
				command: 'if [ ! -e build ]; then echo "Run grunt build first."; exit 1; fi; if [ -e amp.zip ]; then rm amp.zip; fi; cd build; zip -r ../amp.zip .; cd ..; echo; echo "ZIP of build: $(pwd)/amp.zip"',
			},
		},

		// Deploys a git Repo to the WordPress SVN repo.
		wp_deploy: {
			deploy: {
				options: {
					plugin_slug: 'amp',
					build_dir: 'build',
					assets_dir: 'wp-assets',
				},
			},
		},

	} );

	// Load tasks.
	grunt.loadNpmTasks( 'grunt-contrib-clean' );
	grunt.loadNpmTasks( 'grunt-contrib-copy' );
	grunt.loadNpmTasks( 'grunt-shell' );
	grunt.loadNpmTasks( 'grunt-wp-deploy' );

	// Register tasks.
	grunt.registerTask( 'default', [
		'build',
	] );

	grunt.registerTask( 'readme', [
		'shell:readme',
	] );

	grunt.registerTask( 'build', function() {
		const done = this.async();
		const spawnQueue = [];
		const stdout = [];

		spawnQueue.push(
			{
				cmd: 'git',
				args: [ '--no-pager', 'log', '-1', '--format=%h', '--date=short' ],
			},
			{
				cmd: 'git',
				args: [ 'ls-files' ],
			}
		);

		function finalize() {
			const commitHash = stdout.shift();
			const lsOutput = stdout.shift();
			const versionAppend = new Date().toISOString().replace( /\.\d+/, '' ).replace( /-|:/g, '' ) + '-' + commitHash;

			const paths = lsOutput.trim().split( /\n/ ).filter( function( file ) {
				return ! /^(blocks|\.|bin|([^/]+)+\.(md|json|xml)|Gruntfile\.js|postcss\.config\.js|tests|wp-assets|readme\.md|composer\..*|patches|webpack.*|assets\/src)/.test( file );
			} );

			paths.push( 'vendor/autoload.php' );
			paths.push( 'assets/js/*.js' );
			paths.push( 'assets/css/*.css' );
			paths.push( 'vendor/composer/**' );
			paths.push( 'vendor/sabberworm/php-css-parser/lib/**' );
			paths.push( 'vendor/fasterimage/fasterimage/src/**' );
			paths.push( 'vendor/willwashburn/stream/src/**' );

			grunt.config.set( 'copy', {
				build: {
					src: paths,
					dest: 'build',
					expand: true,
					options: {
						noProcess: [ '*/**', 'LICENSE' ], // That is, only process amp.php and readme.txt.
						process( content, srcpath ) {
							let matches, version, versionRegex;
							if ( /amp\.php$/.test( srcpath ) ) {
								versionRegex = /(\*\s+Version:\s+)(\d+(\.\d+)+-\w+)/;

								// If not a stable build (e.g. 0.7.0-beta), amend the version with the git commit and current timestamp.
								matches = content.match( versionRegex );
								if ( matches ) {
									version = matches[ 2 ] + '-' + versionAppend;
									console.log( 'Updating version in amp.php to ' + version );
									content = content.replace( versionRegex, '$1' + version );
									content = content.replace( /(define\(\s*'AMP__VERSION',\s*')(.+?)(?=')/, '$1' + version );
								}
							}
							return content;
						},
					},
				},
			} );
			grunt.task.run( 'readme' );
			grunt.task.run( 'copy' );

			done();
		}

		function doNext() {
			const nextSpawnArgs = spawnQueue.shift();
			if ( ! nextSpawnArgs ) {
				finalize();
			} else {
				grunt.util.spawn(
					nextSpawnArgs,
					function( err, res ) {
						if ( err ) {
							throw new Error( err.message );
						}
						stdout.push( res.stdout );
						doNext();
					}
				);
			}
		}

		doNext();
	} );

	grunt.registerTask( 'create-build-zip', [
		'shell:create_build_zip',
	] );

	grunt.registerTask( 'deploy', [
		'shell:phpunit',
		'shell:verify_matching_versions',
		'wp_deploy',
	] );
};
<commit_msg>Update Gruntfile<commit_after>/* eslint-env node */
/* eslint-disable camelcase, no-console, no-param-reassign */

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

	grunt.initConfig( {

		pkg: grunt.file.readJSON( 'package.json' ),

		// Clean up the build.
		clean: {
			compiled: {
				src: [ 'assets/js/*-compiled.js', 'assets/js/*.deps.json' ],
			},
			build: {
				src: [ 'build' ],
			},
		},

		// Shell actions.
		shell: {
			options: {
				stdout: true,
				stderr: true,
			},
			readme: {
				command: './vendor/xwp/wp-dev-lib/scripts/generate-markdown-readme', // Generate the readme.md.
			},
			phpunit: {
				command: 'phpunit',
			},
			verify_matching_versions: {
				command: 'php bin/verify-version-consistency.php',
			},
			create_build_zip: {
				command: 'if [ ! -e build ]; then echo "Run grunt build first."; exit 1; fi; if [ -e amp.zip ]; then rm amp.zip; fi; cd build; zip -r ../amp.zip .; cd ..; echo; echo "ZIP of build: $(pwd)/amp.zip"',
			},
		},

		// Deploys a git Repo to the WordPress SVN repo.
		wp_deploy: {
			deploy: {
				options: {
					plugin_slug: 'amp',
					build_dir: 'build',
					assets_dir: 'wp-assets',
				},
			},
		},

	} );

	// Load tasks.
	grunt.loadNpmTasks( 'grunt-contrib-clean' );
	grunt.loadNpmTasks( 'grunt-contrib-copy' );
	grunt.loadNpmTasks( 'grunt-shell' );
	grunt.loadNpmTasks( 'grunt-wp-deploy' );

	// Register tasks.
	grunt.registerTask( 'default', [
		'build',
	] );

	grunt.registerTask( 'readme', [
		'shell:readme',
	] );

	grunt.registerTask( 'build', function() {
		const done = this.async();
		const spawnQueue = [];
		const stdout = [];

		spawnQueue.push(
			{
				cmd: 'git',
				args: [ '--no-pager', 'log', '-1', '--format=%h', '--date=short' ],
			},
			{
				cmd: 'git',
				args: [ 'ls-files' ],
			}
		);

		function finalize() {
			const commitHash = stdout.shift();
			const lsOutput = stdout.shift();
			const versionAppend = new Date().toISOString().replace( /\.\d+/, '' ).replace( /-|:/g, '' ) + '-' + commitHash;

			const paths = lsOutput.trim().split( /\n/ ).filter( function( file ) {
				return ! /^(blocks|\.|bin|([^/]+)+\.(md|json|xml)|Gruntfile\.js|postcss\.config\.js|tests|wp-assets|readme\.md|composer\..*|patches|webpack.*|assets\/src)/.test( file );
			} );

			paths.push( 'vendor/autoload.php' );
			paths.push( 'assets/js/*.js' );
			paths.push( 'assets/js/*.deps.json' );
			paths.push( 'assets/css/*.css' );
			paths.push( 'vendor/composer/**' );
			paths.push( 'vendor/sabberworm/php-css-parser/lib/**' );
			paths.push( 'vendor/fasterimage/fasterimage/src/**' );
			paths.push( 'vendor/willwashburn/stream/src/**' );

			grunt.config.set( 'copy', {
				build: {
					src: paths,
					dest: 'build',
					expand: true,
					options: {
						noProcess: [ '*/**', 'LICENSE' ], // That is, only process amp.php and readme.txt.
						process( content, srcpath ) {
							let matches, version, versionRegex;
							if ( /amp\.php$/.test( srcpath ) ) {
								versionRegex = /(\*\s+Version:\s+)(\d+(\.\d+)+-\w+)/;

								// If not a stable build (e.g. 0.7.0-beta), amend the version with the git commit and current timestamp.
								matches = content.match( versionRegex );
								if ( matches ) {
									version = matches[ 2 ] + '-' + versionAppend;
									console.log( 'Updating version in amp.php to ' + version );
									content = content.replace( versionRegex, '$1' + version );
									content = content.replace( /(define\(\s*'AMP__VERSION',\s*')(.+?)(?=')/, '$1' + version );
								}
							}
							return content;
						},
					},
				},
			} );
			grunt.task.run( 'readme' );
			grunt.task.run( 'copy' );

			done();
		}

		function doNext() {
			const nextSpawnArgs = spawnQueue.shift();
			if ( ! nextSpawnArgs ) {
				finalize();
			} else {
				grunt.util.spawn(
					nextSpawnArgs,
					function( err, res ) {
						if ( err ) {
							throw new Error( err.message );
						}
						stdout.push( res.stdout );
						doNext();
					}
				);
			}
		}

		doNext();
	} );

	grunt.registerTask( 'create-build-zip', [
		'shell:create_build_zip',
	] );

	grunt.registerTask( 'deploy', [
		'shell:phpunit',
		'shell:verify_matching_versions',
		'wp_deploy',
	] );
};
<|endoftext|>


<commit_before>/*global module:false*/
"use strict";
module.exports = function(grunt) {
  require("time-grunt")(grunt);
  require("load-grunt-tasks")(grunt);

  grunt.initConfig({
    pkg: grunt.file.readJSON("package.json"),
    banner : [
      "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ",
      "<%= grunt.template.today('yyyy-mm-dd') %>\n",
      "<%= pkg.homepage ? '* ' + pkg.homepage + '\\n' : '' %>",
      "* Copyright (c) <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>;",
      " Licensed <%= _.pluck(pkg.licenses, 'type').join(", ") %> */\n"
    ].join(""),
    jshint: {
      files: ["Gruntfile.js", "*.js", "src/**/*.js" ],
      options: {
        jshintrc: true,
        reporter: require("jshint-stylish")
      }
    },
    concat: {
      options: {
        banner: "<%=banner%>\"use strict\";\n",
        process : function(src) {
          src = src.replace(/(^|\n)[ \t]*('use strict'|"use strict");?\s*/g, "$1"); // remove "use strict";
          src = src.replace(/#__VERSION__#/g, grunt.config.data.pkg.version); // change version;
          return src;
        }
      },
      build: {
        src: ["src/polyfill/**/*.js", "src/module.js", "src/eg.js", "src/customEvent/*.js", "src/class.js", "src/component.js", "src/movableCoord.js", "src/flicking.js", "src/*.js" ],
        dest: "dist/<%=pkg.outputname%>.js"
      },
    },
    uglify: {
      options: {
        banner: "<%=banner%>"
      },
      dist : {
        src: "dist/<%=pkg.outputname%>.js",
        dest: "dist/<%=pkg.outputname%>.min.js"
      }
    },
    copy : {
      lib : {
        expand : true,
        flatten : true,
        src : [
            "bower_components/jquery/jquery.js",
            "bower_components/hammer.js/hammer.js",
            "bower_components/jquery.easing/js/jquery.easing.js",
          ],
        dest : "dist/lib"
      },
      doc : {
        files: [
          {expand : true, flatten : true, src: ["node_modules/egjs-jsdoc-template/jsdoc-plugin/*.*"], dest: "node_modules/grunt-jsdoc/node_modules/jsdoc/plugins"}
        ]
      }
    },
    qunit : {
      options : {
        timeout : 10000,
        "--web-security": "no",
        coverage: {
          disposeCollector: true,
          src: ["src/**/*.js"],
          instrumentedFiles: "temp/",
          htmlReport: "report",
          coberturaReport: "report",
          linesThresholdPct: 0
        }
      }
    },
    watch : {
      source : {
        files : [ "src/**/*.js"],
        tasks : [ "build" ],
        options : {
          spawn : false
        }
      }
    },
    jsdoc : {
        dist : {
            src: ["src/**/*.js", "README.md"],
            options: {
                destination: "doc",
                template : "node_modules/jsdoc-template-jsdoc",
                configure : "jsdoc.json"
            }
        }
    }
  });

  grunt.registerTask("test", function() {
    var eachfile = Array.prototype.slice.apply(arguments);
    if(eachfile.length) {
      eachfile = eachfile.map(function(v) {
        return "test/" + v + ".test.html";
      }, this);
    } else {
        eachfile.push("test/*.test.html");
    }
    grunt.config.set("qunit.each", eachfile);
    grunt.log.oklns(grunt.config.get("qunit.each"));
    grunt.task.run("qunit:each");
  });

  grunt.registerTask("docBuild", ["copy:doc", "jsdoc"]);
  grunt.registerTask("build", ["concat", "uglify", "copy:lib", "docBuild"]);
  grunt.registerTask("default", ["jshint", "test", "build"]);
};
<commit_msg>Fix (Gruntfile) : Fix jsdoc template name<commit_after>/*global module:false*/
"use strict";
module.exports = function(grunt) {
  require("time-grunt")(grunt);
  require("load-grunt-tasks")(grunt);

  grunt.initConfig({
    pkg: grunt.file.readJSON("package.json"),
    banner : [
      "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ",
      "<%= grunt.template.today('yyyy-mm-dd') %>\n",
      "<%= pkg.homepage ? '* ' + pkg.homepage + '\\n' : '' %>",
      "* Copyright (c) <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>;",
      " Licensed <%= _.pluck(pkg.licenses, 'type').join(", ") %> */\n"
    ].join(""),
    jshint: {
      files: ["Gruntfile.js", "*.js", "src/**/*.js" ],
      options: {
        jshintrc: true,
        reporter: require("jshint-stylish")
      }
    },
    concat: {
      options: {
        banner: "<%=banner%>\"use strict\";\n",
        process : function(src) {
          src = src.replace(/(^|\n)[ \t]*('use strict'|"use strict");?\s*/g, "$1"); // remove "use strict";
          src = src.replace(/#__VERSION__#/g, grunt.config.data.pkg.version); // change version;
          return src;
        }
      },
      build: {
        src: ["src/polyfill/**/*.js", "src/module.js", "src/eg.js", "src/customEvent/*.js", "src/class.js", "src/component.js", "src/movableCoord.js", "src/flicking.js", "src/*.js" ],
        dest: "dist/<%=pkg.outputname%>.js"
      },
    },
    uglify: {
      options: {
        banner: "<%=banner%>"
      },
      dist : {
        src: "dist/<%=pkg.outputname%>.js",
        dest: "dist/<%=pkg.outputname%>.min.js"
      }
    },
    copy : {
      lib : {
        expand : true,
        flatten : true,
        src : [
            "bower_components/jquery/jquery.js",
            "bower_components/hammer.js/hammer.js",
            "bower_components/jquery.easing/js/jquery.easing.js",
          ],
        dest : "dist/lib"
      },
      doc : {
        files: [
          {expand : true, flatten : true, src: ["node_modules/egjs-jsdoc-template/jsdoc-plugin/*.*"], dest: "node_modules/grunt-jsdoc/node_modules/jsdoc/plugins"}
        ]
      }
    },
    qunit : {
      options : {
        timeout : 10000,
        "--web-security": "no",
        coverage: {
          disposeCollector: true,
          src: ["src/**/*.js"],
          instrumentedFiles: "temp/",
          htmlReport: "report",
          coberturaReport: "report",
          linesThresholdPct: 0
        }
      }
    },
    watch : {
      source : {
        files : [ "src/**/*.js"],
        tasks : [ "build" ],
        options : {
          spawn : false
        }
      }
    },
    jsdoc : {
        dist : {
            src: ["src/**/*.js", "README.md"],
            options: {
                destination: "doc",
                template : "node_modules/egjs-jsdoc-template",
                configure : "jsdoc.json"
            }
        }
    }
  });

  grunt.registerTask("test", function() {
    var eachfile = Array.prototype.slice.apply(arguments);
    if(eachfile.length) {
      eachfile = eachfile.map(function(v) {
        return "test/" + v + ".test.html";
      }, this);
    } else {
        eachfile.push("test/*.test.html");
    }
    grunt.config.set("qunit.each", eachfile);
    grunt.log.oklns(grunt.config.get("qunit.each"));
    grunt.task.run("qunit:each");
  });

  grunt.registerTask("docBuild", ["copy:doc", "jsdoc"]);
  grunt.registerTask("build", ["concat", "uglify", "copy:lib", "docBuild"]);
  grunt.registerTask("default", ["jshint", "test", "build"]);
};
<|endoftext|>


<commit_before>module.exports = function(grunt) {

  grunt.initConfig({
    'json-minify': {
      build: {
        files: 'dist/mathmaps/**/*.json'
      }
    },
    gitclone: {
      'speech-rule-engine': {
        options: {
          repository: 'https://github.com/zorkow/speech-rule-engine.git',
          branch: 'v1.0.1',
          cwd: "."
        }
      }
    },
    'uglify': {
      mathmaps: {
        files: {
          'dist/mathmaps/mathmaps_ie.js': 'dist/mathmaps/mathmaps_ie.js'
        }
      },
      build: {
        files: {
          'dist/accessibility-menu.js': 'extensions/accessibility-menu.js',
          'dist/explorer.js': 'extensions/explorer.js',
          'dist/auto-collapse.js': 'extensions/auto-collapse.js',
          'dist/collapsible.js': 'extensions/collapsible.js',
          'dist/semantic-enrich.js': 'extensions/semantic-enrich.js'
        },
        options: {
          beautify: {
            ascii_only: true
          }
        }
      }
    },
    shell: {
      clean_dist: {
        command: 'rm -rf dist'
      },
      make_dist: {
        command: 'mkdir -p dist'
      },
      clean_sre: {
        command: 'rm -rf speech-rule-engine'
      },
      clean_node: {
        command: 'rm -rf node_modules'
      },
      prepare: {
        command: [
          '<%= shell.clean_dist.command %>',
          '<%= shell.make_dist.command %>'
        ].join('&&')
      },
      clean: {
        command: [
          '<%= shell.clean_node.command %>',
          '<%= shell.clean_sre.command %>',
          '<%= shell.clean_dist.command %>'
        ].join('&&')
      },
      compile: {
        command: [
          'npm install',
          'npm install --only=dev',
          'npm install wicked-good-xpath',
          'make mathjax'
        ].join('&&'),
        options: {
          execOptions: {
            cwd: 'speech-rule-engine'
          }
        }
      },
      copy: [
        'cp speech-rule-engine/lib/mathjax-sre.js dist/mathjax-sre.js',
        'cp speech-rule-engine/node_modules/wicked-good-xpath/dist/wgxpath.install.js dist/',
        'cp -R speech-rule-engine/src/mathmaps dist/',
        'cp extensions/*.ogg dist/',
        'cp extensions/*.mp3 dist/',
        'rm dist/mathmaps/math_map.js'
      ].join('&&')
    }
  });

  // Cloning git repos.
  grunt.loadNpmTasks('grunt-git');
  // Run shell commands.
  grunt.loadNpmTasks('grunt-shell');
  // Minify JSON files.
  grunt.loadNpmTasks('grunt-json-minify');
  // Minify regular files.
  grunt.loadNpmTasks('grunt-contrib-uglify');

  grunt.registerTask('default', [
    'shell:prepare',
    'gitclone',
    'shell:compile',
    'shell:copy',
    'json-minify',
    'uglify',
    'shell:clean_sre'
  ]);

};
<commit_msg>Moves to SRE v1.1.0<commit_after>module.exports = function(grunt) {

  grunt.initConfig({
    'json-minify': {
      build: {
        files: 'dist/mathmaps/**/*.json'
      }
    },
    gitclone: {
      'speech-rule-engine': {
        options: {
          repository: 'https://github.com/zorkow/speech-rule-engine.git',
          branch: 'v1.1.0',
          cwd: "."
        }
      }
    },
    'uglify': {
      mathmaps: {
        files: {
          'dist/mathmaps/mathmaps_ie.js': 'dist/mathmaps/mathmaps_ie.js'
        }
      },
      build: {
        files: {
          'dist/accessibility-menu.js': 'extensions/accessibility-menu.js',
          'dist/explorer.js': 'extensions/explorer.js',
          'dist/auto-collapse.js': 'extensions/auto-collapse.js',
          'dist/collapsible.js': 'extensions/collapsible.js',
          'dist/semantic-enrich.js': 'extensions/semantic-enrich.js'
        },
        options: {
          beautify: {
            ascii_only: true
          }
        }
      }
    },
    shell: {
      clean_dist: {
        command: 'rm -rf dist'
      },
      make_dist: {
        command: 'mkdir -p dist'
      },
      clean_sre: {
        command: 'rm -rf speech-rule-engine'
      },
      clean_node: {
        command: 'rm -rf node_modules'
      },
      prepare: {
        command: [
          '<%= shell.clean_dist.command %>',
          '<%= shell.make_dist.command %>'
        ].join('&&')
      },
      clean: {
        command: [
          '<%= shell.clean_node.command %>',
          '<%= shell.clean_sre.command %>',
          '<%= shell.clean_dist.command %>'
        ].join('&&')
      },
      compile: {
        command: [
          'npm install',
          'npm install --only=dev',
          'npm install wicked-good-xpath',
          'make mathjax'
        ].join('&&'),
        options: {
          execOptions: {
            cwd: 'speech-rule-engine'
          }
        }
      },
      copy: [
        'cp speech-rule-engine/lib/mathjax-sre.js dist/mathjax-sre.js',
        'cp speech-rule-engine/node_modules/wicked-good-xpath/dist/wgxpath.install.js dist/',
        'cp -R speech-rule-engine/src/mathmaps dist/',
        'cp extensions/*.ogg dist/',
        'cp extensions/*.mp3 dist/',
        'rm dist/mathmaps/math_map.js'
      ].join('&&')
    }
  });

  // Cloning git repos.
  grunt.loadNpmTasks('grunt-git');
  // Run shell commands.
  grunt.loadNpmTasks('grunt-shell');
  // Minify JSON files.
  grunt.loadNpmTasks('grunt-json-minify');
  // Minify regular files.
  grunt.loadNpmTasks('grunt-contrib-uglify');

  grunt.registerTask('default', [
    'shell:prepare',
    'gitclone',
    'shell:compile',
    'shell:copy',
    'json-minify',
    'uglify',
    'shell:clean_sre'
  ]);

};
<|endoftext|>


<commit_before>var child_process = require('child_process');

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

  require('load-grunt-tasks')(grunt);

  var pkg = require('./package.json');
  var protractorConfig = grunt.option('protractorConfig') || 'camunda-webapp-test/ci.conf.js';

  var config = pkg.gruntConfig || {};

  config.grunt = grunt;
  config.pkg = pkg;
  config.protractorConfig = protractorConfig;

  var browserifyConf = { };

  require('./grunt/config/browserify')(config, browserifyConf);
  require('./ui/admin/grunt/config/browserify')(config, browserifyConf);
  require('./ui/tasklist/grunt/config/browserify')(config, browserifyConf);
  require('./ui/cockpit/grunt/config/browserify')(config, browserifyConf);

  var copyConf = require('./grunt/config/copy');
  require('./ui/admin/grunt/config/copy')(config, copyConf);
  require('./ui/cockpit/grunt/config/copy')(config, copyConf);
  require('./ui/tasklist/grunt/config/copy')(config, copyConf);

  var lessConf = { };
  require('./grunt/config/less')(config, lessConf, {
    appName: 'admin',
    sourceDir: pkg.gruntConfig.adminSourceDir,
    buildTarget: pkg.gruntConfig.adminBuildTarget,
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'cockpit',
    sourceDir: pkg.gruntConfig.cockpitSourceDir,
    buildTarget: pkg.gruntConfig.cockpitBuildTarget,
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.tasklistSourceDir,
    buildTarget: pkg.gruntConfig.tasklistBuildTarget,
  });

  var localesConf = { };
  require('./grunt/config/localescompile')(config, localesConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.tasklistSourceDir,
    buildTarget: pkg.gruntConfig.tasklistBuildTarget,
  });

  var watchConf = {
    commons_styles: {
      options: {
        liverreload: false,
      },
      files: ['node_modules/camunda-commons-ui/{lib,resources}/**/*.less'],
      tasks: ['less']
    }
  };
  require('./ui/tasklist/grunt/config/watch')(config, watchConf);
  require('./ui/cockpit/grunt/config/watch')(config, watchConf);
  require('./ui/admin/grunt/config/watch')(config, watchConf);

  var uglifyConf = {};
  require('./grunt/config/uglify')(config, uglifyConf);
  require('./ui/admin/grunt/config/uglify')(config, uglifyConf);
  require('./ui/tasklist/grunt/config/uglify')(config, uglifyConf);
  require('./ui/cockpit/grunt/config/uglify')(config, uglifyConf);

  grunt.initConfig({
    buildMode:        'dev',

    pkg:              pkg,

    browserify:       browserifyConf,

    copy:             copyConf,

    less:             lessConf,

    localescompile:   localesConf,

    uglify:           uglifyConf,

    clean:            require('./grunt/config/clean')(config),

    watch:            watchConf,

    protractor:       require('./grunt/config/protractor')(config)
  });

  require('camunda-commons-ui/grunt/tasks/localescompile')(grunt);

  grunt.registerTask('build', function(mode, app) {

    if(typeof app !== 'undefined') {
      console.log(' ------------  will build ' + app + ' -------------');
      var objs = [browserifyConf, copyConf, lessConf, localesConf, watchConf, uglifyConf];
      for(var i = 0; i < objs.length; i++) {
        var obj = objs[i];
        for (var key in obj) {
          if (obj.hasOwnProperty(key) && key.toLowerCase().indexOf(app) === -1 && key !== 'options' &&
                                         key.toLowerCase().indexOf('webapp') === -1 &&
                                         key.toLowerCase().indexOf('sdk') === -1) {
              delete obj[key];
          }
        }
      }
    }

    grunt.config.data.buildMode = mode || 'prod';

    var tasksToRun = [
      'clean',
      'browserify',
      'copy',
      'less'
    ];

    if(typeof app === 'undefined' || app === 'tasklist') {
      tasksToRun.push('localescompile');
    }

    if(grunt.config.data.buildMode === 'prod') {
      tasksToRun.push('uglify');
    }

    grunt.task.run(tasksToRun);

  });

  grunt.registerTask('auto-build', function(app) {
    if(app) {
      grunt.task.run([
        'build:dev:' + app,
        'watch'
      ]);
    } else {
      grunt.task.run([
        'build:dev',
        'watch'
      ]);
    }
  });

  grunt.registerTask('ensureSelenium', function() {
    // async task
    var done = this.async();

    child_process.execFile('node', [__dirname + '/node_modules/grunt-protractor-runner/node_modules/protractor/bin/webdriver-manager', '--chrome', 'update'], function(err) {
      done();
    });
  });

  grunt.registerTask('default', ['build']);

  grunt.registerTask('test-e2e', ['ensureSelenium', 'protractor:e2e']);
};
<commit_msg>fix(tests): use correct path to ci.conf<commit_after>var child_process = require('child_process');

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

  require('load-grunt-tasks')(grunt);

  var pkg = require('./package.json');
  var protractorConfig = grunt.option('protractorConfig') || 'ui/common/tests/ci.conf.js';

  var config = pkg.gruntConfig || {};

  config.grunt = grunt;
  config.pkg = pkg;
  config.protractorConfig = protractorConfig;

  var browserifyConf = { };

  require('./grunt/config/browserify')(config, browserifyConf);
  require('./ui/admin/grunt/config/browserify')(config, browserifyConf);
  require('./ui/tasklist/grunt/config/browserify')(config, browserifyConf);
  require('./ui/cockpit/grunt/config/browserify')(config, browserifyConf);

  var copyConf = require('./grunt/config/copy');
  require('./ui/admin/grunt/config/copy')(config, copyConf);
  require('./ui/cockpit/grunt/config/copy')(config, copyConf);
  require('./ui/tasklist/grunt/config/copy')(config, copyConf);

  var lessConf = { };
  require('./grunt/config/less')(config, lessConf, {
    appName: 'admin',
    sourceDir: pkg.gruntConfig.adminSourceDir,
    buildTarget: pkg.gruntConfig.adminBuildTarget,
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'cockpit',
    sourceDir: pkg.gruntConfig.cockpitSourceDir,
    buildTarget: pkg.gruntConfig.cockpitBuildTarget,
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.tasklistSourceDir,
    buildTarget: pkg.gruntConfig.tasklistBuildTarget,
  });

  var localesConf = { };
  require('./grunt/config/localescompile')(config, localesConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.tasklistSourceDir,
    buildTarget: pkg.gruntConfig.tasklistBuildTarget,
  });

  var watchConf = {
    commons_styles: {
      options: {
        liverreload: false,
      },
      files: ['node_modules/camunda-commons-ui/{lib,resources}/**/*.less'],
      tasks: ['less']
    }
  };
  require('./ui/tasklist/grunt/config/watch')(config, watchConf);
  require('./ui/cockpit/grunt/config/watch')(config, watchConf);
  require('./ui/admin/grunt/config/watch')(config, watchConf);

  var uglifyConf = {};
  require('./grunt/config/uglify')(config, uglifyConf);
  require('./ui/admin/grunt/config/uglify')(config, uglifyConf);
  require('./ui/tasklist/grunt/config/uglify')(config, uglifyConf);
  require('./ui/cockpit/grunt/config/uglify')(config, uglifyConf);

  grunt.initConfig({
    buildMode:        'dev',

    pkg:              pkg,

    browserify:       browserifyConf,

    copy:             copyConf,

    less:             lessConf,

    localescompile:   localesConf,

    uglify:           uglifyConf,

    clean:            require('./grunt/config/clean')(config),

    watch:            watchConf,

    protractor:       require('./grunt/config/protractor')(config)
  });

  require('camunda-commons-ui/grunt/tasks/localescompile')(grunt);

  grunt.registerTask('build', function(mode, app) {

    if(typeof app !== 'undefined') {
      console.log(' ------------  will build ' + app + ' -------------');
      var objs = [browserifyConf, copyConf, lessConf, localesConf, watchConf, uglifyConf];
      for(var i = 0; i < objs.length; i++) {
        var obj = objs[i];
        for (var key in obj) {
          if (obj.hasOwnProperty(key) && key.toLowerCase().indexOf(app) === -1 && key !== 'options' &&
                                         key.toLowerCase().indexOf('webapp') === -1 &&
                                         key.toLowerCase().indexOf('sdk') === -1) {
              delete obj[key];
          }
        }
      }
    }

    grunt.config.data.buildMode = mode || 'prod';

    var tasksToRun = [
      'clean',
      'browserify',
      'copy',
      'less'
    ];

    if(typeof app === 'undefined' || app === 'tasklist') {
      tasksToRun.push('localescompile');
    }

    if(grunt.config.data.buildMode === 'prod') {
      tasksToRun.push('uglify');
    }

    grunt.task.run(tasksToRun);

  });

  grunt.registerTask('auto-build', function(app) {
    if(app) {
      grunt.task.run([
        'build:dev:' + app,
        'watch'
      ]);
    } else {
      grunt.task.run([
        'build:dev',
        'watch'
      ]);
    }
  });

  grunt.registerTask('ensureSelenium', function() {
    // async task
    var done = this.async();

    child_process.execFile('node', [__dirname + '/node_modules/grunt-protractor-runner/node_modules/protractor/bin/webdriver-manager', '--chrome', 'update'], function(err) {
      done();
    });
  });

  grunt.registerTask('default', ['build']);

  grunt.registerTask('test-e2e', ['ensureSelenium', 'protractor:e2e']);
};
<|endoftext|>


<commit_before>var _ = require('lodash');

module.exports = function(grunt) {
  grunt.initConfig  ({

    less: {
      options: {
        ieCompat: true
      },
      files: {
        expand: true,
        cwd: 'app/less/',
        src: '*.less',
        dest: 'app/css/',
        ext: '.css'
      }
    },

    connect: {
      development: {
        options: {
          port: process.env.PORT || 8083,
          base: './app',
          livereload: true,

          middleware: function(connect, options, middlewares) {
            var morgan = require('morgan')

            middlewares.unshift(morgan('dev'))
            return middlewares;
          }
        }
      },
      heroku: {
        options: {
          port: process.env.PORT,
          base: './app',
          keepalive: true
        }
      }
    },

    watch: {
      css: {
        files: 'app/less/*.less',
        tasks: ['less'],
        options: {
          livereload: true
        }
      },
      template: {
        files: 'app/index.html.template',
        tasks: ['template']
      },
      config: {
        files: 'config/modulusui.conf.js',
        tasks: 'config'
      }
    }
  })

  grunt.loadNpmTasks('grunt-contrib-less')
  grunt.loadNpmTasks('grunt-contrib-watch')
  grunt.loadNpmTasks('grunt-contrib-connect')

  grunt.registerTask('default', ['build'])
  grunt.registerTask('serve', ['build', 'connect:development', 'watch'])
  grunt.registerTask('heroku', ['connect:heroku'])
  grunt.registerTask('build', ['config', 'less'])

  grunt.registerTask('config', function() {

    var config = require('./config/modulusui.conf.js');
    var env = {
      conf: process.env.MODULUS_UI_CONF || process.env.BAMBOO_MODULUS_UI_CONF,
      base: process.env.MODULUS_API_BASE_URL ||
        process.env.BAMBOO_MODULUS_API_BASE_URL,
      readOnly: process.env.MODULUS_API_READ_ONLY ||
        process.env.BAMBOO_MODULUS_API_READ_ONLY
    };

    if (env.conf) {
      try {
        var override = JSON.parse(env.conf);
        config = _.assign(config, override);
      } catch (error) {
        grunt.log.error("Failed to parse configuration in MODULUS_UI_CONF " +
          "environment variable.");
      }
    }

    if (env.base) {
      config.api.baseUrl = env.base;
    }

    if (env.readOnly) {
      config.api.readOnly = env.readOnly;
    }

    var contents = "angular.module('modulusOne').constant('Config', " +
      JSON.stringify(config) + ");"
    grunt.file.write('app/js/config.js', contents);

    grunt.log.writeln("Wrote current configuration to app/js/config.js");
  })
}<commit_msg>Bamboo uses lowercase characters in env variables<commit_after>var _ = require('lodash');

module.exports = function(grunt) {
  grunt.initConfig  ({

    less: {
      options: {
        ieCompat: true
      },
      files: {
        expand: true,
        cwd: 'app/less/',
        src: '*.less',
        dest: 'app/css/',
        ext: '.css'
      }
    },

    connect: {
      development: {
        options: {
          port: process.env.PORT || 8083,
          base: './app',
          livereload: true,

          middleware: function(connect, options, middlewares) {
            var morgan = require('morgan')

            middlewares.unshift(morgan('dev'))
            return middlewares;
          }
        }
      },
      heroku: {
        options: {
          port: process.env.PORT,
          base: './app',
          keepalive: true
        }
      }
    },

    watch: {
      css: {
        files: 'app/less/*.less',
        tasks: ['less'],
        options: {
          livereload: true
        }
      },
      template: {
        files: 'app/index.html.template',
        tasks: ['template']
      },
      config: {
        files: 'config/modulusui.conf.js',
        tasks: 'config'
      }
    }
  })

  grunt.loadNpmTasks('grunt-contrib-less')
  grunt.loadNpmTasks('grunt-contrib-watch')
  grunt.loadNpmTasks('grunt-contrib-connect')

  grunt.registerTask('default', ['build'])
  grunt.registerTask('serve', ['build', 'connect:development', 'watch'])
  grunt.registerTask('heroku', ['connect:heroku'])
  grunt.registerTask('build', ['config', 'less'])

  grunt.registerTask('config', function() {

    var config = require('./config/modulusui.conf.js');
    var env = {
      conf: process.env.MODULUS_UI_CONF || process.env.bamboo_MODULUS_UI_CONF,
      base: process.env.MODULUS_API_BASE_URL ||
        process.env.bamboo_MODULUS_API_BASE_URL,
      readOnly: process.env.MODULUS_API_READ_ONLY ||
        process.env.bamboo_MODULUS_API_READ_ONLY
    };

    console.log(env)

    if (env.conf) {
      try {
        var override = JSON.parse(env.conf);
        config = _.assign(config, override);
      } catch (error) {
        grunt.log.error("Failed to parse configuration in MODULUS_UI_CONF " +
          "environment variable.");
      }
    }

    if (env.base) {
      config.api.baseUrl = env.base;
    }

    if (env.readOnly) {
      config.api.readOnly = env.readOnly;
    }

    var contents = "angular.module('modulusOne').constant('Config', " +
      JSON.stringify(config) + ");"
    grunt.file.write('app/js/config.js', contents);

    grunt.log.writeln("Wrote current configuration to app/js/config.js");
  })
}<|endoftext|>


<commit_before>var request = require("request");
var AdmZip = require('adm-zip');
var fs = require("fs");

var dataCacheDir = __dirname + "/data/";
var dataFile = dataCacheDir + "/appState.json";

var headers = null;
var appData = null;

// write app data so we know the state of our app content and can upgrade incrementally
function SaveAppContent(cb)
{
	fs.writeFile(dataFile, JSON.stringify({
		headers: headers,
		appData: appData
	}, null, 2), cb);
}

// restore app content we've already fetched
function RestoreAppContent(cb)
{
	if (headers != null && appData != null)
	{
		return cb();
	}

	fs.exists(dataFile, function(e) {
		if (e)
		{
			fs.readFile(dataFile, function(err, data) {
				var json;
				try
				{
					json = JSON.parse(data);
				}
				catch(e)
				{
					// delete data file if it's not parsing (update from scratch!)
					fs.unlinkSync(dataFile);
					headers = {};
				}

				if (json && json.headers && json.appData)
				{
					headers = json.headers;
					appData = json.appData;
				}
				else
				{
					headers = {};
					appData = {};
				}

				return cb();
			});
		}
		else
		{
			headers = {};
			appData = {};
			return cb();
		}
	});
}

// attraction content IDs
var attractionIDs = [
	1, // attractions
	2, // shops
	3, // hotels
	4, // characters
	5, // shows
	6, // parades
	7, // restaurants
	8, // other (ATM machines etc.)
	9, // bars
];

function FetchContentList(ids, loc_id, cb)
{
	var step = function()
	{
		var c = ids.shift();
		if (!c)
		{
			return cb(null, true);
		}

		UpdateContent(c, loc_id, function(err, data) {
			process.nextTick(step);
		});
	};
	process.nextTick(step);
}

function UpdateContent(content_id, loc_id, cb)
{
	// make sure we've restored our app content first
	RestoreAppContent(function() {
		// default loc_id to 0
		if (typeof(loc_id) == "function")
		{
			cb = loc_id;
			loc_id = 0;
		}

		// create a fresh header to pull the full app data
		var header = {tp: content_id, lg: loc_id, s: 0, h1: 0, h2: 0};
		// ... unless there is a saved header from our last fetch! Then use that instad
		if (headers[ content_id ]) header = headers[ content_id ];

		// goto cache if fetched in last two hours
		if (appData[ content_id ] && appData[ content_id ].updated > ( Date.now() - 1000 * 60 * 60 * 2 ))
		{
			console.log("Using cached content pack " + content_id + ".");
			return cb(null, appData[ content_id ].data);
		}

		GetUpdateList(header, function(err, data) {
			if (err) return console.log(err);

			// if there is anything (usually just a 0) in the array, we have an update to download!
			if (data.a.length == 1)
			{
				console.log("New content diffs for content pack " + content_id + " are available! Fetching...");
				GetUpdate(header, function(err, data) {
					if (err) return console.error(err);

					// save content_id header
					headers[ content_id ] = data.h;

					// store our content
					if (appData[ content_id ])
					{
						// merge into existing content!
						if (data.l)
						{
							for(var i=0; i<data.l.length; i++)
							{
								// first check if the item already exists in our data set
								var replaced = false;
								for(var j=0; j<appData[ content_id ].data.j.length; j++)
								{
									if (appData[ content_id ].data.l[i])
									{
										if (appData[ content_id ].data.l[i][0] == data.l[i][0])
										{
											console.log("Overwriting item " + data.l[i][0] + " in content pack " + content_id);

											// item already exists! replace it
											appData[ content_id ].data.l[i] = data.l[i];
											replaced = true;
											break;
										}
									}
								}

								// otherwise, push onto the end!
								if (!replaced)
								{
									console.log("Adding new item " + data.l[i][0] + " to content pack " + content_id);

									appData[ content_id ].data.l.push(data.l[i]);
								}
							}

							// mark object as updated
							appData[ content_id ].updated = Date.now();
						}
					}
					else
					{
						appData[ content_id ] = {
							data: data,
							updated: Date.now()
						};
					}

					// save app state
					SaveAppContent(function() {
						cb(null, data);
					});
				});
			}
			else
			{
				console.log("Server has no updates for content pack " + content_id + ".");

				// mark cache as updated
				if (appData[ content_id ]) appData[ content_id ].updated = Date.now();

				// save app state with updated cache timer
				SaveAppContent(function() {

					// no updated data to fetch, so return cached data
					return cb(null, appData[ content_id ].data);

				});
			}
		});
	});
}

function GetUpdateList(headers, cb)
{
	headers = [].concat(headers);

	GetParisURL("http://disney.cms.pureagency.com/cms/ProxyContentList", {
		l: headers
	}, function(err, body) {
		return cb(null, JSON.parse(body.toString()));
	});
}

function GetParisURL(url, json, cb)
{
	var form = {key: "Ajjjsh;Uj"};

	if (json)
	{
		form.json = JSON.stringify(json);
	}

	request({
		url: url,
		method: "POST",
		headers: {
			'User-Agent': 'Disneyland 1.0 (iPhone; iPhone OS 4.1; en_GB)',
	        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
		},
		form: form,
		strictSSL: false,
		encoding: null
	}, function(err, resp, body) {
		if (err) return cb(err);

		return cb(null, body);
	});
}

function GetUpdate(headers, cb)
{
	// make sure we've restored our app content first
	RestoreAppContent(function() {
		GetParisURL("http://disney.cms.pureagency.com/cms/ProxyContent", headers, function(err, body) {
			if (err)
			{
				console.log("ERROR: " + err);
				return cb(err);
			}

			try
			{
				var zip = new AdmZip(body);
			}
			catch(e)
			{
				console.error("ERROR READING ZIP FOR " + JSON.stringify(headers));
				return;
			}

			var files = zip.getEntries();

			for(var i=0; i<files.length; i++)
			{
				return cb(null, JSON.parse(zip.readAsText(files[i].entryName)));
			}

			return cb("No data found");
		});
	});
}

// store ride names
var rideNames = null;
function CacheRideNames(cb)
{
	if (rideNames) return cb(null, true);

	UpdateContent(1, 2, function(err, data) {
		if (err) return cb(err);

		if (data && data.l)
		{
			rideNames = {};

			for(var i=0; i<data.l.length; i++)
			{
				rideNames[ data.l[i][12] ] = {
					name: data.l[i][1],
					desc: data.l[i][11]
				};
			}

			return cb(null, true);
		}
		else
		{
			cb("No ride name data found");
		}
	});
}

function GetRideTimes(cb)
{
	// make sure we've restored our app content first
	RestoreAppContent(function() {
		console.log("Fetching live ride times...");

		GetParisURL("http://disney.cms.pureagency.com/cms/ProxyTempsAttente", null, function(err, body) {
			if (err)
			{
				console.log("ERROR: " + err);
				return cb(err);
			}

			try
			{
				var zip = new AdmZip(body);
			}
			catch(e)
			{
				console.error("ERROR READING ZIP FOR RIDE TIMES");
				return;
			}

			var files = zip.getEntries();

			for(var i=0; i<files.length; i++)
			{
				var data = JSON.parse(zip.readAsText(files[i].entryName));

				if (data && data.l)
				{
					// make sure we have all our ride names before building our result object
					CacheRideNames(function(err, res) {
						if (err) return console.error(err);

						var rides = [];

						for(var i=0; i<data.l.length; i+=5)
						{
							rides.push({
								id: data.l[i],
								name: rideNames[ data.l[i] ] ? rideNames[ data.l[i] ].name : "UNKNOWN",
								openingTime: data.l[i + 1],
								closingTime: data.l[i + 2],
								active: data.l[i + 3] ? true : false,
								waitTime: data.l[i + 4]
							});
						}
						return cb(null, rides);
					});

					return;
				}
			}

			return cb("No data found");
		});
	});
}

if (!module.parent)
{
	GetRideTimes(function(err, res) {
		if (err) return console.error(err);

		for(var i=0; i<res.length; i++)
		{
			// console log Tower of Terror (love this ride) for debugging
			if (res[i].id == "P2ZA02")
			{
				console.log(JSON.stringify(res[i], null, 2));
			}
		}
	});
}

// === Below is some example content for fetching various content packs from the EuroDisney app */
/*
var localisedContentIDs = [
	989, // "Recommended Routes"
	992, // advert video and image
	993, // park list (Park, Studios, Village and Hotels)
	994, // "Tips & Tricks"
	995, // "Specific Needs"
	996, // visuals
	998, // "Practical Information"
];

// these content packs don't want a localisation ID, and will return errors if we try
var contentIDs = [
	988, // app contact numbers (for about page)
	990, // Landmarks
	991, // today's show times (match up IDs with content ID 5)
	997, // regions (US) to full country names (United States)
	999, // map configs
];

// to fetch all app content files
FetchContentList(contentIDs, 0, function() {
	FetchContentList(localisedContentIDs, 2, cb);
});
*/<commit_msg>Fetch all attraction names, as some of the characters etc. also have times<commit_after>var request = require("request");
var AdmZip = require('adm-zip');
var fs = require("fs");

var dataCacheDir = __dirname + "/data/";
var dataFile = dataCacheDir + "/appState.json";

var headers = null;
var appData = null;

var checkForNewContentMinutes = 5;

// write app data so we know the state of our app content and can upgrade incrementally
function SaveAppContent(cb)
{
	fs.writeFile(dataFile, JSON.stringify({
		headers: headers,
		appData: appData
	}, null, 2), cb);
}

// restore app content we've already fetched
function RestoreAppContent(cb)
{
	if (headers != null && appData != null)
	{
		return cb();
	}

	fs.exists(dataFile, function(e) {
		if (e)
		{
			fs.readFile(dataFile, function(err, data) {
				var json;
				try
				{
					json = JSON.parse(data);
				}
				catch(e)
				{
					// delete data file if it's not parsing (update from scratch!)
					fs.unlinkSync(dataFile);
					headers = {};
				}

				if (json && json.headers && json.appData)
				{
					headers = json.headers;
					appData = json.appData;
				}
				else
				{
					headers = {};
					appData = {};
				}

				return cb();
			});
		}
		else
		{
			headers = {};
			appData = {};
			return cb();
		}
	});
}

// attraction content IDs
var attractionIDs = [
	1, // attractions
	2, // shops
	3, // hotels
	4, // characters
	5, // shows
	6, // parades
	7, // restaurants
	8, // other (ATM machines etc.)
	9, // bars
];

function FetchContentList(ids, loc_id, cb)
{
	// gather the content lists into one list
	var result = null;

	var step = function()
	{
		var c = ids.shift();
		if (!c)
		{
			return cb(null, result);
		}

		UpdateContent(c, loc_id, function(err, data) {

			if (!result)
			{
				// first result becomes the returned object
				result = data;
			}
			else if (data.l)
			{
				// merge array into result array
				for(var i=0; i<data.l.length; i++)
				{
					result.l.push(data.l[i]);
				}
			}

			process.nextTick(step);
		});
	};

	process.nextTick(step);
}

function UpdateContent(content_id, loc_id, cb)
{
	// make sure we've restored our app content first
	RestoreAppContent(function() {
		// default loc_id to 0
		if (typeof(loc_id) == "function")
		{
			cb = loc_id;
			loc_id = 0;
		}

		// create a fresh header to pull the full app data
		var header = {tp: content_id, lg: loc_id, s: 0, h1: 0, h2: 0};
		// ... unless there is a saved header from our last fetch! Then use that instad
		if (headers[ content_id ]) header = headers[ content_id ];

		// goto cache if fetched in last two hours
		if (appData[ content_id ] && appData[ content_id ].updated > ( Date.now() - 1000 * 60 * checkForNewContentMinutes ))
		{
			console.log("Using cached content pack " + content_id + ".");
			return cb(null, appData[ content_id ].data);
		}

		GetUpdateList(header, function(err, data) {
			if (err) return console.log(err);

			// if there is anything (usually just a 0) in the array, we have an update to download!
			if (data.a.length == 1)
			{
				console.log("New content diffs for content pack " + content_id + " are available! Fetching...");
				GetUpdate(header, function(err, data) {
					if (err) return console.error(err);

					// save content_id header
					headers[ content_id ] = data.h;

					// store our content
					if (appData[ content_id ])
					{
						// merge into existing content!
						if (data.l)
						{
							for(var i=0; i<data.l.length; i++)
							{
								// first check if the item already exists in our data set
								var replaced = false;
								for(var j=0; j<appData[ content_id ].data.j.length; j++)
								{
									if (appData[ content_id ].data.l[i])
									{
										if (appData[ content_id ].data.l[i][0] == data.l[i][0])
										{
											console.log("Overwriting item " + data.l[i][0] + " in content pack " + content_id);

											// item already exists! replace it
											appData[ content_id ].data.l[i] = data.l[i];
											replaced = true;
											break;
										}
									}
								}

								// otherwise, push onto the end!
								if (!replaced)
								{
									console.log("Adding new item " + data.l[i][0] + " to content pack " + content_id);

									appData[ content_id ].data.l.push(data.l[i]);
								}
							}

							// mark object as updated
							appData[ content_id ].updated = Date.now();
						}
					}
					else
					{
						appData[ content_id ] = {
							data: data,
							updated: Date.now()
						};
					}

					// save app state
					SaveAppContent(function() {
						cb(null, data);
					});
				});
			}
			else
			{
				console.log("Server has no updates for content pack " + content_id + ".");

				// mark cache as updated
				if (appData[ content_id ]) appData[ content_id ].updated = Date.now();

				// save app state with updated cache timer
				SaveAppContent(function() {

					// no updated data to fetch, so return cached data
					return cb(null, appData[ content_id ].data);

				});
			}
		});
	});
}

function GetUpdateList(headers, cb)
{
	headers = [].concat(headers);

	GetParisURL("http://disney.cms.pureagency.com/cms/ProxyContentList", {
		l: headers
	}, function(err, body) {
		return cb(null, JSON.parse(body.toString()));
	});
}

function GetParisURL(url, json, cb)
{
	var form = {key: "Ajjjsh;Uj"};

	if (json)
	{
		form.json = JSON.stringify(json);
	}

	request({
		url: url,
		method: "POST",
		headers: {
			'User-Agent': 'Disneyland 1.0 (iPhone; iPhone OS 4.1; en_GB)',
	        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
		},
		form: form,
		strictSSL: false,
		encoding: null
	}, function(err, resp, body) {
		if (err) return cb(err);

		return cb(null, body);
	});
}

function GetUpdate(headers, cb)
{
	// make sure we've restored our app content first
	RestoreAppContent(function() {
		GetParisURL("http://disney.cms.pureagency.com/cms/ProxyContent", headers, function(err, body) {
			if (err)
			{
				console.log("ERROR: " + err);
				return cb(err);
			}

			try
			{
				var zip = new AdmZip(body);
			}
			catch(e)
			{
				console.error("ERROR READING ZIP FOR " + JSON.stringify(headers));
				return;
			}

			var files = zip.getEntries();

			for(var i=0; i<files.length; i++)
			{
				return cb(null, JSON.parse(zip.readAsText(files[i].entryName)));
			}

			return cb("No data found");
		});
	});
}

// store ride names
var rideNames = null;
function CacheRideNames(cb)
{
	if (rideNames) return cb(null, true);

	FetchContentList(attractionIDs, 2, function(err, data) {
		if (err) return cb(err);

		if (data && data.l)
		{
			rideNames = {};

			for(var i=0; i<data.l.length; i++)
			{
				rideNames[ data.l[i][12] ] = {
					name: data.l[i][1],
					desc: data.l[i][11]
				};
			}

			return cb(null, true);
		}
		else
		{
			cb("No ride name data found");
		}
	});
}

function GetRideTimes(cb)
{
	// make sure we've restored our app content first
	RestoreAppContent(function() {
		console.log("Fetching live ride times...");

		GetParisURL("http://disney.cms.pureagency.com/cms/ProxyTempsAttente", null, function(err, body) {
			if (err)
			{
				console.log("ERROR: " + err);
				return cb(err);
			}

			try
			{
				var zip = new AdmZip(body);
			}
			catch(e)
			{
				console.error("ERROR READING ZIP FOR RIDE TIMES");
				return;
			}

			var files = zip.getEntries();

			for(var i=0; i<files.length; i++)
			{
				var data = JSON.parse(zip.readAsText(files[i].entryName));

				if (data && data.l)
				{
					// make sure we have all our ride names before building our result object
					CacheRideNames(function(err, res) {
						if (err) return console.error(err);

						var rides = [];

						for(var i=0; i<data.l.length; i+=5)
						{
							rides.push({
								id: data.l[i],
								name: rideNames[ data.l[i] ] ? rideNames[ data.l[i] ].name : "UNKNOWN",
								openingTime: data.l[i + 1],
								closingTime: data.l[i + 2],
								active: data.l[i + 3] ? true : false,
								waitTime: data.l[i + 4]
							});
						}
						return cb(null, rides);
					});

					return;
				}
			}

			return cb("No data found");
		});
	});
}

if (!module.parent)
{
	GetRideTimes(function(err, res) {
		if (err) return console.error(err);

		for(var i=0; i<res.length; i++)
		{
			// console log Tower of Terror (love this ride) for debugging
			if (res[i].id == "P2ZA02")
			{
				console.log(JSON.stringify(res[i], null, 2));
			}
		}
	});
}

// === Below is some example content for fetching various content packs from the EuroDisney app */
/*
var localisedContentIDs = [
	989, // "Recommended Routes"
	992, // advert video and image
	993, // park list (Park, Studios, Village and Hotels)
	994, // "Tips & Tricks"
	995, // "Specific Needs"
	996, // visuals
	998, // "Practical Information"
];

// these content packs don't want a localisation ID, and will return errors if we try
var contentIDs = [
	988, // app contact numbers (for about page)
	990, // Landmarks
	991, // today's show times (match up IDs with content ID 5)
	997, // regions (US) to full country names (United States)
	999, // map configs
];

// to fetch all app content files
FetchContentList(contentIDs, 0, function() {
	FetchContentList(localisedContentIDs, 2, cb);
});
*/<|endoftext|>