| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		return Module; | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (function() { | 
					
						
							|  |  |  | 	var engine = Engine; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var DOWNLOAD_ATTEMPTS_MAX = 4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var basePath = null; | 
					
						
							|  |  |  | 	var engineLoadPromise = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var loadingFiles = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function getBasePath(path) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (path.endsWith('/')) | 
					
						
							|  |  |  | 			path = path.slice(0, -1); | 
					
						
							|  |  |  | 		if (path.lastIndexOf('.') > path.lastIndexOf('/')) | 
					
						
							|  |  |  | 			path = path.slice(0, path.lastIndexOf('.')); | 
					
						
							|  |  |  | 		return path; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function getBaseName(path) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		path = getBasePath(path); | 
					
						
							|  |  |  | 		return path.slice(path.lastIndexOf('/') + 1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Engine = function Engine() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.rtenv = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		var initPromise = null; | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		var unloadAfterInit = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		var preloadedFiles = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var resizeCanvasOnStart = true; | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		var progressFunc = null; | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		var preloadProgressTracker = {}; | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		var lastProgress = { loaded: 0, total: 0 }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var canvas = null; | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		var executableName = null; | 
					
						
							|  |  |  | 		var locale = null; | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		var stdout = null; | 
					
						
							|  |  |  | 		var stderr = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		this.init = function(newBasePath) { | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 			if (!initPromise) { | 
					
						
							|  |  |  | 				initPromise = Engine.load(newBasePath).then( | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 					instantiate.bind(this) | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				requestAnimationFrame(animateProgress); | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 				if (unloadAfterInit) | 
					
						
							|  |  |  | 					initPromise.then(Engine.unloadEngine); | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 			return initPromise; | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		function instantiate(wasmBuf) { | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 			var rtenvProps = { | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 				engine: this, | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 				ENV: {}, | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			}; | 
					
						
							|  |  |  | 			if (typeof stdout === 'function') | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 				rtenvProps.print = stdout; | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			if (typeof stderr === 'function') | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 				rtenvProps.printErr = stderr; | 
					
						
							|  |  |  | 			rtenvProps.instantiateWasm = function(imports, onSuccess) { | 
					
						
							|  |  |  | 				WebAssembly.instantiate(wasmBuf, imports).then(function(result) { | 
					
						
							|  |  |  | 					onSuccess(result.instance); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				return {}; | 
					
						
							|  |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return new Promise(function(resolve, reject) { | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 				rtenvProps.onRuntimeInitialized = resolve; | 
					
						
							|  |  |  | 				rtenvProps.onAbort = reject; | 
					
						
							|  |  |  | 				rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps); | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		this.preloadFile = function(pathOrBuffer, bufferFilename) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (pathOrBuffer instanceof ArrayBuffer) { | 
					
						
							|  |  |  | 				pathOrBuffer = new Uint8Array(pathOrBuffer); | 
					
						
							|  |  |  | 			} else if (ArrayBuffer.isView(pathOrBuffer)) { | 
					
						
							|  |  |  | 				pathOrBuffer = new Uint8Array(pathOrBuffer.buffer); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (pathOrBuffer instanceof Uint8Array) { | 
					
						
							|  |  |  | 				preloadedFiles.push({ | 
					
						
							|  |  |  | 					name: bufferFilename, | 
					
						
							|  |  |  | 					buffer: pathOrBuffer | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				return Promise.resolve(); | 
					
						
							|  |  |  | 			} else if (typeof pathOrBuffer === 'string') { | 
					
						
							|  |  |  | 				return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) { | 
					
						
							|  |  |  | 					preloadedFiles.push({ | 
					
						
							|  |  |  | 						name: pathOrBuffer, | 
					
						
							|  |  |  | 						buffer: xhr.response | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				throw Promise.reject("Invalid object for preloading"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.start = function() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return this.init().then( | 
					
						
							|  |  |  | 				Function.prototype.apply.bind(synchronousStart, this, arguments) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.startGame = function(mainPack) { | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 			executableName = getBaseName(mainPack); | 
					
						
							|  |  |  | 			return Promise.all([this.init(getBasePath(mainPack)), this.preloadFile(mainPack)]).then( | 
					
						
							|  |  |  | 				Function.prototype.apply.bind(synchronousStart, this, []) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		function synchronousStart() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			if (canvas instanceof HTMLCanvasElement) { | 
					
						
							|  |  |  | 				this.rtenv.canvas = canvas; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				var firstCanvas = document.getElementsByTagName('canvas')[0]; | 
					
						
							|  |  |  | 				if (firstCanvas instanceof HTMLCanvasElement) { | 
					
						
							|  |  |  | 					this.rtenv.canvas = firstCanvas; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					throw new Error("No canvas found"); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var actualCanvas = this.rtenv.canvas; | 
					
						
							|  |  |  | 			// canvas can grab focus on click
 | 
					
						
							|  |  |  | 			if (actualCanvas.tabIndex < 0) { | 
					
						
							|  |  |  | 				actualCanvas.tabIndex = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// necessary to calculate cursor coordinates correctly
 | 
					
						
							|  |  |  | 			actualCanvas.style.padding = 0; | 
					
						
							|  |  |  | 			actualCanvas.style.borderWidth = 0; | 
					
						
							|  |  |  | 			actualCanvas.style.borderStyle = 'none'; | 
					
						
							|  |  |  | 			// until context restoration is implemented
 | 
					
						
							|  |  |  | 			actualCanvas.addEventListener('webglcontextlost', function(ev) { | 
					
						
							|  |  |  | 				alert("WebGL context lost, please reload the page"); | 
					
						
							|  |  |  | 				ev.preventDefault(); | 
					
						
							|  |  |  | 			}, false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 			if (locale) { | 
					
						
							|  |  |  | 				this.rtenv.locale = locale; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				this.rtenv.locale = navigator.languages ? navigator.languages[0] : navigator.language; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			this.rtenv.locale = this.rtenv.locale.split('.')[0]; | 
					
						
							|  |  |  | 			this.rtenv.resizeCanvasOnStart = resizeCanvasOnStart; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.rtenv.thisProgram = executableName || getBaseName(basePath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			preloadedFiles.forEach(function(file) { | 
					
						
							|  |  |  | 				this.rtenv.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true); | 
					
						
							|  |  |  | 			}, this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			preloadedFiles = null; | 
					
						
							|  |  |  | 			initPromise = null; | 
					
						
							|  |  |  | 			this.rtenv.callMain(arguments); | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.setProgressFunc = function(func) { | 
					
						
							|  |  |  | 			progressFunc = func; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		this.setResizeCanvasOnStart = function(enabled) { | 
					
						
							|  |  |  | 			resizeCanvasOnStart = enabled; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		function animateProgress() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var loaded = 0; | 
					
						
							|  |  |  | 			var total = 0; | 
					
						
							|  |  |  | 			var totalIsValid = true; | 
					
						
							|  |  |  | 			var progressIsFinal = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 			[loadingFiles, preloadProgressTracker].forEach(function(tracker) { | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 				Object.keys(tracker).forEach(function(file) { | 
					
						
							|  |  |  | 					if (!tracker[file].final) | 
					
						
							|  |  |  | 						progressIsFinal = false; | 
					
						
							|  |  |  | 					if (!totalIsValid || tracker[file].total === 0) { | 
					
						
							|  |  |  | 						totalIsValid = false; | 
					
						
							|  |  |  | 						total = 0; | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						total += tracker[file].total; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					loaded += tracker[file].loaded; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			if (loaded !== lastProgress.loaded || total !== lastProgress.total) { | 
					
						
							|  |  |  | 				lastProgress.loaded = loaded; | 
					
						
							|  |  |  | 				lastProgress.total = total; | 
					
						
							|  |  |  | 				if (typeof progressFunc === 'function') | 
					
						
							|  |  |  | 					progressFunc(loaded, total); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!progressIsFinal) | 
					
						
							|  |  |  | 				requestAnimationFrame(animateProgress); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.setCanvas = function(elem) { | 
					
						
							|  |  |  | 			canvas = elem; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		this.setExecutableName = function(newName) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			executableName = newName; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.setLocale = function(newLocale) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			locale = newLocale; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		this.setUnloadAfterInit = function(enabled) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 			if (enabled && !unloadAfterInit && initPromise) { | 
					
						
							|  |  |  | 				initPromise.then(Engine.unloadEngine); | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			unloadAfterInit = enabled; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.setStdoutFunc = function(func) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var print = function(text) { | 
					
						
							|  |  |  | 				if (arguments.length > 1) { | 
					
						
							|  |  |  | 					text = Array.prototype.slice.call(arguments).join(" "); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				func(text); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			if (this.rtenv) | 
					
						
							|  |  |  | 				this.rtenv.print = print; | 
					
						
							|  |  |  | 			stdout = print; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.setStderrFunc = function(func) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var printErr = function(text) { | 
					
						
							|  |  |  | 				if (arguments.length > 1) | 
					
						
							|  |  |  | 					text = Array.prototype.slice.call(arguments).join(" "); | 
					
						
							|  |  |  | 				func(text); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			if (this.rtenv) | 
					
						
							|  |  |  | 				this.rtenv.printErr = printErr; | 
					
						
							|  |  |  | 			stderr = printErr; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	}; // Engine()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Engine.RuntimeEnvironment = engine.RuntimeEnvironment; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-15 04:00:32 +01:00
										 |  |  | 	Engine.isWebGLAvailable = function(majorVersion = 1) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var testContext = false; | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			var testCanvas = document.createElement('canvas'); | 
					
						
							|  |  |  | 			if (majorVersion === 1) { | 
					
						
							|  |  |  | 				testContext = testCanvas.getContext('webgl') || testCanvas.getContet('experimental-webgl'); | 
					
						
							|  |  |  | 			} else if (majorVersion === 2) { | 
					
						
							|  |  |  | 				testContext = testCanvas.getContext('webgl2') || testCanvas.getContet('experimental-webgl2'); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} catch (e) {} | 
					
						
							|  |  |  | 		return !!testContext; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 	Engine.load = function(newBasePath) { | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (newBasePath !== undefined) basePath = getBasePath(newBasePath); | 
					
						
							|  |  |  | 		if (engineLoadPromise === null) { | 
					
						
							| 
									
										
										
										
											2017-11-18 05:50:26 +01:00
										 |  |  | 			if (typeof WebAssembly !== 'object') | 
					
						
							|  |  |  | 				return Promise.reject(new Error("Browser doesn't support WebAssembly")); | 
					
						
							|  |  |  | 			// TODO cache/retrieve module to/from idb
 | 
					
						
							|  |  |  | 			engineLoadPromise = loadPromise(basePath + '.wasm').then(function(xhr) { | 
					
						
							|  |  |  | 				return xhr.response; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			engineLoadPromise = engineLoadPromise.catch(function(err) { | 
					
						
							|  |  |  | 				engineLoadPromise = null; | 
					
						
							|  |  |  | 				throw err; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return engineLoadPromise; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 	Engine.unload = function() { | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 		engineLoadPromise = null; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function loadPromise(file, tracker) { | 
					
						
							|  |  |  | 		if (tracker === undefined) | 
					
						
							|  |  |  | 			tracker = loadingFiles; | 
					
						
							|  |  |  | 		return new Promise(function(resolve, reject) { | 
					
						
							|  |  |  | 			loadXHR(resolve, reject, file, tracker); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function loadXHR(resolve, reject, file, tracker) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var xhr = new XMLHttpRequest; | 
					
						
							|  |  |  | 		xhr.open('GET', file); | 
					
						
							|  |  |  | 		if (!file.endsWith('.js')) { | 
					
						
							|  |  |  | 			xhr.responseType = 'arraybuffer'; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 		['loadstart', 'progress', 'load', 'error', 'abort'].forEach(function(ev) { | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			xhr.addEventListener(ev, onXHREvent.bind(xhr, resolve, reject, file, tracker)); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		xhr.send(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function onXHREvent(resolve, reject, file, tracker, ev) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (this.status >= 400) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (this.status < 500 || ++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) { | 
					
						
							|  |  |  | 				reject(new Error("Failed loading file '" + file + "': " + this.statusText)); | 
					
						
							|  |  |  | 				this.abort(); | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 				setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000); | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch (ev.type) { | 
					
						
							|  |  |  | 			case 'loadstart': | 
					
						
							|  |  |  | 				if (tracker[file] === undefined) { | 
					
						
							|  |  |  | 					tracker[file] = { | 
					
						
							|  |  |  | 						total: ev.total, | 
					
						
							|  |  |  | 						loaded: ev.loaded, | 
					
						
							|  |  |  | 						attempts: 0, | 
					
						
							|  |  |  | 						final: false, | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case 'progress': | 
					
						
							|  |  |  | 				tracker[file].loaded = ev.loaded; | 
					
						
							|  |  |  | 				tracker[file].total = ev.total; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case 'load': | 
					
						
							|  |  |  | 				tracker[file].final = true; | 
					
						
							|  |  |  | 				resolve(this); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case 'error': | 
					
						
							|  |  |  | 				if (++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) { | 
					
						
							|  |  |  | 					tracker[file].final = true; | 
					
						
							|  |  |  | 					reject(new Error("Failed loading file '" + file + "'")); | 
					
						
							|  |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-11-19 15:30:09 +01:00
										 |  |  | 					setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000); | 
					
						
							| 
									
										
										
										
											2017-08-13 13:10:04 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case 'abort': | 
					
						
							|  |  |  | 				tracker[file].final = true; | 
					
						
							|  |  |  | 				reject(new Error("Loading file '" + file + "' was aborted.")); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | })(); |