text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
  	value: true
  });
  
  var _getIterator2 = require('babel-runtime/core-js/get-iterator');
  
  var _getIterator3 = _interopRequireDefault(_getIterator2);
  
  var _keys = require('babel-runtime/core-js/object/keys');
  
  var _keys2 = _interopRequireDefault(_keys);
  
  var _stringify = require('babel-runtime/core-js/json/stringify');
  
  var _stringify2 = _interopRequireDefault(_stringify);
  
  exports.default = write_assets;
  exports.extract_path = extract_path;
  
  var _fsExtra = require('fs-extra');
  
  var _fsExtra2 = _interopRequireDefault(_fsExtra);
  
  var _path = require('path');
  
  var _path2 = _interopRequireDefault(_path);
  
  var _semver = require('semver');
  
  var _semver2 = _interopRequireDefault(_semver);
  
  var _requireHacker = require('require-hacker');
  
  var _requireHacker2 = _interopRequireDefault(_requireHacker);
  
  var _serializeJavascript = require('../tools/serialize-javascript');
  
  var _serializeJavascript2 = _interopRequireDefault(_serializeJavascript);
  
  var _helpers = require('../helpers');
  
  var _common = require('../common');
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  // one can supply a custom filter
  var default_filter = function default_filter(module, regular_expression) {
  	return regular_expression.test(module.name);
  };
  // one can supply a custom namer
  var default_asset_path = function default_asset_path(module) {
  	return module.name;
  };
  // one can supply a custom parser
  var default_parser = function default_parser(module) {
  	return module.source;
  };
  
  // writes webpack-assets.json file, which contains assets' file paths
  function write_assets(json, options, log) {
  	// take the passed in options
  	options = (0, _helpers.clone)(options);
  
  	log.debug('running write assets webpack plugin v' + require('../../package.json').version + ' with options', options);
  
  	// make webpack stats accessible for asset functions (parser, path, filter)
  	options.webpack_stats = json;
  
  	var development = options.development;
  
  	if (development) {
  		log.debug(' (development mode is on)');
  	}
  
  	// write webpack stats json for debugging purpose
  	if (options.debug) {
  		// write webpack stats file
  		log.debug('writing webpack stats to ' + options.webpack_stats_path);
  
  		// write the file
  		// (format the JSON for better readability)
  		_fsExtra2.default.outputFileSync(options.webpack_stats_path, (0, _stringify2.default)(json, null, 2));
  	}
  
  	// Note Webpack version due to breaking changes between v2 and v3.
  	// https://github.com/catamphetamine/webpack-isomorphic-tools/issues/142
  	//
  	// Convert things like `3.0.0-alpha.1` to just `3.0.0`.
  	//
  	var version = new _semver2.default(json.version);
  	version = version.major + '.' + version.minor + '.' + version.patch;
  	options.webpackVersion = version;
  	options.webpackUsesTildeForNodeModules = (0, _common.webpack_uses_tilde_for_node_modules)(version);
  
  	// the output object with assets
  	var output = options.output;
  	output.webpack = { version: version };
  
  	// populate the output object with assets
  	populate_assets(output, json, options, log);
  
  	// write webpack assets info file
  	if (options.output_to_a_file) {
  		// format the JSON for better readability if in debug mode
  		var assets_info = development ? (0, _stringify2.default)(output, null, 2) : (0, _stringify2.default)(output);
  
  		// rewrite `webpack-assets.json`
  		var rewrite = true;
  
  		// for `webpack-assets.json` caching to work
  		// chunks info should be moved out of it,
  		// otherwise chunk hashsums constantly change,
  		// and there won't be any caching.
  		//
  		// const assets_buffer = Buffer.from(assets_info)
  		//
  		// // if webpack-assets.json already exists,
  		// // then maybe no need to rewrite it
  		// if (fs.existsSync(options.webpack_assets_path))
  		// {
  		// 	// previously written webpack-assets.json
  		// 	const previous_assets_buffer = fs.readFileSync(options.webpack_assets_path)
  		//
  		// 	// if webpack-assets.json rewrite is not needed, then don't do it
  		// 	if (assets_buffer.equals(previous_assets_buffer))
  		// 	{
  		// 		rewrite = false
  		// 	}
  		// }
  
  		// if webpack-assets.json rewrite is needed, then do it
  		if (rewrite) {
  			log.debug('writing webpack assets info to ' + options.webpack_assets_path);
  			// write the file
  			_fsExtra2.default.outputFileSync(options.webpack_assets_path, assets_info);
  		}
  	} else {
  		log.debug('serving webpack assets from memory');
  	}
  
  	// return Webpack assets JSON object
  	// for serving it through HTTP service
  	return output;
  }
  
  // populates the output object with assets
  function populate_assets(output, json, options, log) {
  	// for each chunk name ("main", "common", ...)
  	(0, _keys2.default)(json.assetsByChunkName).forEach(function (name) {
  		log.debug('getting javascript and styles for chunk "' + name + '"');
  
  		// get javascript chunk real file path
  
  		var javascript = get_assets(name, 'js')[0];
  		// the second asset is usually a source map
  
  		if (javascript) {
  			log.debug(' (got javascript)');
  			output.javascript[name] = javascript;
  		}
  
  		// get style chunk real file path
  
  		var style = get_assets(name, 'css')[0];
  		// the second asset is usually a source map
  
  		if (style) {
  			log.debug(' (got style)');
  			output.styles[name] = style;
  		}
  	});
  
  	// gets asset paths by name and extension of their chunk
  	function get_assets(name) {
  		var extension = arguments.length <= 1 || arguments[1] === undefined ? 'js' : arguments[1];
  
  		var chunk = json.assetsByChunkName[name];
  
  		// a chunk could be a string or an array, so make sure it is an array
  		if (!Array.isArray(chunk)) {
  			chunk = [chunk];
  		}
  
  		return chunk
  		// filter by extension
  		.filter(function (name) {
  			return _path2.default.extname(extract_path(name)) === '.' + extension;
  		})
  		// adjust the real path (can be http, filesystem)
  		.map(function (name) {
  			return options.assets_base_url + name;
  		});
  	}
  
  	// 1st pass
  	var parsed_assets = {};
  
  	// global paths to parsed asset paths
  	var global_paths_to_parsed_asset_paths = {};
  
  	// define __webpack_public_path__ webpack variable
  	// (resolves "ReferenceError: __webpack_public_path__ is not defined")
  	var define_webpack_public_path = 'var __webpack_public_path__ = ' + (0, _stringify2.default)(options.assets_base_url) + ';\n';
  
  	// for each user specified asset type
  	var _iteratorNormalCompletion = true;
  	var _didIteratorError = false;
  	var _iteratorError = undefined;
  
  	try {
  		var _loop = function _loop() {
  			var asset_type = _step.value;
  
  			// asset type settings
  			var asset_type_settings = options.assets[asset_type];
  
  			// one can supply his own filter
  			var filter = asset_type_settings.filter || default_filter; //.bind(this)
  			// one can supply his own path parser
  			var extract_asset_path = asset_type_settings.path || default_asset_path; //.bind(this)
  			// one can supply his own parser
  			var parser = asset_type_settings.parser || default_parser; //.bind(this)
  
  			// guard agains typos, etc
  
  			// for filter
  			if (!asset_type_settings.filter) {
  				log.debug('No filter specified for "' + asset_type + '" assets. Using a default one.');
  			}
  
  			// for path parser
  			if (!asset_type_settings.path) {
  				log.debug('No path parser specified for "' + asset_type + '" assets. Using a default one.');
  			}
  
  			// for parser
  			if (!asset_type_settings.parser) {
  				log.debug('No parser specified for "' + asset_type + '" assets. Using a default one.');
  			}
  
  			log.debug('parsing assets of type "' + asset_type + '"');
  
  			// timer start
  			var began_at = new Date().getTime();
  
  			// get real paths for all the files from this asset type
  			json.modules
  			// take just modules of this asset type
  			.filter(function (module) {
  				// check that this asset is of the asset type
  				if (!filter(module, options.regular_expressions[asset_type], options, log)) {
  					return false;
  				}
  
  				// guard against an empty source.
  				if (!module.source) {
  					log.error('Module "' + module.name + '" has no source. Maybe Webpack compilation of this module failed. Skipping this asset.');
  					return false;
  				}
  
  				// include this asset
  				return true;
  			}).reduce(function (set, module) {
  				// determine asset real path
  				var asset_path = extract_asset_path(module, options, log);
  
  				// asset module source, or asset content (or whatever else)
  				var parsed_asset = parser(module, options, log);
  
  				log.trace('Adding asset "' + asset_path + '", module id ' + module.id + ' (in webpack-stats.json)');
  
  				// check for naming collisions (just in case)
  				if ((0, _helpers.exists)(set[asset_path])) {
  					log.error('-----------------------------------------------------------------');
  					log.error('Asset with path "' + asset_path + '" was overwritten because of path collision.');
  					log.error('Use the "filter" function of this asset type to narrow the results.');
  					log.error('Previous asset with this path:');
  					log.error(set[asset_path]);
  					log.error('New asset with this path:');
  					log.error(parsed_asset);
  					log.error('-----------------------------------------------------------------');
  				}
  
  				// add this asset to the list
  				//
  				// also resolve "ReferenceError: __webpack_public_path__ is not defined".
  				// because it may be a url-loaded resource (e.g. a font inside a style).
  				set[asset_path] = define_webpack_public_path + _requireHacker2.default.to_javascript_module_source(parsed_asset);
  
  				// add path mapping
  				global_paths_to_parsed_asset_paths[_path2.default.resolve(options.project_path, asset_path)] = asset_path;
  
  				// continue
  				return set;
  			}, parsed_assets);
  
  			// timer stop
  			log.debug(' time taken: ' + (new Date().getTime() - began_at) + ' ms');
  		};
  
  		for (var _iterator = (0, _getIterator3.default)((0, _keys2.default)(options.assets)), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
  			_loop();
  		}
  
  		// register a special require() hook for requiring() raw webpack modules
  	} catch (err) {
  		_didIteratorError = true;
  		_iteratorError = err;
  	} finally {
  		try {
  			if (!_iteratorNormalCompletion && _iterator.return) {
  				_iterator.return();
  			}
  		} finally {
  			if (_didIteratorError) {
  				throw _iteratorError;
  			}
  		}
  	}
  
  	var require_hook = _requireHacker2.default.global_hook('webpack-module', function (required_path, module) {
  		log.debug('require()ing "' + required_path + '"');
  
  		// if Webpack aliases are supplied
  		if (options.alias) {
  			// possibly alias the path
  			var aliased_global_path = (0, _common.alias_hook)(required_path, module, options.project_path, options.alias, log);
  
  			// if an alias is found
  			if (aliased_global_path) {
  				var result = {
  					source: _requireHacker2.default.to_javascript_module_source(safe_require(aliased_global_path, log)),
  					path: aliased_global_path
  				};
  
  				return result;
  			}
  		}
  
  		// If the `required_path` is an npm package path
  		// still can't simply `return` and fall back to default Node.js behaviour
  		// because it could still be an asset like
  		// `require('bootstrap/style.css')` inside `./style.css`.
  		//
  		// If the `required_path` is not an asset though
  		// (which means "has no extension" in this case — should work)
  		// then `require()` it as usual.
  		//
  		if (required_path.split(_path2.default.sep).slice(-1)[0].indexOf('.') === -1) {
  			return;
  		}
  
  		// find an asset with this path
  		//
  		// the require()d path will be global path in case of the for..of require() loop
  		// for the assets (the code a couple of screens below).
  		//
  		// (it can be anything in other cases (e.g. nested require() calls from the assets))
  		//
  		if ((0, _helpers.exists)(global_paths_to_parsed_asset_paths[required_path])) {
  			log.debug(' found in parsed assets');
  
  			var _result = {
  				source: parsed_assets[global_paths_to_parsed_asset_paths[required_path]],
  				path: required_path
  			};
  
  			return _result;
  		}
  
  		log.debug(' not found in parsed assets, searching in webpack stats');
  
  		// find a webpack module which has a reason with this path
  
  		var candidates = [];
  
  		var _iteratorNormalCompletion2 = true;
  		var _didIteratorError2 = false;
  		var _iteratorError2 = undefined;
  
  		try {
  			for (var _iterator2 = (0, _getIterator3.default)(json.modules), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
  				var _module = _step2.value;
  				var _iteratorNormalCompletion4 = true;
  				var _didIteratorError4 = false;
  				var _iteratorError4 = undefined;
  
  				try {
  					for (var _iterator4 = (0, _getIterator3.default)(_module.reasons), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
  						var reason = _step4.value;
  
  						if (reason.userRequest === required_path) {
  							candidates.push(_module);
  							break;
  						}
  					}
  				} catch (err) {
  					_didIteratorError4 = true;
  					_iteratorError4 = err;
  				} finally {
  					try {
  						if (!_iteratorNormalCompletion4 && _iterator4.return) {
  							_iterator4.return();
  						}
  					} finally {
  						if (_didIteratorError4) {
  							throw _iteratorError4;
  						}
  					}
  				}
  			}
  
  			// guard against ambiguity
  		} catch (err) {
  			_didIteratorError2 = true;
  			_iteratorError2 = err;
  		} finally {
  			try {
  				if (!_iteratorNormalCompletion2 && _iterator2.return) {
  					_iterator2.return();
  				}
  			} finally {
  				if (_didIteratorError2) {
  					throw _iteratorError2;
  				}
  			}
  		}
  
  		if (candidates.length === 1) {
  			log.debug(' found in webpack stats, module id ' + candidates[0].id);
  
  			// also resolve "ReferenceError: __webpack_public_path__ is not defined".
  			// because it may be a url-loaded resource (e.g. a font inside a style).
  
  			var _result2 = {
  				source: define_webpack_public_path + candidates[0].source,
  				path: candidates[0].identifier
  			};
  
  			return _result2;
  		}
  
  		// if there are more than one candidate for this require()d path,
  		// then try to guess which one is the one require()d
  
  		if (candidates.length > 1) {
  			log.debug(' More than a single candidate module was found in webpack stats for require()d path "' + required_path + '"');
  
  			var _iteratorNormalCompletion3 = true;
  			var _didIteratorError3 = false;
  			var _iteratorError3 = undefined;
  
  			try {
  				for (var _iterator3 = (0, _getIterator3.default)(candidates), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
  					var candidate = _step3.value;
  
  					log.debug(' ', candidate);
  				}
  
  				// (loaders matter so the program can't simply throw them away from the required path)
  				//
  				// // tries to normalize a cryptic Webpack loader path
  				// // into a regular relative file path
  				// // https://webpack.github.io/docs/loaders.html
  				// let filesystem_required_path = last(required_path
  				// 	.replace(/^!!/, '')
  				// 	.replace(/^!/, '')
  				// 	.replace(/^-!/, '')
  				// 	.split('!'))
  			} catch (err) {
  				_didIteratorError3 = true;
  				_iteratorError3 = err;
  			} finally {
  				try {
  					if (!_iteratorNormalCompletion3 && _iterator3.return) {
  						_iterator3.return();
  					}
  				} finally {
  					if (_didIteratorError3) {
  						throw _iteratorError3;
  					}
  				}
  			}
  
  			var fail = function fail() {
  				throw new Error('More than a single candidate module was found in webpack stats for require()d path "' + required_path + '". Enable "debug: true" flag in webpack-isomorphic-tools configuration for more info.');
  			};
  
  			// https://webpack.github.io/docs/loaders.html
  			var is_webpack_loader_path = required_path.indexOf('!') >= 0;
  
  			// if it's a Webpack loader-powered path, the code gives up
  			if (is_webpack_loader_path) {
  				fail();
  			}
  
  			// from here on it's either a filesystem path or an npm module path
  
  			// if it's a global path it can be resolved right away
  			if ((0, _common.is_global_path)(required_path)) {
  				var _result3 = {
  					source: _requireHacker2.default.to_javascript_module_source(safe_require(required_path, log)),
  					path: required_path
  				};
  
  				return _result3;
  			}
  
  			// from here on it's either a relative filesystem path or an npm module path,
  			// so it can be resolved against the require()ing file path (if it can be recovered).
  
  			// `module.filename` here can be anything, not just a filesystem absolute path,
  			// since some advanced require() hook trickery is involved.
  			// therefore it will be parsed.
  			//
  			var requiring_file_path = module.filename.replace(/\.webpack-module$/, '');
  
  			// if it's a webpack loader-powered path, then extract the filesystem path from it
  			if (requiring_file_path.indexOf('!') >= 0) {
  				requiring_file_path = requiring_file_path.substring(requiring_file_path.lastIndexOf('!') + 1);
  			}
  
  			// make relative path global
  			if ((0, _common.is_relative_path)(requiring_file_path)) {
  				requiring_file_path = _path2.default.resolve(options.project_path, requiring_file_path);
  			}
  
  			// if `requiring_file_path` is a filesystem path (not an npm module path),
  			// then the require()d path can possibly be resolved
  			if ((0, _common.is_global_path)(requiring_file_path)) {
  				log.debug(' The module is being require()d from "' + requiring_file_path + '", so resolving the path against this file');
  
  				// if it's a relative path, can try to resolve it
  				if ((0, _common.is_relative_path)(required_path)) {
  					var absolute_path = _path2.default.resolve(requiring_file_path, '..', required_path);
  
  					var _result4 = {
  						source: _requireHacker2.default.to_javascript_module_source(safe_require(absolute_path, log)),
  						path: absolute_path
  					};
  
  					return _result4;
  				}
  
  				// if it's an npm module path (e.g. 'babel-runtime/core-js/object/assign'),
  				// can try to require() it from the requiring asset path
  				if ((0, _common.is_package_path)(required_path) && (0, _common.is_global_path)(module.filename)) {
  					var _absolute_path = _requireHacker2.default.resolve(required_path, module);
  
  					var _result5 = {
  						source: _requireHacker2.default.to_javascript_module_source(safe_require(_absolute_path, log)),
  						path: _absolute_path
  					};
  
  					return _result5;
  				}
  			}
  
  			// if it's still here then it means it's either a
  			fail();
  		}
  	});
  
  	log.debug('compiling assets');
  
  	// timer start
  	var began_at = new Date().getTime();
  
  	// evaluate parsed assets source code
  	var _iteratorNormalCompletion5 = true;
  	var _didIteratorError5 = false;
  	var _iteratorError5 = undefined;
  
  	try {
  		for (var _iterator5 = (0, _getIterator3.default)((0, _keys2.default)(parsed_assets)), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
  			var asset_path = _step5.value;
  
  			var compile = true;
  
  			// If this asset should be compiled at runtime then skip its compilation.
  			// (runtime compilation can be used for Webpack loaders returning
  			//  javascript functions or React component classes — stuff like that,
  			//  because it's not serializable to `webpack-assets.json`)
  			var _iteratorNormalCompletion6 = true;
  			var _didIteratorError6 = false;
  			var _iteratorError6 = undefined;
  
  			try {
  				for (var _iterator6 = (0, _getIterator3.default)((0, _keys2.default)(options.assets)), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
  					var _asset_type = _step6.value;
  
  					if (options.regular_expressions[_asset_type].test(asset_path)) {
  						if (options.assets[_asset_type].runtime) {
  							compile = false;
  						}
  					}
  				}
  			} catch (err) {
  				_didIteratorError6 = true;
  				_iteratorError6 = err;
  			} finally {
  				try {
  					if (!_iteratorNormalCompletion6 && _iterator6.return) {
  						_iterator6.return();
  					}
  				} finally {
  					if (_didIteratorError6) {
  						throw _iteratorError6;
  					}
  				}
  			}
  
  			if (!compile) {
  				output.assets[asset_path] = parsed_assets[asset_path];
  				continue;
  			}
  
  			// set asset value
  			log.debug('compiling asset "' + asset_path + '"');
  			output.assets[asset_path] = safe_require(_path2.default.resolve(options.project_path, asset_path), log);
  
  			// inside that require() call above
  			// all the assets are resolved relative to this `module`,
  			// which is irrelevant because they are all absolute filesystem paths.
  			//
  			// if in some of those assets a nested require() call is present
  			// then it will be resolved relative to that asset folder.
  		}
  
  		// unmount the previously installed require() hook
  	} catch (err) {
  		_didIteratorError5 = true;
  		_iteratorError5 = err;
  	} finally {
  		try {
  			if (!_iteratorNormalCompletion5 && _iterator5.return) {
  				_iterator5.return();
  			}
  		} finally {
  			if (_didIteratorError5) {
  				throw _iteratorError5;
  			}
  		}
  	}
  
  	require_hook.unmount();
  
  	// timer stop
  	log.debug(' time taken: ' + (new Date().getTime() - began_at) + ' ms');
  }
  
  function safe_require(path, log) {
  	try {
  		return require(path);
  	} catch (error) {
  		log.error(error);
  		return undefined;
  	}
  }
  
  function extract_path(from) {
  	var question_mark_index = from.indexOf('?');
  	if (question_mark_index === -1) {
  		return from;
  	}
  	return from.slice(0, question_mark_index);
  }
  //# sourceMappingURL=write assets.js.map