/*
							 | 
						|
									MIT License http://www.opensource.org/licenses/mit-license.php
							 | 
						|
									Author Tobias Koppers @sokra
							 | 
						|
								*/
							 | 
						|
								"use strict";
							 | 
						|
								
							 | 
						|
								const Queue = require("./util/Queue");
							 | 
						|
								
							 | 
						|
								const addToSet = (a, b) => {
							 | 
						|
									const size = a.size;
							 | 
						|
									for (const item of b) {
							 | 
						|
										a.add(item);
							 | 
						|
									}
							 | 
						|
									return a.size !== size;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								class FlagDependencyExportsPlugin {
							 | 
						|
									apply(compiler) {
							 | 
						|
										compiler.hooks.compilation.tap(
							 | 
						|
											"FlagDependencyExportsPlugin",
							 | 
						|
											compilation => {
							 | 
						|
												compilation.hooks.finishModules.tap(
							 | 
						|
													"FlagDependencyExportsPlugin",
							 | 
						|
													modules => {
							 | 
						|
														const dependencies = new Map();
							 | 
						|
								
							 | 
						|
														const queue = new Queue();
							 | 
						|
								
							 | 
						|
														let module;
							 | 
						|
														let moduleWithExports;
							 | 
						|
														let moduleProvidedExports;
							 | 
						|
														let providedExportsAreTemporary;
							 | 
						|
								
							 | 
						|
														const processDependenciesBlock = depBlock => {
							 | 
						|
															for (const dep of depBlock.dependencies) {
							 | 
						|
																if (processDependency(dep)) return true;
							 | 
						|
															}
							 | 
						|
															for (const variable of depBlock.variables) {
							 | 
						|
																for (const dep of variable.dependencies) {
							 | 
						|
																	if (processDependency(dep)) return true;
							 | 
						|
																}
							 | 
						|
															}
							 | 
						|
															for (const block of depBlock.blocks) {
							 | 
						|
																if (processDependenciesBlock(block)) return true;
							 | 
						|
															}
							 | 
						|
															return false;
							 | 
						|
														};
							 | 
						|
								
							 | 
						|
														const processDependency = dep => {
							 | 
						|
															const exportDesc = dep.getExports && dep.getExports();
							 | 
						|
															if (!exportDesc) return;
							 | 
						|
															moduleWithExports = true;
							 | 
						|
															const exports = exportDesc.exports;
							 | 
						|
															// break early if it's only in the worst state
							 | 
						|
															if (module.buildMeta.providedExports === true) {
							 | 
						|
																return true;
							 | 
						|
															}
							 | 
						|
															// break if it should move to the worst state
							 | 
						|
															if (exports === true) {
							 | 
						|
																module.buildMeta.providedExports = true;
							 | 
						|
																notifyDependencies();
							 | 
						|
																return true;
							 | 
						|
															}
							 | 
						|
															// merge in new exports
							 | 
						|
															if (Array.isArray(exports)) {
							 | 
						|
																if (addToSet(moduleProvidedExports, exports)) {
							 | 
						|
																	notifyDependencies();
							 | 
						|
																}
							 | 
						|
															}
							 | 
						|
															// store dependencies
							 | 
						|
															const exportDeps = exportDesc.dependencies;
							 | 
						|
															if (exportDeps) {
							 | 
						|
																providedExportsAreTemporary = true;
							 | 
						|
																for (const exportDependency of exportDeps) {
							 | 
						|
																	// add dependency for this module
							 | 
						|
																	const set = dependencies.get(exportDependency);
							 | 
						|
																	if (set === undefined) {
							 | 
						|
																		dependencies.set(exportDependency, new Set([module]));
							 | 
						|
																	} else {
							 | 
						|
																		set.add(module);
							 | 
						|
																	}
							 | 
						|
																}
							 | 
						|
															}
							 | 
						|
															return false;
							 | 
						|
														};
							 | 
						|
								
							 | 
						|
														const notifyDependencies = () => {
							 | 
						|
															const deps = dependencies.get(module);
							 | 
						|
															if (deps !== undefined) {
							 | 
						|
																for (const dep of deps) {
							 | 
						|
																	queue.enqueue(dep);
							 | 
						|
																}
							 | 
						|
															}
							 | 
						|
														};
							 | 
						|
								
							 | 
						|
														// Start with all modules without provided exports
							 | 
						|
														for (const module of modules) {
							 | 
						|
															if (module.buildInfo.temporaryProvidedExports) {
							 | 
						|
																// Clear exports when they are temporary
							 | 
						|
																// and recreate them
							 | 
						|
																module.buildMeta.providedExports = null;
							 | 
						|
																queue.enqueue(module);
							 | 
						|
															} else if (!module.buildMeta.providedExports) {
							 | 
						|
																queue.enqueue(module);
							 | 
						|
															}
							 | 
						|
														}
							 | 
						|
								
							 | 
						|
														while (queue.length > 0) {
							 | 
						|
															module = queue.dequeue();
							 | 
						|
								
							 | 
						|
															if (module.buildMeta.providedExports !== true) {
							 | 
						|
																moduleWithExports =
							 | 
						|
																	module.buildMeta && module.buildMeta.exportsType;
							 | 
						|
																moduleProvidedExports = new Set();
							 | 
						|
																providedExportsAreTemporary = false;
							 | 
						|
																processDependenciesBlock(module);
							 | 
						|
																module.buildInfo.temporaryProvidedExports = providedExportsAreTemporary;
							 | 
						|
																if (!moduleWithExports) {
							 | 
						|
																	module.buildMeta.providedExports = true;
							 | 
						|
																	notifyDependencies();
							 | 
						|
																} else if (module.buildMeta.providedExports !== true) {
							 | 
						|
																	module.buildMeta.providedExports = Array.from(
							 | 
						|
																		moduleProvidedExports
							 | 
						|
																	);
							 | 
						|
																}
							 | 
						|
															}
							 | 
						|
														}
							 | 
						|
													}
							 | 
						|
												);
							 | 
						|
												const providedExportsCache = new WeakMap();
							 | 
						|
												compilation.hooks.rebuildModule.tap(
							 | 
						|
													"FlagDependencyExportsPlugin",
							 | 
						|
													module => {
							 | 
						|
														providedExportsCache.set(module, module.buildMeta.providedExports);
							 | 
						|
													}
							 | 
						|
												);
							 | 
						|
												compilation.hooks.finishRebuildingModule.tap(
							 | 
						|
													"FlagDependencyExportsPlugin",
							 | 
						|
													module => {
							 | 
						|
														module.buildMeta.providedExports = providedExportsCache.get(module);
							 | 
						|
													}
							 | 
						|
												);
							 | 
						|
											}
							 | 
						|
										);
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								module.exports = FlagDependencyExportsPlugin;
							 |