<commit_before>
// A dictionary mapping script URLs to a dictionary mapping
// component key to component for all components that are waiting
// for the script to load.
var scriptObservers = {};

// A dictionary mapping script URL to a boolean value indicating if the script
// has already been loaded.
var loadedScripts = {};

// A dictionary mapping script URL to a boolean value indicating if the script
// has failed to load.
var erroredScripts = {};

// A counter used to generate a unique id for each component that uses
// ScriptLoaderMixin.
var idCount = 0;

var ReactScriptLoader = {
	componentDidMount: function(key, component, scriptURL) {
		if (typeof component.onScriptLoaded !== 'function') {
			throw new Error('ScriptLoader: Component class must implement onScriptLoaded()');
		}
		if (typeof component.onScriptError !== 'function') {
			throw new Error('ScriptLoader: Component class must implement onScriptError()');
		}
		if (loadedScripts[scriptURL]) {
			component.onScriptLoaded();
			return;
		}
		if (erroredScripts[scriptURL]) {
			component.onScriptError();
			return;
		}

		// If the script is loading, add the component to the script's observers
		// and return. Otherwise, initialize the script's observers with the component
		// and start loading the script.
		if (scriptObservers[scriptURL]) {
			scriptObservers[scriptURL][key] = component;
			return;
		}

		var observers = {};
		observers[key] = component;
		scriptObservers[scriptURL] = observers;

		var script = document.createElement('script');

		if (typeof component.onScriptTagCreated === 'function') {
			component.onScriptTagCreated(script);
		}

		script.src = scriptURL;

		var callObserverFuncAndRemoveObserver = function(func) {
			var observers = scriptObservers[scriptURL];
			for (var key in observers) {
				observer = observers[key];
				var removeObserver = func(observer);
				if (removeObserver) {
					delete scriptObservers[scriptURL][key];
				}
			}
			//delete scriptObservers[scriptURL];
		}
		script.onload = function() {
			loadedScripts[scriptURL] = true;
			callObserverFuncAndRemoveObserver(function(observer) {
				if (observer.deferOnScriptLoaded && observer.deferOnScriptLoaded()) {
					return false;
				}
				observer.onScriptLoaded();
				return true;
			});
		};
		script.onerror = function(event) {
			erroredScripts[scriptURL] = true;
			callObserverFuncAndRemoveObserver(function(observer) {
				observer.onScriptError();
				return true;
			});
		};
		document.body.appendChild(script);
	},
	componentWillUnmount: function(key, scriptURL) {
		// If the component is waiting for the script to load, remove the
		// component from the script's observers before unmounting the component.
		var observers = scriptObservers[scriptURL];
		if (observers) {
			delete observers[key];
		}
	},
	triggerOnScriptLoaded: function(scriptURL) {
		if (!loadedScripts[scriptURL]) {
			throw new Error('Error: only call this function after the script has in fact loaded.');
		}
		var observers = scriptObservers[scriptURL];<commit_msg>Add script async flag && make it work on older MSIE browsers<commit_after>
// A dictionary mapping script URLs to a dictionary mapping
// component key to component for all components that are waiting
// for the script to load.
var scriptObservers = {};

// A dictionary mapping script URL to a boolean value indicating if the script
// has already been loaded.
var loadedScripts = {};

// A dictionary mapping script URL to a boolean value indicating if the script
// has failed to load.
var erroredScripts = {};

// A counter used to generate a unique id for each component that uses
// ScriptLoaderMixin.
var idCount = 0;

var ReactScriptLoader = {
	componentDidMount: function(key, component, scriptURL) {
		if (typeof component.onScriptLoaded !== 'function') {
			throw new Error('ScriptLoader: Component class must implement onScriptLoaded()');
		}
		if (typeof component.onScriptError !== 'function') {
			throw new Error('ScriptLoader: Component class must implement onScriptError()');
		}
		if (loadedScripts[scriptURL]) {
			component.onScriptLoaded();
			return;
		}
		if (erroredScripts[scriptURL]) {
			component.onScriptError();
			return;
		}

		// If the script is loading, add the component to the script's observers
		// and return. Otherwise, initialize the script's observers with the component
		// and start loading the script.
		if (scriptObservers[scriptURL]) {
			scriptObservers[scriptURL][key] = component;
			return;
		}

		var observers = {};
		observers[key] = component;
		scriptObservers[scriptURL] = observers;

		var script = document.createElement('script');

		if (typeof component.onScriptTagCreated === 'function') {
			component.onScriptTagCreated(script);
		}

		script.src = scriptURL;
		script.async = 1;

		var callObserverFuncAndRemoveObserver = function(func) {
			var observers = scriptObservers[scriptURL];
			for (var key in observers) {
				observer = observers[key];
				var removeObserver = func(observer);
				if (removeObserver) {
					delete scriptObservers[scriptURL][key];
				}
			}
			//delete scriptObservers[scriptURL];
		}
		script.onload = function() {
			loadedScripts[scriptURL] = true;
			callObserverFuncAndRemoveObserver(function(observer) {
				if (observer.deferOnScriptLoaded && observer.deferOnScriptLoaded()) {
					return false;
				}
				observer.onScriptLoaded();
				return true;
			});
		};
		script.onerror = function(event) {
			erroredScripts[scriptURL] = true;
			callObserverFuncAndRemoveObserver(function(observer) {
				observer.onScriptError();
				return true;
			});
		};
		// (old) MSIE browsers may call 'onreadystatechange' instead of 'onload'
    		script.onreadystatechange = function() {
      			if (this.readyState == 'loaded') {
        			// wait for other events, then call onload if default onload hadn't been called
        			window.setTimeout(function() {
          				if (loadedScripts[scriptURL] !== true) script.onload();
        			}, 0);
      			}
    		};
		
		document.body.appendChild(script);
	},
	componentWillUnmount: function(key, scriptURL) {
		// If the component is waiting for the script to load, remove the
		// component from the script's observers before unmounting the component.
		var observers = scriptObservers[scriptURL];
		if (observers) {
			delete observers[key];
		}
	},
	triggerOnScriptLoaded: function(scriptURL) {
		if (!loadedScripts[scriptURL]) {
			throw new Error('Error: only call this function after the script has in fact loaded.');
		}
		var observers = scriptObservers[scriptURL];
{'fraction_non_alphanumeric': 0.10302845837772029, 'fraction_numerical': 0.0006087353523055851, 'mean_word_length': 3.8898809523809526, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2806856', 'n_tokens_mistral': 2118, 'n_tokens_neox': 1828, 'n_words': 572}