From 2a87aa16f69d1cfe755baa28ce11b03d6112099c Mon Sep 17 00:00:00 2001
From: danielyxie <danielyxie@gmail.com>
Date: Sat, 5 May 2018 15:23:57 -0500
Subject: [PATCH] Added metakey + b hotkey compatibility for script editor
 close and save. Refactored Server constructor and initialization

---
 dist/bundle.js         | 41381 ++++++++++++++++++++-------------------
 src/ActiveScriptsUI.js |     1 +
 src/Constants.js       |     2 +
 src/Player.js          |     2 +-
 src/Script.js          |     2 +-
 src/Server.js          |   710 +-
 6 files changed, 21192 insertions(+), 20906 deletions(-)

diff --git a/dist/bundle.js b/dist/bundle.js
index 994fd930a..df20086f4 100644
--- a/dist/bundle.js
+++ b/dist/bundle.js
@@ -81,27 +81,27 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Player", function() { return Player; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadPlayer", function() { return loadPlayer; });
 /* harmony import */ var _Augmentations_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Augmentations.js */ 18);
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BitNode.js */ 16);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BitNode.js */ 15);
 /* harmony import */ var _Company_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Company.js */ 9);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _CompanyManagement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CompanyManagement.js */ 40);
-/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./CreateProgram.js */ 13);
+/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./CreateProgram.js */ 14);
 /* harmony import */ var _Crimes_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Crimes.js */ 19);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Faction.js */ 14);
-/* harmony import */ var _Gang_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Gang.js */ 35);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Faction.js */ 11);
+/* harmony import */ var _Gang_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Gang.js */ 36);
 /* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Location.js */ 4);
-/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 30);
+/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 29);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
-/* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./SourceFile.js */ 44);
+/* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./SourceFile.js */ 42);
 /* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/decimal.js */ 23);
 /* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_15__);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/IPAddress.js */ 15);
+/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16);
 /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
 /* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_20__);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
 
@@ -1512,8 +1512,8 @@ PlayerObject.prototype.takeClass = function(numCycles) {
                     "$" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workMoneyGained, 2) + " ($" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workMoneyLossRate * cyclesPerSec, 2) + " / sec) <br><br>" +
                     "You have gained: <br>" +
                     Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workHackExpGained, 4) + " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workHackExpGainRate * cyclesPerSec, 4) + " / sec) hacking exp <br>" +
-                    Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workDefExpGained, 4) + " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workDefExpGainRate * cyclesPerSec, 4) + " / sec) defense exp <br>" +
                     Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workStrExpGained, 4) + " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workStrExpGainRate * cyclesPerSec, 4) + " / sec) strength exp <br>" +
+                    Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workDefExpGained, 4) + " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workDefExpGainRate * cyclesPerSec, 4) + " / sec) defense exp <br>" +
                     Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workDexExpGained, 4) + " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workDexExpGainRate * cyclesPerSec, 4) + " / sec) dexterity exp <br>" +
                     Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workAgiExpGained, 4) + " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workAgiExpGainRate * cyclesPerSec, 4) + " / sec) agility exp <br>" +
                     Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workChaExpGained, 4) + " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_21__["formatNumber"])(this.workChaExpGainRate * cyclesPerSec, 4) + " / sec) charisma exp <br>" +
@@ -4089,6 +4089,8 @@ let CONSTANTS = {
                                "World Stock Exchange account and TIX API Access<br>",
 
     LatestUpdate:
+    "v0.36.1<br>" +
+    "* The ctrl+b hotkey in the text editor is now also triggered by command+b or winkey+b<br>" +
     "v0.36.0<br>" +
     "* Added BN-6: Bladeburners<br>" +
     "* Rebalanced many combat Augmentations so that they are slightly less powerful<br>" +
@@ -4111,25 +4113,25 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Locations", function() { return Locations; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayLocationContent", function() { return displayLocationContent; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initLocationButtons", function() { return initLocationButtons; });
-/* harmony import */ var _Bladeburner_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Bladeburner.js */ 45);
+/* harmony import */ var _Bladeburner_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Bladeburner.js */ 47);
 /* harmony import */ var _Company_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Company.js */ 9);
 /* harmony import */ var _CompanyManagement_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CompanyManagement.js */ 40);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _Crimes_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Crimes.js */ 19);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Infiltration_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Infiltration.js */ 113);
-/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 30);
+/* harmony import */ var _Infiltration_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Infiltration.js */ 112);
+/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 29);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Player.js */ 0);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _ServerPurchases_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ServerPurchases.js */ 78);
 /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/IPAddress.js */ 15);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
+/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
 /* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_15__);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
 
 
 
@@ -6323,40 +6325,40 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_GameOptions_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/GameOptions.js */ 54);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
 /* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_3__);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-/* harmony import */ var _utils_LogBox_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/LogBox.js */ 50);
-/* harmony import */ var _ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ActiveScriptsUI.js */ 42);
+/* harmony import */ var _utils_LogBox_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/LogBox.js */ 51);
+/* harmony import */ var _ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ActiveScriptsUI.js */ 43);
 /* harmony import */ var _Augmentations_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Augmentations.js */ 18);
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./BitNode.js */ 16);
-/* harmony import */ var _Bladeburner_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Bladeburner.js */ 45);
-/* harmony import */ var _CinematicText_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./CinematicText.js */ 66);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./BitNode.js */ 15);
+/* harmony import */ var _Bladeburner_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Bladeburner.js */ 47);
+/* harmony import */ var _CinematicText_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./CinematicText.js */ 67);
 /* harmony import */ var _Company_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./Company.js */ 9);
 /* harmony import */ var _CompanyManagement_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./CompanyManagement.js */ 40);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./CreateProgram.js */ 13);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Faction.js */ 14);
+/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./CreateProgram.js */ 14);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Faction.js */ 11);
 /* harmony import */ var _Fconf_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Fconf.js */ 34);
 /* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Location.js */ 4);
-/* harmony import */ var _Gang_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Gang.js */ 35);
-/* harmony import */ var _HacknetNode_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./HacknetNode.js */ 38);
+/* harmony import */ var _Gang_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Gang.js */ 36);
+/* harmony import */ var _HacknetNode_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./HacknetNode.js */ 39);
 /* harmony import */ var _InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./InteractiveTutorial.js */ 25);
 /* harmony import */ var _Literature_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./Literature.js */ 53);
 /* harmony import */ var _Message_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./Message.js */ 27);
 /* harmony import */ var _Missions_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./Missions.js */ 32);
-/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 30);
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
+/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 29);
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _Prestige_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./Prestige.js */ 67);
-/* harmony import */ var _RedPill_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./RedPill.js */ 49);
-/* harmony import */ var _SaveObject_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./SaveObject.js */ 51);
-/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./Script.js */ 29);
+/* harmony import */ var _Prestige_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./Prestige.js */ 57);
+/* harmony import */ var _RedPill_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./RedPill.js */ 44);
+/* harmony import */ var _SaveObject_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./SaveObject.js */ 46);
+/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./Script.js */ 28);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./Settings.js */ 24);
-/* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./SourceFile.js */ 44);
+/* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./SourceFile.js */ 42);
 /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
-/* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./StockMarket.js */ 20);
+/* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./StockMarket.js */ 21);
 /* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./Terminal.js */ 22);
 
 
@@ -8109,7 +8111,7 @@ window.onload = function() {
 
 
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
 
 /***/ }),
 /* 6 */
@@ -8195,7 +8197,7 @@ function dialogBoxCreate(txt, preformatted=false) {
 
 
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
 
 /***/ }),
 /* 7 */
@@ -8219,18 +8221,18 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isScriptErrorMessage", function() { return isScriptErrorMessage; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "killNetscriptDelay", function() { return killNetscriptDelay; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "evaluateImport", function() { return evaluateImport; });
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 16);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./NetscriptEnvironment.js */ 65);
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
+/* harmony import */ var _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./NetscriptEnvironment.js */ 66);
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Settings.js */ 24);
-/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Script.js */ 29);
-/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/acorn.js */ 36);
+/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Script.js */ 28);
+/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/acorn.js */ 35);
 /* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/IPAddress.js */ 15);
+/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
 
 
@@ -8246,7 +8248,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-var Promise = __webpack_require__(/*! bluebird */ 167);
+var Promise = __webpack_require__(/*! bluebird */ 115);
 
 Promise.config({
     warnings: false,
@@ -10435,14 +10437,14 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initForeignServers", function() { return initForeignServers; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prestigeAllServers", function() { return prestigeAllServers; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prestigeHomeComputer", function() { return prestigeHomeComputer; });
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 16);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CreateProgram.js */ 13);
+/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CreateProgram.js */ 14);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Script.js */ 29);
+/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Script.js */ 28);
 /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/IPAddress.js */ 15);
+/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16);
 /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
 
 
@@ -10454,11 +10456,12 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-function Server(ip=Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname="", organizationName="",
-                isConnectedTo=false, adminRights=false, purchasedByPlayer=false, maxRam=0) {
-	/* Properties */
-	//Connection information
-	this.ip					= 	ip;
+function Server(params={ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:""}) {
+    /* Properties */
+    //Connection information
+    this.ip = params.ip ? params.ip : Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])();
+
+    var hostname = params.hostname;
     var i = 0;
     var suffix = "";
     while (GetServerByHostname(hostname+suffix) != null) {
@@ -10466,76 +10469,74 @@ function Server(ip=Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["crea
         suffix = "-" + i;
         ++i;
     }
-	this.hostname			= 	hostname + suffix;
-	this.organizationName 	= 	organizationName;
-	this.isConnectedTo		= 	isConnectedTo;	//Whether the player is connected to this server
+    this.hostname           =     hostname + suffix;
+    this.organizationName   =     params.organizationName   ? params.organizationName   : "";
+    this.isConnectedTo      =     params.isConnectedTo      ? params.isConnectedTo      : false;
 
-	//Access information
-	this.hasAdminRights		=	adminRights;	//Whether player has admin rights
-	this.purchasedByPlayer	=	purchasedByPlayer;
-    this.manuallyHacked     =   false;  //Flag that tracks whether or not the server has been hacked at least once
+    //Access information
+    this.hasAdminRights     =    params.adminRights         ? params.adminRights        : false;
+    this.purchasedByPlayer  =    params.purchasedByPlayer   ? params.purchasedByPlayer  : false;
+    this.manuallyHacked     =    false;  //Flag that tracks whether or not the server has been hacked at least once
 
-	//RAM, CPU speed and Scripts
-	this.maxRam			=	maxRam;  //GB
-	this.ramUsed		=	0;
-	this.cpuCores		= 	1;       //Max of 8, affects hacking times and Hacking Mission starting Cores
+    //RAM, CPU speed and Scripts
+    this.maxRam     = params.maxRam ? params.maxRam : 0;  //GB
+    this.ramUsed    = 0;
+    this.cpuCores   = 1; //Max of 8, affects hacking times and Hacking Mission starting Cores
 
-	this.scripts 		= 	[];
-	this.runningScripts = 	[]; 	//Stores RunningScript objects
-	this.programs 		= 	[];
-    this.messages       =   [];
-    this.textFiles      =   [];
-    this.dir            =   0; //new Directory(this, null, "");
+    this.scripts        = [];
+    this.runningScripts = [];   //Stores RunningScript objects
+    this.programs       = [];
+    this.messages       = [];
+    this.textFiles      = [];
+    this.dir            = 0;    //new Directory(this, null, ""); TODO
 
-	/* Hacking information (only valid for "foreign" aka non-purchased servers) */
-	//Skill required to attempt a hack. Whether a hack is successful will be determined
-	//by a separate formula
-	this.requiredHackingSkill	= 1;
+    /* Hacking information (only valid for "foreign" aka non-purchased servers) */
+    this.requiredHackingSkill   = params.requiredHackingSkill   ? params.requiredHackingSkill : 1;
+    this.moneyAvailable         = params.moneyAvailable         ? params.moneyAvailable * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].ServerStartingMoney : 1e6;
+    this.moneyMax               = 25 * this.moneyAvailable * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].ServerMaxMoney;
 
-	//Total money available on this server
-	this.moneyAvailable 		= 0;
-    this.moneyMax               = 0;
+    //Hack Difficulty is synonymous with server security. Base Difficulty = Starting difficulty
+    this.hackDifficulty         = params.hackDifficulty ? params.hackDifficulty * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].ServerStartingSecurity : 1;
+    this.baseDifficulty         = this.hackDifficulty;
+    this.minDifficulty          = Math.max(1, Math.round(this.hackDifficulty / 3));
+    this.serverGrowth           = params.serverGrowth   ? params.serverGrowth : 1; //Integer from 0 to 100. Affects money increase from grow()
 
-	//Parameters used in formulas that dictate how moneyAvailable and requiredHackingSkill change.
-	this.hackDifficulty			= 1;	//Affects hack success rate and how the requiredHackingSkill increases over time (1-100)
-    this.baseDifficulty         = 1;    //Starting difficulty
-    this.minDifficulty          = 1;
-	this.serverGrowth			= 0;	//Affects how the moneyAvailable increases (0-100)
-
-	//The IP's of all servers reachable from this one (what shows up if you run scan/netstat)
+    //The IP's of all servers reachable from this one (what shows up if you run scan/netstat)
     //  NOTE: Only contains IP and not the Server objects themselves
-	this.serversOnNetwork		= [];
+    this.serversOnNetwork        = [];
 
-	//Port information, required for porthacking servers to get admin rights
-	this.numOpenPortsRequired 	= 5;
-	this.sshPortOpen 			= false;	//Port 22
-	this.ftpPortOpen 			= false;	//Port 21
-	this.smtpPortOpen 			= false;	//Port 25
-	this.httpPortOpen			= false;	//Port 80
-	this.sqlPortOpen 			= false; 	//Port 1433
-	this.openPortCount 			= 0;
+    //Port information, required for porthacking servers to get admin rights
+    this.numOpenPortsRequired = params.numOpenPortsRequired ? params.numOpenPortsRequired : 5;
+    this.sshPortOpen          = false;    //Port 22
+    this.ftpPortOpen          = false;    //Port 21
+    this.smtpPortOpen         = false;    //Port 25
+    this.httpPortOpen         = false;    //Port 80
+    this.sqlPortOpen          = false;    //Port 1433
+    this.openPortCount        = 0;
 };
 
+/*
 //Set the hacking properties of a server
 Server.prototype.setHackingParameters = function(requiredHackingSkill, moneyAvailable, hackDifficulty, serverGrowth) {
-	this.requiredHackingSkill = requiredHackingSkill;
+    this.requiredHackingSkill = requiredHackingSkill;
     if (isNaN(moneyAvailable)) {
         this.moneyAvailable = 1e6;
     } else {
-        this.moneyAvailable = moneyAvailable * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].ServerStartingMoney;
+        this.moneyAvailable = moneyAvailable * BitNodeMultipliers.ServerStartingMoney;
     }
-    this.moneyMax = 25 * this.moneyAvailable * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].ServerMaxMoney;
-	this.hackDifficulty = hackDifficulty * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].ServerStartingSecurity;
-    this.baseDifficulty = hackDifficulty * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].ServerStartingSecurity;
+    this.moneyMax =
+    this.hackDifficulty = hackDifficulty * BitNodeMultipliers.ServerStartingSecurity;
+    this.baseDifficulty = hackDifficulty * BitNodeMultipliers.ServerStartingSecurity;
     this.minDifficulty = Math.max(1, Math.round(this.hackDifficulty / 3));
-	this.serverGrowth = serverGrowth;
+    this.serverGrowth = serverGrowth;
 }
 
 //Set the port properties of a server
 //Right now its only the number of open ports needed to PortHack the server.
 Server.prototype.setPortProperties = function(numOpenPortsReq) {
-	this.numOpenPortsRequired = numOpenPortsReq;
+    this.numOpenPortsRequired = numOpenPortsReq;
 }
+*/
 
 Server.prototype.setMaxRam = function(ram) {
     this.maxRam = ram;
@@ -10554,12 +10555,12 @@ Server.prototype.getServerOnNetwork = function(i) {
 //Given the name of the script, returns the corresponding
 //script object on the server (if it exists)
 Server.prototype.getScript = function(scriptName) {
-	for (var i = 0; i < this.scripts.length; i++) {
-		if (this.scripts[i].filename == scriptName) {
-			return this.scripts[i];
-		}
-	}
-	return null;
+    for (var i = 0; i < this.scripts.length; i++) {
+        if (this.scripts[i].filename == scriptName) {
+            return this.scripts[i];
+        }
+    }
+    return null;
 }
 
 //Strengthens a server's security level (difficulty) by the specified amount
@@ -10578,413 +10579,554 @@ Server.prototype.weaken = function(amt) {
 
 //Functions for loading and saving a Server
 Server.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_8__["Generic_toJSON"])("Server", this);
+    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_8__["Generic_toJSON"])("Server", this);
 }
 
 Server.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_8__["Generic_fromJSON"])(Server, value.data);
+    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_8__["Generic_fromJSON"])(Server, value.data);
 }
 
 _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_8__["Reviver"].constructors.Server = Server;
 
 function initForeignServers() {
     //MegaCorporations
-    var ECorpServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "ecorp", "ECorp", false, false, false, 0);
-    ECorpServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1150, 1300), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(30000000000, 70000000000), 99, 99);
-    ECorpServer.setPortProperties(5);
+    var ECorpServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"ecorp", organizationName:"ECorp",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1150, 1300), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(30e9, 70e9),
+        hackDifficulty:99,serverGrowth:99, numOpenPortsRequired: 5,
+    });
     AddToAllServers(ECorpServer);
 
-    var MegaCorpServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "megacorp", "MegaCorp", false, false, false, 0);
-    MegaCorpServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1150, 1300), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40000000000, 60000000000), 99, 99);
-    MegaCorpServer.setPortProperties(5);
+    var MegaCorpServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"megacorp", organizationName:"MegaCorp",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1150, 1300), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40e9, 60e9),
+        hackDifficulty:99, serverGrowth:99, numOpenPortsRequired:5
+    });
     AddToAllServers(MegaCorpServer);
 
-    var BachmanAndAssociatesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "b-and-a", "Bachman & Associates", false, false, false, 0);
-    BachmanAndAssociatesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1050), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(20000000000, 25000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 75));
-    BachmanAndAssociatesServer.setPortProperties(5);
+    var BachmanAndAssociatesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"b-and-a", organizationName:"Bachman & Associates",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1050), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(20e9, 25e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 75), numOpenPortsRequired:5
+    });
     AddToAllServers(BachmanAndAssociatesServer);
 
-    var BladeIndustriesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "blade", "Blade Industries", false, false, false, 2);
-    BladeIndustriesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1100), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(12000000000, 20000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(90, 95), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 75));
-    BladeIndustriesServer.setPortProperties(5);
+    var BladeIndustriesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"blade", organizationName:"Blade Industries", maxRam:128,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1100), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(12e9, 20e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(90, 95), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 75), numOpenPortsRequired:5
+    });
     BladeIndustriesServer.messages.push("beyond-man.lit");
     AddToAllServers(BladeIndustriesServer);
 
-    var NWOServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "nwo", "New World Order", false, false, false, 2);
-    NWOServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1200), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(25000000000, 35000000000), 99, Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85));
-    NWOServer.setPortProperties(5);
+    var NWOServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"nwo", organizationName:"New World Order",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1200), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(25e9, 35e9),
+        hackDifficulty:99, serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85), numOpenPortsRequired:5
+    });
     NWOServer.messages.push("the-hidden-world.lit");
     AddToAllServers(NWOServer);
 
-    var ClarkeIncorporatedServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "clarkeinc", "Clarke Incorporated", false, false, false, 2);
-    ClarkeIncorporatedServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1200), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(15000000000, 25000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 60), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 70));
-    ClarkeIncorporatedServer.setPortProperties(5);
+    var ClarkeIncorporatedServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"clarkeinc", organizationName:"Clarke Incorporated",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1200), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(15e9, 25e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 60), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 70), numOpenPortsRequired:5
+    });
     ClarkeIncorporatedServer.messages.push("beyond-man.lit");
     ClarkeIncorporatedServer.messages.push("cost-of-immortality.lit");
     AddToAllServers(ClarkeIncorporatedServer);
 
-    var OmniTekIncorporatedServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "omnitek", "OmniTek Incorporated", false, false, false, 2);
-    OmniTekIncorporatedServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900, 1100), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(15000000000, 20000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(90, 99), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(95, 99));
-    OmniTekIncorporatedServer.setPortProperties(5);
+    var OmniTekIncorporatedServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"omnitek", organizationName:"OmniTek Incorporated", maxRam:256,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900, 1100), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(15e9, 20e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(90, 99), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(95, 99), numOpenPortsRequired:5
+    });
     OmniTekIncorporatedServer.messages.push("coded-intelligence.lit");
+    OmniTekIncorporatedServer.messages.push("history-of-synthoids.lit");
     AddToAllServers(OmniTekIncorporatedServer);
 
-    var FourSigmaServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "4sigma", "FourSigma", false, false, false, 0);
-    FourSigmaServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(950, 1200), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(15000000000, 25000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 70), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 99));
-    FourSigmaServer.setPortProperties(5);
+    var FourSigmaServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"4sigma", organizationName:"FourSigma",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(950, 1200), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(15e9, 25e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 70), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 99), numOpenPortsRequired:5
+    });
     AddToAllServers(FourSigmaServer);
 
-    var KuaiGongInternationalServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "kuai-gong", "KuaiGong International", false, false, false, 0);
-    KuaiGongInternationalServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1250), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(20000000000, 30000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(95, 99), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(90, 99));
-    KuaiGongInternationalServer.setPortProperties(5);
+    var KuaiGongInternationalServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"kuai-gong", organizationName:"KuaiGong International",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1250), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(20e9, 30e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(95, 99), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(90, 99), numOpenPortsRequired:5,
+    });
     AddToAllServers(KuaiGongInternationalServer);
 
     //Technology and communications companies (large targets)
-    var FulcrumTechnologiesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "fulcrumtech", "Fulcrum Technologies", false, false, false, 64);
-    FulcrumTechnologiesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1200), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1400000000, 1800000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 99));
-    FulcrumTechnologiesServer.setPortProperties(5);
+    var FulcrumTechnologiesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"fulcrumtech", organizationName:"Fulcrum Technologies", maxRam:512,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000, 1200), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1.4e9, 1.8e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 99), numOpenPortsRequired:5
+    });
     FulcrumTechnologiesServer.messages.push("simulated-reality.lit");
     AddToAllServers(FulcrumTechnologiesServer);
 
-    var FulcrumSecretTechnologiesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "fulcrumassets", "Fulcrum Technologies Assets", false, false, false, 0);
-    FulcrumSecretTechnologiesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1200, 1500), 1000000, 99, 1);
-    FulcrumSecretTechnologiesServer.setPortProperties(5);
+    var FulcrumSecretTechnologiesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"fulcrumassets", organizationName:"Fulcrum Technologies Assets",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1200, 1500), moneyAvailable:1e6,
+        hackDifficulty:99, serverGrowth:1, numOpenPortsRequired:5
+    });
     AddToAllServers(FulcrumSecretTechnologiesServer);
-	_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].FulcrumSecretTechnologies, FulcrumSecretTechnologiesServer.ip);
+    _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].FulcrumSecretTechnologies, FulcrumSecretTechnologiesServer.ip);
 
-    var StormTechnologiesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "stormtech", "Storm Technologies", false, false, false, 0);
-    StormTechnologiesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900, 1050), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000000000, 1200000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90));
-    StormTechnologiesServer.setPortProperties(5);
+    var StormTechnologiesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"stormtech", organizationName:"Storm Technologies",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900, 1050), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1e9, 1.2e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90), numOpenPortsRequired:5
+    });
     AddToAllServers(StormTechnologiesServer);
 
-    var DefCommServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "defcomm", "DefComm", false, false, false, 0);
-    DefCommServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900, 1000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800000000, 950000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 70));
-    DefCommServer.setPortProperties(5);
+    var DefCommServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"defcomm", organizationName:"DefComm",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900, 1000), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800e6, 950e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 70), numOpenPortsRequired:5
+    });
     AddToAllServers(DefCommServer);
 
-    var InfoCommServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "infocomm", "InfoComm", false, false, false, 0);
-    InfoCommServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(875, 950), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(600000000, 900000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 75));
-    InfoCommServer.setPortProperties(5);
+    var InfoCommServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"infocomm", organizationName:"InfoComm",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(875, 950), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(600e6, 900e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 75), numOpenPortsRequired:5
+    });
     AddToAllServers(InfoCommServer);
 
-    var HeliosLabsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "helios", "Helios Labs", false, false, false, 2);
-    HeliosLabsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 900), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(550000000, 750000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80));
-    HeliosLabsServer.setPortProperties(5);
+    var HeliosLabsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"helios", organizationName:"Helios Labs", maxRam:128,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 900), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(550e6, 750e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), numOpenPortsRequired:5
+    });
     HeliosLabsServer.messages.push("beyond-man.lit");
     AddToAllServers(HeliosLabsServer);
 
-    var VitaLifeServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "vitalife", "VitaLife", false, false, false, 32);
-    VitaLifeServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 900), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(700000000, 800000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80));
-    VitaLifeServer.setPortProperties(5);
+    var VitaLifeServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"vitalife", organizationName:"VitaLife", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 900), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(700e6, 800e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), numOpenPortsRequired:5
+    });
     VitaLifeServer.messages.push("A-Green-Tomorrow.lit");
     AddToAllServers(VitaLifeServer);
 
-    var IcarusMicrosystemsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "icarus", "Icarus Microsystems", false, false, false, 0);
-    IcarusMicrosystemsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(850, 925), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900000000, 1000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95));
-    IcarusMicrosystemsServer.setPortProperties(5);
+    var IcarusMicrosystemsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"icarus", organizationName:"Icarus Microsystems",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(850, 925), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900e6, 1000e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), numOpenPortsRequired:5
+    });
     AddToAllServers(IcarusMicrosystemsServer);
 
-    var UniversalEnergyServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "univ-energy", "Universal Energy", false, false, false, 32);
-    UniversalEnergyServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 900), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1100000000, 1200000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90));
-    UniversalEnergyServer.setPortProperties(4);
+    var UniversalEnergyServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"univ-energy", organizationName:"Universal Energy", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 900), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1.1e9, 1.2e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), numOpenPortsRequired:4
+    });
     AddToAllServers(UniversalEnergyServer);
 
-    var TitanLabsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "titan-labs", "Titan Laboratories", false, false, false, 32);
-    TitanLabsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 875), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(750000000, 900000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80));
-    TitanLabsServer.setPortProperties(5);
+    var TitanLabsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"titan-labs", organizationName:"Titan Laboratories", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 875), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(750e6, 900e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), numOpenPortsRequired:5
+    });
     TitanLabsServer.messages.push("coded-intelligence.lit");
     AddToAllServers(TitanLabsServer);
 
-    var MicrodyneTechnologiesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "microdyne", "Microdyne Technologies", false, false, false, 16);
-    MicrodyneTechnologiesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 875), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(500000000, 700000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 75), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90));
-    MicrodyneTechnologiesServer.setPortProperties(5);
+    var MicrodyneTechnologiesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"microdyne", organizationName:"Microdyne Technologies", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 875), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(500e6, 700e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 75), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90), numOpenPortsRequired:5
+    });
     MicrodyneTechnologiesServer.messages.push("synthetic-muscles.lit");
     AddToAllServers(MicrodyneTechnologiesServer);
 
-    var TaiYangDigitalServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "taiyang-digital", "Taiyang Digital", false, false, false, 2);
-    TaiYangDigitalServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(850, 950), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800000000, 900000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80));
-    TaiYangDigitalServer.setPortProperties(5);
+    var TaiYangDigitalServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"taiyang-digital", organizationName:"Taiyang Digital",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(850, 950), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800e6, 900e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), numOpenPortsRequired:5
+    });
     TaiYangDigitalServer.messages.push("A-Green-Tomorrow.lit");
     TaiYangDigitalServer.messages.push("brighter-than-the-sun.lit");
     AddToAllServers(TaiYangDigitalServer);
 
-    var GalacticCyberSystemsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "galactic-cyber", "Galactic Cybersystems", false, false, false, 0);
-    GalacticCyberSystemsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(825, 875), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(750000000, 850000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90));
-    GalacticCyberSystemsServer.setPortProperties(5);
+    var GalacticCyberSystemsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"galactic-cyber", organizationName:"Galactic Cybersystems",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(825, 875), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(750e6, 850e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90), numOpenPortsRequired:5
+    });
     AddToAllServers(GalacticCyberSystemsServer);
 
     //Defense Companies ("Large" Companies)
-    var AeroCorpServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "aerocorp", "AeroCorp", false, false, false, 2);
-    AeroCorpServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(850, 925), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000000000, 1200000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65));
-    AeroCorpServer.setPortProperties(5);
+    var AeroCorpServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"aerocorp", organizationName:"AeroCorp",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(850, 925), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1e9, 1.2e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), numOpenPortsRequired:5
+    });
     AeroCorpServer.messages.push("man-and-machine.lit");
     AddToAllServers(AeroCorpServer);
 
-    var OmniaCybersystemsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "omnia", "Omnia Cybersystems", false, false, false, 0);
-    OmniaCybersystemsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(850, 950), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900000000, 1000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 70));
-    OmniaCybersystemsServer.setPortProperties(5);
+    var OmniaCybersystemsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"omnia", organizationName:"Omnia Cybersystems", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(850, 950), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900e6, 1e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(85, 95), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 70), numOpenPortsRequired:5
+    });
+    OmniaCybersystemsServer.messages.push("history-of-synthoids.lit");
     AddToAllServers(OmniaCybersystemsServer);
 
-    var ZBDefenseServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "zb-def", "ZB Defense Industries", false, false, false, 2);
-    ZBDefenseServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 825), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900000000, 1100000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 75));
-    ZBDefenseServer.setPortProperties(4);
+    var ZBDefenseServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"zb-def", organizationName:"ZB Defense Industries",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 825), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(900e6, 1.1e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 75), numOpenPortsRequired:4
+    });
     ZBDefenseServer.messages.push("synthetic-muscles.lit");
     AddToAllServers(ZBDefenseServer);
 
-    var AppliedEnergeticsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "applied-energetics", "Applied Energetics", false, false, false, 0);
-    AppliedEnergeticsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 850), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(700000000, 1000000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 75));
-    AppliedEnergeticsServer.setPortProperties(4);
+    var AppliedEnergeticsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"applied-energetics", organizationName:"Applied Energetics",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 850), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(700e6, 1e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 75), numOpenPortsRequired:4
+    });
     AddToAllServers(AppliedEnergeticsServer);
 
-    var SolarisSpaceSystemsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "solaris", "Solaris Space Systems", false, false, false, 2);
-    SolarisSpaceSystemsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(750, 850), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(700000000, 900000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80));
-    SolarisSpaceSystemsServer.setPortProperties(5);
+    var SolarisSpaceSystemsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"solaris", organizationName:"Solaris Space Systems", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(750, 850), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(700e6, 900e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), numOpenPortsRequired:5
+    });
     SolarisSpaceSystemsServer.messages.push("A-Green-Tomorrow.lit");
     SolarisSpaceSystemsServer.messages.push("the-failed-frontier.lit");
     AddToAllServers(SolarisSpaceSystemsServer);
 
-    var DeltaOneServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "deltaone", "Delta One", false, false, false, 0);
-    DeltaOneServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 900), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1300000000, 1700000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 70));
-    DeltaOneServer.setPortProperties(5);
+    var DeltaOneServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"deltaone", organizationName:"Delta One",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 900), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1.3e9, 1.7e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 70), numOpenPortsRequired:5
+    });
     AddToAllServers(DeltaOneServer);
 
     //Health, medicine, pharmaceutical companies ("Large" targets)
-    var GlobalPharmaceuticalsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "global-pharm", "Global Pharmaceuticals", false, false, false, 16);
-    GlobalPharmaceuticalsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(750, 850), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1500000000, 1750000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90));
-    GlobalPharmaceuticalsServer.setPortProperties(4);
+    var GlobalPharmaceuticalsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"global-pharm", organizationName:"Global Pharmaceuticals", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(750, 850), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1.5e9, 1.75e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(80, 90), numOpenPortsRequired:4
+    });
     GlobalPharmaceuticalsServer.messages.push("A-Green-Tomorrow.lit");
     AddToAllServers(GlobalPharmaceuticalsServer);
 
-    var NovaMedicalServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "nova-med", "Nova Medical", false, false, false, 0);
-    NovaMedicalServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 850), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1100000000, 1250000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 85));
-    NovaMedicalServer.setPortProperties(4);
+    var NovaMedicalServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"nova-med", organizationName:"Nova Medical",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 850), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1.1e9, 1.25e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 85), numOpenPortsRequired:4
+    });
     AddToAllServers(NovaMedicalServer);
 
-    var ZeusMedicalServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "zeus-med", "Zeus Medical", false, false, false, 0);
-    ZeusMedicalServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 850), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1300000000, 1500000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80));
-    ZeusMedicalServer.setPortProperties(5);
+    var ZeusMedicalServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"zeus-med", organizationName:"Zeus Medical",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800, 850), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1.3e9, 1.5e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 90), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), numOpenPortsRequired:5
+    });
     AddToAllServers(ZeusMedicalServer);
 
-    var UnitaLifeGroupServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "unitalife", "UnitaLife Group", false, false, false, 32);
-    UnitaLifeGroupServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 825), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1000000000, 1100000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80));
-    UnitaLifeGroupServer.setPortProperties(4);
+    var UnitaLifeGroupServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"unitalife", organizationName:"UnitaLife Group", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(775, 825), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(1e9, 1.1e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), numOpenPortsRequired:4
+    });
     AddToAllServers(UnitaLifeGroupServer);
 
     //"Medium level" targets
-    var LexoCorpServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "lexo-corp", "Lexo Corporation", false, false, false, 16);
-    LexoCorpServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(650, 750), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(700000000, 800000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65));
-    LexoCorpServer.setPortProperties(4);
+    var LexoCorpServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"lexo-corp", organizationName:"Lexo Corporation", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(650, 750), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(700e6, 800e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), numOpenPortsRequired:4
+    });
     AddToAllServers(LexoCorpServer);
 
-    var RhoConstructionServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "rho-construction", "Rho Construction", false, false, false, 0);
-    RhoConstructionServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(475, 525), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(500000000, 700000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60));
-    RhoConstructionServer.setPortProperties(3);
+    var RhoConstructionServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"rho-construction", organizationName:"Rho Construction",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(475, 525), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(500e6, 700e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60), numOpenPortsRequired:3
+    });
     AddToAllServers(RhoConstructionServer);
 
-    var AlphaEnterprisesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "alpha-ent", "Alpha Enterprises", false, false, false, 2);
-    AlphaEnterprisesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(500, 600), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(600000000, 750000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 70), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 60));
-    AlphaEnterprisesServer.setPortProperties(4);
+    var AlphaEnterprisesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"alpha-ent", organizationName:"Alpha Enterprises", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(500, 600), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(600e6, 750e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 70), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 60),numOpenPortsRequired:4
+    });
     AlphaEnterprisesServer.messages.push("sector-12-crime.lit");
     AddToAllServers(AlphaEnterprisesServer);
 
-    var AevumPoliceServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "aevum-police", "Aevum Police Network", false, false, false, 0);
-    AevumPoliceServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(400, 450), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(200000000, 400000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(30, 50));
-    AevumPoliceServer.setPortProperties(4);
+    var AevumPoliceServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"aevum-police", organizationName:"Aevum Police Network", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(400, 450), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(200e6, 400e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(30, 50), numOpenPortsRequired:4
+    });
     AddToAllServers(AevumPoliceServer);
 
-    var RothmanUniversityServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "rothman-uni", "Rothman University Network", false, false, false, 4);
-    RothmanUniversityServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(370, 430), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(175000000, 250000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 55), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 45));
-    RothmanUniversityServer.setPortProperties(3);
+    var RothmanUniversityServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"rothman-uni", organizationName:"Rothman University Network", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(370, 430), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(175e6, 250e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 55), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 45), numOpenPortsRequired:3
+    });
     RothmanUniversityServer.messages.push("secret-societies.lit");
     RothmanUniversityServer.messages.push("the-failed-frontier.lit");
     RothmanUniversityServer.messages.push("tensions-in-tech-race.lit");
     AddToAllServers(RothmanUniversityServer);
 
-    var ZBInstituteOfTechnologyServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "zb-institute", "ZB Institute of Technology Network", false, false, false, 4);
-    ZBInstituteOfTechnologyServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(725, 775), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800000000, 1100000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 85), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85));
-    ZBInstituteOfTechnologyServer.setPortProperties(5);
+    var ZBInstituteOfTechnologyServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"zb-institute", organizationName:"ZB Institute of Technology Network", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(725, 775), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(800e6, 1.1e9),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(65, 85), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(75, 85), numOpenPortsRequired:5
+    });
     AddToAllServers(ZBInstituteOfTechnologyServer);
 
-    var SummitUniversityServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "summit-uni", "Summit University Network", false, false, false, 4);
-    SummitUniversityServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(425, 475), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(200000000, 350000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 65), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60));
-    SummitUniversityServer.setPortProperties(3);
+    var SummitUniversityServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"summit-uni", organizationName:"Summit University Network", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(425, 475), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(200e6, 350e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 65), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60), numOpenPortsRequired:3
+    });
     SummitUniversityServer.messages.push("secret-societies.lit");
     SummitUniversityServer.messages.push("the-failed-frontier.lit");
     SummitUniversityServer.messages.push("synthetic-muscles.lit");
     AddToAllServers(SummitUniversityServer);
 
-    var SysCoreSecuritiesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "syscore", "SysCore Securities", false, false, false, 0);
-    SysCoreSecuritiesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(550, 650), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(400000000, 600000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 70));
-    SysCoreSecuritiesServer.setPortProperties(4);
+    var SysCoreSecuritiesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"syscore", organizationName:"SysCore Securities",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(550, 650), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(400e6, 600e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 70), numOpenPortsRequired:4
+    });
     AddToAllServers(SysCoreSecuritiesServer);
 
-    var CatalystVenturesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "catalyst", "Catalyst Ventures", false, false, false, 2);
-    CatalystVenturesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(400, 450), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(300000000, 550000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 70), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(25, 55));
-    CatalystVenturesServer.setPortProperties(3);
+    var CatalystVenturesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"catalyst", organizationName:"Catalyst Ventures",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(400, 450), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(300e6, 550e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 70), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(25, 55), numOpenPortsRequired:3,
+    });
     CatalystVenturesServer.messages.push("tensions-in-tech-race.lit");
     AddToAllServers(CatalystVenturesServer);
 
-    var TheHubServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "the-hub", "The Hub", false, false, false, 0);
-    TheHubServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(275, 325), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(150000000, 200000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 45), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 55));
-    TheHubServer.setPortProperties(2);
+    var TheHubServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"the-hub", organizationName:"The Hub",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(275, 325), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(150e6, 200e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 45), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 55), numOpenPortsRequired:2
+    });
     AddToAllServers(TheHubServer);
 
-    var CompuTekServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "comptek", "CompuTek", false, false, false, 8);
-    CompuTekServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(300, 400), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(220000000, 250000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 65));
-    CompuTekServer.setPortProperties(3);
+    var CompuTekServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"comptek", organizationName:"CompuTek",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(300, 400), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(220e6, 250e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 65), numOpenPortsRequired:3
+    });
     CompuTekServer.messages.push("man-and-machine.lit");
     AddToAllServers(CompuTekServer);
 
-    var NetLinkTechnologiesServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "netlink", "NetLink Technologies", false, false, false, 2);
-    NetLinkTechnologiesServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(375, 425), 275000000, Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 75));
-    NetLinkTechnologiesServer.setPortProperties(3);
+    var NetLinkTechnologiesServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"netlink", organizationName:"NetLink Technologies", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(375, 425), moneyAvailable:275e6,
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60, 80), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 75), numOpenPortsRequired:3
+    });
     NetLinkTechnologiesServer.messages.push("simulated-reality.lit");
     AddToAllServers(NetLinkTechnologiesServer);
 
-    var JohnsonOrthopedicsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "johnson-ortho", "Johnson Orthopedics", false, false, false, 4);
-    JohnsonOrthopedicsServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(250, 300), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70000000, 85000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 65), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 65));
-    JohnsonOrthopedicsServer.setPortProperties(2);
+    var JohnsonOrthopedicsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"johnson-ortho", organizationName:"Johnson Orthopedics",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(250, 300), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(70e6, 85e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 65), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 65), numOpenPortsRequired:2
+    });
     AddToAllServers(JohnsonOrthopedicsServer);
 
     //"Low level" targets
-    var FoodNStuffServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "foodnstuff", "Food N Stuff Supermarket", false, false, false, 16);
-    FoodNStuffServer.setHackingParameters(1, 2000000, 10, 5);
-    FoodNStuffServer.setPortProperties(0);
+    var FoodNStuffServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"foodnstuff", organizationName:"Food N Stuff Supermarket", maxRam:16,
+        requiredHackingSkill:1, moneyAvailable:2e6,
+        hackDifficulty:10, serverGrowth:5, numOpenPortsRequired:0
+    });
     FoodNStuffServer.messages.push("sector-12-crime.lit");
     AddToAllServers(FoodNStuffServer);
 
-    var SigmaCosmeticsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "sigma-cosmetics", "Sigma Cosmetics", false, false, false, 16);
-    SigmaCosmeticsServer.setHackingParameters(5, 2300000, 10, 10);
-    SigmaCosmeticsServer.setPortProperties(0);
+    var SigmaCosmeticsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"sigma-cosmetics", organizationName:"Sigma Cosmetics", maxRam:16,
+        requiredHackingSkill:5, moneyAvailable:2.3e6,
+        hackDifficulty:10, serverGrowth:10, numOpenPortsRequired:0
+    });
     AddToAllServers(SigmaCosmeticsServer);
 
-    var JoesGunsServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "joesguns", "Joe's Guns", false, false, false, 16);
-    JoesGunsServer.setHackingParameters(10, 2500000, 15, 20);
-    JoesGunsServer.setPortProperties(0);
+    var JoesGunsServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"joesguns", organizationName:"Joe's Guns", maxRam:16,
+        requiredHackingSkill:10, moneyAvailable:2.5e6,
+        hackDifficulty:15, serverGrowth:20, numOpenPortsRequired:0
+    });
     AddToAllServers(JoesGunsServer);
 
-    var Zer0NightclubServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "zer0", "ZER0 Nightclub", false, false, false, 32);
-    Zer0NightclubServer.setHackingParameters(75, 7500000, 25, 40);
-    Zer0NightclubServer.setPortProperties(1);
+    var Zer0NightclubServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"zer0", organizationName:"ZER0 Nightclub", maxRam:32,
+        requiredHackingSkill:75, moneyAvailable:7.5e6,
+        hackDifficulty:25, serverGrowth:40, numOpenPortsRequired:1
+    });
     AddToAllServers(Zer0NightclubServer);
 
-    var NectarNightclubServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "nectar-net", "Nectar Nightclub Network", false, false, false, 8);
-    NectarNightclubServer.setHackingParameters(20, 2750000, 20, 25);
+    var NectarNightclubServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"nectar-net", organizationName:"Nectar Nightclub Network", maxRam:16,
+        requiredHackingSkill:20, moneyAvailable:2.75e6,
+        hackDifficulty:20, serverGrowth:25, numOpenPortsRequired:0
+    });
     NectarNightclubServer.setPortProperties(0);
     AddToAllServers(NectarNightclubServer);
 
-    var NeoNightclubServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "neo-net", "Neo Nightclub Network", false, false, false, 32);
-    NeoNightclubServer.setHackingParameters(50, 5000000, 25, 25);
-    NeoNightclubServer.setPortProperties(1);
+    var NeoNightclubServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"neo-net", organizationName:"Neo Nightclub Network", maxRam:32,
+        requiredHackingSkill:50, moneyAvailable:5e6,
+        hackDifficulty:25, serverGrowth:25, numOpenPortsRequired:1
+    });
     NeoNightclubServer.messages.push("the-hidden-world.lit");
     AddToAllServers(NeoNightclubServer);
 
-    var SilverHelixServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "silver-helix", "Silver Helix", false, false, false, 64);
-    SilverHelixServer.setHackingParameters(150, 45000000, 30, 30);
-    SilverHelixServer.setPortProperties(2);
+    var SilverHelixServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"silver-helix", organizationName:"Silver Helix", maxRam:64,
+        requiredHackingSkill:150, moneyAvailable:45e6,
+        hackDifficulty:30, serverGrowth:30, numOpenPortsRequired:2
+    });
     SilverHelixServer.messages.push("new-triads.lit");
     AddToAllServers(SilverHelixServer);
 
-    var HongFangTeaHouseServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "hong-fang-tea", "HongFang Teahouse", false, false, false, 16);
-    HongFangTeaHouseServer.setHackingParameters(30, 3000000, 15, 20);
-    HongFangTeaHouseServer.setPortProperties(0);
+    var HongFangTeaHouseServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"hong-fang-tea", organizationName:"HongFang Teahouse", maxRam:16,
+        requiredHackingSkill:30, moneyAvailable:3e6,
+        hackDifficulty:15, serverGrowth:20, numOpenPortsRequired:0
+    });
     HongFangTeaHouseServer.messages.push("brighter-than-the-sun.lit");
     AddToAllServers(HongFangTeaHouseServer);
 
-    var HaraKiriSushiBarServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "harakiri-sushi", "HaraKiri Sushi Bar Network", false, false, false, 16);
-    HaraKiriSushiBarServer.setHackingParameters(40, 4000000, 15, 40);
-    HaraKiriSushiBarServer.setPortProperties(0);
+    var HaraKiriSushiBarServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"harakiri-sushi", organizationName:"HaraKiri Sushi Bar Network",maxRam:16,
+        requiredHackingSkill:40, moneyAvailable:4e6,
+        hackDifficulty:15, serverGrowth:40, numOpenPortsRequired:0
+    });
     AddToAllServers(HaraKiriSushiBarServer);
 
-    var PhantasyServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "phantasy", "Phantasy Club", false, false, false, 32);
-    PhantasyServer.setHackingParameters(100, 24000000, 20, 35);
-    PhantasyServer.setPortProperties(2);
+    var PhantasyServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"phantasy", organizationName:"Phantasy Club", maxRam:32,
+        requiredHackingSkill:100, moneyAvailable:24e6,
+        hackDifficulty:20, serverGrowth:35, numOpenPortsRequired:2
+    });
     AddToAllServers(PhantasyServer);
 
-    var MaxHardwareServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "max-hardware", "Max Hardware Store", false, false, false, 32);
-    MaxHardwareServer.setHackingParameters(80, 10000000, 15, 30);
-    MaxHardwareServer.setPortProperties(1);
+    var MaxHardwareServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"max-hardware", organizationName:"Max Hardware Store", maxRam:32,
+        requiredHackingSkill:80, moneyAvailable:10e6,
+        hackDifficulty:15, serverGrowth:30, numOpenPortsRequired:1,
+    });
     AddToAllServers(MaxHardwareServer);
 
-    var OmegaSoftwareServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "omega-net", "Omega Software", false, false, false, 32);
-    OmegaSoftwareServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(180, 220), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60000000, 70000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(25, 35), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(30, 40));
-    OmegaSoftwareServer.setPortProperties(2);
+    var OmegaSoftwareServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"omega-net", organizationName:"Omega Software", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(180, 220), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(60e6, 70e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(25, 35), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(30, 40), numOpenPortsRequired:2
+    });
     OmegaSoftwareServer.messages.push("the-new-god.lit");
     AddToAllServers(OmegaSoftwareServer);
 
     //Gyms
-    var CrushFitnessGymServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "crush-fitness", "Crush Fitness", false, false, false, 0);
-    CrushFitnessGymServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(225, 275), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40000000, 60000000), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 45), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(27, 33));
-    CrushFitnessGymServer.setPortProperties(2);
+    var CrushFitnessGymServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"crush-fitness", organizationName:"Crush Fitness",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(225, 275), moneyAvailable:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40e6, 60e6),
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(35, 45), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(27, 33), numOpenPortsRequired:2
+    });
     AddToAllServers(CrushFitnessGymServer);
 
-    var IronGymServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "iron-gym", "Iron Gym Network", false, false, false, 32);
-    IronGymServer.setHackingParameters(100, 20000000, 30, 20);
-    IronGymServer.setPortProperties(1);
+    var IronGymServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"iron-gym", organizationName:"Iron Gym Network", maxRam:32,
+        requiredHackingSkill:100, moneyAvailable:20e6,
+        hackDifficulty:30, serverGrowth:20, numOpenPortsRequired:1
+    });
     AddToAllServers(IronGymServer);
 
-    var MilleniumFitnessGymServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "millenium-fitness", "Millenium Fitness Network", false, false, false, 0);
-    MilleniumFitnessGymServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(475, 525), 250000000, Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 55), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(25, 45));
-    MilleniumFitnessGymServer.setPortProperties(3);
+    var MilleniumFitnessGymServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"millenium-fitness", organizationName:"Millenium Fitness Network",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(475, 525), moneyAvailable:250e6,
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(45, 55), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(25, 45), numOpenPortsRequired:3,
+    });
     AddToAllServers(MilleniumFitnessGymServer);
 
-    var PowerhouseGymServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "powerhouse-fitness", "Powerhouse Fitness", false, false, false, 0);
-    PowerhouseGymServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(950, 1100), 900000000, Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 60));
-    PowerhouseGymServer.setPortProperties(5);
+    var PowerhouseGymServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"powerhouse-fitness", organizationName:"Powerhouse Fitness",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(950, 1100), moneyAvailable:900e6,
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(55, 65), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(50, 60), numOpenPortsRequired:5,
+    });
     AddToAllServers(PowerhouseGymServer);
 
-    var SnapFitnessGymServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "snap-fitness", "Snap Fitness", false, false, false, 0);
-    SnapFitnessGymServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(675, 800), 450000000, Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60), Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60));
-    SnapFitnessGymServer.setPortProperties(4);
+    var SnapFitnessGymServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"snap-fitness", organizationName:"Snap Fitness",
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(675, 800), moneyAvailable:450e6,
+        hackDifficulty:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60), serverGrowth:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(40, 60), numOpenPortsRequired:4
+    });
     AddToAllServers(SnapFitnessGymServer);
 
-	//Faction servers, cannot hack money from these
-	var BitRunnersServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "run4theh111z", "The Runners", false, false, false,  2);
-    BitRunnersServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(505, 550), 0, 0, 0);
-	BitRunnersServer.setPortProperties(4);
+    //Faction servers, cannot hack money from these
+    var BitRunnersServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"run4theh111z", organizationName:"The Runners", maxRam:128,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(505, 550), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:4
+    });
     BitRunnersServer.messages.push("simulated-reality.lit");
     BitRunnersServer.messages.push("the-new-god.lit");
-	AddToAllServers(BitRunnersServer);
+    AddToAllServers(BitRunnersServer);
     _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].BitRunnersServer, BitRunnersServer.ip);
 
-    var TheBlackHandServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "I.I.I.I", "I.I.I.I", false, false, false, 2);
-    TheBlackHandServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(340, 365), 0, 0, 0);
-    TheBlackHandServer.setPortProperties(3);
+    var TheBlackHandServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"I.I.I.I", organizationName:"I.I.I.I", maxRam:64,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(340, 365), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:3,
+    });
     TheBlackHandServer.messages.push("democracy-is-dead.lit");
     AddToAllServers(TheBlackHandServer);
     _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].TheBlackHandServer, TheBlackHandServer.ip);
 
-	var NiteSecServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "avmnite-02h", "NiteSec", false, false, false, 2);
-    NiteSecServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(202, 220), 0, 0, 0);
-	NiteSecServer.setPortProperties(2);
+    var NiteSecServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"avmnite-02h", organizationName:"NiteSec", maxRam:32,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(202, 220), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:2
+    });
     NiteSecServer.messages.push("democracy-is-dead.lit");
-	AddToAllServers(NiteSecServer);
+    AddToAllServers(NiteSecServer);
     _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].NiteSecServer, NiteSecServer.ip);
 
-	var DarkArmyServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), ".", ".", false, false, false, 0);
-    DarkArmyServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(505, 550), 0, 0, 0);
-	DarkArmyServer.setPortProperties(4);
-	AddToAllServers(DarkArmyServer);
+    var DarkArmyServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:".", organizationName:".", maxRam:16,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(505, 550), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:4
+    });
+    AddToAllServers(DarkArmyServer);
     _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].TheDarkArmyServer, DarkArmyServer.ip);
 
-	var CyberSecServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "CSEC", "CyberSec", false, false, false, 2);
-    CyberSecServer.setHackingParameters(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(51, 60), 0, 0, 0);
-	CyberSecServer.setPortProperties(1);
+    var CyberSecServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"CSEC", organizationName:"CyberSec", maxRam:8,
+        requiredHackingSkill:Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(51, 60), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:1
+    });
     CyberSecServer.messages.push("democracy-is-dead.lit");
-	AddToAllServers(CyberSecServer);
+    AddToAllServers(CyberSecServer);
     _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].CyberSecServer, CyberSecServer.ip);
 
-    var DaedalusServer = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), "The-Cave", "Helios", false, false, false, 2);
-    DaedalusServer.setHackingParameters(925, 0, 0, 0);
-    DaedalusServer.setPortProperties(5);
+    var DaedalusServer = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:"The-Cave", organizationName:"Helios",
+        requiredHackingSkill:925, moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:5
+    });
     DaedalusServer.messages.push("alpha-omega.lit");
     AddToAllServers(DaedalusServer);
     _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].DaedalusServer, DaedalusServer.ip);
 
     //Super special Servers
-    var WorldDaemon = new Server(Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].WorldDaemon, _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].WorldDaemon, false, false, false, 0);
-    WorldDaemon.setHackingParameters(3000, 0, 0, 0);
-    WorldDaemon.setPortProperties(5);
+    var WorldDaemon = new Server({
+        ip:Object(_utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_7__["createRandomIp"])(), hostname:_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].WorldDaemon, organizationName:_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].WorldDaemon,
+        requiredHackingSkill:3000, moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:5
+    });
     AddToAllServers(WorldDaemon);
     _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerIps"].addIp(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_5__["SpecialServerNames"].WorldDaemon, WorldDaemon.ip);
 
@@ -11100,7 +11242,7 @@ function initForeignServers() {
 //Applied server growth for a single server. Returns the percentage growth
 function processSingleServerGrowth(server, numCycles) {
     //Server growth processed once every 450 game cycles
-	var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
+    var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
 
     //Get adjusted growth rate, which accounts for server security
     var growthRate = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].ServerBaseGrowthRate;
@@ -11165,11 +11307,11 @@ function loadAllServers(saveString) {
 }
 
 function SizeOfAllServers() {
-	var size = 0, key;
-	for (key in AllServers) {
-		if (AllServers.hasOwnProperty(key)) size++;
-	}
-	return size;
+    var size = 0, key;
+    for (key in AllServers) {
+        if (AllServers.hasOwnProperty(key)) size++;
+    }
+    return size;
 }
 
 //Add a server onto the map of all servers in the game
@@ -11186,16 +11328,16 @@ function AddToAllServers(server) {
 }
 
 //Returns server object with corresponding hostname
-//	Relatively slow, would rather not use this a lot
+//    Relatively slow, would rather not use this a lot
 function GetServerByHostname(hostname) {
-	for (var ip in AllServers) {
-		if (AllServers.hasOwnProperty(ip)) {
-			if (AllServers[ip].hostname == hostname) {
-				return AllServers[ip];
-			}
-		}
-	}
-	return null;
+    for (var ip in AllServers) {
+        if (AllServers.hasOwnProperty(ip)) {
+            if (AllServers[ip].hostname == hostname) {
+                return AllServers[ip];
+            }
+        }
+    }
+    return null;
 }
 
 //Get server by IP or hostname. Returns null if invalid
@@ -11249,412 +11391,6 @@ Directory.prototype.getPath = function(name) {
 
 /***/ }),
 /* 11 */
-/*!***************************!*\
-  !*** ./utils/YesNoBox.js ***!
-  \***************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxCreate", function() { return yesNoBoxCreate; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxCreate", function() { return yesNoTxtInpBoxCreate; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxGetYesButton", function() { return yesNoBoxGetYesButton; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxGetNoButton", function() { return yesNoBoxGetNoButton; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxGetYesButton", function() { return yesNoTxtInpBoxGetYesButton; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxGetNoButton", function() { return yesNoTxtInpBoxGetNoButton; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxGetInput", function() { return yesNoTxtInpBoxGetInput; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxClose", function() { return yesNoBoxClose; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxClose", function() { return yesNoTxtInpBoxClose; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxOpen", function() { return yesNoBoxOpen; });
-/* harmony import */ var _HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./HelperFunctions.js */ 1);
-
-/* Generic Yes-No Pop-up box
- * Can be used to create pop-up boxes that require a yes/no response from player
- */
-var yesNoBoxOpen = false;
-function yesNoBoxClose() {
-    var container = document.getElementById("yes-no-box-container");
-    if (container) {
-        container.style.display = "none";
-    } else {
-        console.log("ERROR: Container not found for YesNoBox");
-    }
-    yesNoBoxOpen = false;
-    return false; //So that 'return yesNoBoxClose()' is return false in event listeners
-}
-
-function yesNoBoxGetYesButton() {
-    return Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__["clearEventListeners"])("yes-no-box-yes");
-}
-
-function yesNoBoxGetNoButton() {
-    return Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__["clearEventListeners"])("yes-no-box-no");
-}
-
-function yesNoBoxCreate(txt) {
-    if (yesNoBoxOpen) {return false;}   //Already open
-    yesNoBoxOpen = true;
-    var textElement = document.getElementById("yes-no-box-text");
-    if (textElement) {
-        textElement.innerHTML = txt;
-    }
-
-    var c = document.getElementById("yes-no-box-container");
-    if (c) {
-        c.style.display = "block";
-    } else {
-        console.log("ERROR: Container not found for YesNoBox");
-    }
-    return true;
-}
-
-/* Generic Yes-No POp-up Box with Text input */
-function yesNoTxtInpBoxClose() {
-    var c = document.getElementById("yes-no-text-input-box-container");
-    if (c) {
-        c.style.display = "none";
-    } else {
-        console.log("ERROR: Container not found for YesNoTextInputBox");
-    }
-    yesNoBoxOpen = false;
-    document.getElementById("yes-no-text-input-box-input").value = "";
-    return false;
-}
-
-function yesNoTxtInpBoxGetYesButton() {
-    return Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__["clearEventListeners"])("yes-no-text-input-box-yes");
-}
-
-function yesNoTxtInpBoxGetNoButton() {
-    return Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__["clearEventListeners"])("yes-no-text-input-box-no");
-}
-
-function yesNoTxtInpBoxGetInput() {
-    var val = document.getElementById("yes-no-text-input-box-input").value;
-    val = val.replace(/\s+/g, '');
-    return val;
-}
-
-function yesNoTxtInpBoxCreate(txt) {
-    yesNoBoxOpen = true;
-    var txtE = document.getElementById("yes-no-text-input-box-text");
-    if (txtE) {
-        txtE.innerHTML = txt;
-    }
-
-    var c = document.getElementById("yes-no-text-input-box-container");
-    if (c) {
-        c.style.display = "block";
-    } else {
-        console.log("ERROR: Container not found for YesNoTextInputBox");
-    }
-
-    document.getElementById("yes-no-text-input-box-input").focus();
-}
-
-
-
-
-/***/ }),
-/* 12 */
-/*!******************************!*\
-  !*** ./utils/numeral.min.js ***!
-  \******************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @preserve
- * numeral.js
- * version : 2.0.6
- * author : Adam Draper
- * license : MIT
- * http://adamwdraper.github.com/Numeral-js/
- */
-!function(a,b){ true?!(__WEBPACK_AMD_DEFINE_FACTORY__ = (b),
-				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
-				(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
-				__WEBPACK_AMD_DEFINE_FACTORY__),
-				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}(this,function(){function a(a,b){this._input=a,this._value=b}var b,c,d="2.0.6",e={},f={},g={currentLocale:"en",zeroFormat:null,nullFormat:null,defaultFormat:"0,0",scalePercentBy100:!0},h={currentLocale:g.currentLocale,zeroFormat:g.zeroFormat,nullFormat:g.nullFormat,defaultFormat:g.defaultFormat,scalePercentBy100:g.scalePercentBy100};return b=function(d){var f,g,i,j;if(b.isNumeral(d))f=d.value();else if(0===d||"undefined"==typeof d)f=0;else if(null===d||c.isNaN(d))f=null;else if("string"==typeof d)if(h.zeroFormat&&d===h.zeroFormat)f=0;else if(h.nullFormat&&d===h.nullFormat||!d.replace(/[^0-9]+/g,"").length)f=null;else{for(g in e)if(j="function"==typeof e[g].regexps.unformat?e[g].regexps.unformat():e[g].regexps.unformat,j&&d.match(j)){i=e[g].unformat;break}i=i||b._.stringToNumber,f=i(d)}else f=Number(d)||null;return new a(d,f)},b.version=d,b.isNumeral=function(b){return b instanceof a},b._=c={numberToFormat:function(a,c,d){var e,g,h,i,j,k,l,m=f[b.options.currentLocale],n=!1,o=!1,p=0,q="",r=1e12,s=1e9,t=1e6,u=1e3,v="",w=!1;if(a=a||0,g=Math.abs(a),b._.includes(c,"(")?(n=!0,c=c.replace(/[\(|\)]/g,"")):(b._.includes(c,"+")||b._.includes(c,"-"))&&(j=b._.includes(c,"+")?c.indexOf("+"):0>a?c.indexOf("-"):-1,c=c.replace(/[\+|\-]/g,"")),b._.includes(c,"a")&&(e=c.match(/a(k|m|b|t)?/),e=e?e[1]:!1,b._.includes(c," a")&&(q=" "),c=c.replace(new RegExp(q+"a[kmbt]?"),""),g>=r&&!e||"t"===e?(q+=m.abbreviations.trillion,a/=r):r>g&&g>=s&&!e||"b"===e?(q+=m.abbreviations.billion,a/=s):s>g&&g>=t&&!e||"m"===e?(q+=m.abbreviations.million,a/=t):(t>g&&g>=u&&!e||"k"===e)&&(q+=m.abbreviations.thousand,a/=u)),b._.includes(c,"[.]")&&(o=!0,c=c.replace("[.]",".")),h=a.toString().split(".")[0],i=c.split(".")[1],k=c.indexOf(","),p=(c.split(".")[0].split(",")[0].match(/0/g)||[]).length,i?(b._.includes(i,"[")?(i=i.replace("]",""),i=i.split("["),v=b._.toFixed(a,i[0].length+i[1].length,d,i[1].length)):v=b._.toFixed(a,i.length,d),h=v.split(".")[0],v=b._.includes(v,".")?m.delimiters.decimal+v.split(".")[1]:"",o&&0===Number(v.slice(1))&&(v="")):h=b._.toFixed(a,0,d),q&&!e&&Number(h)>=1e3&&q!==m.abbreviations.trillion)switch(h=String(Number(h)/1e3),q){case m.abbreviations.thousand:q=m.abbreviations.million;break;case m.abbreviations.million:q=m.abbreviations.billion;break;case m.abbreviations.billion:q=m.abbreviations.trillion}if(b._.includes(h,"-")&&(h=h.slice(1),w=!0),h.length<p)for(var x=p-h.length;x>0;x--)h="0"+h;return k>-1&&(h=h.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+m.delimiters.thousands)),0===c.indexOf(".")&&(h=""),l=h+v+(q?q:""),n?l=(n&&w?"(":"")+l+(n&&w?")":""):j>=0?l=0===j?(w?"-":"+")+l:l+(w?"-":"+"):w&&(l="-"+l),l},stringToNumber:function(a){var b,c,d,e=f[h.currentLocale],g=a,i={thousand:3,million:6,billion:9,trillion:12};if(h.zeroFormat&&a===h.zeroFormat)c=0;else if(h.nullFormat&&a===h.nullFormat||!a.replace(/[^0-9]+/g,"").length)c=null;else{c=1,"."!==e.delimiters.decimal&&(a=a.replace(/\./g,"").replace(e.delimiters.decimal,"."));for(b in i)if(d=new RegExp("[^a-zA-Z]"+e.abbreviations[b]+"(?:\\)|(\\"+e.currency.symbol+")?(?:\\))?)?$"),g.match(d)){c*=Math.pow(10,i[b]);break}c*=(a.split("-").length+Math.min(a.split("(").length-1,a.split(")").length-1))%2?1:-1,a=a.replace(/[^0-9\.]+/g,""),c*=Number(a)}return c},isNaN:function(a){return"number"==typeof a&&isNaN(a)},includes:function(a,b){return-1!==a.indexOf(b)},insert:function(a,b,c){return a.slice(0,c)+b+a.slice(c)},reduce:function(a,b){if(null===this)throw new TypeError("Array.prototype.reduce called on null or undefined");if("function"!=typeof b)throw new TypeError(b+" is not a function");var c,d=Object(a),e=d.length>>>0,f=0;if(3===arguments.length)c=arguments[2];else{for(;e>f&&!(f in d);)f++;if(f>=e)throw new TypeError("Reduce of empty array with no initial value");c=d[f++]}for(;e>f;f++)f in d&&(c=b(c,d[f],f,d));return c},multiplier:function(a){var b=a.toString().split(".");return b.length<2?1:Math.pow(10,b[1].length)},correctionFactor:function(){var a=Array.prototype.slice.call(arguments);return a.reduce(function(a,b){var d=c.multiplier(b);return a>d?a:d},1)},toFixed:function(a,b,c,d){var e,f,g,h,i=a.toString().split("."),j=b-(d||0);return e=2===i.length?Math.min(Math.max(i[1].length,j),b):j,g=Math.pow(10,e),h=(c(a+"e+"+e)/g).toFixed(e),d>b-e&&(f=new RegExp("\\.?0{1,"+(d-(b-e))+"}$"),h=h.replace(f,"")),h}},b.options=h,b.formats=e,b.locales=f,b.locale=function(a){return a&&(h.currentLocale=a.toLowerCase()),h.currentLocale},b.localeData=function(a){if(!a)return f[h.currentLocale];if(a=a.toLowerCase(),!f[a])throw new Error("Unknown locale : "+a);return f[a]},b.reset=function(){for(var a in g)h[a]=g[a]},b.zeroFormat=function(a){h.zeroFormat="string"==typeof a?a:null},b.nullFormat=function(a){h.nullFormat="string"==typeof a?a:null},b.defaultFormat=function(a){h.defaultFormat="string"==typeof a?a:"0.0"},b.register=function(a,b,c){if(b=b.toLowerCase(),this[a+"s"][b])throw new TypeError(b+" "+a+" already registered.");return this[a+"s"][b]=c,c},b.validate=function(a,c){var d,e,f,g,h,i,j,k;if("string"!=typeof a&&(a+="",console.warn&&console.warn("Numeral.js: Value is not string. It has been co-erced to: ",a)),a=a.trim(),a.match(/^\d+$/))return!0;if(""===a)return!1;try{j=b.localeData(c)}catch(l){j=b.localeData(b.locale())}return f=j.currency.symbol,h=j.abbreviations,d=j.delimiters.decimal,e="."===j.delimiters.thousands?"\\.":j.delimiters.thousands,k=a.match(/^[^\d]+/),null!==k&&(a=a.substr(1),k[0]!==f)?!1:(k=a.match(/[^\d]+$/),null!==k&&(a=a.slice(0,-1),k[0]!==h.thousand&&k[0]!==h.million&&k[0]!==h.billion&&k[0]!==h.trillion)?!1:(i=new RegExp(e+"{2}"),a.match(/[^\d.,]/g)?!1:(g=a.split(d),g.length>2?!1:g.length<2?!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i):1===g[0].length?!!g[0].match(/^\d+$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/):!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/))))},b.fn=a.prototype={clone:function(){return b(this)},format:function(a,c){var d,f,g,i=this._value,j=a||h.defaultFormat;if(c=c||Math.round,0===i&&null!==h.zeroFormat)f=h.zeroFormat;else if(null===i&&null!==h.nullFormat)f=h.nullFormat;else{for(d in e)if(j.match(e[d].regexps.format)){g=e[d].format;break}g=g||b._.numberToFormat,f=g(i,j,c)}return f},value:function(){return this._value},input:function(){return this._input},set:function(a){return this._value=Number(a),this},add:function(a){function b(a,b,c,e){return a+Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([this._value,a],b,0)/d,this},subtract:function(a){function b(a,b,c,e){return a-Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([a],b,Math.round(this._value*d))/d,this},multiply:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)*Math.round(b*f)/Math.round(f*f)}return this._value=c.reduce([this._value,a],b,1),this},divide:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)/Math.round(b*f)}return this._value=c.reduce([this._value,a],b),this},difference:function(a){return Math.abs(b(this._value).subtract(a).value())}},b.register("locale","en",{delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},ordinal:function(a){var b=a%10;return 1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th"},currency:{symbol:"$"}}),function(){b.register("format","bps",{regexps:{format:/(BPS)/,unformat:/(BPS)/},format:function(a,c,d){var e,f=b._.includes(c," BPS")?" ":"";return a=1e4*a,c=c.replace(/\s?BPS/,""),e=b._.numberToFormat(a,c,d),b._.includes(e,")")?(e=e.split(""),e.splice(-1,0,f+"BPS"),e=e.join("")):e=e+f+"BPS",e},unformat:function(a){return+(1e-4*b._.stringToNumber(a)).toFixed(15)}})}(),function(){var a={base:1e3,suffixes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]},c={base:1024,suffixes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},d=a.suffixes.concat(c.suffixes.filter(function(b){return a.suffixes.indexOf(b)<0})),e=d.join("|");e="("+e.replace("B","B(?!PS)")+")",b.register("format","bytes",{regexps:{format:/([0\s]i?b)/,unformat:new RegExp(e)},format:function(d,e,f){var g,h,i,j,k=b._.includes(e,"ib")?c:a,l=b._.includes(e," b")||b._.includes(e," ib")?" ":"";for(e=e.replace(/\s?i?b/,""),h=0;h<=k.suffixes.length;h++)if(i=Math.pow(k.base,h),j=Math.pow(k.base,h+1),null===d||0===d||d>=i&&j>d){l+=k.suffixes[h],i>0&&(d/=i);break}return g=b._.numberToFormat(d,e,f),g+l},unformat:function(d){var e,f,g=b._.stringToNumber(d);if(g){for(e=a.suffixes.length-1;e>=0;e--){if(b._.includes(d,a.suffixes[e])){f=Math.pow(a.base,e);break}if(b._.includes(d,c.suffixes[e])){f=Math.pow(c.base,e);break}}g*=f||1}return g}})}(),function(){b.register("format","currency",{regexps:{format:/(\$)/},format:function(a,c,d){var e,f,g,h=b.locales[b.options.currentLocale],i={before:c.match(/^([\+|\-|\(|\s|\$]*)/)[0],after:c.match(/([\+|\-|\)|\s|\$]*)$/)[0]};for(c=c.replace(/\s?\$\s?/,""),e=b._.numberToFormat(a,c,d),a>=0?(i.before=i.before.replace(/[\-\(]/,""),i.after=i.after.replace(/[\-\)]/,"")):0>a&&!b._.includes(i.before,"-")&&!b._.includes(i.before,"(")&&(i.before="-"+i.before),g=0;g<i.before.length;g++)switch(f=i.before[g]){case"$":e=b._.insert(e,h.currency.symbol,g);break;case" ":e=b._.insert(e," ",g+h.currency.symbol.length-1)}for(g=i.after.length-1;g>=0;g--)switch(f=i.after[g]){case"$":e=g===i.after.length-1?e+h.currency.symbol:b._.insert(e,h.currency.symbol,-(i.after.length-(1+g)));break;case" ":e=g===i.after.length-1?e+" ":b._.insert(e," ",-(i.after.length-(1+g)+h.currency.symbol.length-1))}return e}})}(),function(){b.register("format","exponential",{regexps:{format:/(e\+|e-)/,unformat:/(e\+|e-)/},format:function(a,c,d){var e,f="number"!=typeof a||b._.isNaN(a)?"0e+0":a.toExponential(),g=f.split("e");return c=c.replace(/e[\+|\-]{1}0/,""),e=b._.numberToFormat(Number(g[0]),c,d),e+"e"+g[1]},unformat:function(a){function c(a,c,d,e){var f=b._.correctionFactor(a,c),g=a*f*(c*f)/(f*f);return g}var d=b._.includes(a,"e+")?a.split("e+"):a.split("e-"),e=Number(d[0]),f=Number(d[1]);return f=b._.includes(a,"e-")?f*=-1:f,b._.reduce([e,Math.pow(10,f)],c,1)}})}(),function(){b.register("format","ordinal",{regexps:{format:/(o)/},format:function(a,c,d){var e,f=b.locales[b.options.currentLocale],g=b._.includes(c," o")?" ":"";return c=c.replace(/\s?o/,""),g+=f.ordinal(a),e=b._.numberToFormat(a,c,d),e+g}})}(),function(){b.register("format","percentage",{regexps:{format:/(%)/,unformat:/(%)/},format:function(a,c,d){var e,f=b._.includes(c," %")?" ":"";return b.options.scalePercentBy100&&(a=100*a),c=c.replace(/\s?\%/,""),e=b._.numberToFormat(a,c,d),b._.includes(e,")")?(e=e.split(""),e.splice(-1,0,f+"%"),e=e.join("")):e=e+f+"%",e},unformat:function(a){var c=b._.stringToNumber(a);return b.options.scalePercentBy100?.01*c:c}})}(),function(){b.register("format","time",{regexps:{format:/(:)/,unformat:/(:)/},format:function(a,b,c){var d=Math.floor(a/60/60),e=Math.floor((a-60*d*60)/60),f=Math.round(a-60*d*60-60*e);return d+":"+(10>e?"0"+e:e)+":"+(10>f?"0"+f:f)},unformat:function(a){var b=a.split(":"),c=0;return 3===b.length?(c+=60*Number(b[0])*60,c+=60*Number(b[1]),c+=Number(b[2])):2===b.length&&(c+=60*Number(b[0]),c+=Number(b[1])),Number(c)}})}(),b});
-
-/***/ }),
-/* 13 */
-/*!******************************!*\
-  !*** ./src/CreateProgram.js ***!
-  \******************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Programs", function() { return Programs; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayCreateProgramContent", function() { return displayCreateProgramContent; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNumAvailableCreateProgram", function() { return getNumAvailableCreateProgram; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initCreateProgramButtons", function() { return initCreateProgramButtons; });
-/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-
-
-
-
-/* Create programs */
-let Programs = {
-    NukeProgram:          "NUKE.exe",
-    BruteSSHProgram:      "BruteSSH.exe",
-    FTPCrackProgram:      "FTPCrack.exe",
-    RelaySMTPProgram:     "relaySMTP.exe",
-    HTTPWormProgram:      "HTTPWorm.exe",
-    SQLInjectProgram:     "SQLInject.exe",
-    DeepscanV1:           "DeepscanV1.exe",
-    DeepscanV2:           "DeepscanV2.exe",
-    ServerProfiler:       "ServerProfiler.exe",
-    AutoLink:             "AutoLink.exe",
-    Flight:               "fl1ght.exe",
-    BitFlume:             "b1t_flum3.exe"
-};
-
-var nukeALink, bruteSshALink, ftpCrackALink, relaySmtpALink, httpWormALink, sqlInjectALink,
-    deepscanv1ALink, deepscanv2ALink, servProfilerALink, autolinkALink, bitFlumeALink;
-function displayCreateProgramContent() {
-    nukeALink.style.display = "none";
-    bruteSshALink.style.display = "none";
-    ftpCrackALink.style.display = "none";
-    relaySmtpALink.style.display = "none";
-    httpWormALink.style.display = "none";
-    sqlInjectALink.style.display = "none";
-    deepscanv1ALink.style.display = "none";
-    deepscanv2ALink.style.display = "none";
-    servProfilerALink.style.display = "none";
-    autolinkALink.style.display = "none";
-    bitFlumeALink.style.display = "none";
-
-    //NUKE.exe (in case you delete it lol)
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) {
-        nukeALink.style.display = "inline-block";
-    }
-    //BruteSSH
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.BruteSSHProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 50) {
-        bruteSshALink.style.display = "inline-block";
-    }
-    //FTPCrack
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.FTPCrackProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 100) {
-        ftpCrackALink.style.display = "inline-block";
-    }
-    //relaySMTP
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.RelaySMTPProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 250) {
-        relaySmtpALink.style.display = "inline-block";
-    }
-    //HTTPWorm
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.HTTPWormProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 500) {
-        httpWormALink.style.display = "inline-block";
-    }
-    //SQLInject
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.SQLInjectProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 750) {
-        sqlInjectALink.style.display = "inline-block";
-    }
-    //Deepscan V1 and V2
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.DeepscanV1) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 75) {
-        deepscanv1ALink.style.display = "inline-block";
-    }
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.DeepscanV2) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 400) {
-        deepscanv2ALink.style.display = "inline-block";
-    }
-    //Server profiler
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.ServerProfiler) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 75) {
-        servProfilerALink.style.display = "inline-block";
-    }
-    //Auto Link
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.AutoLink) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 25) {
-        autolinkALink.style.display = "inline-block";
-    }
-    //Bit Flume
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.BitFlume) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].sourceFiles.length > 0 && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 5) {
-        bitFlumeALink.style.display = "inline-block";
-    }
-}
-
-//Returns the number of programs that are currently available to be created
-function getNumAvailableCreateProgram() {
-    var count = 0;
-    //PortHack.exe (in case you delete it lol)
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) {
-        ++count;
-    }
-    //BruteSSH
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.BruteSSHProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 50) {
-        ++count;
-    }
-    //FTPCrack
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.FTPCrackProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 100) {
-        ++count;
-    }
-    //relaySMTP
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.RelaySMTPProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 250) {
-        ++count;
-    }
-    //HTTPWorm
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.HTTPWormProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 500) {
-        ++count;
-    }
-    //SQLInject
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.SQLInjectProgram) == -1 &&
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 750) {
-        ++count;
-    }
-    //Deepscan V1 and V2
-        if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.DeepscanV1) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 75) {
-        ++count;
-    }
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.DeepscanV2) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 400) {
-        ++count;
-    }
-    //Server profiler
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.ServerProfiler) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 75) {
-        ++count;
-    }
-    //Auto link
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.AutoLink) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 25) {
-        ++count;
-    }
-    //Bit Flume
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.BitFlume) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].sourceFiles.length > 0 && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 5) {
-        ++count;
-    }
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].firstProgramAvailable === false && count > 0) {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].firstProgramAvailable = true;
-        document.getElementById("create-program-tab").style.display = "list-item";
-        document.getElementById("hacking-menu-header").click();
-        document.getElementById("hacking-menu-header").click();
-    }
-    return count;
-}
-
-function initCreateProgramButtons() {
-    var createProgramList = document.getElementById("create-program-list");
-    nukeALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-nuke", innerText:Programs.NukeProgram,
-        tooltip:"This virus is used to gain root access to a machine if enough ports are opened.",
-    });
-    createProgramList.appendChild(nukeALink);
-
-    bruteSshALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-brutessh", innerText:Programs.BruteSSHProgram,
-        tooltip:"This program executes a brute force attack that opens SSH ports"
-    });
-    createProgramList.appendChild(bruteSshALink);
-
-    ftpCrackALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-ftpcrack", innerText:Programs.FTPCrackProgram,
-        tooltip:"This program cracks open FTP ports"
-    });
-    createProgramList.appendChild(ftpCrackALink);
-
-    relaySmtpALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-relaysmtp", innerText:Programs.RelaySMTPProgram,
-        tooltip:"This program opens SMTP ports by redirecting data"
-    }) ;
-    createProgramList.appendChild(relaySmtpALink);
-
-    httpWormALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-httpworm", innerText:Programs.HTTPWormProgram,
-        tooltip:"This virus opens up HTTP ports"
-    });
-    createProgramList.appendChild(httpWormALink);
-
-    sqlInjectALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-sqlinject", innerText:Programs.SQLInjectProgram,
-        tooltip:"This virus opens SQL ports"
-    });
-    createProgramList.appendChild(sqlInjectALink);
-
-    deepscanv1ALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-deepscanv1", innerText:Programs.DeepscanV1,
-        tooltip:"This program allows you to use the scan-analyze command with a depth up to 5"
-    });
-    createProgramList.appendChild(deepscanv1ALink);
-
-    deepscanv2ALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-deepscanv2", innerText:Programs.DeepscanV2,
-        tooltip:"This program allows you to use the scan-analyze command with a depth up to 10"
-    });
-    createProgramList.appendChild(deepscanv2ALink);
-
-    servProfilerALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-serverprofiler", innerText:Programs.ServerProfiler,
-        tooltip:"This program is used to display hacking and Netscript-related information about servers"
-    });
-    createProgramList.appendChild(servProfilerALink);
-
-    bitFlumeALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-bitflume", innerText:Programs.BitFlume,
-        tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)"
-    });
-    createProgramList.appendChild(bitFlumeALink);
-
-    autolinkALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
-        class:"a-link-button", id:"create-program-autolink", innerText:"AutoLink.exe",
-        tooltip:"This program allows you to directly connect to other servers through the 'scan-analyze' command"
-    });
-    createProgramList.appendChild(autolinkALink);
-
-    nukeALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.NukeProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerFiveMinutes, 1);
-        return false;
-    });
-    bruteSshALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.BruteSSHProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerFiveMinutes * 2, 50);
-        return false;
-    });
-    ftpCrackALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.FTPCrackProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerHalfHour, 100);
-        return false;
-    });
-    relaySmtpALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.RelaySMTPProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPer2Hours, 250);
-        return false;
-    });
-    httpWormALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.HTTPWormProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPer4Hours, 500);
-        return false;
-    });
-    sqlInjectALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.SQLInjectProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPer8Hours, 750);
-        return false;
-    });
-    deepscanv1ALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.DeepscanV1, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerQuarterHour, 75);
-        return false;
-    });
-    deepscanv2ALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.DeepscanV2, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPer2Hours, 400);
-        return false;
-    });
-    servProfilerALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.ServerProfiler, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerHalfHour, 75);
-        return false;
-    });
-    autolinkALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.AutoLink, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerQuarterHour, 25);
-        return false;
-    });
-    bitFlumeALink.addEventListener("click", function() {
-        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.BitFlume, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerFiveMinutes / 5, 5);
-        return false;
-    });
-}
-
-
-
-
-/***/ }),
-/* 14 */
 /*!************************!*\
   !*** ./src/Faction.js ***!
   \************************/
@@ -11674,7 +11410,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "purchaseAugmentation", function() { return purchaseAugmentation; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "factionExists", function() { return factionExists; });
 /* harmony import */ var _Augmentations_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Augmentations.js */ 18);
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BitNode.js */ 16);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BitNode.js */ 15);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./engine.js */ 5);
 /* harmony import */ var _FactionInfo_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./FactionInfo.js */ 26);
@@ -11683,13 +11419,13 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Player.js */ 0);
 /* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Settings.js */ 24);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_FactionInvitationBox_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/FactionInvitationBox.js */ 114);
+/* harmony import */ var _utils_FactionInvitationBox_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/FactionInvitationBox.js */ 110);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
 /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
 /* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_13__);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
 
 
 
@@ -12814,65 +12550,413 @@ function processPassiveFactionRepGain(numCycles) {
 
 
 /***/ }),
-/* 15 */
-/*!****************************!*\
-  !*** ./utils/IPAddress.js ***!
-  \****************************/
+/* 12 */
+/*!***************************!*\
+  !*** ./utils/YesNoBox.js ***!
+  \***************************/
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createRandomIp", function() { return createRandomIp; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ipExists", function() { return ipExists; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isValidIPAddress", function() { return isValidIPAddress; });
-/* harmony import */ var _src_Server_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../src/Server.js */ 10);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxCreate", function() { return yesNoBoxCreate; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxCreate", function() { return yesNoTxtInpBoxCreate; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxGetYesButton", function() { return yesNoBoxGetYesButton; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxGetNoButton", function() { return yesNoBoxGetNoButton; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxGetYesButton", function() { return yesNoTxtInpBoxGetYesButton; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxGetNoButton", function() { return yesNoTxtInpBoxGetNoButton; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxGetInput", function() { return yesNoTxtInpBoxGetInput; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxClose", function() { return yesNoBoxClose; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoTxtInpBoxClose", function() { return yesNoTxtInpBoxClose; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yesNoBoxOpen", function() { return yesNoBoxOpen; });
+/* harmony import */ var _HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./HelperFunctions.js */ 1);
 
-/* Functions to deal with manipulating IP addresses*/
-
-//Generate a random IP address
-//Will not return an IP address that already exists in the AllServers array
-function createRandomIp() {
-	var ip = createRandomByte(99) +'.' +
-			 createRandomByte(9) +'.' +
-			 createRandomByte(9) +'.' +
-		 	 createRandomByte(9);
-
-    //If the Ip already exists, recurse to create a new one
-    if (ipExists(ip)) {
-        return createRandomIp();
+/* Generic Yes-No Pop-up box
+ * Can be used to create pop-up boxes that require a yes/no response from player
+ */
+var yesNoBoxOpen = false;
+function yesNoBoxClose() {
+    var container = document.getElementById("yes-no-box-container");
+    if (container) {
+        container.style.display = "none";
+    } else {
+        console.log("ERROR: Container not found for YesNoBox");
     }
-	return ip;
+    yesNoBoxOpen = false;
+    return false; //So that 'return yesNoBoxClose()' is return false in event listeners
 }
 
-//Returns true if the IP already exists in one of the game's servers
-function ipExists(ip) {
-    for (var property in _src_Server_js__WEBPACK_IMPORTED_MODULE_0__["AllServers"]) {
-        if (_src_Server_js__WEBPACK_IMPORTED_MODULE_0__["AllServers"].hasOwnProperty(property)) {
-            if (property == ip) {
-                return true;
-            }
-        }
+function yesNoBoxGetYesButton() {
+    return Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__["clearEventListeners"])("yes-no-box-yes");
+}
+
+function yesNoBoxGetNoButton() {
+    return Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__["clearEventListeners"])("yes-no-box-no");
+}
+
+function yesNoBoxCreate(txt) {
+    if (yesNoBoxOpen) {return false;}   //Already open
+    yesNoBoxOpen = true;
+    var textElement = document.getElementById("yes-no-box-text");
+    if (textElement) {
+        textElement.innerHTML = txt;
     }
+
+    var c = document.getElementById("yes-no-box-container");
+    if (c) {
+        c.style.display = "block";
+    } else {
+        console.log("ERROR: Container not found for YesNoBox");
+    }
+    return true;
+}
+
+/* Generic Yes-No POp-up Box with Text input */
+function yesNoTxtInpBoxClose() {
+    var c = document.getElementById("yes-no-text-input-box-container");
+    if (c) {
+        c.style.display = "none";
+    } else {
+        console.log("ERROR: Container not found for YesNoTextInputBox");
+    }
+    yesNoBoxOpen = false;
+    document.getElementById("yes-no-text-input-box-input").value = "";
     return false;
 }
 
-function createRandomByte(n=9) {
-	return Math.round(Math.random()*n);
+function yesNoTxtInpBoxGetYesButton() {
+    return Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__["clearEventListeners"])("yes-no-text-input-box-yes");
 }
 
-function isValidIPAddress(ipaddress) {
-	if (/^(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress))
-	{
-		return true;
-	}
-	return false;
+function yesNoTxtInpBoxGetNoButton() {
+    return Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_0__["clearEventListeners"])("yes-no-text-input-box-no");
+}
+
+function yesNoTxtInpBoxGetInput() {
+    var val = document.getElementById("yes-no-text-input-box-input").value;
+    val = val.replace(/\s+/g, '');
+    return val;
+}
+
+function yesNoTxtInpBoxCreate(txt) {
+    yesNoBoxOpen = true;
+    var txtE = document.getElementById("yes-no-text-input-box-text");
+    if (txtE) {
+        txtE.innerHTML = txt;
+    }
+
+    var c = document.getElementById("yes-no-text-input-box-container");
+    if (c) {
+        c.style.display = "block";
+    } else {
+        console.log("ERROR: Container not found for YesNoTextInputBox");
+    }
+
+    document.getElementById("yes-no-text-input-box-input").focus();
 }
 
 
 
 
 /***/ }),
-/* 16 */
+/* 13 */
+/*!******************************!*\
+  !*** ./utils/numeral.min.js ***!
+  \******************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @preserve
+ * numeral.js
+ * version : 2.0.6
+ * author : Adam Draper
+ * license : MIT
+ * http://adamwdraper.github.com/Numeral-js/
+ */
+!function(a,b){ true?!(__WEBPACK_AMD_DEFINE_FACTORY__ = (b),
+				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
+				(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
+				__WEBPACK_AMD_DEFINE_FACTORY__),
+				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}(this,function(){function a(a,b){this._input=a,this._value=b}var b,c,d="2.0.6",e={},f={},g={currentLocale:"en",zeroFormat:null,nullFormat:null,defaultFormat:"0,0",scalePercentBy100:!0},h={currentLocale:g.currentLocale,zeroFormat:g.zeroFormat,nullFormat:g.nullFormat,defaultFormat:g.defaultFormat,scalePercentBy100:g.scalePercentBy100};return b=function(d){var f,g,i,j;if(b.isNumeral(d))f=d.value();else if(0===d||"undefined"==typeof d)f=0;else if(null===d||c.isNaN(d))f=null;else if("string"==typeof d)if(h.zeroFormat&&d===h.zeroFormat)f=0;else if(h.nullFormat&&d===h.nullFormat||!d.replace(/[^0-9]+/g,"").length)f=null;else{for(g in e)if(j="function"==typeof e[g].regexps.unformat?e[g].regexps.unformat():e[g].regexps.unformat,j&&d.match(j)){i=e[g].unformat;break}i=i||b._.stringToNumber,f=i(d)}else f=Number(d)||null;return new a(d,f)},b.version=d,b.isNumeral=function(b){return b instanceof a},b._=c={numberToFormat:function(a,c,d){var e,g,h,i,j,k,l,m=f[b.options.currentLocale],n=!1,o=!1,p=0,q="",r=1e12,s=1e9,t=1e6,u=1e3,v="",w=!1;if(a=a||0,g=Math.abs(a),b._.includes(c,"(")?(n=!0,c=c.replace(/[\(|\)]/g,"")):(b._.includes(c,"+")||b._.includes(c,"-"))&&(j=b._.includes(c,"+")?c.indexOf("+"):0>a?c.indexOf("-"):-1,c=c.replace(/[\+|\-]/g,"")),b._.includes(c,"a")&&(e=c.match(/a(k|m|b|t)?/),e=e?e[1]:!1,b._.includes(c," a")&&(q=" "),c=c.replace(new RegExp(q+"a[kmbt]?"),""),g>=r&&!e||"t"===e?(q+=m.abbreviations.trillion,a/=r):r>g&&g>=s&&!e||"b"===e?(q+=m.abbreviations.billion,a/=s):s>g&&g>=t&&!e||"m"===e?(q+=m.abbreviations.million,a/=t):(t>g&&g>=u&&!e||"k"===e)&&(q+=m.abbreviations.thousand,a/=u)),b._.includes(c,"[.]")&&(o=!0,c=c.replace("[.]",".")),h=a.toString().split(".")[0],i=c.split(".")[1],k=c.indexOf(","),p=(c.split(".")[0].split(",")[0].match(/0/g)||[]).length,i?(b._.includes(i,"[")?(i=i.replace("]",""),i=i.split("["),v=b._.toFixed(a,i[0].length+i[1].length,d,i[1].length)):v=b._.toFixed(a,i.length,d),h=v.split(".")[0],v=b._.includes(v,".")?m.delimiters.decimal+v.split(".")[1]:"",o&&0===Number(v.slice(1))&&(v="")):h=b._.toFixed(a,0,d),q&&!e&&Number(h)>=1e3&&q!==m.abbreviations.trillion)switch(h=String(Number(h)/1e3),q){case m.abbreviations.thousand:q=m.abbreviations.million;break;case m.abbreviations.million:q=m.abbreviations.billion;break;case m.abbreviations.billion:q=m.abbreviations.trillion}if(b._.includes(h,"-")&&(h=h.slice(1),w=!0),h.length<p)for(var x=p-h.length;x>0;x--)h="0"+h;return k>-1&&(h=h.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+m.delimiters.thousands)),0===c.indexOf(".")&&(h=""),l=h+v+(q?q:""),n?l=(n&&w?"(":"")+l+(n&&w?")":""):j>=0?l=0===j?(w?"-":"+")+l:l+(w?"-":"+"):w&&(l="-"+l),l},stringToNumber:function(a){var b,c,d,e=f[h.currentLocale],g=a,i={thousand:3,million:6,billion:9,trillion:12};if(h.zeroFormat&&a===h.zeroFormat)c=0;else if(h.nullFormat&&a===h.nullFormat||!a.replace(/[^0-9]+/g,"").length)c=null;else{c=1,"."!==e.delimiters.decimal&&(a=a.replace(/\./g,"").replace(e.delimiters.decimal,"."));for(b in i)if(d=new RegExp("[^a-zA-Z]"+e.abbreviations[b]+"(?:\\)|(\\"+e.currency.symbol+")?(?:\\))?)?$"),g.match(d)){c*=Math.pow(10,i[b]);break}c*=(a.split("-").length+Math.min(a.split("(").length-1,a.split(")").length-1))%2?1:-1,a=a.replace(/[^0-9\.]+/g,""),c*=Number(a)}return c},isNaN:function(a){return"number"==typeof a&&isNaN(a)},includes:function(a,b){return-1!==a.indexOf(b)},insert:function(a,b,c){return a.slice(0,c)+b+a.slice(c)},reduce:function(a,b){if(null===this)throw new TypeError("Array.prototype.reduce called on null or undefined");if("function"!=typeof b)throw new TypeError(b+" is not a function");var c,d=Object(a),e=d.length>>>0,f=0;if(3===arguments.length)c=arguments[2];else{for(;e>f&&!(f in d);)f++;if(f>=e)throw new TypeError("Reduce of empty array with no initial value");c=d[f++]}for(;e>f;f++)f in d&&(c=b(c,d[f],f,d));return c},multiplier:function(a){var b=a.toString().split(".");return b.length<2?1:Math.pow(10,b[1].length)},correctionFactor:function(){var a=Array.prototype.slice.call(arguments);return a.reduce(function(a,b){var d=c.multiplier(b);return a>d?a:d},1)},toFixed:function(a,b,c,d){var e,f,g,h,i=a.toString().split("."),j=b-(d||0);return e=2===i.length?Math.min(Math.max(i[1].length,j),b):j,g=Math.pow(10,e),h=(c(a+"e+"+e)/g).toFixed(e),d>b-e&&(f=new RegExp("\\.?0{1,"+(d-(b-e))+"}$"),h=h.replace(f,"")),h}},b.options=h,b.formats=e,b.locales=f,b.locale=function(a){return a&&(h.currentLocale=a.toLowerCase()),h.currentLocale},b.localeData=function(a){if(!a)return f[h.currentLocale];if(a=a.toLowerCase(),!f[a])throw new Error("Unknown locale : "+a);return f[a]},b.reset=function(){for(var a in g)h[a]=g[a]},b.zeroFormat=function(a){h.zeroFormat="string"==typeof a?a:null},b.nullFormat=function(a){h.nullFormat="string"==typeof a?a:null},b.defaultFormat=function(a){h.defaultFormat="string"==typeof a?a:"0.0"},b.register=function(a,b,c){if(b=b.toLowerCase(),this[a+"s"][b])throw new TypeError(b+" "+a+" already registered.");return this[a+"s"][b]=c,c},b.validate=function(a,c){var d,e,f,g,h,i,j,k;if("string"!=typeof a&&(a+="",console.warn&&console.warn("Numeral.js: Value is not string. It has been co-erced to: ",a)),a=a.trim(),a.match(/^\d+$/))return!0;if(""===a)return!1;try{j=b.localeData(c)}catch(l){j=b.localeData(b.locale())}return f=j.currency.symbol,h=j.abbreviations,d=j.delimiters.decimal,e="."===j.delimiters.thousands?"\\.":j.delimiters.thousands,k=a.match(/^[^\d]+/),null!==k&&(a=a.substr(1),k[0]!==f)?!1:(k=a.match(/[^\d]+$/),null!==k&&(a=a.slice(0,-1),k[0]!==h.thousand&&k[0]!==h.million&&k[0]!==h.billion&&k[0]!==h.trillion)?!1:(i=new RegExp(e+"{2}"),a.match(/[^\d.,]/g)?!1:(g=a.split(d),g.length>2?!1:g.length<2?!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i):1===g[0].length?!!g[0].match(/^\d+$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/):!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/))))},b.fn=a.prototype={clone:function(){return b(this)},format:function(a,c){var d,f,g,i=this._value,j=a||h.defaultFormat;if(c=c||Math.round,0===i&&null!==h.zeroFormat)f=h.zeroFormat;else if(null===i&&null!==h.nullFormat)f=h.nullFormat;else{for(d in e)if(j.match(e[d].regexps.format)){g=e[d].format;break}g=g||b._.numberToFormat,f=g(i,j,c)}return f},value:function(){return this._value},input:function(){return this._input},set:function(a){return this._value=Number(a),this},add:function(a){function b(a,b,c,e){return a+Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([this._value,a],b,0)/d,this},subtract:function(a){function b(a,b,c,e){return a-Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([a],b,Math.round(this._value*d))/d,this},multiply:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)*Math.round(b*f)/Math.round(f*f)}return this._value=c.reduce([this._value,a],b,1),this},divide:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)/Math.round(b*f)}return this._value=c.reduce([this._value,a],b),this},difference:function(a){return Math.abs(b(this._value).subtract(a).value())}},b.register("locale","en",{delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},ordinal:function(a){var b=a%10;return 1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th"},currency:{symbol:"$"}}),function(){b.register("format","bps",{regexps:{format:/(BPS)/,unformat:/(BPS)/},format:function(a,c,d){var e,f=b._.includes(c," BPS")?" ":"";return a=1e4*a,c=c.replace(/\s?BPS/,""),e=b._.numberToFormat(a,c,d),b._.includes(e,")")?(e=e.split(""),e.splice(-1,0,f+"BPS"),e=e.join("")):e=e+f+"BPS",e},unformat:function(a){return+(1e-4*b._.stringToNumber(a)).toFixed(15)}})}(),function(){var a={base:1e3,suffixes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]},c={base:1024,suffixes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},d=a.suffixes.concat(c.suffixes.filter(function(b){return a.suffixes.indexOf(b)<0})),e=d.join("|");e="("+e.replace("B","B(?!PS)")+")",b.register("format","bytes",{regexps:{format:/([0\s]i?b)/,unformat:new RegExp(e)},format:function(d,e,f){var g,h,i,j,k=b._.includes(e,"ib")?c:a,l=b._.includes(e," b")||b._.includes(e," ib")?" ":"";for(e=e.replace(/\s?i?b/,""),h=0;h<=k.suffixes.length;h++)if(i=Math.pow(k.base,h),j=Math.pow(k.base,h+1),null===d||0===d||d>=i&&j>d){l+=k.suffixes[h],i>0&&(d/=i);break}return g=b._.numberToFormat(d,e,f),g+l},unformat:function(d){var e,f,g=b._.stringToNumber(d);if(g){for(e=a.suffixes.length-1;e>=0;e--){if(b._.includes(d,a.suffixes[e])){f=Math.pow(a.base,e);break}if(b._.includes(d,c.suffixes[e])){f=Math.pow(c.base,e);break}}g*=f||1}return g}})}(),function(){b.register("format","currency",{regexps:{format:/(\$)/},format:function(a,c,d){var e,f,g,h=b.locales[b.options.currentLocale],i={before:c.match(/^([\+|\-|\(|\s|\$]*)/)[0],after:c.match(/([\+|\-|\)|\s|\$]*)$/)[0]};for(c=c.replace(/\s?\$\s?/,""),e=b._.numberToFormat(a,c,d),a>=0?(i.before=i.before.replace(/[\-\(]/,""),i.after=i.after.replace(/[\-\)]/,"")):0>a&&!b._.includes(i.before,"-")&&!b._.includes(i.before,"(")&&(i.before="-"+i.before),g=0;g<i.before.length;g++)switch(f=i.before[g]){case"$":e=b._.insert(e,h.currency.symbol,g);break;case" ":e=b._.insert(e," ",g+h.currency.symbol.length-1)}for(g=i.after.length-1;g>=0;g--)switch(f=i.after[g]){case"$":e=g===i.after.length-1?e+h.currency.symbol:b._.insert(e,h.currency.symbol,-(i.after.length-(1+g)));break;case" ":e=g===i.after.length-1?e+" ":b._.insert(e," ",-(i.after.length-(1+g)+h.currency.symbol.length-1))}return e}})}(),function(){b.register("format","exponential",{regexps:{format:/(e\+|e-)/,unformat:/(e\+|e-)/},format:function(a,c,d){var e,f="number"!=typeof a||b._.isNaN(a)?"0e+0":a.toExponential(),g=f.split("e");return c=c.replace(/e[\+|\-]{1}0/,""),e=b._.numberToFormat(Number(g[0]),c,d),e+"e"+g[1]},unformat:function(a){function c(a,c,d,e){var f=b._.correctionFactor(a,c),g=a*f*(c*f)/(f*f);return g}var d=b._.includes(a,"e+")?a.split("e+"):a.split("e-"),e=Number(d[0]),f=Number(d[1]);return f=b._.includes(a,"e-")?f*=-1:f,b._.reduce([e,Math.pow(10,f)],c,1)}})}(),function(){b.register("format","ordinal",{regexps:{format:/(o)/},format:function(a,c,d){var e,f=b.locales[b.options.currentLocale],g=b._.includes(c," o")?" ":"";return c=c.replace(/\s?o/,""),g+=f.ordinal(a),e=b._.numberToFormat(a,c,d),e+g}})}(),function(){b.register("format","percentage",{regexps:{format:/(%)/,unformat:/(%)/},format:function(a,c,d){var e,f=b._.includes(c," %")?" ":"";return b.options.scalePercentBy100&&(a=100*a),c=c.replace(/\s?\%/,""),e=b._.numberToFormat(a,c,d),b._.includes(e,")")?(e=e.split(""),e.splice(-1,0,f+"%"),e=e.join("")):e=e+f+"%",e},unformat:function(a){var c=b._.stringToNumber(a);return b.options.scalePercentBy100?.01*c:c}})}(),function(){b.register("format","time",{regexps:{format:/(:)/,unformat:/(:)/},format:function(a,b,c){var d=Math.floor(a/60/60),e=Math.floor((a-60*d*60)/60),f=Math.round(a-60*d*60-60*e);return d+":"+(10>e?"0"+e:e)+":"+(10>f?"0"+f:f)},unformat:function(a){var b=a.split(":"),c=0;return 3===b.length?(c+=60*Number(b[0])*60,c+=60*Number(b[1]),c+=Number(b[2])):2===b.length&&(c+=60*Number(b[0]),c+=Number(b[1])),Number(c)}})}(),b});
+
+/***/ }),
+/* 14 */
+/*!******************************!*\
+  !*** ./src/CreateProgram.js ***!
+  \******************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Programs", function() { return Programs; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayCreateProgramContent", function() { return displayCreateProgramContent; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNumAvailableCreateProgram", function() { return getNumAvailableCreateProgram; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initCreateProgramButtons", function() { return initCreateProgramButtons; });
+/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Constants.js */ 3);
+/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Player.js */ 0);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+
+
+
+
+/* Create programs */
+let Programs = {
+    NukeProgram:          "NUKE.exe",
+    BruteSSHProgram:      "BruteSSH.exe",
+    FTPCrackProgram:      "FTPCrack.exe",
+    RelaySMTPProgram:     "relaySMTP.exe",
+    HTTPWormProgram:      "HTTPWorm.exe",
+    SQLInjectProgram:     "SQLInject.exe",
+    DeepscanV1:           "DeepscanV1.exe",
+    DeepscanV2:           "DeepscanV2.exe",
+    ServerProfiler:       "ServerProfiler.exe",
+    AutoLink:             "AutoLink.exe",
+    Flight:               "fl1ght.exe",
+    BitFlume:             "b1t_flum3.exe"
+};
+
+var nukeALink, bruteSshALink, ftpCrackALink, relaySmtpALink, httpWormALink, sqlInjectALink,
+    deepscanv1ALink, deepscanv2ALink, servProfilerALink, autolinkALink, bitFlumeALink;
+function displayCreateProgramContent() {
+    nukeALink.style.display = "none";
+    bruteSshALink.style.display = "none";
+    ftpCrackALink.style.display = "none";
+    relaySmtpALink.style.display = "none";
+    httpWormALink.style.display = "none";
+    sqlInjectALink.style.display = "none";
+    deepscanv1ALink.style.display = "none";
+    deepscanv2ALink.style.display = "none";
+    servProfilerALink.style.display = "none";
+    autolinkALink.style.display = "none";
+    bitFlumeALink.style.display = "none";
+
+    //NUKE.exe (in case you delete it lol)
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) {
+        nukeALink.style.display = "inline-block";
+    }
+    //BruteSSH
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.BruteSSHProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 50) {
+        bruteSshALink.style.display = "inline-block";
+    }
+    //FTPCrack
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.FTPCrackProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 100) {
+        ftpCrackALink.style.display = "inline-block";
+    }
+    //relaySMTP
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.RelaySMTPProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 250) {
+        relaySmtpALink.style.display = "inline-block";
+    }
+    //HTTPWorm
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.HTTPWormProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 500) {
+        httpWormALink.style.display = "inline-block";
+    }
+    //SQLInject
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.SQLInjectProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 750) {
+        sqlInjectALink.style.display = "inline-block";
+    }
+    //Deepscan V1 and V2
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.DeepscanV1) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 75) {
+        deepscanv1ALink.style.display = "inline-block";
+    }
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.DeepscanV2) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 400) {
+        deepscanv2ALink.style.display = "inline-block";
+    }
+    //Server profiler
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.ServerProfiler) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 75) {
+        servProfilerALink.style.display = "inline-block";
+    }
+    //Auto Link
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.AutoLink) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 25) {
+        autolinkALink.style.display = "inline-block";
+    }
+    //Bit Flume
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.BitFlume) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].sourceFiles.length > 0 && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 5) {
+        bitFlumeALink.style.display = "inline-block";
+    }
+}
+
+//Returns the number of programs that are currently available to be created
+function getNumAvailableCreateProgram() {
+    var count = 0;
+    //PortHack.exe (in case you delete it lol)
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.NukeProgram) == -1) {
+        ++count;
+    }
+    //BruteSSH
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.BruteSSHProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 50) {
+        ++count;
+    }
+    //FTPCrack
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.FTPCrackProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 100) {
+        ++count;
+    }
+    //relaySMTP
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.RelaySMTPProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 250) {
+        ++count;
+    }
+    //HTTPWorm
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.HTTPWormProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 500) {
+        ++count;
+    }
+    //SQLInject
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].getHomeComputer().programs.indexOf(Programs.SQLInjectProgram) == -1 &&
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 750) {
+        ++count;
+    }
+    //Deepscan V1 and V2
+        if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.DeepscanV1) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 75) {
+        ++count;
+    }
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.DeepscanV2) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 400) {
+        ++count;
+    }
+    //Server profiler
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.ServerProfiler) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 75) {
+        ++count;
+    }
+    //Auto link
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.AutoLink) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 25) {
+        ++count;
+    }
+    //Bit Flume
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hasProgram(Programs.BitFlume) && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].sourceFiles.length > 0 && _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].hacking_skill >= 5) {
+        ++count;
+    }
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].firstProgramAvailable === false && count > 0) {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].firstProgramAvailable = true;
+        document.getElementById("create-program-tab").style.display = "list-item";
+        document.getElementById("hacking-menu-header").click();
+        document.getElementById("hacking-menu-header").click();
+    }
+    return count;
+}
+
+function initCreateProgramButtons() {
+    var createProgramList = document.getElementById("create-program-list");
+    nukeALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-nuke", innerText:Programs.NukeProgram,
+        tooltip:"This virus is used to gain root access to a machine if enough ports are opened.",
+    });
+    createProgramList.appendChild(nukeALink);
+
+    bruteSshALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-brutessh", innerText:Programs.BruteSSHProgram,
+        tooltip:"This program executes a brute force attack that opens SSH ports"
+    });
+    createProgramList.appendChild(bruteSshALink);
+
+    ftpCrackALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-ftpcrack", innerText:Programs.FTPCrackProgram,
+        tooltip:"This program cracks open FTP ports"
+    });
+    createProgramList.appendChild(ftpCrackALink);
+
+    relaySmtpALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-relaysmtp", innerText:Programs.RelaySMTPProgram,
+        tooltip:"This program opens SMTP ports by redirecting data"
+    }) ;
+    createProgramList.appendChild(relaySmtpALink);
+
+    httpWormALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-httpworm", innerText:Programs.HTTPWormProgram,
+        tooltip:"This virus opens up HTTP ports"
+    });
+    createProgramList.appendChild(httpWormALink);
+
+    sqlInjectALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-sqlinject", innerText:Programs.SQLInjectProgram,
+        tooltip:"This virus opens SQL ports"
+    });
+    createProgramList.appendChild(sqlInjectALink);
+
+    deepscanv1ALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-deepscanv1", innerText:Programs.DeepscanV1,
+        tooltip:"This program allows you to use the scan-analyze command with a depth up to 5"
+    });
+    createProgramList.appendChild(deepscanv1ALink);
+
+    deepscanv2ALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-deepscanv2", innerText:Programs.DeepscanV2,
+        tooltip:"This program allows you to use the scan-analyze command with a depth up to 10"
+    });
+    createProgramList.appendChild(deepscanv2ALink);
+
+    servProfilerALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-serverprofiler", innerText:Programs.ServerProfiler,
+        tooltip:"This program is used to display hacking and Netscript-related information about servers"
+    });
+    createProgramList.appendChild(servProfilerALink);
+
+    bitFlumeALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-bitflume", innerText:Programs.BitFlume,
+        tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)"
+    });
+    createProgramList.appendChild(bitFlumeALink);
+
+    autolinkALink = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", {
+        class:"a-link-button", id:"create-program-autolink", innerText:"AutoLink.exe",
+        tooltip:"This program allows you to directly connect to other servers through the 'scan-analyze' command"
+    });
+    createProgramList.appendChild(autolinkALink);
+
+    nukeALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.NukeProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerFiveMinutes, 1);
+        return false;
+    });
+    bruteSshALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.BruteSSHProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerFiveMinutes * 2, 50);
+        return false;
+    });
+    ftpCrackALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.FTPCrackProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerHalfHour, 100);
+        return false;
+    });
+    relaySmtpALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.RelaySMTPProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPer2Hours, 250);
+        return false;
+    });
+    httpWormALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.HTTPWormProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPer4Hours, 500);
+        return false;
+    });
+    sqlInjectALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.SQLInjectProgram, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPer8Hours, 750);
+        return false;
+    });
+    deepscanv1ALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.DeepscanV1, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerQuarterHour, 75);
+        return false;
+    });
+    deepscanv2ALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.DeepscanV2, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPer2Hours, 400);
+        return false;
+    });
+    servProfilerALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.ServerProfiler, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerHalfHour, 75);
+        return false;
+    });
+    autolinkALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.AutoLink, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerQuarterHour, 25);
+        return false;
+    });
+    bitFlumeALink.addEventListener("click", function() {
+        _Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].startCreateProgramWork(Programs.BitFlume, _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MillisecondsPerFiveMinutes / 5, 5);
+        return false;
+    });
+}
+
+
+
+
+/***/ }),
+/* 15 */
 /*!************************!*\
   !*** ./src/BitNode.js ***!
   \************************/
@@ -13201,6 +13285,64 @@ function initBitNodeMultipliers() {
 
 
 
+/***/ }),
+/* 16 */
+/*!****************************!*\
+  !*** ./utils/IPAddress.js ***!
+  \****************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createRandomIp", function() { return createRandomIp; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ipExists", function() { return ipExists; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isValidIPAddress", function() { return isValidIPAddress; });
+/* harmony import */ var _src_Server_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../src/Server.js */ 10);
+
+/* Functions to deal with manipulating IP addresses*/
+
+//Generate a random IP address
+//Will not return an IP address that already exists in the AllServers array
+function createRandomIp() {
+	var ip = createRandomByte(99) +'.' +
+			 createRandomByte(9) +'.' +
+			 createRandomByte(9) +'.' +
+		 	 createRandomByte(9);
+
+    //If the Ip already exists, recurse to create a new one
+    if (ipExists(ip)) {
+        return createRandomIp();
+    }
+	return ip;
+}
+
+//Returns true if the IP already exists in one of the game's servers
+function ipExists(ip) {
+    for (var property in _src_Server_js__WEBPACK_IMPORTED_MODULE_0__["AllServers"]) {
+        if (_src_Server_js__WEBPACK_IMPORTED_MODULE_0__["AllServers"].hasOwnProperty(property)) {
+            if (property == ip) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+function createRandomByte(n=9) {
+	return Math.round(Math.random()*n);
+}
+
+function isValidIPAddress(ipaddress) {
+	if (/^(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress))
+	{
+		return true;
+	}
+	return false;
+}
+
+
+
+
 /***/ }),
 /* 17 */
 /*!*********************************!*\
@@ -13285,18 +13427,18 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "augmentationExists", function() { return augmentationExists; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Augmentation", function() { return Augmentation; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayAugmentationsContent", function() { return displayAugmentationsContent; });
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 16);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Faction.js */ 14);
-/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 30);
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Faction.js */ 11);
+/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 29);
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _Prestige_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Prestige.js */ 67);
-/* harmony import */ var _SaveObject_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./SaveObject.js */ 51);
-/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Script.js */ 29);
+/* harmony import */ var _Prestige_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Prestige.js */ 57);
+/* harmony import */ var _SaveObject_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./SaveObject.js */ 46);
+/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Script.js */ 28);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Server.js */ 10);
-/* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./SourceFile.js */ 44);
+/* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./SourceFile.js */ 42);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
 /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
@@ -16224,6 +16366,255 @@ function determineCrimeChanceHeist() {
 
 /***/ }),
 /* 20 */
+/*!********************************!*\
+  !*** ./src/NetscriptWorker.js ***!
+  \********************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WorkerScript", function() { return WorkerScript; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "workerScripts", function() { return workerScripts; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NetscriptPorts", function() { return NetscriptPorts; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptsLoop", function() { return runScriptsLoop; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "killWorkerScript", function() { return killWorkerScript; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addWorkerScript", function() { return addWorkerScript; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateOnlineScriptTimes", function() { return updateOnlineScriptTimes; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prestigeWorkerScripts", function() { return prestigeWorkerScripts; });
+/* harmony import */ var _ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActiveScriptsUI.js */ 43);
+/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
+/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engine.js */ 5);
+/* harmony import */ var _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./NetscriptEnvironment.js */ 66);
+/* harmony import */ var _NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptEvaluator.js */ 7);
+/* harmony import */ var _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./NetscriptPort.js */ 45);
+/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Server.js */ 10);
+/* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Settings.js */ 24);
+/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/acorn.js */ 35);
+/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+
+
+
+
+
+
+
+
+
+
+
+
+
+function WorkerScript(runningScriptObj) {
+	this.name 			= runningScriptObj.filename;
+	this.running 		= false;
+	this.serverIp 		= null;
+	this.code 			= runningScriptObj.scriptRef.code;
+	this.env 			= new _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_3__["Environment"](this);
+    this.env.set("args", runningScriptObj.args.slice());
+	this.output			= "";
+	this.ramUsage		= 0;
+	this.scriptRef		= runningScriptObj;
+    this.errorMessage   = "";
+    this.args           = runningScriptObj.args.slice();
+    this.delay          = null;
+    this.fnWorker       = null; //Workerscript for a function call
+    this.checkingRam    = false;
+    this.loadedFns      = {}; //Stores names of fns that are "loaded" by this script, thus using RAM
+    this.disableLogs    = {}; //Stores names of fns that should have logs disabled
+}
+
+//Returns the server on which the workerScript is running
+WorkerScript.prototype.getServer = function() {
+	return _Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][this.serverIp];
+}
+
+//Array containing all scripts that are running across all servers, to easily run them all
+let workerScripts 			= [];
+
+var NetscriptPorts = [];
+for (var i = 0; i < _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].NumNetscriptPorts; ++i) {
+    NetscriptPorts.push(new _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_5__["NetscriptPort"]());
+}
+
+function prestigeWorkerScripts() {
+    for (var i = 0; i < workerScripts.length; ++i) {
+        Object(_ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__["deleteActiveScriptsItem"])(workerScripts[i]);
+        workerScripts[i].env.stopFlag = true;
+    }
+    workerScripts.length = 0;
+}
+
+//Loop through workerScripts and run every script that is not currently running
+function runScriptsLoop() {
+    //Delete any scripts that finished or have been killed. Loop backwards bc removing
+    //items fucks up the indexing
+    for (var i = workerScripts.length - 1; i >= 0; i--) {
+        if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) {
+            //Delete script from the runningScripts array on its host serverIp
+            var ip = workerScripts[i].serverIp;
+            var name = workerScripts[i].name;
+
+            //Free RAM
+            _Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].ramUsed -= workerScripts[i].ramUsage;
+
+            //Delete script from Active Scripts
+            Object(_ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__["deleteActiveScriptsItem"])(workerScripts[i]);
+
+            for (var j = 0; j < _Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].runningScripts.length; j++) {
+                if (_Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].runningScripts[j].filename == name &&
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["compareArrays"])(_Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].runningScripts[j].args, workerScripts[i].args)) {
+                    _Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].runningScripts.splice(j, 1);
+                    break;
+                }
+            }
+
+            //Delete script from workerScripts
+            workerScripts.splice(i, 1);
+        }
+    }
+
+	//Run any scripts that haven't been started
+	for (var i = 0; i < workerScripts.length; i++) {
+		//If it isn't running, start the script
+		if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
+			try {
+				var ast = Object(_utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__["parse"])(workerScripts[i].code, {sourceType:"module"});
+                //console.log(ast);
+			} catch (e) {
+                console.log("Error parsing script: " + workerScripts[i].name);
+                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Syntax ERROR in " + workerScripts[i].name + ":<br>" +  e);
+                workerScripts[i].env.stopFlag = true;
+				continue;
+			}
+
+			workerScripts[i].running = true;
+			var p = Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["evaluate"])(ast, workerScripts[i]);
+			//Once the code finishes (either resolved or rejected, doesnt matter), set its
+			//running status to false
+			p.then(function(w) {
+				console.log("Stopping script " + w.name + " because it finished running naturally");
+				w.running = false;
+				w.env.stopFlag = true;
+                w.scriptRef.log("Script finished running");
+			}).catch(function(w) {
+				if (w instanceof Error) {
+                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Script runtime unknown error. This is a bug please contact game developer");
+					console.log("ERROR: Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + w.toString());
+                    return;
+                } else if (w.constructor === Array && w.length === 2 && w[0] === "RETURNSTATEMENT") {
+                    //Script ends with a return statement
+                    console.log("Script returning with value: " + w[1]);
+                    //TODO maybe do something with this in the future
+                    return;
+                } else if (w instanceof WorkerScript) {
+                    if (Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["isScriptErrorMessage"])(w.errorMessage)) {
+                        var errorTextArray = w.errorMessage.split("|");
+                        if (errorTextArray.length != 4) {
+                            console.log("ERROR: Something wrong with Error text in evaluator...");
+                            console.log("Error text: " + errorText);
+                            return;
+                        }
+                        var serverIp = errorTextArray[1];
+                        var scriptName = errorTextArray[2];
+                        var errorMsg = errorTextArray[3];
+
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Script runtime error: <br>Server Ip: " + serverIp +
+                                        "<br>Script name: " + scriptName +
+                                        "<br>Args:" + Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["printArray"])(w.args) + "<br>" + errorMsg);
+                        w.scriptRef.log("Script crashed with runtime error");
+                    } else {
+                        w.scriptRef.log("Script killed");
+                    }
+					w.running = false;
+					w.env.stopFlag = true;
+
+				} else if (Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["isScriptErrorMessage"])(w)) {
+                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Script runtime unknown error. This is a bug please contact game developer");
+					console.log("ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: " + w.toString());
+                    return;
+                } else {
+                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("An unknown script died for an unknown reason. This is a bug please contact game dev");
+                }
+			});
+		}
+	}
+
+	setTimeout(runScriptsLoop, 6000);
+}
+
+//Queues a script to be killed by settings its stop flag to true. Then, the code will reject
+//all of its promises recursively, and when it does so it will no longer be running.
+//The runScriptsLoop() will then delete the script from worker scripts
+function killWorkerScript(runningScriptObj, serverIp) {
+	for (var i = 0; i < workerScripts.length; i++) {
+		if (workerScripts[i].name == runningScriptObj.filename && workerScripts[i].serverIp == serverIp &&
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["compareArrays"])(workerScripts[i].args, runningScriptObj.args)) {
+			workerScripts[i].env.stopFlag = true;
+            Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["killNetscriptDelay"])(workerScripts[i]);
+            //Recursively kill all functions
+            var curr = workerScripts[i];
+            while (curr.fnWorker) {
+                curr.fnWorker.env.stopFlag = true;
+                Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["killNetscriptDelay"])(curr.fnWorker);
+                curr = curr.fnWorker;
+            }
+            return true;
+		}
+	}
+    return false;
+}
+
+//Queues a script to be run
+function addWorkerScript(runningScriptObj, server) {
+	var filename = runningScriptObj.filename;
+
+	//Update server's ram usage
+    var threads = 1;
+    if (runningScriptObj.threads && !isNaN(runningScriptObj.threads)) {
+        threads = runningScriptObj.threads;
+    } else {
+        runningScriptObj.threads = 1;
+    }
+    var ramUsage = runningScriptObj.scriptRef.ramUsage * threads
+                   * Math.pow(_Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].MultithreadingRAMCost, threads-1);
+    var ramAvailable = server.maxRam - server.ramUsed;
+    if (ramUsage > ramAvailable) {
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Not enough RAM to run script " + runningScriptObj.filename + " with args " +
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["printArray"])(runningScriptObj.args) + ". This likely occurred because you re-loaded " +
+                        "the game and the script's RAM usage increased (either because of an update to the game or " +
+                        "your changes to the script.)");
+        return;
+    }
+	server.ramUsed += ramUsage;
+
+	//Create the WorkerScript
+	var s = new WorkerScript(runningScriptObj);
+	s.serverIp 	= server.ip;
+	s.ramUsage 	= ramUsage;
+
+	//Add the WorkerScript to the Active Scripts list
+	Object(_ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__["addActiveScriptsItem"])(s);
+
+	//Add the WorkerScript
+	workerScripts.push(s);
+	return;
+}
+
+//Updates the online running time stat of all running scripts
+function updateOnlineScriptTimes(numCycles = 1) {
+	var time = (numCycles * _engine_js__WEBPACK_IMPORTED_MODULE_2__["Engine"]._idleSpeed) / 1000; //seconds
+	for (var i = 0; i < workerScripts.length; ++i) {
+		workerScripts[i].scriptRef.onlineRunningTime += time;
+	}
+}
+
+
+
+
+/***/ }),
+/* 21 */
 /*!****************************!*\
   !*** ./src/StockMarket.js ***!
   \****************************/
@@ -16256,16 +16647,16 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
 /* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Location.js */ 4);
-/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 30);
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
+/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 29);
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Player.js */ 0);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
 /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
 /* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_9__);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
 
 
 
@@ -17597,255 +17988,6 @@ function updateStockOrderList(stock) {
 
 
 
-/***/ }),
-/* 21 */
-/*!********************************!*\
-  !*** ./src/NetscriptWorker.js ***!
-  \********************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WorkerScript", function() { return WorkerScript; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "workerScripts", function() { return workerScripts; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NetscriptPorts", function() { return NetscriptPorts; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptsLoop", function() { return runScriptsLoop; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "killWorkerScript", function() { return killWorkerScript; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addWorkerScript", function() { return addWorkerScript; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateOnlineScriptTimes", function() { return updateOnlineScriptTimes; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prestigeWorkerScripts", function() { return prestigeWorkerScripts; });
-/* harmony import */ var _ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActiveScriptsUI.js */ 42);
-/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./NetscriptEnvironment.js */ 65);
-/* harmony import */ var _NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptEvaluator.js */ 7);
-/* harmony import */ var _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./NetscriptPort.js */ 43);
-/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Server.js */ 10);
-/* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Settings.js */ 24);
-/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/acorn.js */ 36);
-/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-
-
-
-
-
-
-
-
-
-
-
-
-
-function WorkerScript(runningScriptObj) {
-	this.name 			= runningScriptObj.filename;
-	this.running 		= false;
-	this.serverIp 		= null;
-	this.code 			= runningScriptObj.scriptRef.code;
-	this.env 			= new _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_3__["Environment"](this);
-    this.env.set("args", runningScriptObj.args.slice());
-	this.output			= "";
-	this.ramUsage		= 0;
-	this.scriptRef		= runningScriptObj;
-    this.errorMessage   = "";
-    this.args           = runningScriptObj.args.slice();
-    this.delay          = null;
-    this.fnWorker       = null; //Workerscript for a function call
-    this.checkingRam    = false;
-    this.loadedFns      = {}; //Stores names of fns that are "loaded" by this script, thus using RAM
-    this.disableLogs    = {}; //Stores names of fns that should have logs disabled
-}
-
-//Returns the server on which the workerScript is running
-WorkerScript.prototype.getServer = function() {
-	return _Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][this.serverIp];
-}
-
-//Array containing all scripts that are running across all servers, to easily run them all
-let workerScripts 			= [];
-
-var NetscriptPorts = [];
-for (var i = 0; i < _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].NumNetscriptPorts; ++i) {
-    NetscriptPorts.push(new _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_5__["NetscriptPort"]());
-}
-
-function prestigeWorkerScripts() {
-    for (var i = 0; i < workerScripts.length; ++i) {
-        Object(_ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__["deleteActiveScriptsItem"])(workerScripts[i]);
-        workerScripts[i].env.stopFlag = true;
-    }
-    workerScripts.length = 0;
-}
-
-//Loop through workerScripts and run every script that is not currently running
-function runScriptsLoop() {
-    //Delete any scripts that finished or have been killed. Loop backwards bc removing
-    //items fucks up the indexing
-    for (var i = workerScripts.length - 1; i >= 0; i--) {
-        if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) {
-            //Delete script from the runningScripts array on its host serverIp
-            var ip = workerScripts[i].serverIp;
-            var name = workerScripts[i].name;
-
-            //Free RAM
-            _Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].ramUsed -= workerScripts[i].ramUsage;
-
-            //Delete script from Active Scripts
-            Object(_ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__["deleteActiveScriptsItem"])(workerScripts[i]);
-
-            for (var j = 0; j < _Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].runningScripts.length; j++) {
-                if (_Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].runningScripts[j].filename == name &&
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["compareArrays"])(_Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].runningScripts[j].args, workerScripts[i].args)) {
-                    _Server_js__WEBPACK_IMPORTED_MODULE_6__["AllServers"][ip].runningScripts.splice(j, 1);
-                    break;
-                }
-            }
-
-            //Delete script from workerScripts
-            workerScripts.splice(i, 1);
-        }
-    }
-
-	//Run any scripts that haven't been started
-	for (var i = 0; i < workerScripts.length; i++) {
-		//If it isn't running, start the script
-		if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
-			try {
-				var ast = Object(_utils_acorn_js__WEBPACK_IMPORTED_MODULE_8__["parse"])(workerScripts[i].code, {sourceType:"module"});
-                //console.log(ast);
-			} catch (e) {
-                console.log("Error parsing script: " + workerScripts[i].name);
-                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Syntax ERROR in " + workerScripts[i].name + ":<br>" +  e);
-                workerScripts[i].env.stopFlag = true;
-				continue;
-			}
-
-			workerScripts[i].running = true;
-			var p = Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["evaluate"])(ast, workerScripts[i]);
-			//Once the code finishes (either resolved or rejected, doesnt matter), set its
-			//running status to false
-			p.then(function(w) {
-				console.log("Stopping script " + w.name + " because it finished running naturally");
-				w.running = false;
-				w.env.stopFlag = true;
-                w.scriptRef.log("Script finished running");
-			}).catch(function(w) {
-				if (w instanceof Error) {
-                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Script runtime unknown error. This is a bug please contact game developer");
-					console.log("ERROR: Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + w.toString());
-                    return;
-                } else if (w.constructor === Array && w.length === 2 && w[0] === "RETURNSTATEMENT") {
-                    //Script ends with a return statement
-                    console.log("Script returning with value: " + w[1]);
-                    //TODO maybe do something with this in the future
-                    return;
-                } else if (w instanceof WorkerScript) {
-                    if (Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["isScriptErrorMessage"])(w.errorMessage)) {
-                        var errorTextArray = w.errorMessage.split("|");
-                        if (errorTextArray.length != 4) {
-                            console.log("ERROR: Something wrong with Error text in evaluator...");
-                            console.log("Error text: " + errorText);
-                            return;
-                        }
-                        var serverIp = errorTextArray[1];
-                        var scriptName = errorTextArray[2];
-                        var errorMsg = errorTextArray[3];
-
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Script runtime error: <br>Server Ip: " + serverIp +
-                                        "<br>Script name: " + scriptName +
-                                        "<br>Args:" + Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["printArray"])(w.args) + "<br>" + errorMsg);
-                        w.scriptRef.log("Script crashed with runtime error");
-                    } else {
-                        w.scriptRef.log("Script killed");
-                    }
-					w.running = false;
-					w.env.stopFlag = true;
-
-				} else if (Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["isScriptErrorMessage"])(w)) {
-                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Script runtime unknown error. This is a bug please contact game developer");
-					console.log("ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: " + w.toString());
-                    return;
-                } else {
-                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("An unknown script died for an unknown reason. This is a bug please contact game dev");
-                }
-			});
-		}
-	}
-
-	setTimeout(runScriptsLoop, 6000);
-}
-
-//Queues a script to be killed by settings its stop flag to true. Then, the code will reject
-//all of its promises recursively, and when it does so it will no longer be running.
-//The runScriptsLoop() will then delete the script from worker scripts
-function killWorkerScript(runningScriptObj, serverIp) {
-	for (var i = 0; i < workerScripts.length; i++) {
-		if (workerScripts[i].name == runningScriptObj.filename && workerScripts[i].serverIp == serverIp &&
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["compareArrays"])(workerScripts[i].args, runningScriptObj.args)) {
-			workerScripts[i].env.stopFlag = true;
-            Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["killNetscriptDelay"])(workerScripts[i]);
-            //Recursively kill all functions
-            var curr = workerScripts[i];
-            while (curr.fnWorker) {
-                curr.fnWorker.env.stopFlag = true;
-                Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__["killNetscriptDelay"])(curr.fnWorker);
-                curr = curr.fnWorker;
-            }
-            return true;
-		}
-	}
-    return false;
-}
-
-//Queues a script to be run
-function addWorkerScript(runningScriptObj, server) {
-	var filename = runningScriptObj.filename;
-
-	//Update server's ram usage
-    var threads = 1;
-    if (runningScriptObj.threads && !isNaN(runningScriptObj.threads)) {
-        threads = runningScriptObj.threads;
-    } else {
-        runningScriptObj.threads = 1;
-    }
-    var ramUsage = runningScriptObj.scriptRef.ramUsage * threads
-                   * Math.pow(_Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].MultithreadingRAMCost, threads-1);
-    var ramAvailable = server.maxRam - server.ramUsed;
-    if (ramUsage > ramAvailable) {
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_9__["dialogBoxCreate"])("Not enough RAM to run script " + runningScriptObj.filename + " with args " +
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["printArray"])(runningScriptObj.args) + ". This likely occurred because you re-loaded " +
-                        "the game and the script's RAM usage increased (either because of an update to the game or " +
-                        "your changes to the script.)");
-        return;
-    }
-	server.ramUsed += ramUsage;
-
-	//Create the WorkerScript
-	var s = new WorkerScript(runningScriptObj);
-	s.serverIp 	= server.ip;
-	s.ramUsage 	= ramUsage;
-
-	//Add the WorkerScript to the Active Scripts list
-	Object(_ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__["addActiveScriptsItem"])(s);
-
-	//Add the WorkerScript
-	workerScripts.push(s);
-	return;
-}
-
-//Updates the online running time stat of all running scripts
-function updateOnlineScriptTimes(numCycles = 1) {
-	var time = (numCycles * _engine_js__WEBPACK_IMPORTED_MODULE_2__["Engine"]._idleSpeed) / 1000; //seconds
-	for (var i = 0; i < workerScripts.length; ++i) {
-		workerScripts[i].scriptRef.onlineRunningTime += time;
-	}
-}
-
-
-
-
 /***/ }),
 /* 22 */
 /*!*************************!*\
@@ -17859,9 +18001,9 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "post", function() { return post; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Terminal", function() { return Terminal; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KEY", function() { return KEY; });
-/* harmony import */ var _Alias_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Alias.js */ 28);
+/* harmony import */ var _Alias_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Alias.js */ 30);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CreateProgram.js */ 13);
+/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CreateProgram.js */ 14);
 /* harmony import */ var _DarkWeb_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./DarkWeb.js */ 33);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./engine.js */ 5);
 /* harmony import */ var _Fconf_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Fconf.js */ 34);
@@ -17870,21 +18012,21 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Literature_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Literature.js */ 53);
 /* harmony import */ var _Message_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Message.js */ 27);
 /* harmony import */ var _NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./NetscriptEvaluator.js */ 7);
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _RedPill_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./RedPill.js */ 49);
-/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Script.js */ 29);
+/* harmony import */ var _RedPill_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./RedPill.js */ 44);
+/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Script.js */ 28);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Settings.js */ 24);
 /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
-/* harmony import */ var _TextFile_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./TextFile.js */ 39);
+/* harmony import */ var _TextFile_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./TextFile.js */ 41);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_LogBox_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../utils/LogBox.js */ 50);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
-/* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! jszip */ 111);
+/* harmony import */ var _utils_LogBox_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../utils/LogBox.js */ 51);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
+/* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! jszip */ 114);
 /* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_23___default = /*#__PURE__*/__webpack_require__.n(jszip__WEBPACK_IMPORTED_MODULE_23__);
-/* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! file-saver */ 110);
+/* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! file-saver */ 113);
 /* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_24___default = /*#__PURE__*/__webpack_require__.n(file_saver__WEBPACK_IMPORTED_MODULE_24__);
 
 
@@ -19899,7 +20041,7 @@ let Terminal = {
 
 
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
 
 /***/ }),
 /* 23 */
@@ -25682,10 +25824,10 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initMessages", function() { return initMessages; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Message", function() { return Message; });
 /* harmony import */ var _Augmentations_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Augmentations.js */ 18);
-/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CreateProgram.js */ 13);
+/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CreateProgram.js */ 14);
 /* harmony import */ var _Missions_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Missions.js */ 32);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _RedPill_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./RedPill.js */ 49);
+/* harmony import */ var _RedPill_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./RedPill.js */ 44);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Settings.js */ 24);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
@@ -25885,139 +26027,6 @@ function initMessages()  {
 
 /***/ }),
 /* 28 */
-/*!**********************!*\
-  !*** ./src/Alias.js ***!
-  \**********************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Aliases", function() { return Aliases; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GlobalAliases", function() { return GlobalAliases; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "printAliases", function() { return printAliases; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseAliasDeclaration", function() { return parseAliasDeclaration; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeAlias", function() { return removeAlias; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "substituteAliases", function() { return substituteAliases; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadAliases", function() { return loadAliases; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadGlobalAliases", function() { return loadGlobalAliases; });
-/* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Terminal.js */ 22);
-
-
-let Aliases = {};
-let GlobalAliases = {};
-
-function loadAliases(saveString) {
-    if (saveString === "") {
-        Aliases = {};
-    } else {
-        Aliases = JSON.parse(saveString);
-    }
-}
-
-function loadGlobalAliases(saveString) {
-    if (saveString === "") {
-        GlobalAliases = {};
-    } else {
-        GlobalAliases = JSON.parse(saveString);
-    }
-}
-
-//Print all aliases to terminal
-function printAliases() {
-    for (var name in Aliases) {
-        if (Aliases.hasOwnProperty(name)) {
-            Object(_Terminal_js__WEBPACK_IMPORTED_MODULE_0__["post"])("alias " + name + "=" + Aliases[name]);
-        }
-    }
-    for (var name in GlobalAliases) {
-        if (GlobalAliases.hasOwnProperty(name)) {
-            Object(_Terminal_js__WEBPACK_IMPORTED_MODULE_0__["post"])("global alias " + name + "=" + GlobalAliases[name]);
-        }
-    }
-}
-
-//True if successful, false otherwise
-function parseAliasDeclaration(dec,global=false) {
-    var re = /^([_|\w|!|%|,|@]+)="(.+)"$/;
-    var matches = dec.match(re);
-    if (matches == null || matches.length != 3) {return false;}
-    if (global){
-        addGlobalAlias(matches[1],matches[2]);
-    } else {
-        addAlias(matches[1], matches[2]);
-    }
-    return true;
-}
-
-function addAlias(name, value) {
-    if (name in GlobalAliases){
-        delete GlobalAliases[name];
-    }
-    Aliases[name] = value;
-}
-
-function addGlobalAlias(name, value) {
-    if (name in Aliases){
-        delete Aliases[name];
-    }
-    GlobalAliases[name] = value;
-}
-
-function getAlias(name) {
-    if (Aliases.hasOwnProperty(name)) {
-        return Aliases[name];
-    }
-    return null;
-}
-
-function getGlobalAlias(name) {
-    if (GlobalAliases.hasOwnProperty(name)) {
-        return GlobalAliases[name];
-    }
-    return null;
-}
-
-function removeAlias(name) {
-    if (Aliases.hasOwnProperty(name)) {
-        delete Aliases[name];
-        return true;
-    }
-    if (GlobalAliases.hasOwnProperty(name)) {
-        delete GlobalAliases[name];
-        return true;
-    }
-    return false;
-}
-
-//Returns the original string with any aliases substituted in
-//Aliases only applied to "whole words", one level deep
-function substituteAliases(origCommand) {
-    var commandArray = origCommand.split(" ");
-    if (commandArray.length>0){
-        var alias = getAlias(commandArray[0]);
-        if (alias != null) {
-            commandArray[0] = alias;
-        } else {
-            var alias = getGlobalAlias(commandArray[0]);
-            if (alias != null) {
-                commandArray[0] = alias;
-            }
-        }
-        for (var i = 0; i < commandArray.length; ++i) {
-            var alias = getGlobalAlias(commandArray[i]);
-            if (alias != null) {
-                commandArray[i] = alias;
-            }
-        }
-    }
-    return commandArray.join(" ");
-}
-
-
-
-
-/***/ }),
-/* 29 */
 /*!***********************!*\
   !*** ./src/Script.js ***!
   \***********************/
@@ -26037,14 +26046,14 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Fconf_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Fconf.js */ 34);
 /* harmony import */ var _InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./InteractiveTutorial.js */ 25);
 /* harmony import */ var _NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NetscriptEvaluator.js */ 7);
-/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 30);
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
+/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 29);
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Player.js */ 0);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Settings.js */ 24);
 /* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Terminal.js */ 22);
-/* harmony import */ var _TextFile_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./TextFile.js */ 39);
-/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/acorn.js */ 36);
+/* harmony import */ var _TextFile_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./TextFile.js */ 41);
+/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/acorn.js */ 35);
 /* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_utils_acorn_js__WEBPACK_IMPORTED_MODULE_12__);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
@@ -26276,7 +26285,7 @@ function updateScriptEditorContent() {
 $(document).keydown(function(e) {
 	if (_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage == _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.ScriptEditor) {
 		//Ctrl + b
-        if (e.keyCode == 66 && e.ctrlKey) {
+        if (e.keyCode == 66 && (e.ctrlKey || e.metaKey)) {
             e.preventDefault();
 			saveAndCloseScriptEditor();
         }
@@ -26761,10 +26770,10 @@ _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_14__["Reviver"].constructors.AllS
 
 
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
 
 /***/ }),
-/* 30 */
+/* 29 */
 /*!***********************************!*\
   !*** ./src/NetscriptFunctions.js ***!
   \***********************************/
@@ -26781,41 +26790,41 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hasCorporationSF", function() { return hasCorporationSF; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hasAISF", function() { return hasAISF; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hasBladeburnerSF", function() { return hasBladeburnerSF; });
-/* harmony import */ var _ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActiveScriptsUI.js */ 42);
+/* harmony import */ var _ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActiveScriptsUI.js */ 43);
 /* harmony import */ var _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Augmentations.js */ 18);
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./BitNode.js */ 16);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./BitNode.js */ 15);
 /* harmony import */ var _Crimes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Crimes.js */ 19);
 /* harmony import */ var _Company_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Company.js */ 9);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./CreateProgram.js */ 13);
+/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./CreateProgram.js */ 14);
 /* harmony import */ var _DarkWeb_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./DarkWeb.js */ 33);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Faction.js */ 14);
-/* harmony import */ var _HacknetNode_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./HacknetNode.js */ 38);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Faction.js */ 11);
+/* harmony import */ var _HacknetNode_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./HacknetNode.js */ 39);
 /* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./Location.js */ 4);
 /* harmony import */ var _Message_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Message.js */ 27);
 /* harmony import */ var _Missions_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Missions.js */ 32);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Script.js */ 29);
+/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Script.js */ 28);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Settings.js */ 24);
 /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
-/* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./StockMarket.js */ 20);
+/* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./StockMarket.js */ 21);
 /* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./Terminal.js */ 22);
-/* harmony import */ var _TextFile_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./TextFile.js */ 39);
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
+/* harmony import */ var _TextFile_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./TextFile.js */ 41);
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
 /* harmony import */ var _NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./NetscriptEvaluator.js */ 7);
-/* harmony import */ var _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./NetscriptEnvironment.js */ 65);
-/* harmony import */ var _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./NetscriptPort.js */ 43);
+/* harmony import */ var _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./NetscriptEnvironment.js */ 66);
+/* harmony import */ var _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./NetscriptPort.js */ 45);
 /* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../utils/decimal.js */ 23);
 /* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_26___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_26__);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../utils/IPAddress.js */ 15);
+/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
-var sprintf = __webpack_require__(/*! sprintf-js */ 109).sprintf,
-    vsprintf = __webpack_require__(/*! sprintf-js */ 109).vsprintf
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
+var sprintf = __webpack_require__(/*! sprintf-js */ 108).sprintf,
+    vsprintf = __webpack_require__(/*! sprintf-js */ 108).vsprintf
 
 
 
@@ -30358,6 +30367,139 @@ function NetscriptFunctions(workerScript) {
 
 
 
+/***/ }),
+/* 30 */
+/*!**********************!*\
+  !*** ./src/Alias.js ***!
+  \**********************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Aliases", function() { return Aliases; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GlobalAliases", function() { return GlobalAliases; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "printAliases", function() { return printAliases; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseAliasDeclaration", function() { return parseAliasDeclaration; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeAlias", function() { return removeAlias; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "substituteAliases", function() { return substituteAliases; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadAliases", function() { return loadAliases; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadGlobalAliases", function() { return loadGlobalAliases; });
+/* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Terminal.js */ 22);
+
+
+let Aliases = {};
+let GlobalAliases = {};
+
+function loadAliases(saveString) {
+    if (saveString === "") {
+        Aliases = {};
+    } else {
+        Aliases = JSON.parse(saveString);
+    }
+}
+
+function loadGlobalAliases(saveString) {
+    if (saveString === "") {
+        GlobalAliases = {};
+    } else {
+        GlobalAliases = JSON.parse(saveString);
+    }
+}
+
+//Print all aliases to terminal
+function printAliases() {
+    for (var name in Aliases) {
+        if (Aliases.hasOwnProperty(name)) {
+            Object(_Terminal_js__WEBPACK_IMPORTED_MODULE_0__["post"])("alias " + name + "=" + Aliases[name]);
+        }
+    }
+    for (var name in GlobalAliases) {
+        if (GlobalAliases.hasOwnProperty(name)) {
+            Object(_Terminal_js__WEBPACK_IMPORTED_MODULE_0__["post"])("global alias " + name + "=" + GlobalAliases[name]);
+        }
+    }
+}
+
+//True if successful, false otherwise
+function parseAliasDeclaration(dec,global=false) {
+    var re = /^([_|\w|!|%|,|@]+)="(.+)"$/;
+    var matches = dec.match(re);
+    if (matches == null || matches.length != 3) {return false;}
+    if (global){
+        addGlobalAlias(matches[1],matches[2]);
+    } else {
+        addAlias(matches[1], matches[2]);
+    }
+    return true;
+}
+
+function addAlias(name, value) {
+    if (name in GlobalAliases){
+        delete GlobalAliases[name];
+    }
+    Aliases[name] = value;
+}
+
+function addGlobalAlias(name, value) {
+    if (name in Aliases){
+        delete Aliases[name];
+    }
+    GlobalAliases[name] = value;
+}
+
+function getAlias(name) {
+    if (Aliases.hasOwnProperty(name)) {
+        return Aliases[name];
+    }
+    return null;
+}
+
+function getGlobalAlias(name) {
+    if (GlobalAliases.hasOwnProperty(name)) {
+        return GlobalAliases[name];
+    }
+    return null;
+}
+
+function removeAlias(name) {
+    if (Aliases.hasOwnProperty(name)) {
+        delete Aliases[name];
+        return true;
+    }
+    if (GlobalAliases.hasOwnProperty(name)) {
+        delete GlobalAliases[name];
+        return true;
+    }
+    return false;
+}
+
+//Returns the original string with any aliases substituted in
+//Aliases only applied to "whole words", one level deep
+function substituteAliases(origCommand) {
+    var commandArray = origCommand.split(" ");
+    if (commandArray.length>0){
+        var alias = getAlias(commandArray[0]);
+        if (alias != null) {
+            commandArray[0] = alias;
+        } else {
+            var alias = getGlobalAlias(commandArray[0]);
+            if (alias != null) {
+                commandArray[0] = alias;
+            }
+        }
+        for (var i = 0; i < commandArray.length; ++i) {
+            var alias = getGlobalAlias(commandArray[i]);
+            if (alias != null) {
+                commandArray[i] = alias;
+            }
+        }
+    }
+    return commandArray.join(" ");
+}
+
+
+
+
 /***/ }),
 /* 31 */
 /*!*****************************************!*\
@@ -30368,11 +30510,11 @@ function NetscriptFunctions(workerScript) {
 "use strict";
 
 
-var support = __webpack_require__(/*! ./support */ 47);
+var support = __webpack_require__(/*! ./support */ 50);
 var base64 = __webpack_require__(/*! ./base64 */ 99);
-var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ 62);
-var setImmediate = __webpack_require__(/*! core-js/library/fn/set-immediate */ 152);
-var external = __webpack_require__(/*! ./external */ 57);
+var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ 63);
+var setImmediate = __webpack_require__(/*! core-js/library/fn/set-immediate */ 153);
+var external = __webpack_require__(/*! ./external */ 58);
 
 
 /**
@@ -30859,7 +31001,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "currMission", function() { return currMission; });
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Faction.js */ 14);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Faction.js */ 11);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Player.js */ 0);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
@@ -32401,7 +32543,7 @@ HackingMission.prototype.finishMission = function(win) {
 
 
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
 
 /***/ }),
 /* 33 */
@@ -32418,11 +32560,11 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buyDarkwebItem", function() { return buyDarkwebItem; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseDarkwebItemPrice", function() { return parseDarkwebItemPrice; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DarkWebItems", function() { return DarkWebItems; });
-/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./CreateProgram.js */ 13);
+/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./CreateProgram.js */ 14);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Player.js */ 0);
 /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
 /* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Terminal.js */ 22);
-/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/IPAddress.js */ 15);
+/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
 
 
@@ -32635,7 +32777,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createFconf", function() { return createFconf; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseFconfSettings", function() { return parseFconfSettings; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadFconf", function() { return loadFconf; });
-/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/acorn.js */ 36);
+/* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/acorn.js */ 35);
 /* harmony import */ var _utils_acorn_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_utils_acorn_js__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -32759,1474 +32901,6 @@ function loadFconf(saveString) {
 
 /***/ }),
 /* 35 */
-/*!*********************!*\
-  !*** ./src/Gang.js ***!
-  \*********************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Gang", function() { return Gang; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayGangContent", function() { return displayGangContent; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateGangContent", function() { return updateGangContent; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadAllGangs", function() { return loadAllGangs; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AllGangs", function() { return AllGangs; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resetGangs", function() { return resetGangs; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deleteGangDisplayContent", function() { return deleteGangDisplayContent; });
-/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Faction.js */ 14);
-/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7__);
-/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
-
-
-
-
-
-
-
-
-
-
-
-/* Gang.js */
-//Switch between territory and management screen with 1 and 2
-$(document).keydown(function(event) {
-    if (_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage == _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.Gang && !_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoBoxOpen"]) {
-        if (gangMemberFilter != null && gangMemberFilter === document.activeElement) {return;}
-        if (event.keyCode === 49) {
-            if(gangTerritorySubpage.style.display === "block") {
-                managementButton.click();
-            }
-        } else if (event.keyCode === 50) {
-            if (gangManagementSubpage.style.display === "block") {
-                territoryButton.click();
-            }
-        }
-    }
-});
-
-//Delete upgrade box when clicking outside
-$(document).mousedown(function(event) {
-    var boxId = "gang-member-upgrade-popup-box";
-    var contentId = "gang-member-upgrade-popup-box-content";
-    if (gangMemberUpgradeBoxOpened) {
-        if ( $(event.target).closest("#" + contentId).get(0) == null ) {
-            //Delete the box
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeElement"])(gangMemberUpgradeBox);
-            gangMemberUpgradeBox = null;
-            gangMemberUpgradeBoxContent = null;
-            gangMemberUpgradeBoxOpened = false;
-            gangMemberUpgradeBoxElements = null;
-        }
-    }
-});
-
-let GangNames = ["Slum Snakes", "Tetrads", "The Syndicate", "The Dark Army", "Speakers for the Dead",
-             "NiteSec", "The Black Hand"];
-let AllGangs = {
-    "Slum Snakes" : {
-        power: 1,
-        territory: 1/7,
-    },
-    "Tetrads" : {
-        power: 1,
-        territory: 1/7,
-    },
-    "The Syndicate" : {
-        power: 1,
-        territory: 1/7,
-    },
-    "The Dark Army" : {
-        power: 1,
-        territory: 1/7,
-    },
-    "Speakers for the Dead" : {
-        power: 1,
-        territory: 1/7,
-    },
-    "NiteSec" : {
-        power: 1,
-        territory: 1/7,
-    },
-    "The Black Hand" : {
-        power: 1,
-        territory: 1/7,
-    },
-}
-
-function resetGangs() {
-    AllGangs = {
-        "Slum Snakes" : {
-            power: 1,
-            territory: 1/7,
-        },
-        "Tetrads" : {
-            power: 1,
-            territory: 1/7,
-        },
-        "The Syndicate" : {
-            power: 1,
-            territory: 1/7,
-        },
-        "The Dark Army" : {
-            power: 1,
-            territory: 1/7,
-        },
-        "Speakers for the Dead" : {
-            power: 1,
-            territory: 1/7,
-        },
-        "NiteSec" : {
-            power: 1,
-            territory: 1/7,
-        },
-        "The Black Hand" : {
-            power: 1,
-            territory: 1/7,
-        },
-    }
-}
-
-function loadAllGangs(saveString) {
-    AllGangs = JSON.parse(saveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"]);
-}
-
-//Power is an estimate of a gang's ability to gain/defend territory
-let gangStoredPowerCycles = 0;
-function processAllGangPowerGains(numCycles=1) {
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
-    gangStoredPowerCycles += numCycles;
-    if (gangStoredPowerCycles < 150) {return;}
-    var playerGangName = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName;
-    for (var name in AllGangs) {
-        if (AllGangs.hasOwnProperty(name)) {
-            if (name == playerGangName) {
-                AllGangs[name].power += _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.calculatePower();
-            } else {
-                var gain = Math.random() * 0.02; //TODO Adjust as necessary
-                AllGangs[name].power += (gain);
-            }
-        }
-    }
-
-    gangStoredPowerCycles -= 150;
-}
-
-let gangStoredTerritoryCycles = 0;
-function processAllGangTerritory(numCycles=1) {
-    if (!_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
-    gangStoredTerritoryCycles += numCycles;
-    if (gangStoredTerritoryCycles < _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].GangTerritoryUpdateTimer) {return;}
-
-    for (var i = 0; i < GangNames.length; ++i) {
-        var other = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(0, GangNames.length-1);
-        while(other == i) {
-            other = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(0, GangNames.length-1);
-        }
-        var thisPwr = AllGangs[GangNames[i]].power;
-        var otherPwr = AllGangs[GangNames[other]].power;
-        var thisChance = thisPwr / (thisPwr + otherPwr);
-
-        if (Math.random() < thisChance) {
-            if (AllGangs[GangNames[other]].territory <= 0) {
-                return;
-            }
-            AllGangs[GangNames[i]].territory += 0.0001;
-            AllGangs[GangNames[other]].territory -= 0.0001;
-        } else {
-            if (AllGangs[GangNames[i]].territory <= 0) {
-                return;
-            }
-            AllGangs[GangNames[i]].territory -= 0.0001;
-            AllGangs[GangNames[other]].territory += 0.0001;
-        }
-    }
-
-    gangStoredTerritoryCycles -= _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].GangTerritoryUpdateTimer;
-}
-
-/*  faction - Name of corresponding faction
-    hacking - Boolean indicating whether its a hacking gang or not
- */
-function Gang(facName, hacking=false) {
-    this.facName    = facName;
-    this.members    = [];  //Array of GangMembers
-    this.wanted     = 1;
-    this.respect    = 1;
-    this.power      = 0;
-
-    this.isHackingGang = hacking;
-
-    this.respectGainRate = 0;
-    this.wantedGainRate = 0;
-    this.moneyGainRate = 0;
-
-    //When processing gains, this stores the number of cycles until some
-    //limit is reached, and then calculates and applies the gains only at that limit
-    this.storedCycles   = 0;
-}
-
-Gang.prototype.process = function(numCycles=1) {
-    this.processGains(numCycles);
-    this.processExperienceGains(numCycles);
-    processAllGangPowerGains(numCycles);
-    processAllGangTerritory(numCycles);
-}
-
-Gang.prototype.processGains = function(numCycles=1) {
-    this.storedCycles += numCycles;
-    if (isNaN(this.storedCycles)) {
-        console.log("ERROR: Gang's storedCylces is NaN");
-        this.storedCycles = 0;
-    }
-    if (this.storedCycles < 25) {return;} //Only process every 5 seconds at least
-
-    //Get gains per cycle
-    var moneyGains = 0, respectGains = 0, wantedLevelGains = 0;
-    for (var i = 0; i < this.members.length; ++i) {
-        respectGains += (this.members[i].calculateRespectGain());
-        wantedLevelGains += (this.members[i].calculateWantedLevelGain());
-        moneyGains += (this.members[i].calculateMoneyGain());
-    }
-    this.respectGainRate = respectGains;
-    this.wantedGainRate = wantedLevelGains;
-    this.moneyGainRate = moneyGains;
-
-    if (!isNaN(respectGains)) {
-        var gain = respectGains * this.storedCycles;
-        this.respect += (gain);
-        //Faction reputation gains is respect gain divided by some constant
-        var fac = _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Factions"][this.facName];
-        if (!(fac instanceof _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Faction"])) {
-            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__["dialogBoxCreate"])("ERROR: Could not get Faction associates with your gang. This is a bug, please report to game dev");
-        } else {
-            var favorMult = 1 + (fac.favor / 100);
-            fac.playerReputation += ((_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].faction_rep_mult * gain * favorMult) / _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].GangRespectToReputationRatio);
-        }
-
-    } else {
-        console.log("ERROR: respectGains is NaN");
-    }
-    if (!isNaN(wantedLevelGains)) {
-        if (this.wanted === 1 && wantedLevelGains < 0) {
-            //Do nothing
-        } else {
-            this.wanted += (wantedLevelGains * this.storedCycles);
-            if (this.wanted < 1) {this.wanted = 1;}
-        }
-    } else {
-        console.log("ERROR: wantedLevelGains is NaN");
-    }
-    if (!isNaN(moneyGains)) {
-        _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gainMoney(moneyGains * this.storedCycles);
-    } else {
-        console.log("ERROR: respectGains is NaN");
-    }
-
-    this.storedCycles = 0;
-}
-
-Gang.prototype.processExperienceGains = function(numCycles=1) {
-    for (var i = 0; i < this.members.length; ++i) {
-        this.members[i].gainExperience(numCycles);
-        this.members[i].updateSkillLevels();
-    }
-}
-
-//Calculates power GAIN, which is added onto the Gang's existing power
-Gang.prototype.calculatePower = function() {
-    var memberTotal = 0;
-    for (var i = 0; i < this.members.length; ++i) {
-        if (this.members[i].task instanceof GangMemberTask &&
-            this.members[i].task.name == "Territory Warfare") {
-            memberTotal += this.members[i].calculatePower();
-        }
-    }
-    return (0.0005 * memberTotal);
-}
-
-Gang.prototype.autoAssignMemberToTask = function(taskName) {
-    for (var i = 0; i < this.members.length; ++i) {
-        if (this.members[i].task.name === taskName) {
-            this.members[i].assignToTask(taskName);
-            return true;
-        }
-    }
-    return false;
-}
-
-Gang.prototype.autoUnassignMemberFromTask = function(taskName) {
-    for (var i = 0; i < this.members.length; ++i) {
-        if (this.members[i].task.name === taskName) {
-            this.members[i].unassignFromTask();
-            return true;
-        }
-    }
-    return false;
-}
-
-Gang.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_toJSON"])("Gang", this);
-}
-
-Gang.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_fromJSON"])(Gang, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"].constructors.Gang = Gang;
-
-/*** Gang Member object ***/
-function GangMember(name) {
-    this.name   = name;
-    this.task   = GangMemberTasks["Unassigned"]; //GangMemberTask object
-    this.city   = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].city;
-
-    this.hack   = 1;
-    this.str    = 1;
-    this.def    = 1;
-    this.dex    = 1;
-    this.agi    = 1;
-    this.cha    = 1;
-
-    this.hack_exp   = 0;
-    this.str_exp    = 0;
-    this.def_exp    = 0;
-    this.dex_exp    = 0;
-    this.agi_exp    = 0;
-    this.cha_exp    = 0;
-
-    this.hack_mult  = 1;
-    this.str_mult   = 1;
-    this.def_mult   = 1;
-    this.dex_mult   = 1;
-    this.agi_mult   = 1;
-    this.cha_mult   = 1;
-
-    this.upgrades = []; //Names of upgrades
-}
-
-//Same formula for Player
-GangMember.prototype.calculateSkill = function(exp) {
-    return Math.max(Math.floor(32 * Math.log(exp + 534.5) - 200), 1);
-}
-
-GangMember.prototype.updateSkillLevels = function() {
-    this.hack   = Math.floor(this.calculateSkill(this.hack_exp) * this.hack_mult);
-    this.str    = Math.floor(this.calculateSkill(this.str_exp) * this.str_mult);
-    this.def    = Math.floor(this.calculateSkill(this.def_exp) * this.def_mult);
-    this.dex    = Math.floor(this.calculateSkill(this.dex_exp) * this.dex_mult);
-    this.agi    = Math.floor(this.calculateSkill(this.agi_exp) * this.agi_mult);
-    this.cha    = Math.floor(this.calculateSkill(this.cha_exp) * this.cha_mult);
-}
-
-GangMember.prototype.calculatePower = function() {
-    return (this.hack + this.str + this.def +
-            this.dex + this.agi + this.cha) / 100;
-}
-
-GangMember.prototype.assignToTask = function(taskName) {
-    if (GangMemberTasks.hasOwnProperty(taskName)) {
-        this.task = GangMemberTasks[taskName];
-    } else {
-        this.task = GangMemberTasks["Unassigned"];
-    }
-}
-
-GangMember.prototype.unassignFromTask = function() {
-    if (GangMemberTasks.hasOwnProperty("Unassigned")) {
-        this.task = GangMemberTasks["Unassigned"];
-    } else {
-        console.log("ERROR: Can't find Unassigned Gang member task");
-        this.task = null;
-    }
-}
-
-//Gains are per cycle
-GangMember.prototype.calculateRespectGain = function() {
-    var task = this.task;
-    if (task == null || !(task instanceof GangMemberTask) || task.baseRespect === 0) {return 0;}
-    var statWeight =    (task.hackWeight/100) * this.hack +
-                        (task.strWeight/100) * this.str +
-                        (task.defWeight/100) * this.def +
-                        (task.dexWeight/100) * this.dex +
-                        (task.agiWeight/100) * this.agi +
-                        (task.chaWeight/100) * this.cha;
-    statWeight -= (3.5 * task.difficulty);
-    if (statWeight <= 0) {return 0;}
-    var territoryMult = AllGangs[_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName].territory;
-    if (territoryMult <= 0) {return 0;}
-    var respectMult = (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect) / (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect + _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted);
-    return 12 * task.baseRespect * statWeight * territoryMult * respectMult;
-}
-
-GangMember.prototype.calculateWantedLevelGain = function() {
-    var task = this.task;
-    if (task == null || !(task instanceof GangMemberTask) || task.baseWanted === 0) {return 0;}
-    var statWeight =    (task.hackWeight/100) * this.hack +
-                        (task.strWeight/100) * this.str +
-                        (task.defWeight/100) * this.def +
-                        (task.dexWeight/100) * this.dex +
-                        (task.agiWeight/100) * this.agi +
-                        (task.chaWeight/100) * this.cha;
-    statWeight -= (3.5 * task.difficulty);
-    if (statWeight <= 0) {return 0;}
-    var territoryMult = AllGangs[_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName].territory;
-    if (territoryMult <= 0) {return 0;}
-    if (task.baseWanted < 0) {
-        return task.baseWanted * statWeight * territoryMult;
-    } else {
-        return 6 * task.baseWanted / (3 * statWeight * territoryMult);
-    }
-}
-
-GangMember.prototype.calculateMoneyGain = function() {
-    var task = this.task;
-    if (task == null || !(task instanceof GangMemberTask) || task.baseMoney === 0) {return 0;}
-    var statWeight =    (task.hackWeight/100) * this.hack +
-                        (task.strWeight/100) * this.str +
-                        (task.defWeight/100) * this.def +
-                        (task.dexWeight/100) * this.dex +
-                        (task.agiWeight/100) * this.agi +
-                        (task.chaWeight/100) * this.cha;
-    statWeight -= (3.5 * task.difficulty);
-    if (statWeight <= 0) {return 0;}
-    var territoryMult = AllGangs[_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName].territory;
-    if (territoryMult <= 0) {return 0;}
-    var respectMult = (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect) / (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect + _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted);
-    return 5 * task.baseMoney * statWeight * territoryMult * respectMult;
-}
-
-GangMember.prototype.gainExperience = function(numCycles=1) {
-    var task = this.task;
-    if (task == null || !(task instanceof GangMemberTask)) {return;}
-    this.hack_exp   += (task.hackWeight / 1500) * task.difficulty * numCycles;
-    this.str_exp    += (task.strWeight / 1500) * task.difficulty * numCycles;
-    this.def_exp    += (task.defWeight / 1500) * task.difficulty * numCycles;
-    this.dex_exp    += (task.dexWeight / 1500) * task.difficulty * numCycles;
-    this.agi_exp    += (task.agiWeight / 1500) * task.difficulty * numCycles;
-    this.cha_exp    += (task.chaWeight / 1500) * task.difficulty * numCycles;
-}
-
-GangMember.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_toJSON"])("GangMember", this);
-}
-
-GangMember.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_fromJSON"])(GangMember, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"].constructors.GangMember = GangMember;
-
-//Defines tasks that Gang Members can work on
-function GangMemberTask(name="", desc="",
-                        params={baseRespect: 0, baseWanted: 0, baseMoney: 0,
-                                hackWeight: 0, strWeight: 0, defWeight: 0,
-                                dexWeight: 0, agiWeight: 0, chaWeight: 0,
-                                difficulty: 0}) {
-    this.name = name;
-    this.desc = desc;
-
-    this.baseRespect    = params.baseRespect ? params.baseRespect   : 0;
-    this.baseWanted     = params.baseWanted  ? params.baseWanted    : 0;
-    this.baseMoney      = params.baseMoney   ? params.baseMoney     : 0;
-
-    //Weights must add up to 100
-    this.hackWeight     = params.hackWeight ? params.hackWeight : 0;
-    this.strWeight      = params.strWeight  ? params.strWeight  : 0;
-    this.defWeight      = params.defWeight  ? params.defWeight  : 0;
-    this.dexWeight      = params.dexWeight  ? params.dexWeight  : 0;
-    this.agiWeight      = params.agiWeight  ? params.agiWeight  : 0;
-    this.chaWeight      = params.chaWeight  ? params.chaWeight  : 0;
-
-    //1 - 100
-    this.difficulty     = params.difficulty ? params.difficulty : 1;
-}
-
-GangMemberTask.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_toJSON"])("GangMemberTask", this);
-}
-
-GangMemberTask.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_fromJSON"])(GangMemberTask, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"].constructors.GangMemberTask = GangMemberTask;
-
-//TODO Human trafficking and an equivalent hacking crime
-let GangMemberTasks = {
-    "Unassigned" :              new GangMemberTask(
-                                        "Unassigned",
-                                        "This gang member is currently idle"),
-    "Ransomware" :              new GangMemberTask(
-                                        "Ransomware",
-                                        "Assign this gang member to create and distribute ransomware<br><br>" +
-                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
-                                        {baseRespect: 0.00005, baseWanted: 0.00001, baseMoney: 1,
-                                         hackWeight: 100, difficulty: 1}),
-    "Phishing" :                new GangMemberTask(
-                                        "Phishing",
-                                        "Assign this gang member to attempt phishing scams and attacks<br><br>" +
-                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
-                                        {baseRespect: 0.00008, baseWanted: 0.001, baseMoney: 2.5,
-                                         hackWeight: 85, chaWeight: 15, difficulty: 3}),
-    "Identity Theft" :          new GangMemberTask(
-                                        "Identity Theft",
-                                        "Assign this gang member to attempt identity theft<br><br>" +
-                                        "Earns money - Increases respect - Increases wanted level",
-                                        {baseRespect: 0.0001, baseWanted: 0.01, baseMoney: 6,
-                                         hackWeight: 80, chaWeight: 20, difficulty: 4}),
-    "DDoS Attacks" :            new GangMemberTask(
-                                        "DDoS Attacks",
-                                        "Assign this gang member to carry out DDoS attacks<br><br>" +
-                                        "Increases respect - Increases wanted level",
-                                        {baseRespect: 0.0004, baseWanted: 0.05,
-                                         hackWeight: 100, difficulty: 7}),
-    "Plant Virus" :             new GangMemberTask(
-                                        "Plant Virus",
-                                        "Assign this gang member to create and distribute malicious viruses<br><br>" +
-                                        "Increases respect - Increases wanted level",
-                                        {baseRespect: 0.0006, baseWanted: 0.05,
-                                         hackWeight: 100, difficulty: 10}),
-    "Fraud & Counterfeiting" :  new GangMemberTask(
-                                        "Fraud & Counterfeiting",
-                                        "Assign this gang member to commit financial fraud and digital counterfeiting<br><br>" +
-                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
-                                        {baseRespect: 0.0005, baseWanted: 0.1, baseMoney: 15,
-                                         hackWeight: 80, chaWeight: 20, difficulty: 17}),
-    "Money Laundering" :        new GangMemberTask(
-                                        "Money Laundering",
-                                        "Assign this gang member to launder money<br><br>" +
-                                        "Earns money - Increases respect - Increases wanted level",
-                                        {baseRespect: 0.0006, baseWanted:0.2, baseMoney: 40,
-                                         hackWeight: 75, chaWeight: 25, difficulty: 20}),
-    "Cyberterrorism" :          new GangMemberTask(
-                                        "Cyberterrorism",
-                                        "Assign this gang member to commit acts of cyberterrorism<br><br>" +
-                                        "Greatly increases respect - Greatly increases wanted level",
-                                        {baseRespect: 0.001, baseWanted: 0.5,
-                                         hackWeight: 80, chaWeight: 20, difficulty: 33}),
-    "Ethical Hacking" :         new GangMemberTask(
-                                        "Ethical Hacking",
-                                        "Assign this gang member to be an ethical hacker for corporations<br><br>" +
-                                        "Earns money - Lowers wanted level",
-                                        {baseWanted: -0.001, baseMoney: 1,
-                                         hackWeight: 90, chaWeight: 10, difficulty: 1}),
-    "Mug People" :              new GangMemberTask(
-                                        "Mug People",
-                                        "Assign this gang member to mug random people on the streets<br><br>" +
-                                        "Earns money - Slightly increases respect - Very slightly increases wanted level",
-                                         {baseRespect: 0.00005, baseWanted: 0.00001, baseMoney: 1,
-                                          strWeight: 25, defWeight: 25, dexWeight: 25, agiWeight: 10, chaWeight: 15, difficulty: 1}),
-    "Deal Drugs" :              new GangMemberTask(
-                                        "Deal Drugs",
-                                        "Assign this gang member to sell drugs.<br><br>" +
-                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
-                                        {baseRespect: 0.00008, baseWanted: 0.001, baseMoney: 4,
-                                         agiWeight: 20, dexWeight: 20, chaWeight: 60, difficulty: 3}),
-    "Run a Con" :               new GangMemberTask(
-                                        "Run a Con",
-                                        "Assign this gang member to run cons<br><br>" +
-                                        "Earns money - Increases respect - Increases wanted level",
-                                        {baseRespect: 0.00015, baseWanted: 0.01, baseMoney: 10,
-                                         strWeight: 5, defWeight: 5, agiWeight: 25, dexWeight: 25, chaWeight: 40, difficulty: 10}),
-    "Armed Robbery" :           new GangMemberTask(
-                                        "Armed Robbery",
-                                        "Assign this gang member to commit armed robbery on stores, banks and armored cars<br><br>" +
-                                        "Earns money - Increases respect - Increases wanted level",
-                                        {baseRespect: 0.00015, baseWanted: 0.05, baseMoney: 25,
-                                         hackWeight: 20, strWeight: 15, defWeight: 15, agiWeight: 10, dexWeight: 20, chaWeight: 20,
-                                         difficulty: 17}),
-    "Traffick Illegal Arms" :   new GangMemberTask(
-                                        "Traffick Illegal Arms",
-                                        "Assign this gang member to traffick illegal arms<br><br>" +
-                                        "Earns money - Increases respect - Increases wanted level",
-                                        {baseRespect: 0.0003, baseWanted: 0.1, baseMoney: 40,
-                                         hackWeight: 15, strWeight: 20, defWeight: 20, dexWeight: 20, chaWeight: 75,
-                                         difficulty: 25}),
-    "Threaten & Blackmail" :    new GangMemberTask(
-                                        "Threaten & Blackmail",
-                                        "Assign this gang member to threaten and black mail high-profile targets<br><br>" +
-                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
-                                        {baseRespect: 0.0002, baseWanted: 0.05, baseMoney: 15,
-                                         hackWeight: 25, strWeight: 25, dexWeight: 25, chaWeight: 25, difficulty: 28}),
-    "Terrorism" :               new GangMemberTask(
-                                        "Terrorism",
-                                        "Assign this gang member to commit acts of terrorism<br><br>" +
-                                        "Greatly increases respect - Greatly increases wanted level",
-                                        {baseRespect: 0.001, baseWanted: 1,
-                                         hackWeight: 20, strWeight: 20, defWeight: 20,dexWeight: 20, chaWeight: 20,
-                                         difficulty: 33}),
-    "Vigilante Justice" :       new GangMemberTask(
-                                        "Vigilante Justice",
-                                        "Assign this gang member to be a vigilante and protect the city from criminals<br><br>" +
-                                        "Decreases wanted level",
-                                        {baseWanted: -0.001,
-                                         hackWeight: 20, strWeight: 20, defWeight: 20, dexWeight: 20, agiWeight:20,
-                                         difficulty: 1}),
-    "Train Combat" :            new GangMemberTask(
-                                        "Train Combat",
-                                        "Assign this gang member to increase their combat stats (str, def, dex, agi)",
-                                        {strWeight: 25, defWeight: 25, dexWeight: 25, agiWeight: 25, difficulty: 5}),
-    "Train Hacking" :           new GangMemberTask(
-                                        "Train Hacking",
-                                        "Assign this gang member to train their hacking skills",
-                                        {hackWeight: 100, difficulty: 8}),
-    "Territory Warfare" :       new GangMemberTask(
-                                        "Territory Warfare",
-                                        "Assign this gang member to engage in territorial warfare with other gangs. " +
-                                        "Members assigned to this task will help increase your gang's territory " +
-                                        "and will defend your territory from being taken.",
-                                        {hackWeight: 15, strWeight: 20, defWeight: 20, dexWeight: 20, agiWeight: 20,
-                                         chaWeight: 5, difficulty: 3}),
-}
-
-
-function GangMemberUpgrade(name="", desc="", cost=0, type="w") {
-    this.name = name;
-    this.desc = desc;
-    this.cost = cost;
-    this.type = type; //w, a, v, r
-}
-
-//Passes in a GangMember object
-GangMemberUpgrade.prototype.apply = function(member) {
-    switch(this.name) {
-        case "Baseball Bat":
-            member.str_mult *= 1.05;
-            member.def_mult *= 1.05;
-            break;
-        case "Katana":
-            member.str_mult *= 1.1;
-            member.def_mult *= 1.1;
-            member.dex_mult *= 1.1;
-            break;
-        case "Glock 18C":
-            member.str_mult *= 1.15;
-            member.def_mult *= 1.15;
-            member.dex_mult *= 1.15;
-            member.agi_mult *= 1.15;
-            break;
-        case "P90C":
-            member.str_mult *= 1.2;
-            member.def_mult *= 1.2;
-            member.agi_mult *= 1.1;
-            break;
-        case "Steyr AUG":
-            member.str_mult *= 1.25;
-            member.def_mult *= 1.25;
-            break;
-        case "AK-47":
-            member.str_mult *= 1.5;
-            member.def_mult *= 1.5;
-            break;
-        case "M15A10 Assault Rifle":
-            member.str_mult *= 1.6;
-            member.def_mult *= 1.6;
-            break;
-        case "AWM Sniper Rifle":
-            member.str_mult *= 1.5;
-            member.dex_mult *= 1.5;
-            member.agi_mult *= 1.5;
-            break;
-        case "Bulletproof Vest":
-            member.def_mult *= 1.05;
-            break;
-        case "Full Body Armor":
-            member.def_mult *= 1.1;
-            break;
-        case "Liquid Body Armor":
-            member.def_mult *= 1.25;
-            member.agi_mult *= 1.25;
-            break;
-        case "Graphene Plating Armor":
-            member.def_mult *= 1.5;
-            break;
-        case "Ford Flex V20":
-            member.agi_mult *= 1.1;
-            member.cha_mult *= 1.1;
-            break;
-        case "ATX1070 Superbike":
-            member.agi_mult *= 1.15;
-            member.cha_mult *= 1.15;
-            break;
-        case "Mercedes-Benz S9001":
-            member.agi_mult *= 1.2;
-            member.cha_mult *= 1.2;
-            break;
-        case "White Ferrari":
-            member.agi_mult *= 1.25;
-            member.cha_mult *= 1.25;
-            break;
-        case "NUKE Rootkit":
-            member.hack_mult *= 1.1;
-            break;
-        case "Soulstealer Rootkit":
-            member.hack_mult *= 1.2;
-            break;
-        case "Demon Rootkit":
-            member.hack_mult *= 1.3;
-            break;
-        default:
-            console.log("ERROR: Could not find this upgrade: " + this.name);
-            break;
-    }
-}
-
-GangMemberUpgrade.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_toJSON"])("GangMemberUpgrade", this);
-}
-
-GangMemberUpgrade.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_fromJSON"])(GangMemberUpgrade, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"].constructors.GangMemberUpgrade = GangMemberUpgrade;
-
-let GangMemberUpgrades = {
-    "Baseball Bat" : new GangMemberUpgrade("Baseball Bat",
-                            "Increases strength and defense by 5%", 1e6, "w"),
-    "Katana" :       new GangMemberUpgrade("Katana",
-                            "Increases strength, defense, and dexterity by 10%", 12e6, "w"),
-    "Glock 18C" :    new GangMemberUpgrade("Glock 18C",
-                            "Increases strength, defense, dexterity, and agility by 15%", 25e6, "w"),
-    "P90C" :          new GangMemberUpgrade("P90C",
-                            "Increases strength and defense by 20%. Increases agility by 10%", 50e6, "w"),
-    "Steyr AUG" :    new GangMemberUpgrade("Steyr AUG",
-                            "Increases strength and defense by 25%", 60e6, "w"),
-    "AK-47" :        new GangMemberUpgrade("AK-47",
-                            "Increases strength and defense by 50%", 100e6, "w"),
-    "M15A10 Assault Rifle" :    new GangMemberUpgrade("M15A10 Assault Rifle",
-                                        "Increases strength and defense by 60%", 150e6, "w"),
-    "AWM Sniper Rifle" :        new GangMemberUpgrade("AWM Sniper Rifle",
-                                        "Increases strength, dexterity, and agility by 50%", 225e6, "w"),
-    "Bulletproof Vest" :        new GangMemberUpgrade("Bulletproof Vest",
-                                        "Increases defense by 5%", 2e6, "a"),
-    "Full Body Armor" :         new GangMemberUpgrade("Full Body Armor",
-                                        "Increases defense by 10%", 5e6, "a"),
-    "Liquid Body Armor" :       new GangMemberUpgrade("Liquid Body Armor",
-                                        "Increases defense and agility by 25%", 25e6, "a"),
-    "Graphene Plating Armor" :  new GangMemberUpgrade("Graphene Plating Armor",
-                                        "Increases defense by 50%", 40e6, "a"),
-    "Ford Flex V20" :           new GangMemberUpgrade("Ford Flex V20",
-                                        "Increases agility and charisma by 10%", 3e6, "v"),
-    "ATX1070 Superbike" :       new GangMemberUpgrade("ATX1070 Superbike",
-                                        "Increases agility and charisma by 15%", 9e6, "v"),
-    "Mercedes-Benz S9001" :     new GangMemberUpgrade("Mercedes-Benz S9001",
-                                        "Increases agility and charisma by 20%", 18e6, "v"),
-    "White Ferrari" :           new GangMemberUpgrade("White Ferrari",
-                                        "Increases agility and charisma by 25%", 30e6, "v"),
-    "NUKE Rootkit" :            new GangMemberUpgrade("NUKE Rootkit",
-                                        "Increases hacking by 10%", 5e6, "r"),
-    "Soulstealer Rootkit" :     new GangMemberUpgrade("Soulstealer Rootkit",
-                                        "Increases hacking by 20%", 15e6, "r"),
-    "Demon Rootkit" :           new GangMemberUpgrade("Demon Rootkit",
-                                        "Increases hacking by 30%", 50e6, "r"),
-}
-
-//Create a pop-up box that lets player purchase upgrades
-let gangMemberUpgradeBoxOpened = false;
-function createGangMemberUpgradeBox(initialFilter="") {
-    var boxId = "gang-member-upgrade-popup-box";
-    if (gangMemberUpgradeBoxOpened) {
-        //Already opened, refreshing
-        if (gangMemberUpgradeBoxElements == null || gangMemberUpgradeBox == null || gangMemberUpgradeBoxContent == null) {
-            console.log("ERROR: Refreshing Gang member upgrade box throws error because required elements are null");
-            return;
-        }
-
-        for (var i = 1; i < gangMemberUpgradeBoxElements.length; ++i) {
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeElement"])(gangMemberUpgradeBoxElements[i]);
-        }
-        gangMemberUpgradeBoxElements = [gangMemberUpgradeBoxFilter];
-
-        var filter = gangMemberUpgradeBoxFilter.value.toString();
-        for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length; ++i) {
-            if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].name.indexOf(filter) > -1 || _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].task.name.indexOf(filter) > -1) {
-                var newPanel = createGangMemberUpgradePanel(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i]);
-                gangMemberUpgradeBoxContent.appendChild(newPanel);
-                gangMemberUpgradeBoxElements.push(newPanel);
-            }
-        }
-    } else {
-        //New popup
-        gangMemberUpgradeBoxFilter = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("input", {
-            type:"text", placeholder:"Filter gang members",
-            value:initialFilter,
-            onkeyup:()=>{
-                var filterValue = gangMemberUpgradeBoxFilter.value.toString();
-                createGangMemberUpgradeBox(filterValue);
-            }
-        });
-
-        gangMemberUpgradeBoxElements = [gangMemberUpgradeBoxFilter];
-
-        var filter = gangMemberUpgradeBoxFilter.value.toString();
-        for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length; ++i) {
-            if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].name.indexOf(filter) > -1 || _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].task.name.indexOf(filter) > -1) {
-                gangMemberUpgradeBoxElements.push(createGangMemberUpgradePanel(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i]));
-            }
-        }
-
-        gangMemberUpgradeBox = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createPopup"])(boxId, gangMemberUpgradeBoxElements);
-        gangMemberUpgradeBoxContent = document.getElementById(boxId + "-content");
-        gangMemberUpgradeBoxOpened = true;
-    }
-}
-
-//Create upgrade panels for each individual Gang Member
-function createGangMemberUpgradePanel(memberObj) {
-    var container = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-        border:"1px solid white",
-    });
-
-    var header = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("h1", {
-        innerText:memberObj.name + " (" + memberObj.task.name + ")"
-    });
-    container.appendChild(header);
-
-    var text = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("pre", {
-        fontSize:"14px", display: "inline-block", width:"20%",
-        innerText:
-            "Hack: " + memberObj.hack + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.hack_mult, 2) + ")\n" +
-            "Str:  " + memberObj.str  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.str_mult, 2) + ")\n" +
-            "Def:  " + memberObj.def  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.def_mult, 2) + ")\n" +
-            "Dex:  " + memberObj.dex  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.dex_mult, 2) + ")\n" +
-            "Agi:  " + memberObj.agi  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.agi_mult, 2) + ")\n" +
-            "Cha:  " + memberObj.cha  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.cha_mult, 2) + ")\n",
-    });
-
-    //Already purchased upgrades
-    var ownedUpgradesElements = [];
-    for (var i = 0; i < memberObj.upgrades.length; ++i) {
-        var upg = GangMemberUpgrades[memberObj.upgrades[i]];
-        if (upg == null) {
-            console.log("ERR: Could not find this upgrade: " + memberObj.upgrades[i]);
-            continue;
-        }
-        var e = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-            border:"1px solid white", innerText:memberObj.upgrades[i],
-            margin:"1px", padding:"1px", tooltip:upg.desc, fontSize:"12px",
-        });
-        ownedUpgradesElements.push(e);
-    }
-    var ownedUpgrades = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-        display:"inline-block", marginLeft:"6px", width:"75%", innerText:"Purchased Upgrades:",
-    });
-    for (var i = 0; i < ownedUpgradesElements.length; ++i) {
-        ownedUpgrades.appendChild(ownedUpgradesElements[i]);
-    }
-    container.appendChild(text);
-    container.appendChild(ownedUpgrades);
-    container.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
-
-    //Upgrade buttons. Only show upgrades that can be afforded
-    var weaponUpgrades = [], armorUpgrades = [], vehicleUpgrades = [], rootkitUpgrades = [];
-    for (var upgName in GangMemberUpgrades) {
-        if (GangMemberUpgrades.hasOwnProperty(upgName)) {
-            var upg = GangMemberUpgrades[upgName];
-            if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].money.lt(upg.cost) || memberObj.upgrades.includes(upgName)) {continue;}
-            switch (upg.type) {
-                case "w":
-                    weaponUpgrades.push(upg);
-                    break;
-                case "a":
-                    armorUpgrades.push(upg);
-                    break;
-                case "v":
-                    vehicleUpgrades.push(upg);
-                    break;
-                case "r":
-                    rootkitUpgrades.push(upg);
-                    break;
-                default:
-                    console.log("ERROR: Invalid Gang Member Upgrade Type: " + upg.type);
-            }
-        }
-    }
-
-    var weaponDiv   = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {width:"20%", display:"inline-block",});
-    var armorDiv    = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {width:"20%", display:"inline-block",});
-    var vehicleDiv  = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {width:"20%", display:"inline-block",});
-    var rootkitDiv  = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {width:"20%", display:"inline-block",});
-    var upgrades = [weaponUpgrades, armorUpgrades, vehicleUpgrades, rootkitUpgrades];
-    var divs = [weaponDiv, armorDiv, vehicleDiv, rootkitDiv];
-
-    for (var i = 0; i < upgrades.length; ++i) {
-        var upgradeArray = upgrades[i];
-        var div = divs[i];
-        for (var j = 0; j < upgradeArray.length; ++j) {
-            var upg = upgradeArray[j];
-            (function (upg, div, memberObj) {
-                div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
-                    innerText:upg.name + " - " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(upg.cost).format("$0.000a"),
-                    class:"a-link-button", margin:"2px",  padding:"2px", display:"block",
-                    fontSize:"12px",
-                    tooltip:upg.desc,
-                    clickListener:()=>{
-                        if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].money.lt(upg.cost)) {return false;}
-                        _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].loseMoney(upg.cost);
-                        memberObj.upgrades.push(upg.name);
-                        upg.apply(memberObj);
-                        var initFilterValue = gangMemberUpgradeBoxFilter.value.toString();
-                        createGangMemberUpgradeBox(initFilterValue);
-                        return false;
-                    }
-                }));
-            })(upg, div, memberObj);
-        }
-    }
-
-    container.appendChild(weaponDiv);
-    container.appendChild(armorDiv);
-    container.appendChild(vehicleDiv);
-    container.appendChild(rootkitDiv);
-    return container;
-}
-
-//Gang DOM elements
-let gangContentCreated = false,
-    gangContainer = null, managementButton = null, territoryButton = null;
-
-//Subpages
-let gangManagementSubpage = null, gangTerritorySubpage = null;
-
-//Gang Management Elements
-let gangDesc = null, gangInfo = null,
-    gangRecruitMemberButton = null, gangRecruitRequirementText = null,
-    gangExpandAllButton = null, gangCollapseAllButton, gangMemberFilter = null,
-    gangManageEquipmentButton = null,
-    gangMemberList = null;
-
-//Gang Equipment Upgrade Elements
-let gangMemberUpgradeBox = null, gangMemberUpgradeBoxContent = null,
-    gangMemberUpgradeBoxFilter = null, gangMemberUpgradeBoxElements = null;
-
-
-//Gang Territory Elements
-let gangTerritoryDescText = null, gangTerritoryInfoText = null;
-
-function displayGangContent() {
-    if (!gangContentCreated || gangContainer == null) {
-        gangContentCreated = true;
-
-        //Create gang container
-        gangContainer = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-            id:"gang-container", class:"generic-menupage-container",
-        });
-
-        //Get variables
-        var facName = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName,
-            members = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members,
-            wanted = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted,
-            respect = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect;
-
-        //Back button
-        gangContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
-            class:"a-link-button", display:"inline-block", innerText:"Back",
-            clickListener:()=>{
-                _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].loadFactionContent();
-                Object(_Faction_js__WEBPACK_IMPORTED_MODULE_2__["displayFactionContent"])(facName);
-                return false;
-            }
-        }));
-
-        //Buttons to switch between panels
-        managementButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
-            id:"gang-management-subpage-button", class:"a-link-button-inactive",
-            display:"inline-block", innerHTML: "Gang Management (1)",
-            clickListener:()=>{
-                gangManagementSubpage.style.display = "block";
-                gangTerritorySubpage.style.display = "none";
-                managementButton.classList.toggle("a-link-button-inactive");
-                managementButton.classList.toggle("a-link-button");
-                territoryButton.classList.toggle("a-link-button-inactive");
-                territoryButton.classList.toggle("a-link-button");
-                updateGangContent();
-                return false;
-            }
-        })
-        territoryButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
-            id:"gang-territory-subpage-button", class:"a-link-button",
-            display:"inline-block", innerHTML:"Gang Territory (2)",
-            clickListener:()=>{
-                gangManagementSubpage.style.display = "none";
-                gangTerritorySubpage.style.display = "block";
-                managementButton.classList.toggle("a-link-button-inactive");
-                managementButton.classList.toggle("a-link-button");
-                territoryButton.classList.toggle("a-link-button-inactive");
-                territoryButton.classList.toggle("a-link-button");
-                updateGangContent();
-                return false;
-            }
-        });
-        gangContainer.appendChild(managementButton);
-        gangContainer.appendChild(territoryButton);
-
-        //Subpage for managing gang members
-        gangManagementSubpage = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-            display:"block", id:"gang-management-subpage",
-        });
-
-        var lowerWantedTask = "";
-        if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.isHackingGang) {
-            lowerWantedTask = "Ethical Hacking";
-        } else {
-            lowerWantedTask = "Vigilante Justice";
-        }
-        gangDesc = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {width:"70%",
-            innerHTML:
-            "This page is used to manage your gang members and get an overview of your  " +
-            "gang's stats.<br><br>" +
-            "If a gang member is not earning much money or respect, the task that you " +
-            "have assigned to that member might be too difficult. Consider training that " +
-            "member's stats or choosing an easier task. The tasks closer to the " +
-            "top of the dropdown list are generally easier. Alternatively, the gang member's " +
-            "low production might be due to the fact that your wanted level is too high. " +
-            "Consider assigning a few members to the '" + lowerWantedTask + "' " +
-            "task to lower your wanted level. <br><br>" +
-            "Installing Augmentations does NOT reset your progress with your Gang. " +
-            "Furthermore, after installing Augmentations, you will " +
-            "automatically be a member of whatever Faction you created your gang with.<br><br>"
-        });
-        gangManagementSubpage.appendChild(gangDesc);
-
-        gangInfo = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {id:"gang-info", width:"70%"});
-        gangManagementSubpage.appendChild(gangInfo);
-
-        gangRecruitMemberButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
-            id:"gang-management-recruit-member-btn", class:"a-link-button-inactive",
-            innerHTML:"Recruit Gang Member", display:"inline-block", margin:"10px",
-            clickListener:()=>{
-                var yesBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxGetYesButton"])(), noBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxGetNoButton"])();
-                yesBtn.innerHTML = "Recruit Gang Member";
-                noBtn.innerHTML = "Cancel";
-                yesBtn.addEventListener("click", ()=>{
-                    var name = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxGetInput"])();
-                    if (name === "") {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__["dialogBoxCreate"])("You must enter a name for your Gang member!");
-                    } else {
-                        for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length; ++i) {
-                            if (name == _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].name) {
-                                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__["dialogBoxCreate"])("You already have a gang member with this name!");
-                                return false;
-                            }
-                        }
-                        var member = new GangMember(name);
-                        _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.push(member);
-                        createGangMemberDisplayElement(member);
-                        updateGangContent();
-                    }
-                    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxClose"])();
-                });
-                noBtn.addEventListener("click", ()=>{
-                    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxClose"])();
-                });
-                Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxCreate"])("Please enter a name for your new Gang member:");
-                return false;
-            }
-        });
-        gangManagementSubpage.appendChild(gangRecruitMemberButton);
-
-        //Text for how much reputation is required for recruiting next memberList
-        gangRecruitRequirementText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {color:"red", id:"gang-recruit-requirement-text"});
-        gangManagementSubpage.appendChild(gangRecruitRequirementText);
-
-        //Gang Member List management buttons (Expand/Collapse All, select a single member)
-        gangManagementSubpage.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
-        gangExpandAllButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
-            class:"a-link-button", display:"inline-block",
-            innerHTML:"Expand All",
-            clickListener:()=>{
-                var allHeaders = gangManagementSubpage.getElementsByClassName("accordion-header");
-                for (var i = 0; i < allHeaders.length; ++i) {
-                    var hdr = allHeaders[i];
-                    if (!hdr.classList.contains("active")) {
-                        hdr.click();
-                    }
-                }
-                return false;
-            }
-        });
-        gangCollapseAllButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
-            class:"a-link-button", display:"inline-block",
-            innerHTML:"Collapse All",
-            clickListener:()=>{
-                var allHeaders = gangManagementSubpage.getElementsByClassName("accordion-header");
-                for (var i = 0; i < allHeaders.length; ++i) {
-                    var hdr = allHeaders[i];
-                    if (hdr.classList.contains("active")) {
-                        hdr.click();
-                    }
-                }
-                return false;
-            }
-        });
-        gangMemberFilter = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("input", {
-            type:"text", placeholder:"Filter gang members", margin:"5px", padding:"5px",
-            onkeyup:()=>{
-                displayGangMemberList();
-            }
-        });
-        gangManageEquipmentButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
-            class:"a-link-button", display:"inline-block",
-            innerHTML:"Manage Equipment",
-            clickListener:()=>{
-                createGangMemberUpgradeBox();
-            }
-        });
-        gangManagementSubpage.appendChild(gangExpandAllButton);
-        gangManagementSubpage.appendChild(gangCollapseAllButton);
-        gangManagementSubpage.appendChild(gangMemberFilter);
-        gangManagementSubpage.appendChild(gangManageEquipmentButton);
-
-        //Gang Member list
-        gangMemberList = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("ul", {id:"gang-member-list"});
-        displayGangMemberList();
-        gangManagementSubpage.appendChild(gangMemberList);
-
-        //Subpage for seeing gang territory information
-        gangTerritorySubpage = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-            id:"gang-territory-subpage", display:"none"
-        });
-
-        //Info text for territory page
-        gangTerritoryDescText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {
-            width:"70%",
-            innerHTML:"This page shows how much territory your Gang controls. This statistic is listed as a percentage, " +
-            "which represents how much of the total territory you control.<br><br>" +
-            "Territory gain and loss is processed automatically and is updated every ~30 seconds. Your chances " +
-            "to gain and lose territory depend on your Gang's power, which is listed in the display below. " +
-            "Your gang's power is determined by the stats of all Gang members you have assigned to the " +
-            "'Territory Warfare' task. Gang members that are not assigned to this task do not contribute to " +
-            "your Gang's power.<br><br>" +
-            "The amount of territory you have affects all aspects of your Gang members' production, including " +
-            "money, respect, and wanted level. It is very beneficial to have high territory control.<br><br>"
-        });
-        gangTerritorySubpage.appendChild(gangTerritoryDescText);
-
-        var territoryBorder = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("fieldset", {width:"50%", display:"inline-block"});
-
-        gangTerritoryInfoText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {id:"gang-territory-info"});
-
-        territoryBorder.appendChild(gangTerritoryInfoText);
-        gangTerritorySubpage.appendChild(territoryBorder);
-
-        gangContainer.appendChild(gangTerritorySubpage);
-        gangContainer.appendChild(gangManagementSubpage);
-        document.getElementById("entire-game-container").appendChild(gangContainer);
-    }
-    gangContainer.style.display = "block";
-    updateGangContent();
-}
-
-function displayGangMemberList() {
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeChildrenFromElement"])(gangMemberList);
-    var members = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members;
-    var filter = gangMemberFilter.value.toString();
-    for (var i = 0; i < members.length; ++i) {
-        if (members[i].name.indexOf(filter) > -1 || members[i].task.name.indexOf(filter) > -1) {
-            createGangMemberDisplayElement(members[i]);
-        }
-    }
-    //setGangMemberClickHandlers(); //Set buttons to toggle the gang member info panels
-}
-
-function updateGangContent() {
-    if (!gangContentCreated || !_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
-
-    if(gangTerritorySubpage.style.display === "block") {
-        //Update territory information
-        gangTerritoryInfoText.innerHTML = "";
-        for (var gangname in AllGangs) {
-            if (AllGangs.hasOwnProperty(gangname)) {
-                var gangTerritoryInfo = AllGangs[gangname];
-                if (gangname == _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName) {
-                    gangTerritoryInfoText.innerHTML += ("<b>" + gangname + "</b><br>(Power: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(gangTerritoryInfo.power, 6) + "): " +
-                                       Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(100*gangTerritoryInfo.territory, 2) + "%<br><br>");
-                } else {
-                    gangTerritoryInfoText.innerHTML += (gangname + "<br>(Power: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(gangTerritoryInfo.power, 6) + "): " +
-                                       Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(100*gangTerritoryInfo.territory, 2) + "%<br><br>");
-                }
-            }
-        }
-    } else {
-        //Update information for overall gang
-        if (gangInfo instanceof Element) {
-            var faction = _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Factions"][_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName];
-            var rep;
-            if (!(faction instanceof _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Faction"])) {
-                rep = "ERROR";
-            } else {
-                rep = faction.playerReputation;
-            }
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeChildrenFromElement"])(gangInfo);
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {   //Respect
-                display:"inline-block",
-                innerText:"Respect: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect, 6) +
-                          " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respectGainRate, 6) + " / sec)",
-                tooltip:"Represents the amount of respect your gang has from other gangs and criminal " +
-                        "organizations. Your respect affects the amount of money " +
-                        "your gang members will earn, and also determines how much " +
-                        "reputation you are earning with your gang's corresponding Faction."
-            }));
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
-
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {   //Wanted level
-                display:"inline-block",
-                innerText:"Wanted Level: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted, 6) +
-                          " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wantedGainRate, 6) + " / sec)",
-                tooltip:"Represents how much the gang is wanted by law enforcement. The higher " +
-                        "your gang's wanted level, the harder it will be for your gang members " +
-                        "to make money and earn respect. Note that the minimum wanted level is 1."
-            }));
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
-
-            var wantedPenalty = (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect) / (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect + _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted);
-            wantedPenalty = (1 - wantedPenalty) * 100;
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {   //Wanted Level multiplier
-                display:"inline-block",
-                innerText:"Wanted Level Penalty: -" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(wantedPenalty, 2) + "%",
-                tooltip:"Penalty for respect and money gain rates due to Wanted Level"
-            }));
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
-
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {   //Money gain rate
-                display:"inline-block",
-                innerText:"Money gain rate: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.moneyGainRate, 2) +
-                          " / sec",
-            }));
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
-
-            var territoryMult = AllGangs[_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName].territory;
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {  //Territory multiplier
-                display:"inline-block",
-                innerText:"Territory: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(territoryMult * 100, 3) + "%",
-                tooltip:"The percentage of total territory your Gang controls"
-            }));
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
-
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {  //Faction reputation
-                display:"inline-block",
-                innerText:"Faction reputation: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(rep, 3)
-            }));
-            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
-        } else {
-            console.log("ERROR: gang-info DOM element DNE");
-        }
-
-        //Toggle the 'Recruit member button' if valid
-        var numMembers = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length;
-        var repCost = 0;
-        if (numMembers > 0) {
-            var repCost = Math.pow(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].GangRecruitCostMultiplier, numMembers);
-        }
-        var faction = _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Factions"][_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName];
-        if (faction == null) {
-            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__["dialogBoxCreate"])("Could not find your gang's faction. This is probably a bug please report to dev");
-            return;
-        }
-        var btn = gangRecruitMemberButton;
-        if (numMembers >= _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MaximumGangMembers) {
-            btn.className = "a-link-button-inactive";
-            gangRecruitRequirementText.style.display = "block";
-            gangRecruitRequirementText.innerHTML =
-                "You have reached the maximum amount of gang members";
-        } else if (faction.playerReputation >= repCost) {
-            btn.className = "a-link-button";
-            gangRecruitRequirementText.style.display = "none";
-        } else {
-            btn.className = "a-link-button-inactive";
-            gangRecruitRequirementText.style.display = "block";
-            gangRecruitRequirementText.innerHTML =
-                Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(repCost, 2) + " Faction reputation needed to recruit next member";
-        }
-
-        //Update information for each gang member
-        for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length; ++i) {
-            updateGangMemberDisplayElement(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i]);
-        }
-    }
-}
-
-//Takes in a GangMember object
-function createGangMemberDisplayElement(memberObj) {
-    if (!gangContentCreated || !_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
-    var name = memberObj.name;
-
-    var accordion = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createAccordionElement"])({
-        id:name + "gang-member",
-        hdrText:name,
-    });
-    var li = accordion[0];
-    var hdr = accordion[1];
-    var gangMemberDiv = accordion[2];
-
-    //Gang member content divided into 3 panels:
-    //Stats Panel
-    var statsDiv = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-        id: name + "gang-member-stats", class: "gang-member-info-div",
-        width:"30%", display:"inline"
-    });
-    var statsP = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {
-        id:name + "gang-member-stats-text", display:"inline"
-    });
-
-    statsDiv.appendChild(statsP);
-    //statsDiv.appendChild(upgradeButton);
-
-    //Panel for Selecting task and show respect/wanted gain
-    var taskDiv = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-        id: name + "gang-member-task", class:"gang-member-info-div",
-        width:"30%", display:"inline"
-    });
-    var taskSelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("select", {
-        color:"white", backgroundColor:"black",
-        id:name + "gang-member-task-selector"
-    });
-
-    var tasks = null;
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.isHackingGang) {
-        tasks = ["---", "Ransomware", "Phishing", "Identity Theft", "DDoS Attacks",
-                 "Plant Virus", "Fraud & Counterfeiting","Money Laundering",
-                 "Cyberterrorism", "Ethical Hacking", "Train Combat",
-                 "Train Hacking", "Territory Warfare"];
-    } else {
-        tasks = ["---", "Mug People", "Deal Drugs", "Run a Con", "Armed Robbery",
-                 "Traffick Illegal Arms", "Threaten & Blackmail",
-                 "Terrorism", "Vigilante Justice", "Train Combat",
-                 "Train Hacking", "Territory Warfare"];
-    }
-    for (var i = 0; i < tasks.length; ++i) {
-        var option = document.createElement("option");
-        option.text = tasks[i];
-        taskSelector.add(option);
-    }
-    taskSelector.addEventListener("change", function() {
-        var task = taskSelector.options[taskSelector.selectedIndex].text;
-        memberObj.assignToTask(task);
-        setGangMemberTaskDescription(memberObj, task);
-        updateGangContent();
-    });
-    //Set initial task in selector element
-    if (memberObj.task instanceof GangMemberTask) {
-        var taskName = memberObj.task.name;
-        var taskIndex = 0;
-        for (let i = 0; i < tasks.length; ++i) {
-            if (taskName == tasks[i]) {
-                taskIndex = i;
-                break;
-            }
-        }
-        taskSelector.selectedIndex = taskIndex;
-    }
-
-    var gainInfo = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {id:name + "gang-member-gain-info"});
-    taskDiv.appendChild(taskSelector);
-    taskDiv.appendChild(gainInfo);
-
-    //Panel for Description of task
-    var taskDescDiv = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
-        id:name + "gang-member-task-desc", class:"gang-member-info-div",
-        width:"30%", display:"inline"
-    });
-
-    var taskDescP = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {id: name + "gang-member-task-description", display:"inline"});
-    taskDescDiv.appendChild(taskDescP);
-
-    statsDiv.style.width = "30%";
-    taskDiv.style.width = "30%";
-    taskDescDiv.style.width = "30%";
-    statsDiv.style.display = "inline";
-    taskDiv.style.display = "inline";
-    taskDescDiv.style.display = "inline";
-    gangMemberDiv.appendChild(statsDiv);
-    gangMemberDiv.appendChild(taskDiv);
-    gangMemberDiv.appendChild(taskDescDiv);
-
-    gangMemberList.appendChild(li);
-    setGangMemberTaskDescription(memberObj, taskName); //Initialize description
-    updateGangMemberDisplayElement(memberObj);
-}
-
-function updateGangMemberDisplayElement(memberObj) {
-    if (!gangContentCreated || !_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
-    var name = memberObj.name;
-
-    //TODO Add upgrade information
-    var stats = document.getElementById(name + "gang-member-stats-text");
-    if (stats) {
-        stats.innerHTML =
-            "Hacking: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.hack, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.hack_exp).format('(0.00a)') + " exp)<br>" +
-            "Strength: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.str, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.str_exp).format('(0.00a)') + " exp)<br>" +
-            "Defense: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.def, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.def_exp).format('(0.00a)') + " exp)<br>" +
-            "Dexterity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.dex, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.dex_exp).format('(0.00a)') + " exp)<br>" +
-            "Agility: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.agi, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.agi_exp).format('(0.00a)') + " exp)<br>" +
-            "Charisma: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.cha, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.cha_exp).format('(0.00a)') + " exp)<br>";
-    }
-
-    var gainInfo = document.getElementById(name + "gang-member-gain-info");
-    if (gainInfo) {
-        gainInfo.innerHTML =
-            "Money: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*memberObj.calculateMoneyGain(), 2) + " / sec<br>" +
-            "Respect: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*memberObj.calculateRespectGain(), 6) + " / sec<br>" +
-            "Wanted Level: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*memberObj.calculateWantedLevelGain(), 6) + " / sec<br>";
-    }
-}
-
-function setGangMemberTaskDescription(memberObj, taskName) {
-    var name = memberObj.name;
-    var taskDesc = document.getElementById(name + "gang-member-task-description");
-    if (taskDesc) {
-        var task = GangMemberTasks[taskName];
-        if (task == null) {return;}
-        var desc = task.desc;
-        taskDesc.innerHTML = desc;
-    }
-}
-
-function deleteGangDisplayContent() {
-    if (gangContainer != null) {Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeElementById"])(gangContainer.id);}
-
-    gangContentCreated = false;
-    gangContainer = null;
-    managementButton = null;
-    territoryButton = null;
-
-    //Subpages
-    gangManagementSubpage = null;
-    gangTerritorySubpage = null;
-
-    //Gang Management Elements
-    gangDesc = null;
-    gangInfo = null;
-    gangRecruitMemberButton = null;
-    gangRecruitRequirementText = null;
-    gangExpandAllButton = null;
-    gangCollapseAllButton = null;
-    gangMemberFilter = null;
-    gangManageEquipmentButton = null;
-    gangMemberList = null;
-
-    //Gang Equipment Upgrade Elements
-    gangMemberUpgradeBox = null;
-    gangMemberUpgradeBoxContent = null;
-    gangMemberUpgradeBoxFilter = null;
-    gangMemberUpgradeBoxElements = null;
-}
-
-
-
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
-
-/***/ }),
-/* 36 */
 /*!************************!*\
   !*** ./utils/acorn.js ***!
   \************************/
@@ -37863,6 +36537,1474 @@ Object.defineProperty(exports, '__esModule', { value: true });
 
 })));
 
+/***/ }),
+/* 36 */
+/*!*********************!*\
+  !*** ./src/Gang.js ***!
+  \*********************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Gang", function() { return Gang; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayGangContent", function() { return displayGangContent; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateGangContent", function() { return updateGangContent; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadAllGangs", function() { return loadAllGangs; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AllGangs", function() { return AllGangs; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resetGangs", function() { return resetGangs; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deleteGangDisplayContent", function() { return deleteGangDisplayContent; });
+/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Constants.js */ 3);
+/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Faction.js */ 11);
+/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Player.js */ 0);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7__);
+/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
+
+
+
+
+
+
+
+
+
+
+
+/* Gang.js */
+//Switch between territory and management screen with 1 and 2
+$(document).keydown(function(event) {
+    if (_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage == _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.Gang && !_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoBoxOpen"]) {
+        if (gangMemberFilter != null && gangMemberFilter === document.activeElement) {return;}
+        if (event.keyCode === 49) {
+            if(gangTerritorySubpage.style.display === "block") {
+                managementButton.click();
+            }
+        } else if (event.keyCode === 50) {
+            if (gangManagementSubpage.style.display === "block") {
+                territoryButton.click();
+            }
+        }
+    }
+});
+
+//Delete upgrade box when clicking outside
+$(document).mousedown(function(event) {
+    var boxId = "gang-member-upgrade-popup-box";
+    var contentId = "gang-member-upgrade-popup-box-content";
+    if (gangMemberUpgradeBoxOpened) {
+        if ( $(event.target).closest("#" + contentId).get(0) == null ) {
+            //Delete the box
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeElement"])(gangMemberUpgradeBox);
+            gangMemberUpgradeBox = null;
+            gangMemberUpgradeBoxContent = null;
+            gangMemberUpgradeBoxOpened = false;
+            gangMemberUpgradeBoxElements = null;
+        }
+    }
+});
+
+let GangNames = ["Slum Snakes", "Tetrads", "The Syndicate", "The Dark Army", "Speakers for the Dead",
+             "NiteSec", "The Black Hand"];
+let AllGangs = {
+    "Slum Snakes" : {
+        power: 1,
+        territory: 1/7,
+    },
+    "Tetrads" : {
+        power: 1,
+        territory: 1/7,
+    },
+    "The Syndicate" : {
+        power: 1,
+        territory: 1/7,
+    },
+    "The Dark Army" : {
+        power: 1,
+        territory: 1/7,
+    },
+    "Speakers for the Dead" : {
+        power: 1,
+        territory: 1/7,
+    },
+    "NiteSec" : {
+        power: 1,
+        territory: 1/7,
+    },
+    "The Black Hand" : {
+        power: 1,
+        territory: 1/7,
+    },
+}
+
+function resetGangs() {
+    AllGangs = {
+        "Slum Snakes" : {
+            power: 1,
+            territory: 1/7,
+        },
+        "Tetrads" : {
+            power: 1,
+            territory: 1/7,
+        },
+        "The Syndicate" : {
+            power: 1,
+            territory: 1/7,
+        },
+        "The Dark Army" : {
+            power: 1,
+            territory: 1/7,
+        },
+        "Speakers for the Dead" : {
+            power: 1,
+            territory: 1/7,
+        },
+        "NiteSec" : {
+            power: 1,
+            territory: 1/7,
+        },
+        "The Black Hand" : {
+            power: 1,
+            territory: 1/7,
+        },
+    }
+}
+
+function loadAllGangs(saveString) {
+    AllGangs = JSON.parse(saveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"]);
+}
+
+//Power is an estimate of a gang's ability to gain/defend territory
+let gangStoredPowerCycles = 0;
+function processAllGangPowerGains(numCycles=1) {
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
+    gangStoredPowerCycles += numCycles;
+    if (gangStoredPowerCycles < 150) {return;}
+    var playerGangName = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName;
+    for (var name in AllGangs) {
+        if (AllGangs.hasOwnProperty(name)) {
+            if (name == playerGangName) {
+                AllGangs[name].power += _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.calculatePower();
+            } else {
+                var gain = Math.random() * 0.02; //TODO Adjust as necessary
+                AllGangs[name].power += (gain);
+            }
+        }
+    }
+
+    gangStoredPowerCycles -= 150;
+}
+
+let gangStoredTerritoryCycles = 0;
+function processAllGangTerritory(numCycles=1) {
+    if (!_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
+    gangStoredTerritoryCycles += numCycles;
+    if (gangStoredTerritoryCycles < _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].GangTerritoryUpdateTimer) {return;}
+
+    for (var i = 0; i < GangNames.length; ++i) {
+        var other = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(0, GangNames.length-1);
+        while(other == i) {
+            other = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["getRandomInt"])(0, GangNames.length-1);
+        }
+        var thisPwr = AllGangs[GangNames[i]].power;
+        var otherPwr = AllGangs[GangNames[other]].power;
+        var thisChance = thisPwr / (thisPwr + otherPwr);
+
+        if (Math.random() < thisChance) {
+            if (AllGangs[GangNames[other]].territory <= 0) {
+                return;
+            }
+            AllGangs[GangNames[i]].territory += 0.0001;
+            AllGangs[GangNames[other]].territory -= 0.0001;
+        } else {
+            if (AllGangs[GangNames[i]].territory <= 0) {
+                return;
+            }
+            AllGangs[GangNames[i]].territory -= 0.0001;
+            AllGangs[GangNames[other]].territory += 0.0001;
+        }
+    }
+
+    gangStoredTerritoryCycles -= _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].GangTerritoryUpdateTimer;
+}
+
+/*  faction - Name of corresponding faction
+    hacking - Boolean indicating whether its a hacking gang or not
+ */
+function Gang(facName, hacking=false) {
+    this.facName    = facName;
+    this.members    = [];  //Array of GangMembers
+    this.wanted     = 1;
+    this.respect    = 1;
+    this.power      = 0;
+
+    this.isHackingGang = hacking;
+
+    this.respectGainRate = 0;
+    this.wantedGainRate = 0;
+    this.moneyGainRate = 0;
+
+    //When processing gains, this stores the number of cycles until some
+    //limit is reached, and then calculates and applies the gains only at that limit
+    this.storedCycles   = 0;
+}
+
+Gang.prototype.process = function(numCycles=1) {
+    this.processGains(numCycles);
+    this.processExperienceGains(numCycles);
+    processAllGangPowerGains(numCycles);
+    processAllGangTerritory(numCycles);
+}
+
+Gang.prototype.processGains = function(numCycles=1) {
+    this.storedCycles += numCycles;
+    if (isNaN(this.storedCycles)) {
+        console.log("ERROR: Gang's storedCylces is NaN");
+        this.storedCycles = 0;
+    }
+    if (this.storedCycles < 25) {return;} //Only process every 5 seconds at least
+
+    //Get gains per cycle
+    var moneyGains = 0, respectGains = 0, wantedLevelGains = 0;
+    for (var i = 0; i < this.members.length; ++i) {
+        respectGains += (this.members[i].calculateRespectGain());
+        wantedLevelGains += (this.members[i].calculateWantedLevelGain());
+        moneyGains += (this.members[i].calculateMoneyGain());
+    }
+    this.respectGainRate = respectGains;
+    this.wantedGainRate = wantedLevelGains;
+    this.moneyGainRate = moneyGains;
+
+    if (!isNaN(respectGains)) {
+        var gain = respectGains * this.storedCycles;
+        this.respect += (gain);
+        //Faction reputation gains is respect gain divided by some constant
+        var fac = _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Factions"][this.facName];
+        if (!(fac instanceof _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Faction"])) {
+            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__["dialogBoxCreate"])("ERROR: Could not get Faction associates with your gang. This is a bug, please report to game dev");
+        } else {
+            var favorMult = 1 + (fac.favor / 100);
+            fac.playerReputation += ((_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].faction_rep_mult * gain * favorMult) / _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].GangRespectToReputationRatio);
+        }
+
+    } else {
+        console.log("ERROR: respectGains is NaN");
+    }
+    if (!isNaN(wantedLevelGains)) {
+        if (this.wanted === 1 && wantedLevelGains < 0) {
+            //Do nothing
+        } else {
+            this.wanted += (wantedLevelGains * this.storedCycles);
+            if (this.wanted < 1) {this.wanted = 1;}
+        }
+    } else {
+        console.log("ERROR: wantedLevelGains is NaN");
+    }
+    if (!isNaN(moneyGains)) {
+        _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gainMoney(moneyGains * this.storedCycles);
+    } else {
+        console.log("ERROR: respectGains is NaN");
+    }
+
+    this.storedCycles = 0;
+}
+
+Gang.prototype.processExperienceGains = function(numCycles=1) {
+    for (var i = 0; i < this.members.length; ++i) {
+        this.members[i].gainExperience(numCycles);
+        this.members[i].updateSkillLevels();
+    }
+}
+
+//Calculates power GAIN, which is added onto the Gang's existing power
+Gang.prototype.calculatePower = function() {
+    var memberTotal = 0;
+    for (var i = 0; i < this.members.length; ++i) {
+        if (this.members[i].task instanceof GangMemberTask &&
+            this.members[i].task.name == "Territory Warfare") {
+            memberTotal += this.members[i].calculatePower();
+        }
+    }
+    return (0.0005 * memberTotal);
+}
+
+Gang.prototype.autoAssignMemberToTask = function(taskName) {
+    for (var i = 0; i < this.members.length; ++i) {
+        if (this.members[i].task.name === taskName) {
+            this.members[i].assignToTask(taskName);
+            return true;
+        }
+    }
+    return false;
+}
+
+Gang.prototype.autoUnassignMemberFromTask = function(taskName) {
+    for (var i = 0; i < this.members.length; ++i) {
+        if (this.members[i].task.name === taskName) {
+            this.members[i].unassignFromTask();
+            return true;
+        }
+    }
+    return false;
+}
+
+Gang.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_toJSON"])("Gang", this);
+}
+
+Gang.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_fromJSON"])(Gang, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"].constructors.Gang = Gang;
+
+/*** Gang Member object ***/
+function GangMember(name) {
+    this.name   = name;
+    this.task   = GangMemberTasks["Unassigned"]; //GangMemberTask object
+    this.city   = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].city;
+
+    this.hack   = 1;
+    this.str    = 1;
+    this.def    = 1;
+    this.dex    = 1;
+    this.agi    = 1;
+    this.cha    = 1;
+
+    this.hack_exp   = 0;
+    this.str_exp    = 0;
+    this.def_exp    = 0;
+    this.dex_exp    = 0;
+    this.agi_exp    = 0;
+    this.cha_exp    = 0;
+
+    this.hack_mult  = 1;
+    this.str_mult   = 1;
+    this.def_mult   = 1;
+    this.dex_mult   = 1;
+    this.agi_mult   = 1;
+    this.cha_mult   = 1;
+
+    this.upgrades = []; //Names of upgrades
+}
+
+//Same formula for Player
+GangMember.prototype.calculateSkill = function(exp) {
+    return Math.max(Math.floor(32 * Math.log(exp + 534.5) - 200), 1);
+}
+
+GangMember.prototype.updateSkillLevels = function() {
+    this.hack   = Math.floor(this.calculateSkill(this.hack_exp) * this.hack_mult);
+    this.str    = Math.floor(this.calculateSkill(this.str_exp) * this.str_mult);
+    this.def    = Math.floor(this.calculateSkill(this.def_exp) * this.def_mult);
+    this.dex    = Math.floor(this.calculateSkill(this.dex_exp) * this.dex_mult);
+    this.agi    = Math.floor(this.calculateSkill(this.agi_exp) * this.agi_mult);
+    this.cha    = Math.floor(this.calculateSkill(this.cha_exp) * this.cha_mult);
+}
+
+GangMember.prototype.calculatePower = function() {
+    return (this.hack + this.str + this.def +
+            this.dex + this.agi + this.cha) / 100;
+}
+
+GangMember.prototype.assignToTask = function(taskName) {
+    if (GangMemberTasks.hasOwnProperty(taskName)) {
+        this.task = GangMemberTasks[taskName];
+    } else {
+        this.task = GangMemberTasks["Unassigned"];
+    }
+}
+
+GangMember.prototype.unassignFromTask = function() {
+    if (GangMemberTasks.hasOwnProperty("Unassigned")) {
+        this.task = GangMemberTasks["Unassigned"];
+    } else {
+        console.log("ERROR: Can't find Unassigned Gang member task");
+        this.task = null;
+    }
+}
+
+//Gains are per cycle
+GangMember.prototype.calculateRespectGain = function() {
+    var task = this.task;
+    if (task == null || !(task instanceof GangMemberTask) || task.baseRespect === 0) {return 0;}
+    var statWeight =    (task.hackWeight/100) * this.hack +
+                        (task.strWeight/100) * this.str +
+                        (task.defWeight/100) * this.def +
+                        (task.dexWeight/100) * this.dex +
+                        (task.agiWeight/100) * this.agi +
+                        (task.chaWeight/100) * this.cha;
+    statWeight -= (3.5 * task.difficulty);
+    if (statWeight <= 0) {return 0;}
+    var territoryMult = AllGangs[_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName].territory;
+    if (territoryMult <= 0) {return 0;}
+    var respectMult = (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect) / (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect + _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted);
+    return 12 * task.baseRespect * statWeight * territoryMult * respectMult;
+}
+
+GangMember.prototype.calculateWantedLevelGain = function() {
+    var task = this.task;
+    if (task == null || !(task instanceof GangMemberTask) || task.baseWanted === 0) {return 0;}
+    var statWeight =    (task.hackWeight/100) * this.hack +
+                        (task.strWeight/100) * this.str +
+                        (task.defWeight/100) * this.def +
+                        (task.dexWeight/100) * this.dex +
+                        (task.agiWeight/100) * this.agi +
+                        (task.chaWeight/100) * this.cha;
+    statWeight -= (3.5 * task.difficulty);
+    if (statWeight <= 0) {return 0;}
+    var territoryMult = AllGangs[_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName].territory;
+    if (territoryMult <= 0) {return 0;}
+    if (task.baseWanted < 0) {
+        return task.baseWanted * statWeight * territoryMult;
+    } else {
+        return 6 * task.baseWanted / (3 * statWeight * territoryMult);
+    }
+}
+
+GangMember.prototype.calculateMoneyGain = function() {
+    var task = this.task;
+    if (task == null || !(task instanceof GangMemberTask) || task.baseMoney === 0) {return 0;}
+    var statWeight =    (task.hackWeight/100) * this.hack +
+                        (task.strWeight/100) * this.str +
+                        (task.defWeight/100) * this.def +
+                        (task.dexWeight/100) * this.dex +
+                        (task.agiWeight/100) * this.agi +
+                        (task.chaWeight/100) * this.cha;
+    statWeight -= (3.5 * task.difficulty);
+    if (statWeight <= 0) {return 0;}
+    var territoryMult = AllGangs[_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName].territory;
+    if (territoryMult <= 0) {return 0;}
+    var respectMult = (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect) / (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect + _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted);
+    return 5 * task.baseMoney * statWeight * territoryMult * respectMult;
+}
+
+GangMember.prototype.gainExperience = function(numCycles=1) {
+    var task = this.task;
+    if (task == null || !(task instanceof GangMemberTask)) {return;}
+    this.hack_exp   += (task.hackWeight / 1500) * task.difficulty * numCycles;
+    this.str_exp    += (task.strWeight / 1500) * task.difficulty * numCycles;
+    this.def_exp    += (task.defWeight / 1500) * task.difficulty * numCycles;
+    this.dex_exp    += (task.dexWeight / 1500) * task.difficulty * numCycles;
+    this.agi_exp    += (task.agiWeight / 1500) * task.difficulty * numCycles;
+    this.cha_exp    += (task.chaWeight / 1500) * task.difficulty * numCycles;
+}
+
+GangMember.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_toJSON"])("GangMember", this);
+}
+
+GangMember.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_fromJSON"])(GangMember, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"].constructors.GangMember = GangMember;
+
+//Defines tasks that Gang Members can work on
+function GangMemberTask(name="", desc="",
+                        params={baseRespect: 0, baseWanted: 0, baseMoney: 0,
+                                hackWeight: 0, strWeight: 0, defWeight: 0,
+                                dexWeight: 0, agiWeight: 0, chaWeight: 0,
+                                difficulty: 0}) {
+    this.name = name;
+    this.desc = desc;
+
+    this.baseRespect    = params.baseRespect ? params.baseRespect   : 0;
+    this.baseWanted     = params.baseWanted  ? params.baseWanted    : 0;
+    this.baseMoney      = params.baseMoney   ? params.baseMoney     : 0;
+
+    //Weights must add up to 100
+    this.hackWeight     = params.hackWeight ? params.hackWeight : 0;
+    this.strWeight      = params.strWeight  ? params.strWeight  : 0;
+    this.defWeight      = params.defWeight  ? params.defWeight  : 0;
+    this.dexWeight      = params.dexWeight  ? params.dexWeight  : 0;
+    this.agiWeight      = params.agiWeight  ? params.agiWeight  : 0;
+    this.chaWeight      = params.chaWeight  ? params.chaWeight  : 0;
+
+    //1 - 100
+    this.difficulty     = params.difficulty ? params.difficulty : 1;
+}
+
+GangMemberTask.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_toJSON"])("GangMemberTask", this);
+}
+
+GangMemberTask.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_fromJSON"])(GangMemberTask, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"].constructors.GangMemberTask = GangMemberTask;
+
+//TODO Human trafficking and an equivalent hacking crime
+let GangMemberTasks = {
+    "Unassigned" :              new GangMemberTask(
+                                        "Unassigned",
+                                        "This gang member is currently idle"),
+    "Ransomware" :              new GangMemberTask(
+                                        "Ransomware",
+                                        "Assign this gang member to create and distribute ransomware<br><br>" +
+                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
+                                        {baseRespect: 0.00005, baseWanted: 0.00001, baseMoney: 1,
+                                         hackWeight: 100, difficulty: 1}),
+    "Phishing" :                new GangMemberTask(
+                                        "Phishing",
+                                        "Assign this gang member to attempt phishing scams and attacks<br><br>" +
+                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
+                                        {baseRespect: 0.00008, baseWanted: 0.001, baseMoney: 2.5,
+                                         hackWeight: 85, chaWeight: 15, difficulty: 3}),
+    "Identity Theft" :          new GangMemberTask(
+                                        "Identity Theft",
+                                        "Assign this gang member to attempt identity theft<br><br>" +
+                                        "Earns money - Increases respect - Increases wanted level",
+                                        {baseRespect: 0.0001, baseWanted: 0.01, baseMoney: 6,
+                                         hackWeight: 80, chaWeight: 20, difficulty: 4}),
+    "DDoS Attacks" :            new GangMemberTask(
+                                        "DDoS Attacks",
+                                        "Assign this gang member to carry out DDoS attacks<br><br>" +
+                                        "Increases respect - Increases wanted level",
+                                        {baseRespect: 0.0004, baseWanted: 0.05,
+                                         hackWeight: 100, difficulty: 7}),
+    "Plant Virus" :             new GangMemberTask(
+                                        "Plant Virus",
+                                        "Assign this gang member to create and distribute malicious viruses<br><br>" +
+                                        "Increases respect - Increases wanted level",
+                                        {baseRespect: 0.0006, baseWanted: 0.05,
+                                         hackWeight: 100, difficulty: 10}),
+    "Fraud & Counterfeiting" :  new GangMemberTask(
+                                        "Fraud & Counterfeiting",
+                                        "Assign this gang member to commit financial fraud and digital counterfeiting<br><br>" +
+                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
+                                        {baseRespect: 0.0005, baseWanted: 0.1, baseMoney: 15,
+                                         hackWeight: 80, chaWeight: 20, difficulty: 17}),
+    "Money Laundering" :        new GangMemberTask(
+                                        "Money Laundering",
+                                        "Assign this gang member to launder money<br><br>" +
+                                        "Earns money - Increases respect - Increases wanted level",
+                                        {baseRespect: 0.0006, baseWanted:0.2, baseMoney: 40,
+                                         hackWeight: 75, chaWeight: 25, difficulty: 20}),
+    "Cyberterrorism" :          new GangMemberTask(
+                                        "Cyberterrorism",
+                                        "Assign this gang member to commit acts of cyberterrorism<br><br>" +
+                                        "Greatly increases respect - Greatly increases wanted level",
+                                        {baseRespect: 0.001, baseWanted: 0.5,
+                                         hackWeight: 80, chaWeight: 20, difficulty: 33}),
+    "Ethical Hacking" :         new GangMemberTask(
+                                        "Ethical Hacking",
+                                        "Assign this gang member to be an ethical hacker for corporations<br><br>" +
+                                        "Earns money - Lowers wanted level",
+                                        {baseWanted: -0.001, baseMoney: 1,
+                                         hackWeight: 90, chaWeight: 10, difficulty: 1}),
+    "Mug People" :              new GangMemberTask(
+                                        "Mug People",
+                                        "Assign this gang member to mug random people on the streets<br><br>" +
+                                        "Earns money - Slightly increases respect - Very slightly increases wanted level",
+                                         {baseRespect: 0.00005, baseWanted: 0.00001, baseMoney: 1,
+                                          strWeight: 25, defWeight: 25, dexWeight: 25, agiWeight: 10, chaWeight: 15, difficulty: 1}),
+    "Deal Drugs" :              new GangMemberTask(
+                                        "Deal Drugs",
+                                        "Assign this gang member to sell drugs.<br><br>" +
+                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
+                                        {baseRespect: 0.00008, baseWanted: 0.001, baseMoney: 4,
+                                         agiWeight: 20, dexWeight: 20, chaWeight: 60, difficulty: 3}),
+    "Run a Con" :               new GangMemberTask(
+                                        "Run a Con",
+                                        "Assign this gang member to run cons<br><br>" +
+                                        "Earns money - Increases respect - Increases wanted level",
+                                        {baseRespect: 0.00015, baseWanted: 0.01, baseMoney: 10,
+                                         strWeight: 5, defWeight: 5, agiWeight: 25, dexWeight: 25, chaWeight: 40, difficulty: 10}),
+    "Armed Robbery" :           new GangMemberTask(
+                                        "Armed Robbery",
+                                        "Assign this gang member to commit armed robbery on stores, banks and armored cars<br><br>" +
+                                        "Earns money - Increases respect - Increases wanted level",
+                                        {baseRespect: 0.00015, baseWanted: 0.05, baseMoney: 25,
+                                         hackWeight: 20, strWeight: 15, defWeight: 15, agiWeight: 10, dexWeight: 20, chaWeight: 20,
+                                         difficulty: 17}),
+    "Traffick Illegal Arms" :   new GangMemberTask(
+                                        "Traffick Illegal Arms",
+                                        "Assign this gang member to traffick illegal arms<br><br>" +
+                                        "Earns money - Increases respect - Increases wanted level",
+                                        {baseRespect: 0.0003, baseWanted: 0.1, baseMoney: 40,
+                                         hackWeight: 15, strWeight: 20, defWeight: 20, dexWeight: 20, chaWeight: 75,
+                                         difficulty: 25}),
+    "Threaten & Blackmail" :    new GangMemberTask(
+                                        "Threaten & Blackmail",
+                                        "Assign this gang member to threaten and black mail high-profile targets<br><br>" +
+                                        "Earns money - Slightly increases respect - Slightly increases wanted level",
+                                        {baseRespect: 0.0002, baseWanted: 0.05, baseMoney: 15,
+                                         hackWeight: 25, strWeight: 25, dexWeight: 25, chaWeight: 25, difficulty: 28}),
+    "Terrorism" :               new GangMemberTask(
+                                        "Terrorism",
+                                        "Assign this gang member to commit acts of terrorism<br><br>" +
+                                        "Greatly increases respect - Greatly increases wanted level",
+                                        {baseRespect: 0.001, baseWanted: 1,
+                                         hackWeight: 20, strWeight: 20, defWeight: 20,dexWeight: 20, chaWeight: 20,
+                                         difficulty: 33}),
+    "Vigilante Justice" :       new GangMemberTask(
+                                        "Vigilante Justice",
+                                        "Assign this gang member to be a vigilante and protect the city from criminals<br><br>" +
+                                        "Decreases wanted level",
+                                        {baseWanted: -0.001,
+                                         hackWeight: 20, strWeight: 20, defWeight: 20, dexWeight: 20, agiWeight:20,
+                                         difficulty: 1}),
+    "Train Combat" :            new GangMemberTask(
+                                        "Train Combat",
+                                        "Assign this gang member to increase their combat stats (str, def, dex, agi)",
+                                        {strWeight: 25, defWeight: 25, dexWeight: 25, agiWeight: 25, difficulty: 5}),
+    "Train Hacking" :           new GangMemberTask(
+                                        "Train Hacking",
+                                        "Assign this gang member to train their hacking skills",
+                                        {hackWeight: 100, difficulty: 8}),
+    "Territory Warfare" :       new GangMemberTask(
+                                        "Territory Warfare",
+                                        "Assign this gang member to engage in territorial warfare with other gangs. " +
+                                        "Members assigned to this task will help increase your gang's territory " +
+                                        "and will defend your territory from being taken.",
+                                        {hackWeight: 15, strWeight: 20, defWeight: 20, dexWeight: 20, agiWeight: 20,
+                                         chaWeight: 5, difficulty: 3}),
+}
+
+
+function GangMemberUpgrade(name="", desc="", cost=0, type="w") {
+    this.name = name;
+    this.desc = desc;
+    this.cost = cost;
+    this.type = type; //w, a, v, r
+}
+
+//Passes in a GangMember object
+GangMemberUpgrade.prototype.apply = function(member) {
+    switch(this.name) {
+        case "Baseball Bat":
+            member.str_mult *= 1.05;
+            member.def_mult *= 1.05;
+            break;
+        case "Katana":
+            member.str_mult *= 1.1;
+            member.def_mult *= 1.1;
+            member.dex_mult *= 1.1;
+            break;
+        case "Glock 18C":
+            member.str_mult *= 1.15;
+            member.def_mult *= 1.15;
+            member.dex_mult *= 1.15;
+            member.agi_mult *= 1.15;
+            break;
+        case "P90C":
+            member.str_mult *= 1.2;
+            member.def_mult *= 1.2;
+            member.agi_mult *= 1.1;
+            break;
+        case "Steyr AUG":
+            member.str_mult *= 1.25;
+            member.def_mult *= 1.25;
+            break;
+        case "AK-47":
+            member.str_mult *= 1.5;
+            member.def_mult *= 1.5;
+            break;
+        case "M15A10 Assault Rifle":
+            member.str_mult *= 1.6;
+            member.def_mult *= 1.6;
+            break;
+        case "AWM Sniper Rifle":
+            member.str_mult *= 1.5;
+            member.dex_mult *= 1.5;
+            member.agi_mult *= 1.5;
+            break;
+        case "Bulletproof Vest":
+            member.def_mult *= 1.05;
+            break;
+        case "Full Body Armor":
+            member.def_mult *= 1.1;
+            break;
+        case "Liquid Body Armor":
+            member.def_mult *= 1.25;
+            member.agi_mult *= 1.25;
+            break;
+        case "Graphene Plating Armor":
+            member.def_mult *= 1.5;
+            break;
+        case "Ford Flex V20":
+            member.agi_mult *= 1.1;
+            member.cha_mult *= 1.1;
+            break;
+        case "ATX1070 Superbike":
+            member.agi_mult *= 1.15;
+            member.cha_mult *= 1.15;
+            break;
+        case "Mercedes-Benz S9001":
+            member.agi_mult *= 1.2;
+            member.cha_mult *= 1.2;
+            break;
+        case "White Ferrari":
+            member.agi_mult *= 1.25;
+            member.cha_mult *= 1.25;
+            break;
+        case "NUKE Rootkit":
+            member.hack_mult *= 1.1;
+            break;
+        case "Soulstealer Rootkit":
+            member.hack_mult *= 1.2;
+            break;
+        case "Demon Rootkit":
+            member.hack_mult *= 1.3;
+            break;
+        default:
+            console.log("ERROR: Could not find this upgrade: " + this.name);
+            break;
+    }
+}
+
+GangMemberUpgrade.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_toJSON"])("GangMemberUpgrade", this);
+}
+
+GangMemberUpgrade.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Generic_fromJSON"])(GangMemberUpgrade, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_5__["Reviver"].constructors.GangMemberUpgrade = GangMemberUpgrade;
+
+let GangMemberUpgrades = {
+    "Baseball Bat" : new GangMemberUpgrade("Baseball Bat",
+                            "Increases strength and defense by 5%", 1e6, "w"),
+    "Katana" :       new GangMemberUpgrade("Katana",
+                            "Increases strength, defense, and dexterity by 10%", 12e6, "w"),
+    "Glock 18C" :    new GangMemberUpgrade("Glock 18C",
+                            "Increases strength, defense, dexterity, and agility by 15%", 25e6, "w"),
+    "P90C" :          new GangMemberUpgrade("P90C",
+                            "Increases strength and defense by 20%. Increases agility by 10%", 50e6, "w"),
+    "Steyr AUG" :    new GangMemberUpgrade("Steyr AUG",
+                            "Increases strength and defense by 25%", 60e6, "w"),
+    "AK-47" :        new GangMemberUpgrade("AK-47",
+                            "Increases strength and defense by 50%", 100e6, "w"),
+    "M15A10 Assault Rifle" :    new GangMemberUpgrade("M15A10 Assault Rifle",
+                                        "Increases strength and defense by 60%", 150e6, "w"),
+    "AWM Sniper Rifle" :        new GangMemberUpgrade("AWM Sniper Rifle",
+                                        "Increases strength, dexterity, and agility by 50%", 225e6, "w"),
+    "Bulletproof Vest" :        new GangMemberUpgrade("Bulletproof Vest",
+                                        "Increases defense by 5%", 2e6, "a"),
+    "Full Body Armor" :         new GangMemberUpgrade("Full Body Armor",
+                                        "Increases defense by 10%", 5e6, "a"),
+    "Liquid Body Armor" :       new GangMemberUpgrade("Liquid Body Armor",
+                                        "Increases defense and agility by 25%", 25e6, "a"),
+    "Graphene Plating Armor" :  new GangMemberUpgrade("Graphene Plating Armor",
+                                        "Increases defense by 50%", 40e6, "a"),
+    "Ford Flex V20" :           new GangMemberUpgrade("Ford Flex V20",
+                                        "Increases agility and charisma by 10%", 3e6, "v"),
+    "ATX1070 Superbike" :       new GangMemberUpgrade("ATX1070 Superbike",
+                                        "Increases agility and charisma by 15%", 9e6, "v"),
+    "Mercedes-Benz S9001" :     new GangMemberUpgrade("Mercedes-Benz S9001",
+                                        "Increases agility and charisma by 20%", 18e6, "v"),
+    "White Ferrari" :           new GangMemberUpgrade("White Ferrari",
+                                        "Increases agility and charisma by 25%", 30e6, "v"),
+    "NUKE Rootkit" :            new GangMemberUpgrade("NUKE Rootkit",
+                                        "Increases hacking by 10%", 5e6, "r"),
+    "Soulstealer Rootkit" :     new GangMemberUpgrade("Soulstealer Rootkit",
+                                        "Increases hacking by 20%", 15e6, "r"),
+    "Demon Rootkit" :           new GangMemberUpgrade("Demon Rootkit",
+                                        "Increases hacking by 30%", 50e6, "r"),
+}
+
+//Create a pop-up box that lets player purchase upgrades
+let gangMemberUpgradeBoxOpened = false;
+function createGangMemberUpgradeBox(initialFilter="") {
+    var boxId = "gang-member-upgrade-popup-box";
+    if (gangMemberUpgradeBoxOpened) {
+        //Already opened, refreshing
+        if (gangMemberUpgradeBoxElements == null || gangMemberUpgradeBox == null || gangMemberUpgradeBoxContent == null) {
+            console.log("ERROR: Refreshing Gang member upgrade box throws error because required elements are null");
+            return;
+        }
+
+        for (var i = 1; i < gangMemberUpgradeBoxElements.length; ++i) {
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeElement"])(gangMemberUpgradeBoxElements[i]);
+        }
+        gangMemberUpgradeBoxElements = [gangMemberUpgradeBoxFilter];
+
+        var filter = gangMemberUpgradeBoxFilter.value.toString();
+        for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length; ++i) {
+            if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].name.indexOf(filter) > -1 || _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].task.name.indexOf(filter) > -1) {
+                var newPanel = createGangMemberUpgradePanel(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i]);
+                gangMemberUpgradeBoxContent.appendChild(newPanel);
+                gangMemberUpgradeBoxElements.push(newPanel);
+            }
+        }
+    } else {
+        //New popup
+        gangMemberUpgradeBoxFilter = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("input", {
+            type:"text", placeholder:"Filter gang members",
+            value:initialFilter,
+            onkeyup:()=>{
+                var filterValue = gangMemberUpgradeBoxFilter.value.toString();
+                createGangMemberUpgradeBox(filterValue);
+            }
+        });
+
+        gangMemberUpgradeBoxElements = [gangMemberUpgradeBoxFilter];
+
+        var filter = gangMemberUpgradeBoxFilter.value.toString();
+        for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length; ++i) {
+            if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].name.indexOf(filter) > -1 || _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].task.name.indexOf(filter) > -1) {
+                gangMemberUpgradeBoxElements.push(createGangMemberUpgradePanel(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i]));
+            }
+        }
+
+        gangMemberUpgradeBox = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createPopup"])(boxId, gangMemberUpgradeBoxElements);
+        gangMemberUpgradeBoxContent = document.getElementById(boxId + "-content");
+        gangMemberUpgradeBoxOpened = true;
+    }
+}
+
+//Create upgrade panels for each individual Gang Member
+function createGangMemberUpgradePanel(memberObj) {
+    var container = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+        border:"1px solid white",
+    });
+
+    var header = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("h1", {
+        innerText:memberObj.name + " (" + memberObj.task.name + ")"
+    });
+    container.appendChild(header);
+
+    var text = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("pre", {
+        fontSize:"14px", display: "inline-block", width:"20%",
+        innerText:
+            "Hack: " + memberObj.hack + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.hack_mult, 2) + ")\n" +
+            "Str:  " + memberObj.str  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.str_mult, 2) + ")\n" +
+            "Def:  " + memberObj.def  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.def_mult, 2) + ")\n" +
+            "Dex:  " + memberObj.dex  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.dex_mult, 2) + ")\n" +
+            "Agi:  " + memberObj.agi  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.agi_mult, 2) + ")\n" +
+            "Cha:  " + memberObj.cha  + " (x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.cha_mult, 2) + ")\n",
+    });
+
+    //Already purchased upgrades
+    var ownedUpgradesElements = [];
+    for (var i = 0; i < memberObj.upgrades.length; ++i) {
+        var upg = GangMemberUpgrades[memberObj.upgrades[i]];
+        if (upg == null) {
+            console.log("ERR: Could not find this upgrade: " + memberObj.upgrades[i]);
+            continue;
+        }
+        var e = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+            border:"1px solid white", innerText:memberObj.upgrades[i],
+            margin:"1px", padding:"1px", tooltip:upg.desc, fontSize:"12px",
+        });
+        ownedUpgradesElements.push(e);
+    }
+    var ownedUpgrades = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+        display:"inline-block", marginLeft:"6px", width:"75%", innerText:"Purchased Upgrades:",
+    });
+    for (var i = 0; i < ownedUpgradesElements.length; ++i) {
+        ownedUpgrades.appendChild(ownedUpgradesElements[i]);
+    }
+    container.appendChild(text);
+    container.appendChild(ownedUpgrades);
+    container.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
+
+    //Upgrade buttons. Only show upgrades that can be afforded
+    var weaponUpgrades = [], armorUpgrades = [], vehicleUpgrades = [], rootkitUpgrades = [];
+    for (var upgName in GangMemberUpgrades) {
+        if (GangMemberUpgrades.hasOwnProperty(upgName)) {
+            var upg = GangMemberUpgrades[upgName];
+            if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].money.lt(upg.cost) || memberObj.upgrades.includes(upgName)) {continue;}
+            switch (upg.type) {
+                case "w":
+                    weaponUpgrades.push(upg);
+                    break;
+                case "a":
+                    armorUpgrades.push(upg);
+                    break;
+                case "v":
+                    vehicleUpgrades.push(upg);
+                    break;
+                case "r":
+                    rootkitUpgrades.push(upg);
+                    break;
+                default:
+                    console.log("ERROR: Invalid Gang Member Upgrade Type: " + upg.type);
+            }
+        }
+    }
+
+    var weaponDiv   = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {width:"20%", display:"inline-block",});
+    var armorDiv    = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {width:"20%", display:"inline-block",});
+    var vehicleDiv  = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {width:"20%", display:"inline-block",});
+    var rootkitDiv  = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {width:"20%", display:"inline-block",});
+    var upgrades = [weaponUpgrades, armorUpgrades, vehicleUpgrades, rootkitUpgrades];
+    var divs = [weaponDiv, armorDiv, vehicleDiv, rootkitDiv];
+
+    for (var i = 0; i < upgrades.length; ++i) {
+        var upgradeArray = upgrades[i];
+        var div = divs[i];
+        for (var j = 0; j < upgradeArray.length; ++j) {
+            var upg = upgradeArray[j];
+            (function (upg, div, memberObj) {
+                div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
+                    innerText:upg.name + " - " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(upg.cost).format("$0.000a"),
+                    class:"a-link-button", margin:"2px",  padding:"2px", display:"block",
+                    fontSize:"12px",
+                    tooltip:upg.desc,
+                    clickListener:()=>{
+                        if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].money.lt(upg.cost)) {return false;}
+                        _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].loseMoney(upg.cost);
+                        memberObj.upgrades.push(upg.name);
+                        upg.apply(memberObj);
+                        var initFilterValue = gangMemberUpgradeBoxFilter.value.toString();
+                        createGangMemberUpgradeBox(initFilterValue);
+                        return false;
+                    }
+                }));
+            })(upg, div, memberObj);
+        }
+    }
+
+    container.appendChild(weaponDiv);
+    container.appendChild(armorDiv);
+    container.appendChild(vehicleDiv);
+    container.appendChild(rootkitDiv);
+    return container;
+}
+
+//Gang DOM elements
+let gangContentCreated = false,
+    gangContainer = null, managementButton = null, territoryButton = null;
+
+//Subpages
+let gangManagementSubpage = null, gangTerritorySubpage = null;
+
+//Gang Management Elements
+let gangDesc = null, gangInfo = null,
+    gangRecruitMemberButton = null, gangRecruitRequirementText = null,
+    gangExpandAllButton = null, gangCollapseAllButton, gangMemberFilter = null,
+    gangManageEquipmentButton = null,
+    gangMemberList = null;
+
+//Gang Equipment Upgrade Elements
+let gangMemberUpgradeBox = null, gangMemberUpgradeBoxContent = null,
+    gangMemberUpgradeBoxFilter = null, gangMemberUpgradeBoxElements = null;
+
+
+//Gang Territory Elements
+let gangTerritoryDescText = null, gangTerritoryInfoText = null;
+
+function displayGangContent() {
+    if (!gangContentCreated || gangContainer == null) {
+        gangContentCreated = true;
+
+        //Create gang container
+        gangContainer = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+            id:"gang-container", class:"generic-menupage-container",
+        });
+
+        //Get variables
+        var facName = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName,
+            members = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members,
+            wanted = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted,
+            respect = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect;
+
+        //Back button
+        gangContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
+            class:"a-link-button", display:"inline-block", innerText:"Back",
+            clickListener:()=>{
+                _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].loadFactionContent();
+                Object(_Faction_js__WEBPACK_IMPORTED_MODULE_2__["displayFactionContent"])(facName);
+                return false;
+            }
+        }));
+
+        //Buttons to switch between panels
+        managementButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
+            id:"gang-management-subpage-button", class:"a-link-button-inactive",
+            display:"inline-block", innerHTML: "Gang Management (1)",
+            clickListener:()=>{
+                gangManagementSubpage.style.display = "block";
+                gangTerritorySubpage.style.display = "none";
+                managementButton.classList.toggle("a-link-button-inactive");
+                managementButton.classList.toggle("a-link-button");
+                territoryButton.classList.toggle("a-link-button-inactive");
+                territoryButton.classList.toggle("a-link-button");
+                updateGangContent();
+                return false;
+            }
+        })
+        territoryButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
+            id:"gang-territory-subpage-button", class:"a-link-button",
+            display:"inline-block", innerHTML:"Gang Territory (2)",
+            clickListener:()=>{
+                gangManagementSubpage.style.display = "none";
+                gangTerritorySubpage.style.display = "block";
+                managementButton.classList.toggle("a-link-button-inactive");
+                managementButton.classList.toggle("a-link-button");
+                territoryButton.classList.toggle("a-link-button-inactive");
+                territoryButton.classList.toggle("a-link-button");
+                updateGangContent();
+                return false;
+            }
+        });
+        gangContainer.appendChild(managementButton);
+        gangContainer.appendChild(territoryButton);
+
+        //Subpage for managing gang members
+        gangManagementSubpage = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+            display:"block", id:"gang-management-subpage",
+        });
+
+        var lowerWantedTask = "";
+        if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.isHackingGang) {
+            lowerWantedTask = "Ethical Hacking";
+        } else {
+            lowerWantedTask = "Vigilante Justice";
+        }
+        gangDesc = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {width:"70%",
+            innerHTML:
+            "This page is used to manage your gang members and get an overview of your  " +
+            "gang's stats.<br><br>" +
+            "If a gang member is not earning much money or respect, the task that you " +
+            "have assigned to that member might be too difficult. Consider training that " +
+            "member's stats or choosing an easier task. The tasks closer to the " +
+            "top of the dropdown list are generally easier. Alternatively, the gang member's " +
+            "low production might be due to the fact that your wanted level is too high. " +
+            "Consider assigning a few members to the '" + lowerWantedTask + "' " +
+            "task to lower your wanted level. <br><br>" +
+            "Installing Augmentations does NOT reset your progress with your Gang. " +
+            "Furthermore, after installing Augmentations, you will " +
+            "automatically be a member of whatever Faction you created your gang with.<br><br>"
+        });
+        gangManagementSubpage.appendChild(gangDesc);
+
+        gangInfo = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {id:"gang-info", width:"70%"});
+        gangManagementSubpage.appendChild(gangInfo);
+
+        gangRecruitMemberButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
+            id:"gang-management-recruit-member-btn", class:"a-link-button-inactive",
+            innerHTML:"Recruit Gang Member", display:"inline-block", margin:"10px",
+            clickListener:()=>{
+                var yesBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxGetYesButton"])(), noBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxGetNoButton"])();
+                yesBtn.innerHTML = "Recruit Gang Member";
+                noBtn.innerHTML = "Cancel";
+                yesBtn.addEventListener("click", ()=>{
+                    var name = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxGetInput"])();
+                    if (name === "") {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__["dialogBoxCreate"])("You must enter a name for your Gang member!");
+                    } else {
+                        for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length; ++i) {
+                            if (name == _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i].name) {
+                                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__["dialogBoxCreate"])("You already have a gang member with this name!");
+                                return false;
+                            }
+                        }
+                        var member = new GangMember(name);
+                        _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.push(member);
+                        createGangMemberDisplayElement(member);
+                        updateGangContent();
+                    }
+                    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxClose"])();
+                });
+                noBtn.addEventListener("click", ()=>{
+                    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxClose"])();
+                });
+                Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_9__["yesNoTxtInpBoxCreate"])("Please enter a name for your new Gang member:");
+                return false;
+            }
+        });
+        gangManagementSubpage.appendChild(gangRecruitMemberButton);
+
+        //Text for how much reputation is required for recruiting next memberList
+        gangRecruitRequirementText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {color:"red", id:"gang-recruit-requirement-text"});
+        gangManagementSubpage.appendChild(gangRecruitRequirementText);
+
+        //Gang Member List management buttons (Expand/Collapse All, select a single member)
+        gangManagementSubpage.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
+        gangExpandAllButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
+            class:"a-link-button", display:"inline-block",
+            innerHTML:"Expand All",
+            clickListener:()=>{
+                var allHeaders = gangManagementSubpage.getElementsByClassName("accordion-header");
+                for (var i = 0; i < allHeaders.length; ++i) {
+                    var hdr = allHeaders[i];
+                    if (!hdr.classList.contains("active")) {
+                        hdr.click();
+                    }
+                }
+                return false;
+            }
+        });
+        gangCollapseAllButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
+            class:"a-link-button", display:"inline-block",
+            innerHTML:"Collapse All",
+            clickListener:()=>{
+                var allHeaders = gangManagementSubpage.getElementsByClassName("accordion-header");
+                for (var i = 0; i < allHeaders.length; ++i) {
+                    var hdr = allHeaders[i];
+                    if (hdr.classList.contains("active")) {
+                        hdr.click();
+                    }
+                }
+                return false;
+            }
+        });
+        gangMemberFilter = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("input", {
+            type:"text", placeholder:"Filter gang members", margin:"5px", padding:"5px",
+            onkeyup:()=>{
+                displayGangMemberList();
+            }
+        });
+        gangManageEquipmentButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("a", {
+            class:"a-link-button", display:"inline-block",
+            innerHTML:"Manage Equipment",
+            clickListener:()=>{
+                createGangMemberUpgradeBox();
+            }
+        });
+        gangManagementSubpage.appendChild(gangExpandAllButton);
+        gangManagementSubpage.appendChild(gangCollapseAllButton);
+        gangManagementSubpage.appendChild(gangMemberFilter);
+        gangManagementSubpage.appendChild(gangManageEquipmentButton);
+
+        //Gang Member list
+        gangMemberList = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("ul", {id:"gang-member-list"});
+        displayGangMemberList();
+        gangManagementSubpage.appendChild(gangMemberList);
+
+        //Subpage for seeing gang territory information
+        gangTerritorySubpage = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+            id:"gang-territory-subpage", display:"none"
+        });
+
+        //Info text for territory page
+        gangTerritoryDescText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {
+            width:"70%",
+            innerHTML:"This page shows how much territory your Gang controls. This statistic is listed as a percentage, " +
+            "which represents how much of the total territory you control.<br><br>" +
+            "Territory gain and loss is processed automatically and is updated every ~30 seconds. Your chances " +
+            "to gain and lose territory depend on your Gang's power, which is listed in the display below. " +
+            "Your gang's power is determined by the stats of all Gang members you have assigned to the " +
+            "'Territory Warfare' task. Gang members that are not assigned to this task do not contribute to " +
+            "your Gang's power.<br><br>" +
+            "The amount of territory you have affects all aspects of your Gang members' production, including " +
+            "money, respect, and wanted level. It is very beneficial to have high territory control.<br><br>"
+        });
+        gangTerritorySubpage.appendChild(gangTerritoryDescText);
+
+        var territoryBorder = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("fieldset", {width:"50%", display:"inline-block"});
+
+        gangTerritoryInfoText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {id:"gang-territory-info"});
+
+        territoryBorder.appendChild(gangTerritoryInfoText);
+        gangTerritorySubpage.appendChild(territoryBorder);
+
+        gangContainer.appendChild(gangTerritorySubpage);
+        gangContainer.appendChild(gangManagementSubpage);
+        document.getElementById("entire-game-container").appendChild(gangContainer);
+    }
+    gangContainer.style.display = "block";
+    updateGangContent();
+}
+
+function displayGangMemberList() {
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeChildrenFromElement"])(gangMemberList);
+    var members = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members;
+    var filter = gangMemberFilter.value.toString();
+    for (var i = 0; i < members.length; ++i) {
+        if (members[i].name.indexOf(filter) > -1 || members[i].task.name.indexOf(filter) > -1) {
+            createGangMemberDisplayElement(members[i]);
+        }
+    }
+    //setGangMemberClickHandlers(); //Set buttons to toggle the gang member info panels
+}
+
+function updateGangContent() {
+    if (!gangContentCreated || !_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
+
+    if(gangTerritorySubpage.style.display === "block") {
+        //Update territory information
+        gangTerritoryInfoText.innerHTML = "";
+        for (var gangname in AllGangs) {
+            if (AllGangs.hasOwnProperty(gangname)) {
+                var gangTerritoryInfo = AllGangs[gangname];
+                if (gangname == _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName) {
+                    gangTerritoryInfoText.innerHTML += ("<b>" + gangname + "</b><br>(Power: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(gangTerritoryInfo.power, 6) + "): " +
+                                       Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(100*gangTerritoryInfo.territory, 2) + "%<br><br>");
+                } else {
+                    gangTerritoryInfoText.innerHTML += (gangname + "<br>(Power: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(gangTerritoryInfo.power, 6) + "): " +
+                                       Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(100*gangTerritoryInfo.territory, 2) + "%<br><br>");
+                }
+            }
+        }
+    } else {
+        //Update information for overall gang
+        if (gangInfo instanceof Element) {
+            var faction = _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Factions"][_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName];
+            var rep;
+            if (!(faction instanceof _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Faction"])) {
+                rep = "ERROR";
+            } else {
+                rep = faction.playerReputation;
+            }
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeChildrenFromElement"])(gangInfo);
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {   //Respect
+                display:"inline-block",
+                innerText:"Respect: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect, 6) +
+                          " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respectGainRate, 6) + " / sec)",
+                tooltip:"Represents the amount of respect your gang has from other gangs and criminal " +
+                        "organizations. Your respect affects the amount of money " +
+                        "your gang members will earn, and also determines how much " +
+                        "reputation you are earning with your gang's corresponding Faction."
+            }));
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
+
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {   //Wanted level
+                display:"inline-block",
+                innerText:"Wanted Level: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted, 6) +
+                          " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wantedGainRate, 6) + " / sec)",
+                tooltip:"Represents how much the gang is wanted by law enforcement. The higher " +
+                        "your gang's wanted level, the harder it will be for your gang members " +
+                        "to make money and earn respect. Note that the minimum wanted level is 1."
+            }));
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
+
+            var wantedPenalty = (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect) / (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.respect + _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.wanted);
+            wantedPenalty = (1 - wantedPenalty) * 100;
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {   //Wanted Level multiplier
+                display:"inline-block",
+                innerText:"Wanted Level Penalty: -" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(wantedPenalty, 2) + "%",
+                tooltip:"Penalty for respect and money gain rates due to Wanted Level"
+            }));
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
+
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {   //Money gain rate
+                display:"inline-block",
+                innerText:"Money gain rate: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.moneyGainRate, 2) +
+                          " / sec",
+            }));
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
+
+            var territoryMult = AllGangs[_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName].territory;
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {  //Territory multiplier
+                display:"inline-block",
+                innerText:"Territory: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(territoryMult * 100, 3) + "%",
+                tooltip:"The percentage of total territory your Gang controls"
+            }));
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
+
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {  //Faction reputation
+                display:"inline-block",
+                innerText:"Faction reputation: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(rep, 3)
+            }));
+            gangInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("br", {}));
+        } else {
+            console.log("ERROR: gang-info DOM element DNE");
+        }
+
+        //Toggle the 'Recruit member button' if valid
+        var numMembers = _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length;
+        var repCost = 0;
+        if (numMembers > 0) {
+            var repCost = Math.pow(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].GangRecruitCostMultiplier, numMembers);
+        }
+        var faction = _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Factions"][_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.facName];
+        if (faction == null) {
+            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__["dialogBoxCreate"])("Could not find your gang's faction. This is probably a bug please report to dev");
+            return;
+        }
+        var btn = gangRecruitMemberButton;
+        if (numMembers >= _Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].MaximumGangMembers) {
+            btn.className = "a-link-button-inactive";
+            gangRecruitRequirementText.style.display = "block";
+            gangRecruitRequirementText.innerHTML =
+                "You have reached the maximum amount of gang members";
+        } else if (faction.playerReputation >= repCost) {
+            btn.className = "a-link-button";
+            gangRecruitRequirementText.style.display = "none";
+        } else {
+            btn.className = "a-link-button-inactive";
+            gangRecruitRequirementText.style.display = "block";
+            gangRecruitRequirementText.innerHTML =
+                Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(repCost, 2) + " Faction reputation needed to recruit next member";
+        }
+
+        //Update information for each gang member
+        for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members.length; ++i) {
+            updateGangMemberDisplayElement(_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.members[i]);
+        }
+    }
+}
+
+//Takes in a GangMember object
+function createGangMemberDisplayElement(memberObj) {
+    if (!gangContentCreated || !_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
+    var name = memberObj.name;
+
+    var accordion = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createAccordionElement"])({
+        id:name + "gang-member",
+        hdrText:name,
+    });
+    var li = accordion[0];
+    var hdr = accordion[1];
+    var gangMemberDiv = accordion[2];
+
+    //Gang member content divided into 3 panels:
+    //Stats Panel
+    var statsDiv = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+        id: name + "gang-member-stats", class: "gang-member-info-div",
+        width:"30%", display:"inline"
+    });
+    var statsP = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {
+        id:name + "gang-member-stats-text", display:"inline"
+    });
+
+    statsDiv.appendChild(statsP);
+    //statsDiv.appendChild(upgradeButton);
+
+    //Panel for Selecting task and show respect/wanted gain
+    var taskDiv = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+        id: name + "gang-member-task", class:"gang-member-info-div",
+        width:"30%", display:"inline"
+    });
+    var taskSelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("select", {
+        color:"white", backgroundColor:"black",
+        id:name + "gang-member-task-selector"
+    });
+
+    var tasks = null;
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].gang.isHackingGang) {
+        tasks = ["---", "Ransomware", "Phishing", "Identity Theft", "DDoS Attacks",
+                 "Plant Virus", "Fraud & Counterfeiting","Money Laundering",
+                 "Cyberterrorism", "Ethical Hacking", "Train Combat",
+                 "Train Hacking", "Territory Warfare"];
+    } else {
+        tasks = ["---", "Mug People", "Deal Drugs", "Run a Con", "Armed Robbery",
+                 "Traffick Illegal Arms", "Threaten & Blackmail",
+                 "Terrorism", "Vigilante Justice", "Train Combat",
+                 "Train Hacking", "Territory Warfare"];
+    }
+    for (var i = 0; i < tasks.length; ++i) {
+        var option = document.createElement("option");
+        option.text = tasks[i];
+        taskSelector.add(option);
+    }
+    taskSelector.addEventListener("change", function() {
+        var task = taskSelector.options[taskSelector.selectedIndex].text;
+        memberObj.assignToTask(task);
+        setGangMemberTaskDescription(memberObj, task);
+        updateGangContent();
+    });
+    //Set initial task in selector element
+    if (memberObj.task instanceof GangMemberTask) {
+        var taskName = memberObj.task.name;
+        var taskIndex = 0;
+        for (let i = 0; i < tasks.length; ++i) {
+            if (taskName == tasks[i]) {
+                taskIndex = i;
+                break;
+            }
+        }
+        taskSelector.selectedIndex = taskIndex;
+    }
+
+    var gainInfo = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {id:name + "gang-member-gain-info"});
+    taskDiv.appendChild(taskSelector);
+    taskDiv.appendChild(gainInfo);
+
+    //Panel for Description of task
+    var taskDescDiv = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("div", {
+        id:name + "gang-member-task-desc", class:"gang-member-info-div",
+        width:"30%", display:"inline"
+    });
+
+    var taskDescP = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["createElement"])("p", {id: name + "gang-member-task-description", display:"inline"});
+    taskDescDiv.appendChild(taskDescP);
+
+    statsDiv.style.width = "30%";
+    taskDiv.style.width = "30%";
+    taskDescDiv.style.width = "30%";
+    statsDiv.style.display = "inline";
+    taskDiv.style.display = "inline";
+    taskDescDiv.style.display = "inline";
+    gangMemberDiv.appendChild(statsDiv);
+    gangMemberDiv.appendChild(taskDiv);
+    gangMemberDiv.appendChild(taskDescDiv);
+
+    gangMemberList.appendChild(li);
+    setGangMemberTaskDescription(memberObj, taskName); //Initialize description
+    updateGangMemberDisplayElement(memberObj);
+}
+
+function updateGangMemberDisplayElement(memberObj) {
+    if (!gangContentCreated || !_Player_js__WEBPACK_IMPORTED_MODULE_3__["Player"].inGang()) {return;}
+    var name = memberObj.name;
+
+    //TODO Add upgrade information
+    var stats = document.getElementById(name + "gang-member-stats-text");
+    if (stats) {
+        stats.innerHTML =
+            "Hacking: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.hack, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.hack_exp).format('(0.00a)') + " exp)<br>" +
+            "Strength: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.str, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.str_exp).format('(0.00a)') + " exp)<br>" +
+            "Defense: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.def, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.def_exp).format('(0.00a)') + " exp)<br>" +
+            "Dexterity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.dex, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.dex_exp).format('(0.00a)') + " exp)<br>" +
+            "Agility: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.agi, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.agi_exp).format('(0.00a)') + " exp)<br>" +
+            "Charisma: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(memberObj.cha, 0) + " (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_7___default()(memberObj.cha_exp).format('(0.00a)') + " exp)<br>";
+    }
+
+    var gainInfo = document.getElementById(name + "gang-member-gain-info");
+    if (gainInfo) {
+        gainInfo.innerHTML =
+            "Money: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*memberObj.calculateMoneyGain(), 2) + " / sec<br>" +
+            "Respect: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*memberObj.calculateRespectGain(), 6) + " / sec<br>" +
+            "Wanted Level: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(5*memberObj.calculateWantedLevelGain(), 6) + " / sec<br>";
+    }
+}
+
+function setGangMemberTaskDescription(memberObj, taskName) {
+    var name = memberObj.name;
+    var taskDesc = document.getElementById(name + "gang-member-task-description");
+    if (taskDesc) {
+        var task = GangMemberTasks[taskName];
+        if (task == null) {return;}
+        var desc = task.desc;
+        taskDesc.innerHTML = desc;
+    }
+}
+
+function deleteGangDisplayContent() {
+    if (gangContainer != null) {Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["removeElementById"])(gangContainer.id);}
+
+    gangContentCreated = false;
+    gangContainer = null;
+    managementButton = null;
+    territoryButton = null;
+
+    //Subpages
+    gangManagementSubpage = null;
+    gangTerritorySubpage = null;
+
+    //Gang Management Elements
+    gangDesc = null;
+    gangInfo = null;
+    gangRecruitMemberButton = null;
+    gangRecruitRequirementText = null;
+    gangExpandAllButton = null;
+    gangCollapseAllButton = null;
+    gangMemberFilter = null;
+    gangManageEquipmentButton = null;
+    gangMemberList = null;
+
+    //Gang Equipment Upgrade Elements
+    gangMemberUpgradeBox = null;
+    gangMemberUpgradeBoxContent = null;
+    gangMemberUpgradeBoxFilter = null;
+    gangMemberUpgradeBoxElements = null;
+}
+
+
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
+
 /***/ }),
 /* 37 */
 /*!********************************************************!*\
@@ -38138,5583 +38280,6 @@ module.exports = GenericWorker;
 
 /***/ }),
 /* 38 */
-/*!****************************!*\
-  !*** ./src/HacknetNode.js ***!
-  \****************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hacknetNodesInit", function() { return hacknetNodesInit; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HacknetNode", function() { return HacknetNode; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "purchaseHacknet", function() { return purchaseHacknet; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateTotalHacknetProduction", function() { return updateTotalHacknetProduction; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCostOfNextHacknetNode", function() { return getCostOfNextHacknetNode; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateHacknetNodesMultiplierButtons", function() { return updateHacknetNodesMultiplierButtons; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getMaxNumberLevelUpgrades", function() { return getMaxNumberLevelUpgrades; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayHacknetNodesContent", function() { return displayHacknetNodesContent; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateHacknetNodesContent", function() { return updateHacknetNodesContent; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "processAllHacknetNodeEarnings", function() { return processAllHacknetNodeEarnings; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getHacknetNode", function() { return getHacknetNode; });
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 16);
-/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./InteractiveTutorial.js */ 25);
-/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-
-
-
-
-
-
-
-
-
-
-/* HacknetNode.js */
-function hacknetNodesInit() {
-    var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
-    mult1x.addEventListener("click", function() {
-        hacknetNodePurchaseMultiplier = 1;
-        updateHacknetNodesMultiplierButtons();
-        updateHacknetNodesContent();
-        return false;
-    });
-    var mult5x = document.getElementById("hacknet-nodes-5x-multiplier");
-    mult5x.addEventListener("click", function() {
-        hacknetNodePurchaseMultiplier = 5;
-        updateHacknetNodesMultiplierButtons();
-        updateHacknetNodesContent();
-        return false;
-    });
-    var mult10x = document.getElementById("hacknet-nodes-10x-multiplier");
-    mult10x.addEventListener("click", function() {
-        hacknetNodePurchaseMultiplier = 10;
-        updateHacknetNodesMultiplierButtons();
-        updateHacknetNodesContent();
-        return false;
-    });
-    var multMax = document.getElementById("hacknet-nodes-max-multiplier");
-    multMax.addEventListener("click", function() {
-        hacknetNodePurchaseMultiplier = 0;
-        updateHacknetNodesMultiplierButtons();
-        updateHacknetNodesContent();
-        return false;
-    });
-}
-document.addEventListener("DOMContentLoaded", hacknetNodesInit, false);
-
-function HacknetNode(name) {
-    this.level      = 1;
-    this.ram        = 1; //GB
-    this.cores      = 1;
-
-    this.name       = name;
-
-    this.totalMoneyGenerated    = 0;
-    this.onlineTimeSeconds      = 0;
-
-    this.moneyGainRatePerSecond = 0;
-}
-
-HacknetNode.prototype.updateMoneyGainRate = function() {
-    //How much extra $/s is gained per level
-    var gainPerLevel = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMoneyGainPerLevel;
-
-    this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
-                                  Math.pow(1.035, this.ram-1) *
-                                  ((this.cores + 5) / 6) *
-                                  _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_money_mult *
-                                  _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].HacknetNodeMoney;
-    if (isNaN(this.moneyGainRatePerSecond)) {
-        this.moneyGainRatePerSecond = 0;
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_5__["dialogBoxCreate"])("Error in calculating Hacknet Node production. Please report to game developer");
-    }
-
-    updateTotalHacknetProduction();
-}
-
-HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
-    levels = Math.round(levels);
-    if (isNaN(levels) || levels < 1) {return 0;}
-    var mult = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeUpgradeLevelMult;
-    var totalMultiplier = 0; //Summed
-    var currLevel = this.level;
-    for (var i = 0; i < levels; ++i) {
-        totalMultiplier += Math.pow(mult, currLevel);
-        ++currLevel;
-    }
-    return _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].BaseCostForHacknetNode / 2 * totalMultiplier * _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_level_cost_mult;
-}
-
-//Wrapper function for Netscript
-HacknetNode.prototype.getLevelUpgradeCost = function(levels=1) {
-    return this.calculateLevelUpgradeCost(levels);
-}
-
-HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
-    levels = Math.round(levels);
-    var cost = this.calculateLevelUpgradeCost(levels);
-    if (isNaN(cost) || levels < 0) {return false;}
-    if (this.level + levels > _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel) {
-        var diff = Math.max(0, _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel - this.level);
-        return this.purchaseLevelUpgrade(diff);
-    }
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {return false;}
-    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].loseMoney(cost);
-    this.level += levels;
-    this.updateMoneyGainRate();
-    return true;
-}
-
-//Wrapper function for Netscript
-HacknetNode.prototype.upgradeLevel = function(levels=1) {
-    return this.purchaseLevelUpgrade(levels);
-}
-
-HacknetNode.prototype.calculateRamUpgradeCost = function() {
-    var numUpgrades = Math.log2(this.ram);
-
-    //Calculate cost
-    //Base cost of RAM is 50k per 1GB, increased by some multiplier for each time RAM is upgraded
-    var baseCost = this.ram * _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].BaseCostFor1GBOfRamHacknetNode;
-    var mult = Math.pow(_Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeUpgradeRamMult, numUpgrades);
-    return baseCost * mult * _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_ram_cost_mult;
-}
-
-//Wrapper function for Netscript
-HacknetNode.prototype.getRamUpgradeCost = function() {
-    return this.calculateRamUpgradeCost();
-}
-
-HacknetNode.prototype.purchaseRamUpgrade = function() {
-    var cost = this.calculateRamUpgradeCost();
-    if (isNaN(cost)) {return false;}
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {return false;}
-    if (this.ram >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxRam) {return false;}
-    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].loseMoney(cost);
-    this.ram *= 2; //Ram is always doubled
-    this.updateMoneyGainRate();
-    return true;
-}
-
-//Wrapper function for Netscript
-HacknetNode.prototype.upgradeRam = function() {
-    return this.purchaseRamUpgrade();
-}
-
-HacknetNode.prototype.calculateCoreUpgradeCost = function() {
-    var coreBaseCost = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].BaseCostForHacknetNodeCore;
-    var mult = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeUpgradeCoreMult;
-    return coreBaseCost * Math.pow(mult, this.cores-1) * _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_core_cost_mult;
-}
-
-//Wrapper function for Netscript
-HacknetNode.prototype.getCoreUpgradeCost = function() {
-    return this.calculateCoreUpgradeCost();
-}
-
-HacknetNode.prototype.purchaseCoreUpgrade = function() {
-    var cost = this.calculateCoreUpgradeCost();
-    if (isNaN(cost)) {return false;}
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {return false;}
-    if (this.cores >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxCores) {return false;}
-    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].loseMoney(cost);
-    ++this.cores;
-    this.updateMoneyGainRate();
-    return true;
-}
-
-//Wrapper function for Netscript
-HacknetNode.prototype.upgradeCore = function() {
-    return this.purchaseCoreUpgrade();
-}
-
-/* Saving and loading HackNets */
-HacknetNode.prototype.toJSON = function() {
-    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__["Generic_toJSON"])("HacknetNode", this);
-}
-
-HacknetNode.fromJSON = function(value) {
-    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__["Generic_fromJSON"])(HacknetNode, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__["Reviver"].constructors.HacknetNode = HacknetNode;
-
-
-function purchaseHacknet() {
-    /* INTERACTIVE TUTORIAL */
-    if (_InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__["iTutorialIsRunning"]) {
-        if (_InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__["currITutorialStep"] == _InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__["iTutorialSteps"].HacknetNodesIntroduction) {
-            Object(_InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__["iTutorialNextStep"])();
-        } else {
-            return;
-        }
-    }
-
-    /* END INTERACTIVE TUTORIAL */
-
-    var cost = getCostOfNextHacknetNode();
-    if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {
-        //dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
-        return false;
-    }
-
-    //Auto generate a name for the node for now...TODO
-    var numOwned = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length;
-    var name = "hacknet-node-" + numOwned;
-    var node = new HacknetNode(name);
-    node.updateMoneyGainRate();
-
-    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].loseMoney(cost);
-    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.push(node);
-
-    displayHacknetNodesContent();
-    updateTotalHacknetProduction();
-    return numOwned;
-}
-
-//Calculates the total production from all HacknetNodes
-function updateTotalHacknetProduction() {
-    var total = 0;
-    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
-        total += _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].moneyGainRatePerSecond;
-    }
-    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].totalHacknetNodeProduction = total;
-}
-
-function getCostOfNextHacknetNode() {
-    //Cost increases exponentially based on how many you own
-    var numOwned = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length;
-    var mult = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodePurchaseNextMult;
-    return _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].BaseCostForHacknetNode * Math.pow(mult, numOwned) * _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_purchase_cost_mult;
-}
-
-var hacknetNodePurchaseMultiplier = 1;
-function updateHacknetNodesMultiplierButtons() {
-    var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
-    var mult5x = document.getElementById("hacknet-nodes-5x-multiplier");
-    var mult10x = document.getElementById("hacknet-nodes-10x-multiplier");
-    var multMax = document.getElementById("hacknet-nodes-max-multiplier");
-    mult1x.setAttribute("class", "a-link-button");
-    mult5x.setAttribute("class", "a-link-button");
-    mult10x.setAttribute("class", "a-link-button");
-    multMax.setAttribute("class", "a-link-button");
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length == 0) {
-        mult1x.setAttribute("class", "a-link-button-inactive");
-        mult5x.setAttribute("class", "a-link-button-inactive");
-        mult10x.setAttribute("class", "a-link-button-inactive");
-        multMax.setAttribute("class", "a-link-button-inactive");
-    } else if (hacknetNodePurchaseMultiplier == 1) {
-        mult1x.setAttribute("class", "a-link-button-inactive");
-    } else if (hacknetNodePurchaseMultiplier == 5) {
-        mult5x.setAttribute("class", "a-link-button-inactive");
-    } else if (hacknetNodePurchaseMultiplier == 10) {
-        mult10x.setAttribute("class", "a-link-button-inactive");
-    } else {
-        multMax.setAttribute("class", "a-link-button-inactive");
-    }
-}
-
-//Calculate the maximum number of times the Player can afford to upgrade
-//a Hacknet Node's level"
-function getMaxNumberLevelUpgrades(nodeObj) {
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(nodeObj.calculateLevelUpgradeCost(1))) {return 0;}
-    var min = 1;
-    var max = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel-1;
-    var levelsToMax = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel - nodeObj.level;
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax))) {
-        return levelsToMax;
-    }
-
-    while (min <= max) {
-        var curr = (min + max) / 2 | 0;
-        if (curr != _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel &&
-            _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.gt(nodeObj.calculateLevelUpgradeCost(curr)) &&
-            _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(nodeObj.calculateLevelUpgradeCost(curr+1))) {
-            return Math.min(levelsToMax, curr);
-        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(nodeObj.calculateLevelUpgradeCost(curr))) {
-            max = curr - 1;
-        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.gt(nodeObj.calculateLevelUpgradeCost(curr))) {
-            min = curr + 1;
-        } else {
-            return Math.min(levelsToMax, curr);
-        }
-    }
-}
-
-//Creates Hacknet Node DOM elements when the page is opened
-function displayHacknetNodesContent() {
-    //Update Hacknet Nodes button
-    var newPurchaseButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["clearEventListeners"])("hacknet-nodes-purchase-button");
-
-    newPurchaseButton.addEventListener("click", function() {
-        purchaseHacknet();
-        return false;
-    });
-
-    //Handle Purchase multiplier buttons
-    updateHacknetNodesMultiplierButtons();
-
-    //Remove all old hacknet Node DOM elements
-    var hacknetNodesList = document.getElementById("hacknet-nodes-list");
-        while (hacknetNodesList.firstChild) {
-        hacknetNodesList.removeChild(hacknetNodesList.firstChild);
-    }
-
-    //Then re-create them
-    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
-        createHacknetNodeDomElement(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]);
-    }
-    updateHacknetNodesContent();
-}
-
-//Update information on all Hacknet Node DOM elements
-function updateHacknetNodesContent() {
-    //Set purchase button to inactive if not enough money, and update its price display
-    var cost = getCostOfNextHacknetNode();
-    var purchaseButton = document.getElementById("hacknet-nodes-purchase-button");
-    purchaseButton.innerHTML = "Purchase Hacknet Node - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(cost, 2);
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {
-        purchaseButton.setAttribute("class", "a-link-button-inactive");
-    } else {
-        purchaseButton.setAttribute("class", "a-link-button");
-    }
-
-    //Update player's money
-    var moneyElem = document.getElementById("hacknet-nodes-money");
-    moneyElem.innerHTML = "Money: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.toNumber(), 2) + "<br>" +
-                          "Total production from all Hacknet Nodes: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].totalHacknetNodeProduction, 2) + " / second";
-
-    //Update information in each owned hacknet node
-    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
-        updateHacknetNodeDomElement(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]);
-    }
-}
-
-//Creates a single Hacknet Node DOM element
-function createHacknetNodeDomElement(nodeObj) {
-    var nodeName = nodeObj.name;
-
-    var listItem = document.createElement("li");
-    listItem.setAttribute("class", "hacknet-node");
-
-    var span = document.createElement("span");
-    span.style.display = "inline";
-
-    var buttonDiv = document.createElement("div");
-    buttonDiv.setAttribute("class", "hacknet-node-button-div");
-
-    //Text
-    var txt = document.createElement("p");
-    //txt.setAttribute("id", "hacknet-node-text-" + nodeName);
-    txt.id = "hacknet-node-text-" + nodeName;
-
-    //Upgrade buttons
-    var upgradeLevelButton = document.createElement("a");
-    var upgradeRamButton = document.createElement("a");
-    var upgradeCoreButton = document.createElement("a");
-
-    //upgradeLevelButton.setAttribute("id", "hacknet-node-upgrade-level-" + nodeName);
-    upgradeLevelButton.id = "hacknet-node-upgrade-level-" + nodeName;
-    upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
-    upgradeLevelButton.addEventListener("click", function() {
-        var numUpgrades = hacknetNodePurchaseMultiplier;
-        if (hacknetNodePurchaseMultiplier == 0) {
-            numUpgrades = getMaxNumberLevelUpgrades(nodeObj);
-        }
-        nodeObj.purchaseLevelUpgrade(numUpgrades);
-        updateHacknetNodesContent();
-        return false;
-    });
-    //upgradeRamButton.setAttribute("id", "hacknet-node-upgrade-ram-" + nodeName);
-    upgradeRamButton.id = "hacknet-node-upgrade-ram-" + nodeName;
-    upgradeRamButton.setAttribute("class", "a-link-button-inactive");
-    upgradeRamButton.addEventListener("click", function() {
-        nodeObj.purchaseRamUpgrade();
-        updateHacknetNodesContent();
-        return false;
-    });
-    //upgradeCoreButton.setAttribute("id", "hacknet-node-upgrade-core-" + nodeName);
-    upgradeCoreButton.id = "hacknet-node-upgrade-core-" + nodeName;
-    upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
-    upgradeCoreButton.addEventListener("click", function() {
-        nodeObj.purchaseCoreUpgrade();
-        updateHacknetNodesContent();
-        return false;
-    });
-
-    //Put all the components together in the li element
-    span.appendChild(txt);
-    buttonDiv.appendChild(upgradeLevelButton);
-    buttonDiv.appendChild(upgradeRamButton);
-    buttonDiv.appendChild(upgradeCoreButton);
-    span.appendChild(buttonDiv);
-    listItem.appendChild(span);
-
-    document.getElementById("hacknet-nodes-list").appendChild(listItem);
-
-    //Set the text and stuff inside the DOM element
-    updateHacknetNodeDomElement(nodeObj);
-}
-
-//Updates information on a single hacknet node DOM element
-function updateHacknetNodeDomElement(nodeObj) {
-    var nodeName = nodeObj.name;
-    var txt = document.getElementById("hacknet-node-text-" + nodeName);
-    if (txt == null) {throw new Error("Cannot find text element");}
-    txt.innerHTML = "Node name:  " + nodeName + "<br>" +
-                    "Production: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(nodeObj.totalMoneyGenerated, 2) +
-                                 " ($" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(nodeObj.moneyGainRatePerSecond, 2) + " / second) <br>" +
-                    "Level:      " + nodeObj.level + "<br>" +
-                    "RAM:        " + nodeObj.ram + "GB<br>" +
-                    "Cores:      " + nodeObj.cores;
-
-    //Upgrade level
-    var upgradeLevelButton = document.getElementById("hacknet-node-upgrade-level-" + nodeName);
-    if (upgradeLevelButton == null) {throw new Error("Cannot find upgrade level button element");}
-    if (nodeObj.level >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel) {
-        upgradeLevelButton.innerHTML = "MAX LEVEL";
-        upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
-    } else {
-        var multiplier = 0;
-        if (hacknetNodePurchaseMultiplier == 0) {
-            //Max
-            multiplier = getMaxNumberLevelUpgrades(nodeObj);
-        } else {
-            var levelsToMax = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel - nodeObj.level;
-            multiplier = Math.min(levelsToMax, hacknetNodePurchaseMultiplier);
-        }
-
-        var upgradeLevelCost = nodeObj.calculateLevelUpgradeCost(multiplier);
-        upgradeLevelButton.innerHTML = "Upgrade Hacknet Node Level x" + multiplier +
-                                       " - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(upgradeLevelCost, 2);
-        if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(upgradeLevelCost)) {
-            upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
-        } else {
-            upgradeLevelButton.setAttribute("class", "a-link-button");
-        }
-    }
-
-    //Upgrade RAM
-    var upgradeRamButton = document.getElementById("hacknet-node-upgrade-ram-" + nodeName);
-    if (upgradeRamButton == null) {throw new Error("Cannot find upgrade ram button element");}
-    if (nodeObj.ram >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxRam) {
-        upgradeRamButton.innerHTML = "MAX RAM";
-        upgradeRamButton.setAttribute("class", "a-link-button-inactive");
-    } else {
-        var upgradeRamCost = nodeObj.calculateRamUpgradeCost();
-        upgradeRamButton.innerHTML = "Upgrade Hacknet Node RAM - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(upgradeRamCost, 2);
-        if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(upgradeRamCost)) {
-            upgradeRamButton.setAttribute("class", "a-link-button-inactive");
-        } else {
-            upgradeRamButton.setAttribute("class", "a-link-button");
-        }
-    }
-
-    //Upgrade Cores
-    var upgradeCoreButton = document.getElementById("hacknet-node-upgrade-core-" + nodeName);
-    if (upgradeCoreButton == null) {throw new Error("Cannot find upgrade cores button element");}
-    if (nodeObj.cores >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxCores) {
-        upgradeCoreButton.innerHTML = "MAX CORES";
-        upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
-    } else {
-        var upgradeCoreCost = nodeObj.calculateCoreUpgradeCost();
-        upgradeCoreButton.innerHTML = "Purchase additional CPU Core - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(upgradeCoreCost, 2);
-        if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(upgradeCoreCost)) {
-            upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
-        } else {
-            upgradeCoreButton.setAttribute("class", "a-link-button");
-        }
-    }
-}
-
-function processAllHacknetNodeEarnings(numCycles) {
-    var total = 0;
-    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
-        total += processSingleHacknetNodeEarnings(numCycles, _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]);
-    }
-    return total;
-}
-
-function processSingleHacknetNodeEarnings(numCycles, nodeObj) {
-    var cyclesPerSecond = 1000 / _engine_js__WEBPACK_IMPORTED_MODULE_2__["Engine"]._idleSpeed;
-    var earningPerCycle = nodeObj.moneyGainRatePerSecond / cyclesPerSecond;
-    if (isNaN(earningPerCycle)) {
-        console.log("ERROR: Hacknet Node Calculated earnings is NaN");
-        earningPerCycle = 0;
-    }
-    var totalEarnings = numCycles * earningPerCycle;
-    nodeObj.totalMoneyGenerated += totalEarnings;
-    nodeObj.onlineTimeSeconds += (numCycles * (_engine_js__WEBPACK_IMPORTED_MODULE_2__["Engine"]._idleSpeed / 1000));
-    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].gainMoney(totalEarnings);
-    return totalEarnings;
-}
-
-function getHacknetNode(name) {
-    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
-        if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].name == name) {
-            return _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i];
-        }
-    }
-    return null;
-}
-
-
-
-
-/***/ }),
-/* 39 */
-/*!*************************!*\
-  !*** ./src/TextFile.js ***!
-  \*************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextFile", function() { return TextFile; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getTextFile", function() { return getTextFile; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createTextFile", function() { return createTextFile; });
-/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Server.js */ 10);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-
-
-
-
-function TextFile(fn="", txt="") {
-    this.fn = fn.endsWith(".txt") ? fn : fn + ".txt";
-    this.fn = this.fn.replace(/\s+/g, '');
-    this.text = String(txt);
-}
-
-TextFile.prototype.append = function(txt) {
-    this.text += String(txt);
-}
-
-TextFile.prototype.write = function(txt) {
-    this.text = String(txt);
-}
-
-TextFile.prototype.read = function() {
-    return this.txt;
-}
-
-TextFile.prototype.show = function() {
-    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_1__["dialogBoxCreate"])(this.fn + "<br><br>" + this.text, true);
-}
-
-TextFile.prototype.download = function() {
-    var filename = this.fn;
-    var file = new Blob([this.text], {type: 'text/plain'});
-    if (window.navigator.msSaveOrOpenBlob) {// IE10+
-        window.navigator.msSaveOrOpenBlob(file, filename);
-    } else { // Others
-        var a = document.createElement("a"),
-                url = URL.createObjectURL(file);
-        a.href = url;
-        a.download = this.fn;
-        document.body.appendChild(a);
-        a.click();
-        setTimeout(function() {
-            document.body.removeChild(a);
-            window.URL.revokeObjectURL(url);
-        }, 0);
-    }
-}
-
-TextFile.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_2__["Generic_toJSON"])("TextFile", this);
-}
-
-TextFile.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_2__["Generic_fromJSON"])(TextFile, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_2__["Reviver"].constructors.TextFile = TextFile;
-
-function getTextFile(fn, server) {
-    if (!fn.endsWith(".txt")) {fn += ".txt";}
-    for (var i = 0; i < server.textFiles.length; ++i) {
-        if (server.textFiles[i].fn === fn) {
-            return server.textFiles[i];
-        }
-    }
-    return null;
-}
-
-//Returns the TextFile object that was just created
-function createTextFile(fn, txt, server) {
-    if (getTextFile(fn, server) !== null) {
-        console.log("ERROR: createTextFile failed because the specified " +
-                    "server already has a text file with the same fn");
-        return;
-    }
-    var file = new TextFile(fn, txt);
-    server.textFiles.push(file);
-    return file;
-}
-
-function deleteTextFile(fn, server) {
-    if (!fn.endsWith(".txt")) {fn += ".txt";}
-    for (var i = 0; i < server.textFiles.length; ++i) {
-        if (server.textFiles[i].fn === fn) {
-            server.textFiles.splice(i, 1);
-            return true;
-        }
-    }
-    return false;
-}
-
-
-
-
-/***/ }),
-/* 40 */
-/*!**********************************!*\
-  !*** ./src/CompanyManagement.js ***!
-  \**********************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Corporation", function() { return Corporation; });
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 16);
-/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Faction.js */ 14);
-/* harmony import */ var _Literature_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Literature.js */ 53);
-/* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Location.js */ 4);
-/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/decimal.js */ 23);
-/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_6__);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10__);
-/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* State */
-var companyStates = ["START", "PURCHASE", "PRODUCTION", "SALE", "EXPORT"];
-function CorporationState() {
-    this.state = 0;
-}
-
-CorporationState.prototype.nextState = function() {
-    if (this.state < 0 || this.state >= companyStates.length) {
-        this.state = 0;
-    }
-
-    ++this.state;
-    if (this.state >= companyStates.length) {
-        this.state = 0;
-    }
-}
-
-CorporationState.prototype.getState = function() {
-    return companyStates[this.state];
-}
-
-CorporationState.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("CorporationState", this);
-}
-
-CorporationState.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(CorporationState, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.CorporationState = CorporationState;
-
-/* Constants */
-var TOTALSHARES = 1e9; //Total number of shares you have at your company
-var CyclesPerMarketCycle    = 75;
-var CyclesPerIndustryStateCycle = CyclesPerMarketCycle / companyStates.length;
-var SecsPerMarketCycle      = CyclesPerMarketCycle / 5;
-var Cities = ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"];
-var WarehouseInitialCost        = 5e9; //Initial purchase cost of warehouse
-var WarehouseInitialSize        = 100;
-var WarehouseUpgradeBaseCost    = 1e9;
-
-var OfficeInitialCost           = 4e9;
-var OfficeInitialSize           = 3;
-var OfficeUpgradeBaseCost       = 1e9;
-
-var BribeThreshold              = 100e12; //Money needed to be able to bribe for faction rep
-var BribeToRepRatio             = 1e9;   //Bribe Value divided by this = rep gain
-
-var ProductProductionCostRatio  = 5;    //Ratio of material cost of a product to its production cost
-
-function Material(params={}) {
-    this.name = params.name ? params.name : "";
-    this.qty    = 0; //Quantity
-    this.qlt    = 0; //Quality, unbounded
-    this.dmd    = 0; //Demand, 0-100?
-    this.dmdR   = 0; //Range of possible demand
-    this.cmp    = 0; //Competition, 0-100
-    this.cmpR   = 0; //Range of possible competition
-    this.mv     = 0; //Maximum Volatility of stats
-
-    //Markup. Determines how high of a price you can charge on the material
-    //compared to the market price (bCost) based on quality
-    //Quality is divided by this to determine markup limits
-    //e.g if mku is 10 and quality is 100 then you can mark up prices by 100/10 = 10
-    //without consequences
-    this.mku    = 0;
-
-    this.buy = 0; //How much of this material is being bought per second
-    this.sll = 0; //How much of this material is being sold per second
-    this.prd = 0; //How much of this material is being produced per second
-    this.exp = []; //Exports of this material to another warehouse/industry
-    this.totalExp = 0; //Total export amount for last cycle
-    this.imp = 0;
-    this.bCost = 0; //$ Cost/sec to buy material
-    this.sCost = 0; //$ Cost/sec to sell material
-
-    //[Whether production/sale is limited, limit amount]
-    this.prdman = [false, 0]; //Production for this material is manually limited
-    this.sllman = [false, 0]; //Sale of this material is manually limited
-    this.init();
-}
-
-Material.prototype.init = function(mats={}) {
-    switch(this.name) {
-        case "Water":
-            this.dmd = 75; this.dmdR = [65, 85];
-            this.cmp = 50; this.cmpR = [40, 60];
-            this.bCost = 1000; this.mv = 0.2;
-            this.mku = 6;
-            break;
-        case "Energy":
-            this.dmd = 90; this.dmdR = [80, 100];
-            this.cmp = 80; this.cmpR = [65, 95];
-            this.bCost = 1500; this.mv = 0.2;
-            this.mku = 6;
-            break;
-        case "Food":
-            this.dmd = 80; this.dmdR = [70, 90];
-            this.cmp = 60; this.cmpR = [35, 85];
-            this.bCost = 5000; this.mv = 1;
-            this.mku = 3;
-            break;
-        case "Plants":
-            this.dmd = 70; this.dmdR = [20, 90];
-            this.cmp = 50; this.cmpR = [30, 70];
-            this.bCost = 3000; this.mv = 0.6;
-            this.mku = 3.75;
-            break;
-        case "Metal":
-            this.dmd = 80; this.dmdR = [75, 85];
-            this.cmp = 70; this.cmpR = [60, 80];
-            this.bCost = 2650; this.mv = 1;
-            this.mku = 6;
-            break;
-        case "Hardware":
-            this.dmd = 85; this.dmdR = [80, 90];
-            this.cmp = 80; this.cmpR = [65, 95];
-            this.bCost = 4000; this.mv = 0.5; //Less mv bc its processed twice
-            this.mku = 1;
-            break;
-        case "Chemicals":
-            this.dmd = 55; this.dmdR = [40, 70];
-            this.cmp = 60; this.cmpR = [40, 80];
-            this.bCost = 6750; this.mv = 1.2;
-            this.mku = 2;
-            break;
-        case "Real Estate":
-            this.dmd = 50; this.dmdR = [5, 100];
-            this.cmp = 50; this.cmpR = [25, 75];
-            this.bCost = 16e3; this.mv = 1.5; //Less mv bc its processed twice
-            this.mku = 1.5;
-            break;
-        case "Drugs":
-            this.dmd = 60; this.dmdR = [45, 75];
-            this.cmp = 70; this.cmpR = [40, 100];
-            this.bCost = 8e3; this.mv = 1.6;
-            this.mku = 1;
-            break;
-        case "Robots":
-            this.dmd = 90; this.dmdR = [80, 100];
-            this.cmp = 90; this.cmpR = [80, 100];
-            this.bCost = 20e3; this.mv = 0.5; //Less mv bc its processed twice
-            this.mku = 1;
-            break;
-        case "AI Cores":
-            this.dmd = 90; this.dmdR = [80, 100];
-            this.cmp = 90; this.cmpR = [80, 100];
-            this.bCost = 27e3; this.mv = 0.8; //Less mv bc its processed twice
-            this.mku = 0.5;
-            break;
-        case "Scientific Research":
-            break;
-        default:
-            console.log("Invalid material type in init(): " + this.name);
-            break;
-    }
-}
-
-//Process change in demand, competition, and buy cost of this material
-Material.prototype.processMarket = function() {
-    //This 1st random check determines whether competition increases or decreases
-    //More competition = lower market price
-    var v = (Math.random() * this.mv) / 100;
-    var pv = (Math.random() * this.mv) / 300;
-    if (Math.random() < 0.42) {
-        this.cmp *= (1+v);
-        if (this.cmp > this.cmpR[1]) {this.cmp = this.cmpR[1]};
-        this.bCost *= (1-pv);
-    } else {
-        this.cmp *= (1-v);
-        if (this.cmp < this.cmpR[0]) {this.cmp = this.cmpR[0];}
-        this.bCost *= (1+pv);
-    }
-
-    //This 2nd random check determines whether demand increases or decreases
-    //More demand = higher market price
-    v = (Math.random() * this.mv) / 100;
-    pv = (Math.random() * this.mv) / 300;
-    if (Math.random() < 0.45) {
-        this.dmd *= (1+v);
-        if (this.dmd > this.dmdR[1]) {this.dmd = this.dmdR[1];}
-        this.bCost *= (1+pv);
-    } else {
-        this.dmd *= (1-v);
-        if (this.dmd < this.dmdR[0]) {this.dmd = this.dmdR[0];}
-        this.bCost *= (1-pv);
-    }
-}
-
-Material.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Material", this);
-}
-
-Material.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Material, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Material = Material;
-
-//Map of material (by name) to their sizes (how much space it takes in warehouse)
-let MaterialSizes = {
-    Water:      0.05,
-    Energy:     0.01,
-    Food:       0.03,
-    Plants:     0.05,
-    Metal:      0.1,
-    Hardware:   0.06,
-    Chemicals:  0.05,
-    Drugs:      0.02,
-    Robots:     0.5,
-    "AICores": 0.1
-}
-
-function Product(params={}) {
-    this.name = params.name         ? params.name           : 0;
-    this.dmd = params.demand        ? params.demand         : 0;
-    this.cmp = params.competition   ? params.competition    : 0;
-    this.mku = params.markup        ? params.markup         : 0;
-    this.pCost = 0; //An estimate of how much money it costs to make this
-    this.sCost = 0; //How much this is selling for
-
-    //Variables for creation of product
-    this.fin = false;       //Finished being created
-    this.prog = 0;          //0-100% created
-    this.createCity = params.createCity ? params.createCity : ""; // City in which the product is being created
-    this.designCost     = params.designCost ? params.designCost : 0;
-    this.advCost        = params.advCost ? params.advCost : 0;
-
-    //Aggregate score for a product's 'rating' based on the other properties below
-    //The weighting of the other properties (performance, durability)
-    //differs between industries
-    this.rat = 0;
-
-    this.qlt = params.quality       ? params.quality        : 0;
-    this.per = params.performance   ? params.performance    : 0;
-    this.dur = params.durability    ? params.durability     : 0;
-    this.rel = params.reliability   ? params.reliability    : 0;
-    this.aes = params.aesthetics    ? params.aesthetics     : 0;
-    this.fea = params.features      ? params.features       : 0;
-
-    //Data refers to the production, sale, and quantity of the products
-    //These values are specific to a city
-    //The data is [qty, prod, sell]
-    this.data = {
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: [0, 0, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chongqing]: [0, 0, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: [0, 0, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: [0, 0, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: [0, 0, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: [0, 0, 0],
-    }
-
-    //Only applies for location-based products like restaurants/hospitals
-    this.loc = params.loc ? params.loc : 0;
-
-    //How much space it takes in the warehouse. Not applicable for all products
-    this.siz = params.size ? params.size : 0;
-
-    //Material requirements. An object that maps the name of a material to how much it requires
-    //to make 1 unit of the product.
-    this.reqMats = params.req           ? params.req            : {};
-
-    //[Whether production/sale is limited, limit amount]
-    this.prdman = {
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chongqing]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: [false, 0],
-    }
-
-    this.sllman = {
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chongqing]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: [false, 0],
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: [false, 0],
-    }
-}
-
-//empWorkMult is a multiplier that increases progress rate based on
-//productivity of employees
-Product.prototype.createProduct = function(marketCycles=1, empWorkMult=1) {
-    if (this.fin) {return;}
-    this.prog += (marketCycles * .01 * empWorkMult);
-}
-
-//'industry' is a reference to the industry that makes the product
-Product.prototype.finishProduct = function(employeeProd, industry) {
-    this.fin = true;
-
-    //Calculate properties
-    var progrMult = this.prog / 100;
-
-    var engrRatio   = employeeProd[EmployeePositions.Engineer] / employeeProd["total"],
-        mgmtRatio   = employeeProd[EmployeePositions.Management] / employeeProd["total"],
-        rndRatio    = employeeProd[EmployeePositions.RandD] / employeeProd["total"],
-        opsRatio    = employeeProd[EmployeePositions.Operations] / employeeProd["total"],
-        busRatio    = employeeProd[EmployeePositions.Business] / employeeProd["total"];
-    var designMult = 1 + (Math.pow(this.designCost, 0.1) / 100);
-    console.log("designMult: " + designMult);
-    var balanceMult = (1.2 * engrRatio) + (0.9 * mgmtRatio) + (1.3 * rndRatio) +
-                      (1.5 * opsRatio) + (busRatio);
-    var sciMult = 1 + (Math.pow(industry.sciResearch.qty, industry.sciFac) / 800);
-    var totalMult = progrMult * balanceMult * designMult * sciMult;
-
-    this.qlt = totalMult * ((0.10 * employeeProd[EmployeePositions.Engineer]) +
-                            (0.05 * employeeProd[EmployeePositions.Management]) +
-                            (0.05 * employeeProd[EmployeePositions.RandD]) +
-                            (0.02 * employeeProd[EmployeePositions.Operations]) +
-                            (0.02 * employeeProd[EmployeePositions.Business]));
-    this.per = totalMult * ((0.15 * employeeProd[EmployeePositions.Engineer]) +
-                            (0.02 * employeeProd[EmployeePositions.Management]) +
-                            (0.02 * employeeProd[EmployeePositions.RandD]) +
-                            (0.02 * employeeProd[EmployeePositions.Operations]) +
-                            (0.02 * employeeProd[EmployeePositions.Business]));
-    this.dur = totalMult * ((0.05 * employeeProd[EmployeePositions.Engineer]) +
-                            (0.02 * employeeProd[EmployeePositions.Management]) +
-                            (0.08 * employeeProd[EmployeePositions.RandD]) +
-                            (0.05 * employeeProd[EmployeePositions.Operations]) +
-                            (0.05 * employeeProd[EmployeePositions.Business]));
-    this.rel = totalMult * ((0.02 * employeeProd[EmployeePositions.Engineer]) +
-                            (0.08 * employeeProd[EmployeePositions.Management]) +
-                            (0.02 * employeeProd[EmployeePositions.RandD]) +
-                            (0.05 * employeeProd[EmployeePositions.Operations]) +
-                            (0.08 * employeeProd[EmployeePositions.Business]));
-    this.aes = totalMult * ((0.00 * employeeProd[EmployeePositions.Engineer]) +
-                            (0.08 * employeeProd[EmployeePositions.Management]) +
-                            (0.05 * employeeProd[EmployeePositions.RandD]) +
-                            (0.02 * employeeProd[EmployeePositions.Operations]) +
-                            (0.10 * employeeProd[EmployeePositions.Business]));
-    this.fea = totalMult * ((0.08 * employeeProd[EmployeePositions.Engineer]) +
-                            (0.05 * employeeProd[EmployeePositions.Management]) +
-                            (0.02 * employeeProd[EmployeePositions.RandD]) +
-                            (0.05 * employeeProd[EmployeePositions.Operations]) +
-                            (0.05 * employeeProd[EmployeePositions.Business]));
-    this.calculateRating(industry);
-    var advMult = 1 + (Math.pow(this.advCost, 0.1) / 100);
-    this.mku = 100 / (advMult * Math.pow((this.qlt + 0.001), 0.65) * (busRatio + mgmtRatio));
-    this.dmd = industry.awareness === 0 ? 20 : Math.min(100, advMult * (100 * (industry.popularity / industry.awareness)));
-    this.cmp = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(0, 70);
-
-    //Calculate the product's required materials
-    //For now, just set it to be the same as the requirements to make materials
-    for (var matName in industry.reqMats) {
-        if (industry.reqMats.hasOwnProperty(matName)) {
-            this.reqMats[matName] = industry.reqMats[matName];
-        }
-    }
-
-    //Calculate the product's size
-    //For now, just set it to be the same size as the requirements to make materials
-    this.siz = 0;
-    for (var matName in industry.reqMats) {
-        this.siz += MaterialSizes[matName] * industry.reqMats[matName];
-    }
-
-    //Delete unneeded variables
-    delete this.prog;
-    delete this.createCity;
-    delete this.designCost;
-    delete this.advCost;
-}
-
-
-Product.prototype.calculateRating = function(industry) {
-    var weights = ProductRatingWeights[industry.type];
-    if (weights == null) {
-        console.log("ERROR: Could not find product rating weights for: " + industry);
-        return;
-    }
-    this.rat = 0;
-    this.rat += weights.Quality     ? this.qlt * weights.Quality : 0;
-    this.rat += weights.Performance ? this.per * weights.Performance : 0;
-    this.rat += weights.Durability  ? this.dur * weights.Durability : 0;
-    this.rat += weights.Reliability ? this.rel * weights.Reliability : 0;
-    this.rat += weights.Aesthetics  ? this.aes * weights.Aesthetics : 0;
-    this.rat += weights.Features    ? this.fea * weights.Features : 0;
-}
-
-Product.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Product", this);
-}
-
-Product.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Product, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Product = Product;
-
-var Industries = {
-    Energy: "Energy",
-    Utilities: "Water Utilities",
-    Agriculture: "Agriculture",
-    Fishing: "Fishing",
-    Mining: "Mining",
-    Food: "Food",
-    Tobacco: "Tobacco",
-    Chemical: "Chemical",
-    Pharmaceutical: "Pharmaceutical",
-    Computer: "Computer Hardware",
-    Robotics: "Robotics",
-    Software: "Software",
-    Healthcare: "Healthcare",
-    RealEstate: "RealEstate",
-}
-
-var IndustryStartingCosts = {
-    Energy: 225e9,
-    Utilities: 150e9,
-    Agriculture: 40e9,
-    Fishing: 80e9,
-    Mining: 300e9,
-    Food: 10e9,
-    Tobacco: 20e9,
-    Chemical: 70e9,
-    Pharmaceutical: 200e9,
-    Computer: 500e9,
-    Robotics: 1e12,
-    Software: 25e9,
-    Healthcare: 750e9,
-    RealEstate: 600e9,
-}
-
-var IndustryDescriptions = {
-    Energy: "Engage in the production and distribution of energy.<br><br>" +
-            "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Energy).format("$0.000a") + "<br>" +
-            "Recommended starting Industry: NO",
-    Utilities: "Distributes water and provides wastewater services.<br><br>" +
-               "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Utilities).format("$0.000a") + "<br>" +
-               "Recommended starting Industry: NO",
-    Agriculture: "Cultive crops and breed livestock to produce food.<br><br>" +
-                 "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Agriculture).format("$0.000a") + "<br>" +
-                 "Recommended starting Industry: YES",
-    Fishing: "Produce food through the breeding and processing of fish and fish products<br><br>" +
-             "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Fishing).format("$0.000a") + "<br>" +
-             "Recommended starting Industry: NO",
-    Mining: "Extract and process metals from the earth.<br><br>" +
-            "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Mining).format("$0.000a") + "<br>" +
-            "Recommended starting Industry: NO",
-    Food: "Create your own restaurants all around the world.<br><br>" +
-          "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Food).format("$0.000a") + "<br>" +
-          "Recommended starting Industry: YES",
-    Tobacco: "Create and distribute tobacco and tobacco-related products.<br><br>" +
-             "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Tobacco).format("$0.000a") + "<br>" +
-             "Recommended starting Industry: YES",
-    Chemical: "Product industrial chemicals<br><br>" +
-              "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Chemical).format("$0.000a") + "<br>" +
-              "Recommended starting Industry: NO",
-    Pharmaceutical: "Discover, develop, and create new pharmaceutical drugs.<br><br>" +
-                    "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Pharmaceutical).format("$0.000a") + "<br>" +
-                    "Recommended starting Industry: NO",
-    Computer: "Develop and manufacture new computer hardware and networking infrastructures.<br><br>" +
-              "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Computer).format("$0.000a") + "<br>" +
-              "Recommended starting Industry: NO",
-    Robotics: "Develop and create robots.<br><br>" +
-              "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Robotics).format("$0.000a") + "<br>" +
-              "Recommended starting Industry: NO",
-    Software: "Develop computer software and create AI Cores.<br><br>" +
-              "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Software).format("$0.000a") + "<br>" +
-              "Recommended starting Industry: YES",
-    Healthcare: "Create and manage hospitals.<br><br>" +
-                "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Healthcare).format("$0.000a") + "<br>" +
-                "Recommended starting Industry: NO",
-    RealEstate: "Develop and manage real estate properties.<br><br>" +
-                "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.RealEstate).format("$0.000a") + "<br>" +
-                "Recommended starting Industry: NO",
-}
-
-var ProductRatingWeights = {
-    [Industries.Food]: {
-        Quality:        0.7,
-        Durability:     0.1,
-        Aesthetics:     0.2,
-    },
-    [Industries.Tobacco]: {
-        Quality:        0.4,
-        Durability:     0.2,
-        Reliability:    0.2,
-        Aesthetics:     0.2,
-    },
-    [Industries.Pharmaceutical]: {
-        Quality:        0.2,
-        Performance:    0.2,
-        Durability:     0.1,
-        Reliability:    0.3,
-        Features:       0.2,
-    },
-    [Industries.Computer]: {
-        Quality:        0.15,
-        Performance:    0.25,
-        Durability:     0.25,
-        Reliability:    0.2,
-        Aesthetics:     0.05,
-        Features:       0.1,
-    },
-    "Computer" : {  //Repeat
-        Quality:        0.15,
-        Performance:    0.25,
-        Durability:     0.25,
-        Reliability:    0.2,
-        Aesthetics:     0.05,
-        Features:       0.1,
-    },
-    [Industries.Robotics]: {
-        Quality:        0.1,
-        Performance:    0.2,
-        Durability:     0.2,
-        Reliability:    0.2,
-        Aesthetics:     0.1,
-        Features:       0.2,
-    },
-    [Industries.Software]: {
-        Quality:        0.2,
-        Performance:    0.2,
-        Reliability:    0.2,
-        Durability:     0.2,
-        Features:       0.2,
-    },
-    [Industries.Healthcare]: {
-        Quality:        0.4,
-        Performance:    0.1,
-        Durability:     0.1,
-        Reliability:    0.3,
-        Features:       0.1,
-    },
-    [Industries.RealEstate]: {
-        Quality:        0.2,
-        Durability:     0.25,
-        Reliability:    0.1,
-        Aesthetics:     0.35,
-        Features:       0.1,
-    }
-}
-
-//Industry upgrades
-//The structure is:
-//  [index in array, base price, price mult, benefit mult (if applicable), name, desc]
-var IndustryUpgrades = {
-    "0":    [0, 500e3, 1, 1.05,
-            "Coffee", "Provide your employees with coffee, increasing their energy by 5%."],
-    "1":    [1, 1e9, 1.06, 1.03,
-            "AdVert.Inc", "Hire AdVert.Inc to advertise your company. Each level of " +
-            "this upgrade grants your company a static increase of 3 and 1 to its awareness and " +
-            "popularity, respectively. It will then increase your company's awareness by 1%, and its popularity " +
-            "by a random percentage between 1% and 3%. These effects are increased by other upgrades " +
-            "that increase the power of your advertising."]
-}
-
-var empManualAssignmentModeActive = false;
-function Industry(params={}) {
-    this.offices = { //Maps locations to offices. 0 if no office at that location
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: 0,
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chongqing]: 0,
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: new OfficeSpace({
-            loc:_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12,
-            size:OfficeInitialSize,
-        }),
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: 0,
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: 0,
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: 0
-    };
-
-    this.warehouses = { //Maps locations to warehouses. 0 if no warehouse at that location
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: 0,
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chonqing]: 0,
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: new Warehouse({
-            loc:_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12,
-            size: WarehouseInitialSize,
-        }),
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: 0,
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: 0,
-        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: 0
-    };
-
-    this.name   = params.name ? params.name : 0;
-    this.type   = params.type ? params.type : 0;
-
-    this.sciResearch    = new Material({name: "Scientific Research"});
-
-    //A map of the NAME of materials required to create produced materials to
-    //how many are needed to produce 1 unit of produced materials
-    this.reqMats = {};
-
-    //An array of the name of materials being produced
-    this.prodMats = [];
-
-    this.products  = {};
-    this.makesProducts = false;
-
-    this.awareness      = 0;
-    this.popularity     = 0; //Should always be less than awareness
-    this.startingCost   = 0;
-
-    /* The following are factors for how much production/other things are increased by
-       different factors. The production increase always has diminishing returns,
-       and they are all reprsented by exponentials of < 1 (e.g x ^ 0.5, x ^ 0.8)
-       The number for these represent the exponential. A lower number means more
-       diminishing returns */
-    this.reFac      = 0; //Real estate Factor
-    this.sciFac     = 0; //Scientific Research Factor, affects quality
-    this.hwFac      = 0; //Hardware factor
-    this.robFac     = 0; //Robotics Factor
-    this.aiFac      = 0; //AI Cores factor;
-    this.advFac     = 0; //Advertising factor, affects sales
-
-    this.prodMult   = 0; //Production multiplier
-
-    //Financials
-    this.lastCycleRevenue   = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-    this.lastCycleExpenses  = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-    this.thisCycleRevenue   = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-    this.thisCycleExpenses  = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-
-    //Upgrades
-    var numUpgrades = Object.keys(IndustryUpgrades).length;
-    this.upgrades = Array(numUpgrades).fill(0);
-
-    this.state = "START";
-    this.newInd = true;
-
-    this.init();
-}
-
-Industry.prototype.init = function() {
-    //Set the unique properties of an industry (how much its affected by real estate/scientific research, etc.)
-    this.startingCost = IndustryStartingCosts[this.type];
-    switch (this.type) {
-        case Industries.Energy:
-            this.reFac  = 0.65;
-            this.sciFac = 0.7;
-            this.robFac = 0.05;
-            this.aiFac  = 0.3;
-            this.advFac = 0.08;
-            this.reqMats = {
-                "Hardware": 0.1,
-                "Metal":    0.2,
-            };
-            this.prodMats = ["Energy"];
-            break;
-        case Industries.Utilities:
-        case "Utilities":
-            this.reFac  = 0.5;
-            this.sciFac = 0.6;
-            this.robFac = 0.4;
-            this.aiFac  = 0.4;
-            this.advFac = 0.08;
-            this.reqMats = {
-                "Hardware": 0.1,
-                "Metal":    0.1,
-            }
-            this.prodMats = ["Water"];
-            break;
-        case Industries.Agriculture:
-            this.reFac  = 0.75;
-            this.sciFac = 0.5;
-            this.hwFac  = 0.2;
-            this.robFac = 0.3;
-            this.aiFac  = 0.3;
-            this.advFac = 0.04;
-            this.reqMats = {
-                "Water":    0.5,
-                "Energy":   0.5,
-            }
-            this.prodMats = ["Plants", "Food"];
-            break;
-        case Industries.Fishing:
-            this.reFac  = 0.15;
-            this.sciFac = 0.35;
-            this.hwFac  = 0.35;
-            this.robFac = 0.5;
-            this.aiFac  = 0.2;
-            this.advFac = 0.08;
-            this.reqMats = {
-                "Energy":   0.5,
-            }
-            this.prodMats = ["Food"];
-            break;
-        case Industries.Mining:
-            this.reFac  = 0.3;
-            this.sciFac = 0.26;
-            this.hwFac  = 0.4;
-            this.robFac = 0.45;
-            this.aiFac  = 0.45;
-            this.advFac = 0.06;
-            this.reqMats = {
-                "Energy":   0.8,
-            }
-            this.prodMats = ["Metal"];
-            break;
-        case Industries.Food:
-            //reFac is unique for this bc it diminishes greatly per city. Handle this separately in code?
-            this.sciFac = 0.12;
-            this.hwFac  = 0.15;
-            this.robFac = 0.3;
-            this.aiFac  = 0.25;
-            this.advFac = 0.25;
-            this.reFac  = 0.05;
-            this.reqMats = {
-                "Food":     0.5,
-                "Water":    0.5,
-                "Energy":   0.2,
-            }
-            this.makesProducts = true;
-            break;
-        case Industries.Tobacco:
-            this.reFac  = 0.15;
-            this.sciFac = 0.75;
-            this.hwFac  = 0.15;
-            this.robFac = 0.2;
-            this.aiFac  = 0.15;
-            this.advFac = 0.2;
-            this.reqMats = {
-                "Plants":   1,
-                "Water":    0.2,
-            }
-            this.makesProducts = true;
-            break;
-        case Industries.Chemical:
-            this.reFac  = 0.25;
-            this.sciFac = 0.75;
-            this.hwFac  = 0.2;
-            this.robFac = 0.25;
-            this.aiFac  = 0.2;
-            this.advFac = 0.07;
-            this.reqMats = {
-                "Plants":   1,
-                "Energy":   0.5,
-                "Water":    0.5,
-            }
-            this.prodMats = ["Chemicals"];
-            break;
-        case Industries.Pharmaceutical:
-            this.reFac  = 0.05;
-            this.sciFac = 0.8;
-            this.hwFac  = 0.15;
-            this.robFac = 0.25;
-            this.aiFac  = 0.2;
-            this.advFac = 0.16;
-            this.reqMats = {
-                "Chemicals":    2,
-                "Energy":       1,
-                "Water":        0.5,
-            }
-            this.prodMats = ["Drugs"];
-            this.makesProducts = true;
-            break;
-        case Industries.Computer:
-        case "Computer":
-            this.reFac  = 0.2;
-            this.sciFac = 0.62;
-            this.robFac = 0.36;
-            this.aiFac  = 0.19;
-            this.advFac = 0.17;
-            this.reqMats = {
-                "Metal":    2.5,
-                "Energy":   1,
-            }
-            this.prodMats = ["Hardware"];
-            this.makesProducts = true;
-            break;
-        case Industries.Robotics:
-            this.reFac  = 0.32;
-            this.sciFac = 0.65;
-            this.aiFac  = 0.36;
-            this.advFac = 0.18;
-            this.hwFac  = 0.19;
-            this.reqMats = {
-                "Hardware":     5,
-                "Energy":       3,
-            }
-            this.prodMats = ["Robots"];
-            this.makesProducts = true;
-            break;
-        case Industries.Software:
-            this.sciFac = 0.62;
-            this.advFac = 0.16;
-            this.hwFac  = 0.25;
-            this.reFac  = 0.1;
-            this.aiFac  = 0.1;
-            this.robFac = 0.05;
-            this.reqMats = {
-                "Hardware":     0.5,
-                "Energy":       1,
-            }
-            this.prodMats = ["AICores"];
-            this.makesProducts = true;
-            break;
-        case Industries.Healthcare:
-            this.reFac  = 0.1;
-            this.sciFac = 0.75;
-            this.advFac = 0.11;
-            this.hwFac  = 0.1;
-            this.robFac = 0.1;
-            this.aiFac  = 0.1;
-            this.reqMats = {
-                "Robots":       10,
-                "AICores":     5,
-                "Energy":       5,
-                "Water":        5,
-            }
-            this.makesProducts = true;
-            break;
-        case Industries.RealEstate:
-            this.robFac = 0.6;
-            this.aiFac  = 0.6;
-            this.advFac = 0.25;
-            this.sciFac = 0.05;
-            this.hwFac  = 0.05;
-            this.reqMats = {
-                "Metal":    20,
-                "Energy":   10,
-                "Water":    10,
-                "Hardware": 5
-            }
-            this.prodMats = ["RealEstate"];
-            this.makesProducts = true;
-            break;
-        default:
-            console.log("ERR: Invalid Industry Type passed into Industry.init(): " + this.type);
-            return;
-    }
-}
-
-Industry.prototype.getProductDescriptionText = function() {
-    if (!this.makesProducts) {return;}
-    switch (this.type) {
-        case Industries.Food:
-            return "create and manage restaurants";
-            break;
-        case Industries.Tobacco:
-            return "create tobacco and tobacco-related products";
-            break;
-        case Industries.Pharmaceutical:
-            return "develop new pharmaceutical drugs";
-            break;
-        case Industries.Computer:
-        case "Computer":
-            return "create new computer hardware and networking infrastructures";
-            break;
-        case Industries.Robotics:
-            return "build specialized robots and robot-related products";
-            break;
-        case Industries.Software:
-            return "develop computer software";
-            break;
-        case Industries.HealthCare:
-            return "build and manage hospitals";
-            break;
-        case Industries.RealEstate:
-            return "develop and manage real estate properties";
-            break;
-        default:
-            console.log("ERROR: Invalid industry type in Industry.getProductDescriptionText");
-            return "";
-    }
-}
-
-//Calculates the values that factor into the production and properties of
-//materials/products (such as quality, etc.)
-Industry.prototype.calculateProductionFactors = function() {
-    var multSum = 0;
-    for (var i = 0; i < Cities.length; ++i) {
-        var city = Cities[i];
-        var warehouse = this.warehouses[city];
-        if (!(warehouse instanceof Warehouse)) {
-            continue;
-        }
-
-        var materials = warehouse.materials,
-            office = this.offices[city];
-
-        var cityMult =  Math.pow(0.002 * materials.RealEstate.qty+1, this.reFac) *
-                        Math.pow(0.002 * materials.Hardware.qty+1, this.hwFac) *
-                        Math.pow(0.002 * materials.Robots.qty+1, this.robFac) *
-                        Math.pow(0.002 * materials.AICores.qty+1, this.aiFac);
-        multSum += Math.pow(cityMult, 0.73);
-    }
-
-    multSum < 1 ? this.prodMult = 1 : this.prodMult = multSum;
-}
-
-Industry.prototype.updateWarehouseSizeUsed = function(warehouse) {
-    if (warehouse instanceof Warehouse) {
-        //This resets the size back to 0 and then accounts for materials
-        warehouse.updateMaterialSizeUsed();
-    }
-
-    for (var prodName in this.products) {
-        if (this.products.hasOwnProperty(prodName)) {
-            var prod = this.products[prodName];
-            warehouse.sizeUsed += (prod.data[warehouse.loc][0] * prod.siz);
-            if (prod.data[warehouse.loc][0] > 0) {
-                warehouse.breakdown += (prodName + ": " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(prod.data[warehouse.loc][0] * prod.siz, 0) + "<br>");
-            }
-        }
-    }
-}
-
-Industry.prototype.process = function(marketCycles=1, state, company) {
-    this.state = state;
-
-    //At the start of a cycle, store and reset revenue/expenses
-    //Then calculate salaries and processs the markets
-    if (state === "START") {
-        if (isNaN(this.thisCycleRevenue) || isNaN(this.thisCycleExpenses)) {
-            console.log("ERROR: NaN in Corporation's computed revenue/expenses");
-            console.log(this.thisCycleRevenue.toString());
-            console.log(this.thisCycleExpenses.toString());
-            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Something went wrong when compting Corporation's revenue/expenses. This is a bug. Please report to game developer");
-            this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-            this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-        }
-        this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(marketCycles * SecsPerMarketCycle);
-        this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(marketCycles * SecsPerMarketCycle);
-        this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-        this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-
-        //Once you start making revenue, the player should no longer be
-        //considered new, and therefore no longer needs the 'tutorial' UI elements
-        if (this.lastCycleRevenue.gt(0)) {this.newInd = false;}
-
-        //Process offices (and the employees in them)
-        var employeeSalary = 0;
-        for (var officeLoc in this.offices) {
-            if (this.offices.hasOwnProperty(officeLoc) &&
-                this.offices[officeLoc] instanceof OfficeSpace) {
-                employeeSalary += this.offices[officeLoc].process(marketCycles, {industry:this, corporation:company});
-            }
-        }
-        this.thisCycleExpenses = this.thisCycleExpenses.plus(employeeSalary);
-
-        //Process change in demand/competition of materials/products
-        this.processMaterialMarket(marketCycles);
-        this.processProductMarket(marketCycles);
-
-        //Process loss of popularity
-        this.popularity -= (marketCycles * .0001);
-        this.popularity = Math.max(0, this.popularity);
-
-        //Process Dreamsense gains
-        var popularityGain = company.getDreamSenseGain(), awarenessGain = popularityGain * 4;
-        if (popularityGain > 0) {
-            this.popularity += (popularityGain * marketCycles);
-            this.awareness += (awarenessGain * marketCycles);
-        }
-
-        return;
-    }
-
-    //Process production, purchase, and import/export of materials
-    var res = this.processMaterials(marketCycles, company);
-    this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
-    this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
-
-    //Process creation, production & sale of products
-    res = this.processProducts(marketCycles, company);
-    this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
-    this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
-
-}
-
-//Process change in demand and competition for this industry's materials
-Industry.prototype.processMaterialMarket = function(marketCycles=1) {
-    //References to prodMats and reqMats
-    var reqMats = this.reqMats, prodMats = this.prodMats;
-
-    //Only 'process the market' for materials that this industry deals with
-    for (var i = 0; i < Cities.length; ++i) {
-        //If this industry has a warehouse in this city, process the market
-        //for every material this industry requires or produces
-        if (this.warehouses[Cities[i]] instanceof Warehouse) {
-            var wh = this.warehouses[Cities[i]];
-            for (var name in reqMats) {
-                if (reqMats.hasOwnProperty(name)) {
-                    wh.materials[name].processMarket();
-                }
-            }
-
-            //Produced materials are stored in an array
-            for (var foo = 0; foo < prodMats.length; ++foo) {
-                wh.materials[prodMats[foo]].processMarket();
-            }
-
-            //Process these twice because these boost production
-            wh.materials["Hardware"].processMarket();
-            wh.materials["Robots"].processMarket();
-            wh.materials["AICores"].processMarket();
-            wh.materials["RealEstate"].processMarket();
-        }
-    }
-}
-
-//Process change in demand and competition for this industry's products
-Industry.prototype.processProductMarket = function(marketCycles=1) {
-    //Demand gradually decreases, and competition gradually increases
-    for (var name in this.products) {
-        if (this.products.hasOwnProperty(name)) {
-            var product = this.products[name];
-            var change = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(1, 3) * 0.0004;
-            if (this.type === Industries.Pharmaceutical || this.type === Industries.Software ||
-                this.type === Industries.Robotics) {
-                change *= 3;
-            }
-            change *= marketCycles;
-            product.dmd -= change;
-            product.cmp += change;
-            product.cmp = Math.min(product.cmp, 99.99);
-            product.dmd = Math.max(product.dmd, 0.001);
-        }
-    }
-}
-
-//Process production, purchase, and import/export of materials
-Industry.prototype.processMaterials = function(marketCycles=1, company) {
-    var revenue = 0, expenses = 0, industry = this;
-    this.calculateProductionFactors();
-
-    //At the start of the export state, set the imports of everything to 0
-    if (this.state === "EXPORT") {
-        for (var i = 0; i < Cities.length; ++i) {
-            var city = Cities[i], office = this.offices[city];
-            if (!(this.warehouses[city] instanceof Warehouse)) {
-                continue;
-            }
-            var warehouse = this.warehouses[city];
-            for (var matName in warehouse.materials) {
-                if (warehouse.materials.hasOwnProperty(matName)) {
-                    var mat = warehouse.materials[matName];
-                    mat.imp = 0;
-                }
-            }
-        }
-    }
-
-    for (var i = 0; i < Cities.length; ++i) {
-        var city = Cities[i], office = this.offices[city];
-
-        if (this.warehouses[city] instanceof Warehouse) {
-            var warehouse = this.warehouses[city];
-
-            switch(this.state) {
-
-            case "PURCHASE":
-            /* Process purchase of materials */
-            for (var matName in warehouse.materials) {
-                if (warehouse.materials.hasOwnProperty(matName)) {
-                    (function(matName, ind) {
-                    var mat = warehouse.materials[matName];
-                    var buyAmt, maxAmt;
-                    if (warehouse.smartSupplyEnabled && Object.keys(ind.reqMats).includes(matName)) {
-                        //Smart supply tracker is stored as per second rate
-                        mat.buy = ind.reqMats[matName] * warehouse.smartSupplyStore;
-                        buyAmt = mat.buy * SecsPerMarketCycle * marketCycles;
-                    } else {
-                        buyAmt = (mat.buy * SecsPerMarketCycle * marketCycles);
-                    }
-
-                    if (matName == "RealEstate") {
-                        maxAmt = buyAmt;
-                    } else {
-                        maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / MaterialSizes[matName]);
-                    }
-                    var buyAmt = Math.min(buyAmt, maxAmt);
-                    if (buyAmt > 0) {
-                        mat.qty += buyAmt;
-                        expenses += (buyAmt * mat.bCost);
-                    }
-                })(matName, industry);
-                    this.updateWarehouseSizeUsed(warehouse);
-                }
-            } //End process purchase of materials
-            break;
-
-            case "PRODUCTION":
-            warehouse.smartSupplyStore = 0; //Reset smart supply amount
-
-            /* Process production of materials */
-            if (this.prodMats.length > 0) {
-                var mat = warehouse.materials[this.prodMats[0]];
-                //Calculate the maximum production of this material based
-                //on the office's productivity
-                var maxProd = this.getOfficeProductivity(office) * this.prodMult * company.getProductionMultiplier(), prod;
-
-                if (mat.prdman[0]) {
-                    //Production is manually limited
-                    prod = Math.min(maxProd, mat.prdman[1]);
-                } else {
-                    prod = maxProd;
-                }
-                prod *= (SecsPerMarketCycle * marketCycles); //Convert production from per second to per market cycle
-                //Calculate net change in warehouse storage making
-                //the produced materials will cost
-                var totalMatSize = 0;
-                for (var tmp = 0; tmp < this.prodMats.length; ++tmp) {
-                    totalMatSize += (MaterialSizes[this.prodMats[tmp]]);
-                }
-                for (var reqMatName in this.reqMats) {
-                    if (this.reqMats.hasOwnProperty(reqMatName)) {
-                        var normQty = this.reqMats[reqMatName];
-                        totalMatSize -= (MaterialSizes[reqMatName] * normQty);
-                    }
-                }
-                //If not enough space in warehouse, limit the amount of produced materials
-                if (totalMatSize > 0) {
-                    var maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / totalMatSize);
-                    prod = Math.min(maxAmt, prod);
-                }
-
-                if (prod < 0) {prod = 0;}
-
-                //Keep track of production for smart supply (/s)
-                warehouse.smartSupplyStore += (prod / (SecsPerMarketCycle * marketCycles));
-
-                //Make sure we have enough resource to make our materials
-                var producableFrac = 1;
-                for (var reqMatName in this.reqMats) {
-                    if (this.reqMats.hasOwnProperty(reqMatName)) {
-                        var req = this.reqMats[reqMatName] * prod;
-                        if (warehouse.materials[reqMatName].qty < req) {
-                            producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req);
-                        }
-                    }
-                }
-                if (producableFrac <= 0) {producableFrac = 0; prod = 0;}
-
-                //Make our materials if they are producable
-                if (producableFrac > 0 && prod > 0) {
-                    for (var reqMatName in this.reqMats) {
-                        if (this.reqMats.hasOwnProperty(reqMatName)) {
-                            var reqMatQtyNeeded = (this.reqMats[reqMatName] * prod * producableFrac);
-                            warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
-                            warehouse.materials[reqMatName].prd = 0;
-                            warehouse.materials[reqMatName].prd -= reqMatQtyNeeded / (SecsPerMarketCycle * marketCycles);
-                        }
-                    }
-                    for (var j = 0; j < this.prodMats.length; ++j) {
-                        warehouse.materials[this.prodMats[j]].qty += (prod * producableFrac);
-                        warehouse.materials[this.prodMats[j]].qlt =
-                            (office.employeeProd[EmployeePositions.Engineer] / 100 +
-                             Math.pow(this.sciResearch.qty, this.sciFac) +
-                             Math.pow(warehouse.materials["AICores"].qty, this.aiFac) / 10e3);
-                    }
-                } else {
-                    for (var reqMatName in this.reqMats) {
-                        if (this.reqMats.hasOwnProperty(reqMatName)) {
-                            warehouse.materials[reqMatName].prd = 0;
-                        }
-                    }
-                }
-
-                //Per second
-                var fooProd = prod * producableFrac / (SecsPerMarketCycle * marketCycles);
-                for (var fooI = 0; fooI < this.prodMats.length; ++fooI) {
-                    warehouse.materials[this.prodMats[fooI]].prd = fooProd;
-                }
-            } else {
-                //If this doesn't produce any materials, then it only creates
-                //Products. Creating products will consume materials. The
-                //Production of all consumed materials must be set to 0
-                for (var reqMatName in this.reqMats) {
-                    if (this.reqMats.hasOwnProperty(reqMatName)) {
-                        warehouse.materials[reqMatName].prd = 0;
-                    }
-                }
-            }
-            break;
-
-            case "SALE":
-            /* Process sale of materials */
-            for (var matName in warehouse.materials) {
-                if (warehouse.materials.hasOwnProperty(matName)) {
-                    var mat = warehouse.materials[matName];
-                    if (mat.sCost < 0 || mat.sllman[0] === false) {
-                        mat.sll = 0;
-                        continue;
-                    }
-                    var mat = warehouse.materials[matName];
-
-                    var sCost;
-                    if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(mat.sCost)) {
-                        sCost = mat.sCost.replace(/MP/g, mat.bCost);
-                        sCost = eval(sCost);
-                    } else {
-                        sCost = mat.sCost;
-                    }
-
-                    //Calculate how much of the material sells (per second)
-                    var markup = 1, markupLimit = mat.qlt / mat.mku;
-                    if (sCost > mat.bCost) {
-                        //Penalty if difference between sCost and bCost is greater than markup limit
-                        if ((sCost - mat.bCost) > markupLimit) {
-                            markup = markupLimit / (sCost - mat.bCost);
-                        }
-                    } else if (sCost < mat.bCost) {
-                        if (sCost <= 0) {
-                            markup = 1e12; //Sell everything, essentially discard
-                        } else {
-                            //Lower prices than market increases sales
-                            markup = mat.bCost / sCost;
-                        }
-                    }
-                    //var businessFactor = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]);
-                    var businessFactor = this.getBusinessFactor(office);        //Business employee productivity
-                    var advertisingFactor = this.getAdvertisingFactors()[0];    //Awareness + popularity
-                    var marketFactor = this.getMarketFactor(mat);               //Competition + demand
-                    var maxSell = (mat.qlt + .001) * marketFactor * markup * businessFactor *
-                                  company.getSalesMultiplier() * advertisingFactor;
-
-                    var sellAmt;
-                    if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(mat.sllman[1])) {
-                        //Dynamically evaluated
-                        var tmp = mat.sllman[1].replace(/MAX/g, maxSell);
-                        tmp = tmp.replace(/PROD/g, mat.prd);
-                        try {
-                            sellAmt = eval(tmp);
-                        } catch(e) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Error evaluating your sell amount for material " + mat.name +
-                                            " in " + this.name + "'s " + city + " office. The sell amount " +
-                                            "is being set to zero");
-                            sellAmt = 0;
-                        }
-                        sellAmt = Math.min(maxSell, sellAmt);
-                    } else if (mat.sllman[1] === -1) {
-                        //Backwards compatibility, -1 = MAX
-                        sellAmt = maxSell;
-                    } else {
-                        //Player's input value is just a number
-                        sellAmt = Math.min(maxSell, mat.sllman[1]);
-                    }
-
-                    sellAmt = (sellAmt * SecsPerMarketCycle * marketCycles);
-                    sellAmt = Math.min(mat.qty, sellAmt);
-                    if (sellAmt < 0) {
-                        console.log("sellAmt calculated to be negative");
-                        mat.sll = 0;
-                        continue;
-                    }
-                    if (sellAmt && sCost >= 0) {
-                        mat.qty -= sellAmt;
-                        revenue += (sellAmt * sCost);
-                        mat.sll = sellAmt / (SecsPerMarketCycle * marketCycles);
-                    } else {
-                        mat.sll = 0;
-                    }
-                }
-            } //End processing of sale of materials
-            break;
-
-            case "EXPORT":
-                for (var matName in warehouse.materials) {
-                    if (warehouse.materials.hasOwnProperty(matName)) {
-                        var mat = warehouse.materials[matName];
-                        mat.totalExp = 0; //Reset export
-                        for (var expI = 0; expI < mat.exp.length; ++expI) {
-                            var exp = mat.exp[expI];
-                            var amt = exp.amt.replace(/MAX/g, mat.qty / (SecsPerMarketCycle * marketCycles));
-                            try {
-                                amt = eval(amt);
-                            } catch(e) {
-                                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Calculating export for " + mat.name + " in " +
-                                                this.name +  "'s " + city + " division failed with " +
-                                                "error: " + e);
-                                continue;
-                            }
-                            if (isNaN(amt)) {
-                                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Error calculating export amount for " + mat.name +  " in " +
-                                                this.name + "'s " + city + " division.");
-                                continue;
-                            }
-                            amt = amt * SecsPerMarketCycle * marketCycles;
-
-                            if (mat.qty < amt) {
-                                amt = mat.qty;
-                            }
-                            if (amt === 0) {
-                                break; //None left
-                            }
-                            for (var foo = 0; foo < company.divisions.length; ++foo) {
-                                if (company.divisions[foo].name === exp.ind) {
-                                    var expIndustry = company.divisions[foo];
-                                    var expWarehouse = expIndustry.warehouses[exp.city];
-                                    if (!(expWarehouse instanceof Warehouse)) {
-                                        console.log("ERROR: Invalid export! " + expIndustry.name + " "  + exp.city);
-                                        break;
-                                    }
-
-                                    //Make sure theres enough space in warehouse
-                                    if (expWarehouse.sizeUsed >= expWarehouse.size) {
-                                        return; //Warehouse at capacity
-                                    } else {
-                                        var maxAmt = Math.floor((expWarehouse.size - expWarehouse.sizeUsed) / MaterialSizes[matName]);
-                                        amt = Math.min(maxAmt, amt);
-                                    }
-                                    expWarehouse.materials[matName].imp += (amt / (SecsPerMarketCycle * marketCycles));
-                                    expWarehouse.materials[matName].qty += amt;
-                                    expWarehouse.materials[matName].qlt = mat.qlt;
-                                    mat.qty -= amt;
-                                    mat.totalExp += amt;
-                                    expIndustry.updateWarehouseSizeUsed(expWarehouse);
-                                    break;
-                                }
-                            }
-                        }
-                        //totalExp should be per second
-                        mat.totalExp /= (SecsPerMarketCycle * marketCycles);
-                    }
-                }
-
-                break;
-
-            case "START":
-                break;
-            default:
-                console.log("ERROR: Invalid state: " + this.state);
-                break;
-            } //End switch(this.state)
-            this.updateWarehouseSizeUsed(warehouse);
-
-        } // End warehouse
-
-        //Produce Scientific Research based on R&D employees
-        //Scientific Research can be produced without a warehouse
-        if (office instanceof OfficeSpace) {
-            this.sciResearch.qty += (.005 * Math.pow(office.employeeProd[EmployeePositions.RandD], 0.5)
-                                     * company.getScientificResearchMultiplier());
-        }
-    }
-    return [revenue, expenses];
-}
-
-//Process production & sale of this industry's FINISHED products (including all of their stats)
-Industry.prototype.processProducts = function(marketCycles=1, corporation) {
-    var revenue = 0, expenses = 0;
-
-    //Create products
-    if (this.state === "PRODUCTION") {
-        for (var prodName in this.products) {
-            if (this.products.hasOwnProperty(prodName)) {
-                var prod = this.products[prodName];
-                if (!prod.fin) {
-                    var city = prod.createCity, office = this.offices[city];
-                    var total = office.employeeProd[EmployeePositions.Operations] +
-                                office.employeeProd[EmployeePositions.Engineer] +
-                                office.employeeProd[EmployeePositions.Management], ratio;
-                    if (total === 0) {
-                        ratio = 0;
-                    } else {
-                        ratio = office.employeeProd[EmployeePositions.Engineer] / total +
-                                office.employeeProd[EmployeePositions.Operations] / total +
-                                office.employeeProd[EmployeePositions.Management] / total;
-                    }
-                    prod.createProduct(marketCycles, ratio * Math.pow(total, 0.29));
-                    if (prod.prog >= 100) {
-                         prod.finishProduct(office.employeeProd, this);
-                    }
-                    break;
-                }
-            }
-        }
-    }
-
-    //Produce Products
-    for (var prodName in this.products) {
-        if (this.products.hasOwnProperty(prodName)) {
-            var prod = this.products[prodName];
-            if (prod instanceof Product && prod.fin) {
-                revenue += this.processProduct(marketCycles, prod, corporation);
-            }
-        }
-    }
-    return [revenue, expenses];
-}
-
-//Processes FINISHED products
-Industry.prototype.processProduct = function(marketCycles=1, product, corporation) {
-    var totalProfit = 0;
-    for (var i = 0; i < Cities.length; ++i) {
-        var city = Cities[i], office = this.offices[city], warehouse = this.warehouses[city];
-        if (warehouse instanceof Warehouse) {
-            switch(this.state) {
-
-            case "PRODUCTION":
-            //Calculate the maximum production of this material based
-            //on the office's productivity
-            var maxProd = this.getOfficeProductivity(office, {forProduct:true}) *
-                          corporation.getProductionMultiplier() * this.prodMult, prod;
-
-            //Account for whether production is manually limited
-            if (product.prdman[city][0]) {
-                prod = Math.min(maxProd, product.prdman[city][1]);
-            } else {
-                prod = maxProd;
-            }
-            prod *= (SecsPerMarketCycle * marketCycles);
-
-            //Calculate net change in warehouse storage making the Products will cost
-            var netStorageSize = product.siz;
-            for (var reqMatName in product.reqMats) {
-                if (product.reqMats.hasOwnProperty(reqMatName)) {
-                    var normQty = product.reqMats[reqMatName];
-                    netStorageSize -= (MaterialSizes[reqMatName] * normQty);
-                }
-            }
-
-            //If there's not enough space in warehouse, limit the amount of Product
-            if (netStorageSize > 0) {
-                var maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / netStorageSize);
-                prod = Math.min(maxAmt, prod);
-            }
-
-            warehouse.smartSupplyStore += (prod / (SecsPerMarketCycle * marketCycles));
-
-            //Make sure we have enough resources to make our Products
-            var producableFrac = 1;
-            for (var reqMatName in product.reqMats) {
-                if (product.reqMats.hasOwnProperty(reqMatName)) {
-                    var req = product.reqMats[reqMatName] * prod;
-                    if (warehouse.materials[reqMatName].qty < req) {
-                        producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req);
-                    }
-                }
-            }
-
-            //Make our Products if they are producable
-            if (producableFrac > 0 && prod > 0) {
-                for (var reqMatName in product.reqMats) {
-                    if (product.reqMats.hasOwnProperty(reqMatName)) {
-                        var reqMatQtyNeeded = (product.reqMats[reqMatName] * prod * producableFrac);
-                        warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
-                        warehouse.materials[reqMatName].prd -= reqMatQtyNeeded / (SecsPerMarketCycle * marketCycles);
-                    }
-                }
-                //Quantity
-                product.data[city][0] += (prod * producableFrac);
-            }
-
-            //Keep track of production Per second
-            product.data[city][1] = prod * producableFrac / (SecsPerMarketCycle * marketCycles);
-            break;
-
-            case "SALE":
-            //Process sale of Products
-            product.pCost = 0; //Estimated production cost
-            for (var reqMatName in product.reqMats) {
-                if (product.reqMats.hasOwnProperty(reqMatName)) {
-                    product.pCost += (product.reqMats[reqMatName] * warehouse.materials[reqMatName].bCost);
-                }
-            }
-
-            //Since its a product, its production cost is increased for labor
-            product.pCost *= ProductProductionCostRatio;
-
-            //Calculate Sale Cost (sCost), which could be dynamically evaluated
-            var sCost;
-            if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(product.sCost)) {
-                sCost = product.sCost.replace(/MP/g, product.pCost + product.rat / product.mku);
-                sCost = eval(sCost);
-            } else {
-                sCost = product.sCost;
-            }
-
-            var markup = 1, markupLimit = product.rat / product.mku;
-            if (sCost > product.pCost) {
-                if ((sCost - product.pCost) > markupLimit) {
-                    markup = markupLimit / (sCost - product.pCost);
-                }
-            }
-            var businessFactor = this.getBusinessFactor(office);        //Business employee productivity
-            var advertisingFactor = this.getAdvertisingFactors()[0];    //Awareness + popularity
-            var marketFactor = this.getMarketFactor(product);        //Competition + demand
-            var maxSell = 0.5 * Math.pow(product.rat, 0.65) * marketFactor * corporation.getSalesMultiplier() *
-                          Math.pow(markup, 2) * businessFactor * advertisingFactor;
-            var sellAmt;
-            if (product.sllman[city][0] && Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(product.sllman[city][1])) {
-                //Sell amount is dynamically evaluated
-                var tmp = product.sllman[city][1].replace(/MAX/g, maxSell);
-                tmp = tmp.replace(/PROD/g, product.data[city][1]);
-                try {
-                    tmp = eval(tmp);
-                } catch(e) {
-                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Error evaluating your sell price expression for " + product.name +
-                                    " in " + this.name + "'s " + city + " office. Sell price is being set to MAX");
-                    tmp = maxSell;
-                }
-                sellAmt = Math.min(maxSell, tmp);
-            } else if (product.sllman[city][0] && product.sllman[city][1] > 0) {
-                //Sell amount is manually limited
-                sellAmt = Math.min(maxSell, product.sllman[city][1]);
-            } else {
-                //Backwards compatibility, -1 = 0
-                sellAmt = maxSell;
-            }
-            sellAmt = sellAmt * SecsPerMarketCycle * marketCycles;
-            sellAmt = Math.min(product.data[city][0], sellAmt); //data[0] is qty
-            if (sellAmt && sCost) {
-                product.data[city][0] -= sellAmt; //data[0] is qty
-                totalProfit += (sellAmt * sCost);
-                product.data[city][2] = sellAmt / (SecsPerMarketCycle * marketCycles); //data[2] is sell property
-            } else {
-                product.data[city][2] = 0; //data[2] is sell property
-            }
-            break;
-
-            case "START":
-            case "PURCHASE":
-            case "EXPORT":
-                break;
-            default:
-                console.log("ERROR: Invalid State: " + this.state);
-                break;
-            } //End switch(this.state)
-        }
-    }
-    return totalProfit;
-}
-
-Industry.prototype.discontinueProduct = function(product, parentRefs) {
-    var company = parentRefs.company, industry = parentRefs.industry;
-    for (var productName in this.products) {
-        if (this.products.hasOwnProperty(productName)) {
-            if (product === this.products[productName]) {
-                delete this.products[productName];
-                company.updateUIContent();
-            }
-        }
-    }
-}
-
-Industry.prototype.upgrade = function(upgrade, refs) {
-    var corporation = refs.corporation, division = refs.division,
-        office = refs.office;
-    var upgN = upgrade[0], basePrice = upgrade[1], priceMult = upgrade[2],
-        upgradeBenefit = upgrade[3];
-    while (this.upgrades.length <= upgN) {this.upgrades.push(0);}
-    ++this.upgrades[upgN];
-
-    switch (upgN) {
-        case 0: //Coffee, 5% energy per employee
-            for (var i = 0; i < office.employees.length; ++i) {
-                office.employees[i].ene = Math.min(office.employees[i].ene * 1.05, 100);
-            }
-            break;
-        case 1: //AdVert.Inc,
-            var advMult = corporation.getAdvertisingMultiplier();
-            this.awareness += (3 * advMult);
-            this.popularity += (1 * advMult);
-            this.awareness *= (1.01 * advMult);
-            this.popularity *= ((1 + Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(1, 3) / 100) * advMult);
-            break;
-        default:
-            console.log("ERROR: Un-implemented function index: " + upgN);
-            break;
-    }
-}
-
-//Returns how much of a material can be produced based of office productivity (employee stats)
-Industry.prototype.getOfficeProductivity = function(office, params) {
-    var total = office.employeeProd[EmployeePositions.Operations] +
-                office.employeeProd[EmployeePositions.Engineer] +
-                office.employeeProd[EmployeePositions.Management], ratio;
-    if (total === 0) {
-        ratio = 0;
-    } else {
-        ratio = (office.employeeProd[EmployeePositions.Operations] / total) *
-                (office.employeeProd[EmployeePositions.Engineer] / total) *
-                (office.employeeProd[EmployeePositions.Management] / total);
-        ratio = Math.max(0.01, ratio); //Minimum ratio value if you have employees
-    }
-    if (params && params.forProduct) {
-        return ratio * Math.pow(total, 0.2);
-    } else {
-        return 2 * ratio * Math.pow(total, 0.3);
-    }
-}
-
-//Returns a multiplier based on the office' 'Business' employees that affects sales
-Industry.prototype.getBusinessFactor = function(office) {
-    var ratioMult = 1;
-    if (office.employeeProd["total"] > 0) {
-        ratioMult = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]);
-    }
-    return ratioMult * Math.pow(1 + office.employeeProd[EmployeePositions.Business], 0.15);
-}
-
-//Returns a set of multipliers based on the Industry's awareness, popularity, and advFac. This
-//multiplier affects sales. The result is:
-//  [Total sales mult, total awareness mult, total pop mult, awareness/pop ratio mult]
-Industry.prototype.getAdvertisingFactors = function() {
-    var awarenessFac = Math.pow(this.awareness + 1, this.advFac);
-    var popularityFac = Math.pow(this.popularity + 1, this.advFac);
-    var ratioFac = (this.awareness === 0 ? 0.01 : Math.max((this.popularity + .001) / this.awareness, 0.01));
-    var totalFac = Math.pow(awarenessFac * popularityFac * ratioFac, 0.85);
-    return [totalFac, awarenessFac, popularityFac, ratioFac];
-}
-
-//Returns a multiplier based on a materials demand and competition that affects sales
-Industry.prototype.getMarketFactor = function(mat) {
-    return mat.dmd * (100 - mat.cmp)/100;
-}
-
-Industry.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Industry", this);
-}
-
-Industry.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Industry, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Industry = Industry;
-
-var EmployeePositions = {
-    Operations: "Operations",
-    Engineer: "Engineer",
-    Business: "Business",
-    Management: "Management",
-    RandD: "Research & Development",
-    Training:"Training",
-    Unassigned:"Unassigned",
-}
-
-function Employee(params={}) {
-    if (!(this instanceof Employee)) {
-        return new Employee(params);
-    }
-    this.name   = params.name           ? params.name           : "Bobby";
-
-    //Morale, happiness, and energy are 0-100
-    this.mor    = params.morale         ? params.morale         : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100);
-    this.hap    = params.happiness      ? params.happiness      : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100);
-    this.ene    = params.energy         ? params.energy         : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100);
-
-    this.age    = params.age            ? params.age            : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(20, 50);
-    this.int    = params.intelligence   ? params.intelligence   : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
-    this.cha    = params.charisma       ? params.charisma       : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
-    this.exp    = params.experience     ? params.experience     : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
-    this.cre    = params.creativity     ? params.creativity     : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
-    this.eff    = params.efficiency     ? params.efficiency     : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
-    this.sal    = params.salary         ? params.salary         : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(0.1, 5);
-    this.pro    = 0; //Productivity, This is calculated
-
-    this.loc    = params.loc            ? params.loc : "";
-    this.pos    = EmployeePositions.Unassigned;
-}
-
-//Returns the amount the employee needs to be paid
-Employee.prototype.process = function(marketCycles=1, office) {
-    var gain = 0.001 * marketCycles,
-        det = gain * Math.random();
-    this.age += gain;
-    this.exp += gain;
-    if (this.age > 150) {
-        this.int -= det;
-        this.eff -= det;
-        this.cha -= det;
-    }
-
-    //Training
-    var trainingEff = gain * Math.random();
-    if (this.pos === EmployeePositions.Training) {
-        //To increase creativity and intelligence special upgrades are needed
-        this.cha += trainingEff;
-        this.exp += trainingEff;
-        this.eff += trainingEff;
-    }
-
-    //Weight based on how full office is
-    //Too many employees = more likely to decrease energy and happiness
-    var officeCapacityWeight = 0.5 * (office.employees.length / office.size - 0.5);
-    if (Math.random() < 0.5 - officeCapacityWeight) {
-        this.ene += det;
-        this.hap += det;
-    } else {
-        this.ene -= det;
-        this.hap -= det;
-    }
-    if (this.ene < office.minEne) {this.ene = office.minEne;}
-    if (this.hap < office.minHap) {this.hap = office.minHap;}
-    var salary = this.sal * marketCycles * SecsPerMarketCycle;
-    return salary;
-}
-
-Employee.prototype.calculateProductivity = function(corporation) {
-    var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
-        effCha = this.cha * corporation.getEmployeeChaMultiplier(),
-        effInt = this.int * corporation.getEmployeeIntMultiplier(),
-        effEff = this.eff * corporation.getEmployeeEffMultiplier();
-    var prodBase = this.mor * this.hap * this.ene * 1e-6, prodMult;
-    switch(this.pos) {
-        //Calculate productivity based on position. This is multipled by prodBase
-        //to get final value
-        case EmployeePositions.Operations:
-            prodMult = (0.6 * effInt) + (0.1 * effCha) + (this.exp) +
-                       (0.5 * effCre) + (effEff);
-            break;
-        case EmployeePositions.Engineer:
-            prodMult = (effInt) + (0.1 * effCha) + (1.5 * this.exp) +
-                       (effEff);
-            break;
-        case EmployeePositions.Business:
-            prodMult = (0.4 * effInt) + (effCha) + (0.5 * this.exp);
-            break;
-        case EmployeePositions.Management:
-            prodMult = (2 * effCha) + (this.exp) + (0.2 * effCre) +
-                       (0.7 * effEff);
-            break;
-        case EmployeePositions.RandD:
-            prodMult = (1.5 * effInt) + (0.8 * this.exp) + (effCre) +
-                       (0.5 * effEff);
-            break;
-        case EmployeePositions.Unassigned:
-        case EmployeePositions.Training:
-            prodMult = 0;
-            break;
-        default:
-            console.log("ERROR: Invalid employee position: " + this.pos);
-            break;
-    }
-    return prodBase * prodMult;
-}
-
-//Process benefits from having an office party thrown
-Employee.prototype.throwParty = function(money) {
-    var mult = 1 + (money / 10e6);
-    this.mor *= mult;
-    this.mor = Math.min(100, this.mor);
-    this.hap *= mult;
-    this.hap = Math.min(100, this.hap);
-    return mult;
-}
-
-//'panel' is the DOM element on which to create the UI
-Employee.prototype.createUI = function(panel, corporation) {
-    var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
-        effCha = this.cha * corporation.getEmployeeChaMultiplier(),
-        effInt = this.int * corporation.getEmployeeIntMultiplier(),
-        effEff = this.eff * corporation.getEmployeeEffMultiplier();
-    panel.style.color = "white";
-    panel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        id:"cmpy-mgmt-employee-" + this.name + "-panel-text",
-        innerHTML:"Morale: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.mor, 3) + "<br>" +
-                  "Happiness: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.hap, 3) + "<br>" +
-                  "Energy: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.ene, 3) + "<br>" +
-                  "Age: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.age, 3) + "<br>" +
-                  "Intelligence: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effInt, 3) + "<br>" +
-                  "Charisma: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effCha, 3) + "<br>" +
-                  "Experience: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.exp, 3) + "<br>" +
-                  "Creativity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effCre, 3) + "<br>" +
-                  "Efficiency: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effEff, 3) + "<br>" +
-                  "Salary: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.sal).format("$0.000a") + "/ s<br>",
-    }));
-
-    //Selector for employee position
-    var selector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {});
-    for (var key in EmployeePositions) {
-        if (EmployeePositions.hasOwnProperty(key)) {
-            selector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                text: EmployeePositions[key],
-                value: EmployeePositions[key],
-            }));
-        }
-    }
-
-    selector.addEventListener("change", ()=>{
-        this.pos = selector.options[selector.selectedIndex].value;
-    });
-
-    //Set initial value of selector
-    for (var i = 0; i < selector.length; ++i) {
-        if (selector.options[i].value === this.pos) {
-            selector.selectedIndex = i;
-            break;
-        }
-    }
-    panel.appendChild(selector);
-}
-
-Employee.prototype.updateUI = function(panel, corporation) {
-    var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
-        effCha = this.cha * corporation.getEmployeeChaMultiplier(),
-        effInt = this.int * corporation.getEmployeeIntMultiplier(),
-        effEff = this.eff * corporation.getEmployeeEffMultiplier();
-    if (panel == null) {
-        console.log("ERROR: Employee.updateUI() called with null panel");
-        return;
-    }
-    var text = document.getElementById("cmpy-mgmt-employee-" + this.name + "-panel-text");
-    if (text == null) {
-        return this.createUI(panel);
-    }
-    text.innerHTML  = "Morale: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.mor, 3) + "<br>" +
-                      "Happiness: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.hap, 3) + "<br>" +
-                      "Energy: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.ene, 3) + "<br>" +
-                      "Age: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.age, 3) + "<br>" +
-                      "Intelligence: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effInt, 3) + "<br>" +
-                      "Charisma: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effCha, 3) + "<br>" +
-                      "Experience: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.exp, 3) + "<br>" +
-                      "Creativity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effCre, 3) + "<br>" +
-                      "Efficiency: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effEff, 3) + "<br>" +
-                      "Salary: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.sal).format("$0.000a") + "/ s<br>";
-}
-
-Employee.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Employee", this);
-}
-
-Employee.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Employee, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Employee = Employee;
-
-var OfficeSpaceTiers = {
-    Basic: "Basic",
-    Enhanced: "Enhanced",
-    Luxurious: "Luxurious",
-    Extravagant: "Extravagant"
-}
-
-function OfficeSpace(params={}) {
-    this.loc    = params.loc        ? params.loc        : "";
-    this.cost   = params.cost       ? params.cost       : 1;
-    this.size   = params.size       ? params.size       : 1;
-    this.comf   = params.comfort    ? params.comfort    : 1;
-    this.beau   = params.beauty      ? params.beauty     : 1;
-    this.tier   = OfficeSpaceTiers.Basic;
-
-    this.minEne     = 0; //Minimum energy of employees, based on office
-    this.minHap     = 0; //Minimum happiness of employees, based on office.
-
-    this.employees = [];
-    this.employeeProd = {
-        [EmployeePositions.Operations]:   0,
-        [EmployeePositions.Engineer]:     0,
-        [EmployeePositions.Business]:     0,
-        [EmployeePositions.Management]:   0,
-        [EmployeePositions.RandD]:        0,
-        total:                            0,
-    };
-}
-
-OfficeSpace.prototype.process = function(marketCycles=1, parentRefs) {
-    var corporation = parentRefs.corporation, industry = parentRefs.industry;
-    var perfMult=1; //Multiplier for employee morale/happiness/energy based on company performance
-    if (industry.funds < 0 && industry.lastCycleRevenue < 0) {
-        perfMult = Math.pow(0.99, marketCycles);
-    } else if (industry.funds > 0 && industry.lastCycleRevenue > 0) {
-        perfMult = Math.pow(1.01, marketCycles);
-    }
-
-    var salaryPaid = 0;
-    for (var i = 0; i < this.employees.length; ++i) {
-        var emp = this.employees[i];
-        emp.mor *= perfMult;
-        emp.hap *= perfMult;
-        emp.ene *= perfMult;
-        var salary = emp.process(marketCycles, this);
-        salaryPaid += salary;
-    }
-    this.calculateEmployeeProductivity(marketCycles, corporation);
-    return salaryPaid;
-}
-
-OfficeSpace.prototype.calculateEmployeeProductivity = function(marketCycles=1, corporation) {
-    //Reset
-    for (var name in this.employeeProd) {
-        if (this.employeeProd.hasOwnProperty(name)) {
-            this.employeeProd[name] = 0;
-        }
-    }
-
-    var total = 0;
-    for (var i = 0; i < this.employees.length; ++i) {
-        var employee = this.employees[i];
-        var prod = employee.calculateProductivity(corporation);
-        this.employeeProd[employee.pos] += prod;
-        total += prod;
-    }
-    this.employeeProd["total"] = total;
-}
-
-//Takes care of UI as well
-OfficeSpace.prototype.findEmployees = function(parentRefs) {
-    var company = parentRefs.corporation, division = parentRefs.division;
-    if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;}
-
-    //Generate three random employees (meh, decent, amazing)
-    var mult1 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(25, 50)/100,
-        mult2 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(51, 75)/100,
-        mult3 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(76, 100)/100;
-    var int = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        cha = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        exp = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        cre = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        eff = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        sal = 2.2 * (int + cha + exp + cre + eff);
-
-    var emp1 = new Employee({
-        intelligence: int * mult1,
-        charisma: cha * mult1,
-        experience: exp * mult1,
-        creativity: cre * mult1,
-        efficiency: eff * mult1,
-        salary: sal * mult1,
-    });
-
-    var emp2 = new Employee({
-        intelligence: int * mult2,
-        charisma: cha * mult2,
-        experience: exp * mult2,
-        creativity: cre * mult2,
-        efficiency: eff * mult2,
-        salary: sal * mult2,
-    });
-
-    var emp3 = new Employee({
-        intelligence: int * mult3,
-        charisma: cha * mult3,
-        experience: exp * mult3,
-        creativity: cre * mult3,
-        efficiency: eff * mult3,
-        salary: sal * mult3,
-    });
-
-    var text = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("h1", {
-        innerHTML: "Select one of the following candidates for hire:",
-    });
-
-    var createEmpDiv = function(employee, office) {
-        var div = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-            class:"cmpy-mgmt-find-employee-option",
-            innerHTML:  "Intelligence: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.int, 1) + "<br>" +
-                        "Charisma: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.cha, 1) + "<br>" +
-                        "Experience: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.exp, 1) + "<br>" +
-                        "Creativity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.cre, 1) + "<br>" +
-                        "Efficiency: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.eff, 1) + "<br>" +
-                        "Salary: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(employee.sal).format('$0.000a') + " \ s<br>",
-            clickListener:()=>{
-                office.hireEmployee(employee, parentRefs);
-                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])("cmpy-mgmt-hire-employee-popup");
-                return false;
-            }
-        });
-        return div;
-    };
-
-    var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:"a-link-button",
-        innerText:"Cancel",
-        float:"right",
-        clickListener:()=>{
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])("cmpy-mgmt-hire-employee-popup");
-            return false;
-        }
-    });
-
-    var elems = [text,
-                 createEmpDiv(emp1, this),
-                 createEmpDiv(emp2, this),
-                 createEmpDiv(emp3, this),
-                 cancelBtn];
-
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])("cmpy-mgmt-hire-employee-popup", elems);
-}
-
-OfficeSpace.prototype.hireEmployee = function(employee, parentRefs) {
-    var company = parentRefs.corporation, division = parentRefs.division;
-    var yesBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxGetYesButton"])(),
-        noBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxGetNoButton"])();
-    yesBtn.innerHTML = "Hire";
-    noBtn.innerHTML = "Cancel";
-    yesBtn.addEventListener("click", ()=>{
-        var name = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxGetInput"])();
-        for (var i = 0; i < this.employees.length; ++i) {
-            if (this.employees[i].name === name) {
-                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You already have an employee with this nickname! Please give every employee a unique nickname.");
-                return false;
-            }
-        }
-        employee.name = name;
-        this.employees.push(employee);
-        company.displayDivisionContent(division, currentCityUi);
-        return Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxClose"])();
-    });
-    noBtn.addEventListener("click", ()=>{
-        return Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxClose"])();
-    });
-    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxCreate"])("Give your employee a nickname!");
-}
-
-OfficeSpace.prototype.hireRandomEmployee = function(parentRefs) {
-    var company = parentRefs.corporation, division = parentRefs.division;
-    if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;}
-
-    //Generate three random employees (meh, decent, amazing)
-    var mult = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(76, 100)/100;
-    var int = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        cha = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        exp = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        cre = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        eff = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
-        sal = 2.2 * (int + cha + exp + cre + eff);
-
-    var emp = new Employee({
-        intelligence: int * mult,
-        charisma: cha * mult,
-        experience: exp * mult,
-        creativity: cre * mult,
-        efficiency: eff * mult,
-        salary: sal * mult,
-    });
-
-    var name = Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["generateRandomString"])(7);
-
-    for (var i = 0; i < this.employees.length; ++i) {
-        if (this.employees[i].name === name) {
-            return this.hireRandomEmployee(parentRefs);
-        }
-    }
-    emp.name = name;
-    this.employees.push(emp);
-    company.displayDivisionContent(division, currentCityUi);
-}
-
-//Finds the first unassigned employee and assigns its to the specified job
-OfficeSpace.prototype.assignEmployeeToJob = function(job) {
-    for (var i = 0; i < this.employees.length; ++i) {
-        if (this.employees[i].pos === EmployeePositions.Unassigned) {
-            this.employees[i].pos = job;
-            return true;
-        }
-    }
-    return false;
-}
-
-//Finds the first employee with the given job and unassigns it
-OfficeSpace.prototype.unassignEmployeeFromJob = function(job) {
-    for (var i = 0; i < this.employees.length; ++i) {
-        if (this.employees[i].pos === job) {
-            this.employees[i].pos = EmployeePositions.Unassigned;
-            return true;
-        }
-    }
-    return false;
-}
-
-OfficeSpace.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("OfficeSpace", this);
-}
-
-OfficeSpace.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(OfficeSpace, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.OfficeSpace = OfficeSpace;
-
-function Warehouse(params={}) {
-    this.loc    = params.loc        ? params.loc    : "";
-    this.size   = params.size       ? params.size   : 0;
-    this.level  = 0;
-    this.sizeUsed = 0;
-    this.smartSupplyEnabled = false; //Whether or not smart supply is enabled
-    this.breakdown = "";
-
-    //Stores the amount of product to be produced. Used for Smart Supply unlock.
-    //The production tracked by smart supply is always based on the previous cycle,
-    //so it will always trail the "true" production by 1 cycle
-    this.smartSupplyStore = 0;
-
-    this.materials = {
-        Water:      new Material({name: "Water"}),
-        Energy:     new Material({name: "Energy"}),
-        Food:       new Material({name: "Food"}),
-        Plants:     new Material({name: "Plants"}),
-        Metal:      new Material({name: "Metal"}),
-        Hardware:   new Material({name: "Hardware"}),
-        Chemicals:  new Material({name: "Chemicals"}),
-        Drugs:      new Material({name: "Drugs"}),
-        Robots:     new Material({name: "Robots"}),
-        AICores:    new Material({name: "AI Cores"}),
-        RealEstate: new Material({name: "Real Estate"})
-    }
-}
-
-Warehouse.prototype.updateMaterialSizeUsed = function() {
-    this.sizeUsed = 0;
-    this.breakdown = "";
-    for (var matName in this.materials) {
-        if (this.materials.hasOwnProperty(matName)) {
-            var mat = this.materials[matName];
-            if (MaterialSizes.hasOwnProperty(matName)) {
-                this.sizeUsed += (mat.qty * MaterialSizes[matName]);
-                if (mat.qty > 0) {
-                    this.breakdown += (matName + ": " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.qty * MaterialSizes[matName], 0) + "<br>");
-                }
-            }
-        }
-    }
-    if (this.sizeUsed > this.size) {
-        console.log("ERROR: Warehouse size used greater than capacity, something went wrong");
-    }
-}
-
-Warehouse.prototype.updateSize = function(corporation) {
-    //Backwards compatibility
-    if (this.level == null || this.level === 0) {
-        this.level = Math.round(this.size / 100);
-    }
-
-    this.size = (this.level * 100) * corporation.getStorageMultiplier();
-}
-
-Warehouse.prototype.createUI = function(parentRefs) {
-    if (parentRefs.company == null || parentRefs.industry == null) {
-        console.log("ERROR: Warehouse.createUI called without parentRefs.company or parentRefs.industry");
-        return;
-    }
-    var company = parentRefs.company, industry = parentRefs.industry;
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryWarehousePanel);
-    industryWarehouseStorageText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        display:"inline-block", class:"tooltip",
-        color: this.sizeUsed >= this.size ? "red" : "white",
-    });
-    industryWarehousePanel.appendChild(industryWarehouseStorageText);
-
-    //Upgrade warehouse size button
-    var upgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, this.level+1);
-    industryWarehouseUpgradeSizeButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        innerText:"Upgrade Warehouse Size - " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgradeCost).format('$0.000a'),
-        display:"inline-block",
-        class: company.funds.lt(upgradeCost) ? "a-link-button-inactive" : "a-link-button",
-        clickListener:()=>{
-            //Backwards compatibility
-            if (this.level == null || this.level === 0) {
-                this.level = Math.round(this.size / 100);
-            }
-
-            ++this.level;
-            this.updateSize(company);
-            company.funds = company.funds.minus(upgradeCost);
-            this.createUI(parentRefs);
-            return;
-        }
-    });
-    industryWarehousePanel.appendChild(industryWarehouseUpgradeSizeButton);
-
-    //Material requirement text
-    var reqText = "This Industry uses [" + Object.keys(industry.reqMats).join(", ") +
-                  "] in order to ";
-    if (industry.prodMats.length > 0) {
-        reqText += "produce [" + industry.prodMats.join(", ") + "] ";
-        if (industry.makesProducts) {
-            reqText += " and " + industry.getProductDescriptionText();
-        }
-    } else if (industry.makesProducts) {
-        reqText += industry.getProductDescriptionText();
-    }
-    reqText += "<br><br>To get started with production, purchase your required " +
-               "materials or import them from another of your company's divisions.<br><br>";
-
-    //Material ratio text for tooltip
-    var reqRatioText = "The exact requirements for production are:<br>";
-    for (var matName in industry.reqMats) {
-        if (industry.reqMats.hasOwnProperty(matName)) {
-            reqRatioText += (industry.reqMats[matName] + " " + matName + "<br>");
-        }
-    }
-    reqRatioText += "in order to create ";
-    if (industry.prodMats.length > 0) {
-        reqRatioText += "one of each produced Material (" + industry.prodMats.join(", ") + ") ";
-        if (industry.makesProducts) {
-            reqRatioText += "or to create one of its Products";
-        }
-    } else if (industry.makesProducts) {
-        reqRatioText += "one of its Products";
-    }
-
-    industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        innerHTML:reqText, tooltipleft:reqRatioText
-    }));
-
-    //Current state
-    industryWarehouseStateText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p");
-    industryWarehousePanel.appendChild(industryWarehouseStateText);
-
-    //Smart Supply Enable/Disable
-    if (company.unlockUpgrades[1]) {
-        if (this.smartSupplyEnabled == null) {this.smartSupplyEnabled = false;}
-        var smartSupplyCheckboxId = "cmpy-mgmt-smart-supply-checkbox";
-        industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("label", {
-            for:smartSupplyCheckboxId, innerText:"Enable Smart Supply",
-            color:"white"
-        }));
-        industrySmartSupplyCheckbox = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-            type:"checkbox", id:smartSupplyCheckboxId, margin:"3px",
-            changeListener:()=>{
-                this.smartSupplyEnabled = industrySmartSupplyCheckbox.checked;
-            }
-        });
-        industrySmartSupplyCheckbox.checked = this.smartSupplyEnabled;
-        industryWarehousePanel.appendChild(industrySmartSupplyCheckbox);
-    }
-
-    //Materials
-    industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        innerHTML: "<br>Materials:<br>",
-    }));
-    industryWarehouseMaterials = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("ul");
-    industryWarehousePanel.appendChild(industryWarehouseMaterials);
-
-    //Products
-    if (industry.makesProducts && Object.keys(industry.products).length > 0) {
-        industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-            innerHTML: "<br>Products:<br>",
-        }));
-        industryWarehouseProducts = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("ul");
-        industryWarehousePanel.appendChild(industryWarehouseProducts);
-    }
-
-    this.updateUI(parentRefs);
-}
-
-Warehouse.prototype.updateUI = function(parentRefs) {
-    if (parentRefs.company == null || parentRefs.industry == null) {
-        console.log("ERROR: Warehouse.updateUI called without parentRefs.company or parentRefs.industry");
-        return;
-    }
-    var company = parentRefs.company, industry = parentRefs.industry;
-
-    //Storage text
-    var storageText = "Storage: " +
-                      (this.sizedUsed >= this.size ? Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.sizeUsed, 3) : Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.sizeUsed, 3)) +
-                      "/" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.size, 3);
-    if (this.breakdown != null && this.breakdown != "") {
-        storageText += ("<span class='tooltiptext'>" +
-                        this.breakdown + "</span>");
-    }
-    industryWarehouseStorageText.innerHTML = storageText;
-
-    //Upgrade warehouse size button
-    var upgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, this.level+1);
-    if (company.funds.lt(upgradeCost)) {
-        industryWarehouseUpgradeSizeButton.className = "a-link-button-inactive";
-    } else {
-        industryWarehouseUpgradeSizeButton.className = "a-link-button";
-    }
-
-    //Current state
-    var stateText = "Current state: ";
-    switch(industry.state) {
-        case "START":
-            stateText += "Preparing...";
-            break;
-        case "PURCHASE":
-            stateText += "Purchasing materials...";
-            break;
-        case "PRODUCTION":
-            stateText += "Producing materials and/or products...";
-            break;
-        case "SALE":
-            stateText += "Selling materials and/or products...";
-            break;
-        case "EXPORT":
-            stateText += "Exporting materials and/or products...";
-            break;
-        default:
-            console.log("ERROR: Invalid state: " + industry.state);
-            break;
-    }
-    industryWarehouseStateText.innerText = stateText;
-
-    //Materials
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryWarehouseMaterials);
-    for (var matName in this.materials) {
-        if (this.materials.hasOwnProperty(matName) && this.materials[matName] instanceof Material) {
-            if (Object.keys(industry.reqMats).includes(matName) || industry.prodMats.includes(matName) ||
-                matName === "Hardware" || matName === "Robots" || matName === "AICores" ||
-                matName === "RealEstate") {
-                industryWarehouseMaterials.appendChild(this.createMaterialUI(this.materials[matName], matName, parentRefs));
-            }
-        }
-    }
-
-    //Products
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryWarehouseProducts);
-    if (industry.makesProducts && Object.keys(industry.products).length > 0) {
-        for (var productName in industry.products) {
-            if (industry.products.hasOwnProperty(productName) && industry.products[productName] instanceof Product) {
-                industryWarehouseProducts.appendChild(this.createProductUI(industry.products[productName], parentRefs));
-            }
-        }
-    }
-}
-
-Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
-    if (parentRefs.company == null || parentRefs.industry == null) {
-        console.log("ERROR: Warehouse.createMaterialUI called without industry or company parent refs");
-        return;
-    }
-    var company = parentRefs.company, industry = parentRefs.industry;
-    var purchasePopupId = "cmpy-mgmt-material-purchase-popup",
-        sellPopupid = "cmpy-mgmt-material-sell-popup";
-    var div = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        class:"cmpy-mgmt-warehouse-material-div",
-    });
-
-    var totalGain = mat.buy + mat.prd + mat.imp - mat.sll - mat.totalExp;
-
-    //If Market Research upgrades are unlocked, add competition and demand info
-    var cmpAndDmdText = "";
-    if (company.unlockUpgrades[2] === 1) {
-        cmpAndDmdText += "<br>Competition: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.cmp, 3);
-    }
-    if (company.unlockUpgrades[3] === 1) {
-        cmpAndDmdText += "<br>Demand: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.dmd, 3);
-    }
-    var innerTxt = "<p class='tooltip'>" + mat.name + ": " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.qty, 3) +
-                   "(" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(totalGain, 3) +  "/s)" +
-                   "<span class='tooltiptext'>Buy: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.buy, 3) +
-                   "/s<br>Prod: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.prd, 3) + "/s<br>Sell: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sll, 3) +
-                   "/s<br>Export: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.totalExp, 3) + "/s<br>Import: " +
-                   Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.imp, 3) + "/s" + cmpAndDmdText + "</span></p><br>" +
-                   "<p class='tooltip'>MP: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.bCost, 2) +
-                   "<span class='tooltiptext'>Market Price: The price you would pay if " +
-                   "you were to buy this material on the market</span></p><br>" +
-                   "<p class='tooltip'>Quality: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.qlt, 2) +
-                   "<span class='tooltiptext'>The quality of your material. Higher quality " +
-                   "will lead to more sales</span></p>";
-
-    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        innerHTML: innerTxt,
-        id: "cmpy-mgmt-warehouse-" + matName + "-text", display:"inline-block",
-    }));
-
-    var buttonPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        display:"inline-block",
-    });
-    div.appendChild(buttonPanel);
-
-    //Button to set purchase amount
-    var tutorial = industry.newInd && Object.keys(industry.reqMats).includes(mat.name) &&
-                   mat.buy === 0 && mat.imp === 0;
-    var buyButtonParams = {
-        innerText: "Buy (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.buy, 3) + ")", display:"inline-block",
-        class: tutorial ? "a-link-button flashing-button" : "a-link-button",
-        clickListener:()=>{
-            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerHTML: "Enter the amount of " + mat.name + " you would like " +
-                           "to purchase per second. This material's cost changes constantly"
-            });
-            var confirmBtn;
-            var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                type:"number", value:mat.buy ? mat.buy : null, placeholder: "Purchase amount",
-                onkeyup:(e)=>{
-                    e.preventDefault();
-                    if (e.keyCode === 13) {confirmBtn.click();}
-                }
-            });
-            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                innerText:"Confirm", class:"a-link-button",
-                clickListener:()=>{
-                    if (isNaN(input.value)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid amount");
-                    } else {
-                        mat.buy = parseFloat(input.value);
-                        if (isNaN(mat.buy)) {mat.buy = 0;}
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(purchasePopupId);
-                        this.createUI(parentRefs);
-                        return false;
-                    }
-                }
-            });
-            var clearButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                innerText:"Clear Purchase", class:"a-link-button",
-                clickListener:()=>{
-                    mat.buy = 0;
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(purchasePopupId);
-                    this.createUI(parentRefs);
-                    return false;
-                }
-            });
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                innerText:"Cancel", class:"a-link-button",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(purchasePopupId);
-                }
-            });
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(purchasePopupId, [txt, input, confirmBtn, clearButton, cancelBtn]);
-            input.focus();
-        }
-    };
-    if (tutorial) {
-        buyButtonParams.tooltip = "Purchase your required materials to get production started!";
-    }
-    buttonPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", buyButtonParams));
-
-    //Button to manage exports
-    if (company.unlockUpgrades[0] === 1) { //Export unlock upgrade
-        function createExportPopup() {
-            var popupId = "cmpy-mgmt-export-popup";
-            var exportTxt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerText:"Select the industry and city to export this material to, as well as " +
-                          "how much of this material to export per second. You can set the export " +
-                          "amount to 'MAX' to export all of the materials in this warehouse."
-            });
-
-            //Select industry and city to export to
-            var citySelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select");
-            var industrySelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {
-                changeListener:()=>{
-                    var industryName = industrySelector.options[industrySelector.selectedIndex].value;
-                    for (var foo = 0; foo < company.divisions.length; ++foo) {
-                        if (company.divisions[foo].name == industryName) {
-                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["clearSelector"])(citySelector);
-                            var selectedIndustry = company.divisions[foo];
-                            for (var cityName in company.divisions[foo].warehouses) {
-                                if (company.divisions[foo].warehouses[cityName] instanceof Warehouse) {
-                                    citySelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                                        value:cityName, text:cityName,
-                                    }));
-                                }
-                            }
-                            return;
-                        }
-                    }
-                }
-            });
-
-            for (var i = 0; i < company.divisions.length; ++i) {
-                industrySelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                    text:company.divisions[i].name, value:company.divisions[i].name,
-                })); //End create element option
-            } //End for
-
-            var currIndustry = industrySelector.options[industrySelector.selectedIndex].value;
-            for (var i = 0; i < company.divisions.length; ++i) {
-                if (company.divisions[i].name == currIndustry) {
-                    for (var cityName in company.divisions[i].warehouses) {
-                        if (company.divisions[i].warehouses.hasOwnProperty(cityName) &&
-                            company.divisions[i].warehouses[cityName] instanceof Warehouse) {
-                            citySelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                                value:cityName, text:cityName,
-                            }));
-                        }
-                    }
-                    break;
-                }
-            }
-
-            //Select amount to export
-            var exportAmount = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                placeholder:"Export amount / s"
-            });
-
-            var exportBtn  = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button", display:"inline-block", innerText:"Export",
-                clickListener:()=>{
-                    var industryName = industrySelector.options[industrySelector.selectedIndex].text,
-                        cityName = citySelector.options[citySelector.selectedIndex].text,
-                        amt = exportAmount.value;
-                    //Sanitize amt
-                    var sanitizedAmt = amt.replace(/\s+/g, '');
-                    sanitizedAmt = sanitizedAmt.replace(/[^-()\d/*+.MAX]/g, '');
-                    var temp = sanitizedAmt.replace(/MAX/g, 1);
-                    try {
-                        temp = eval(temp);
-                    } catch(e) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid expression entered for export amount: " + e);
-                        return false;
-                    }
-
-                    if (temp == null || isNaN(temp)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid amount entered for export");
-                        return;
-                    }
-                    var exportObj = {ind:industryName, city:cityName, amt:sanitizedAmt};
-                    mat.exp.push(exportObj);
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button", display:"inline-block", innerText:"Cancel",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-
-            var currExportsText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerText:"Below is a list of all current exports of this material from this warehouse. " +
-                          "Clicking on one of the exports below will REMOVE that export."
-            });
-            var currExports = [];
-            for (var i = 0; i < mat.exp.length; ++i) {
-                (function(i, mat, currExports){
-                currExports.push(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-                    class:"cmpy-mgmt-existing-export",
-                    innerHTML: "Industry: " + mat.exp[i].ind + "<br>" +
-                               "City: " + mat.exp[i].city + "<br>" +
-                               "Amount/s: " + mat.exp[i].amt,
-                    clickListener:()=>{
-                        mat.exp.splice(i, 1); //Remove export object
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        createExportPopup();
-                    }
-                }));
-                })(i, mat, currExports);
-            }
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [exportTxt, industrySelector, citySelector, exportAmount,
-                                  exportBtn, cancelBtn, currExportsText].concat(currExports));
-        }
-        buttonPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            innerText:"Export", display:"inline-block", class:"a-link-button",
-            clickListener:()=>{createExportPopup();}
-        }));
-    }
-
-    buttonPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {})); // Force line break
-
-    //Button to set sell amount
-    var innerTextString;
-    if (mat.sllman[0]) {
-        innerTextString = (mat.sllman[1] === -1 ? "Sell (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sll, 3) + "/MAX)" :
-                          "Sell (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sll, 3) + "/" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sllman[1], 3) + ")");
-        if (mat.sCost) {
-            if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(mat.sCost)) {
-                var sCost = mat.sCost.replace(/MP/g, mat.bCost);
-                innerTextString += " @ $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(eval(sCost), 2);
-            } else {
-                innerTextString += " @ $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sCost, 2);
-            }
-        }
-    } else {
-        innerTextString = "Sell (0.000/0.000)";
-    }
-
-    buttonPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        innerText: innerTextString, display:"inline-block", class:"a-link-button",
-        clickListener:()=>{
-            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerHTML: "Enter the maximum amount of " + mat.name + " you would like " +
-                           "to sell per second, as well as the price at which you would " +
-                           "like to sell at.<br><br>" +
-                           "If the sell amount is set to 0, then the material will not be sold. If the sell price " +
-                           "if set to 0, then the material will be discarded<br><br>" +
-                           "Setting the sell amount to 'MAX' will result in you always selling the " +
-                           "maximum possible amount of the material.<br><br>" +
-                           "When setting the sell amount, you can use the 'PROD' variable to designate a dynamically " +
-                           "changing amount that depends on your production. For example, if you set the sell amount " +
-                           "to 'PROD-5' then you will always sell 5 less of the material than you produce.<br><br>" +
-                           "When setting the sell price, you can use the 'MP' variable to designate a dynamically " +
-                           "changing price that depends on the market price. For example, if you set the sell price " +
-                           "to 'MP+10' then it will always be sold at $10 above the market price.",
-            });
-            var br = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {});
-            var confirmBtn;
-            var inputQty = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                type:"text", marginTop:"4px",
-                value: mat.sllman[1] ? mat.sllman[1] : null, placeholder: "Sell amount",
-                onkeyup:(e)=>{
-                    e.preventDefault();
-                    if (e.keyCode === 13) {confirmBtn.click();}
-                }
-            });
-            var inputPx = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                type:"text", marginTop:"4px",
-                value: mat.sCost ? mat.sCost : null, placeholder: "Sell price",
-                onkeyup:(e)=>{
-                    e.preventDefault();
-                    if (e.keyCode === 13) {confirmBtn.click();}
-                }
-            });
-            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                innerText:"Confirm", class:"a-link-button", margin:"6px",
-                clickListener:()=>{
-                    //Parse price
-                    var cost = inputPx.value.replace(/\s+/g, '');
-                    cost = cost.replace(/[^-()\d/*+.MP]/g, ''); //Sanitize cost
-                    var temp = cost.replace(/MP/g, mat.bCost);
-                    try {
-                        temp = eval(temp);
-                    } catch(e) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field: " + e);
-                        return false;
-                    }
-
-                    if (temp == null || isNaN(temp)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field");
-                        return false;
-                    }
-
-                    if (cost.includes("MP")) {
-                        mat.sCost = cost; //Dynamically evaluated
-                    } else {
-                        mat.sCost = temp;
-                    }
-
-                    //Parse quantity
-                    if (inputQty.value.includes("MAX") || inputQty.value.includes("PROD")) {
-                        var qty = inputQty.value.replace(/\s+/g, '');
-                        qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
-                        var temp = qty.replace(/MAX/g, 1);
-                        temp = temp.replace(/PROD/g, 1);
-                        try {
-                            temp = eval(temp);
-                        } catch(e) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field: " + e);
-                            return false;
-                        }
-
-                        if (temp == null || isNaN(temp)) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field");
-                            return false;
-                        }
-
-                        mat.sllman[0] = true;
-                        mat.sllman[1] = qty; //Use sanitized input
-                    } else if (isNaN(inputQty.value)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for sell quantity field! Must be numeric or 'MAX'");
-                        return false;
-                    } else {
-                        var qty = parseFloat(inputQty.value);
-                        if (isNaN(qty)) {qty = 0;}
-                        if (qty === 0) {
-                            mat.sllman[0] = false;
-                            mat.sllman[1] = 0;
-                        } else {
-                            mat.sllman[0] = true;
-                            mat.sllman[1] = qty;
-                        }
-                    }
-
-                    this.createUI(parentRefs);
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(sellPopupid);
-                    return false;
-                }
-            });
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                innerText:"Cancel", class:"a-link-button", margin: "6px",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(sellPopupid);
-                }
-            });
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(sellPopupid, [txt, br, inputQty, inputPx, confirmBtn, cancelBtn]);
-            inputQty.focus();
-        }
-    }));
-
-    return div;
-}
-
-Warehouse.prototype.createProductUI = function(product, parentRefs) {
-    var company = parentRefs.company, industry = parentRefs.industry,
-        city = currentCityUi;
-    var div = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        class:"cmpy-mgmt-warehouse-product-div"
-    });
-
-    //Products being designed TODO
-    if (!product.fin) {
-        div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-            innerHTML: "Designing " + product.name + "...<br>" +
-                        Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.prog, 2) + "% complete",
-        }));
-        return div;
-    }
-
-    //Completed products
-    var cmpAndDmdText = "";
-    if (company.unlockUpgrades[2] === 1) {
-        cmpAndDmdText += "<br>Competition: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.cmp, 3);
-    }
-    if (company.unlockUpgrades[3] === 1) {
-        cmpAndDmdText += "<br>Demand: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.dmd, 3);
-    }
-    var totalGain = product.data[city][1] - product.data[city][2]; //Production - sale
-    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        innerHTML: "<p class='tooltip'>" + product.name + ": " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][0], 3) + //Quantity
-                   "(" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(totalGain, 3) + "/s)" +
-                   "<span class='tooltiptext'>Prod: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][1], 3) + "/s<br>" +
-                   "Sell: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][2], 3) + "/s</span></p><br>" +
-                   "<p class='tooltip'>Rating: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.rat, 3) +
-                   "<span class='tooltiptext'>Quality: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.qlt, 3) + "<br>" +
-                   "Performance: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.per, 3) + "<br>" +
-                   "Durability: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.dur, 3) + "<br>" +
-                   "Reliability: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.rel, 3) + "<br>" +
-                   "Aesthetics: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.aes, 3) + "<br>" +
-                   "Features: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.fea, 3) +
-                   cmpAndDmdText + "</span></p><br>" +
-                   "<p class='tooltip'>Est. Production Cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(product.pCost / ProductProductionCostRatio).format("$0.000a") +
-                   "<span class='tooltiptext'>An estimate of the material cost it takes to create this Product.</span></p><br>" +
-                   "<p class='tooltip'>Est. Market Price: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(product.pCost + product.rat / product.mku).format("$0.000a") +
-                   "<span class='tooltiptext'>An estimate of how much consumers are willing to pay for this product. " +
-                   "Setting the sale price above this may result in less sales. Setting the sale price below this may result " +
-                   "in more sales.</span></p>"
-    }));
-    var buttonPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        display:"inline-block",
-    });
-    div.appendChild(buttonPanel);
-
-    //Sell button
-    var sellInnerTextString = (product.sllman[city][1] === -1 ? "Sell (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][2], 3) + "/MAX)" :
-                              "Sell (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][2], 3) + "/" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.sllman[city][1], 3) + ")");
-    if (product.sCost) {
-        if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(product.sCost)) {
-            sellInnerTextString += (" @ " + product.sCost);
-        } else {
-            sellInnerTextString += (" @ " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(product.sCost).format("$0.000a"));
-        }
-    }
-    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        innerText:sellInnerTextString, class:"a-link-button", display:"inline-block",margin:"6px",
-        clickListener:()=>{
-            var popupId = "cmpy-mgmt-sell-product-popup";
-            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerHTML:"Enter the maximum amount of " + product.name + " you would like " +
-                          "to sell per second, as well as the price at which you would like to " +
-                          "sell it at.<br><br>" +
-                          "If the sell amount is set to 0, then the product will not be sold. If the " +
-                          "sell price is set to 0, then the product will be discarded.<br><br>" +
-                          "Setting the sell amount to 'MAX' will result in you always selling the " +
-                          "maximum possible amount of the material.<br><br>" +
-                          "When setting the sell amount, you can use the 'PROD' variable to designate a " +
-                          "dynamically changing amount that depends on your production. For example, " +
-                          "if you set the sell amount to 'PROD-1' then you will always sell 1 less of  " +
-                          "the material than you produce.<br><br>" +
-                          "When setting the sell price, you can use the 'MP' variable to set a " +
-                          "dynamically changing price that depends on the Product's estimated " +
-                          "market price. For example, if you set it to 'MP*5' then it " +
-                          "will always be sold at five times the estimated market price.",
-            });
-            var confirmBtn;
-            var inputQty = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                type:"text", value:product.sllman[city][1] ? product.sllman[city][1] : null, placeholder: "Sell amount",
-                onkeyup:(e)=>{
-                    e.preventDefault();
-                    if (e.keyCode === 13) {confirmBtn.click();}
-                }
-            });
-            var inputPx = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                type:"text", value: product.sCost ? product.sCost : null, placeholder: "Sell price",
-                onkeyup:(e)=>{
-                    e.preventDefault();
-                    if (e.keyCode === 13) {confirmBtn.click();}
-                }
-            });
-            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button", innerText:"Confirm",
-                clickListener:()=>{
-                    //Parse price
-                    if (inputPx.value.includes("MP")) {
-                        //Dynamically evaluated quantity. First test to make sure its valid
-                        //Sanitize input, then replace dynamic variables with arbitrary numbers
-                        var price = inputPx.value.replace(/\s+/g, '');
-                        price = price.replace(/[^-()\d/*+.MP]/g, '');
-                        var temp = price.replace(/MP/g, 1);
-                        try {
-                            temp = eval(temp);
-                        } catch(e) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell quantity field: " + e);
-                            return false;
-                        }
-                        if (temp == null || isNaN(temp)) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell quantity field.");
-                            return false;
-                        }
-                        product.sCost = price; //Use sanitized price
-                    } else {
-                        var cost = parseFloat(inputPx.value);
-                        if (isNaN(cost)) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for sell price field");
-                            return false;
-                        }
-                        product.sCost = cost;
-                    }
-
-                    //Parse quantity
-                    if (inputQty.value.includes("MAX") || inputQty.value.includes("PROD")) {
-                        //Dynamically evaluated quantity. First test to make sure its valid
-                        var qty = inputQty.value.replace(/\s+/g, '');
-                        qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
-                        var temp = qty.replace(/MAX/g, 1);
-                        temp = temp.replace(/PROD/g, 1);
-                        try {
-                            temp = eval(temp);
-                        } catch(e) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field: " + e);
-                            return false;
-                        }
-
-                        if (temp == null || isNaN(temp)) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field");
-                            return false;
-                        }
-                        product.sllman[city][0] = true;
-                        product.sllman[city][1] = qty; //Use sanitized input
-                    } else if (isNaN(inputQty.value)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for sell quantity field! Must be numeric");
-                        return false;
-                    } else {
-                        var qty = parseFloat(inputQty.value);
-                        if (isNaN(qty)) {qty = 0;}
-                        if (qty === 0) {
-                            product.sllman[city][0] = false;
-                        } else {
-                            product.sllman[city][0] = true;
-                            product.sllman[city][1] = qty;
-                        }
-                    }
-                    this.createUI(parentRefs);
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button", innerText:"Cancel",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, inputQty, inputPx, confirmBtn, cancelBtn]);
-            inputQty.focus();
-        }
-    }));
-    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br",{})); //force line break
-
-    //Limit production button
-    var limitProductionInnerText = "Limit Production";
-    if (product.prdman[city][0]) {
-        limitProductionInnerText += " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.prdman[city][1], 3) + ")";
-    }
-    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:"a-link-button", innerText:limitProductionInnerText,display:"inline-block",
-        clickListener:()=>{
-            var popupId = "cmpy-mgmt-limit-product-production-popup";
-            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerText:"Enter a limit to the amount of this product you would " +
-                          "like to product per second. Leave the box empty to set no limit."
-            });
-            var confirmBtn;
-            var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                type:"number", placeholder:"Limit",
-                onkeyup:(e)=>{
-                    e.preventDefault();
-                    if (e.keyCode === 13) {confirmBtn.click();}
-                }
-            });
-            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button", display:"inline-block", innerText:"Limit production", margin:'6px',
-                clickListener:()=>{
-                    if (input.value === "") {
-                        product.prdman[city][0] = false;
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        return false;
-                    }
-                    var qty = parseFloat(input.value);
-                    if (isNaN(qty)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value entered");
-                        return false;
-                    }
-                    if (qty < 0) {
-                        product.prdman[city][0] = false;
-                    } else {
-                        product.prdman[city][0] = true;
-                        product.prdman[city][1] = qty;
-                    }
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button", display:"inline-block", innerText:"Cancel", margin:"6px",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, input, confirmBtn, cancelBtn]);
-        }
-    }));
-
-    //Discontinue button
-    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:'a-link-button', display:"inline-block",innerText:"Discontinue",
-        clickListener:()=>{
-            var popupId = "cmpy-mgmt-discontinue-product-popup";
-            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerText:"Are you sure you want to do this? Discontinuing a product " +
-                          "removes it completely and permanently. You will no longer " +
-                          "produce this product and all of its existing stock will be " +
-                          "removed and left unsold",
-            });
-            var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button",innerText:"Discontinue",
-                clickListener:()=>{
-                    industry.discontinueProduct(product, parentRefs);
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button", innerText:"Cancel",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, confirmBtn, cancelBtn]);
-        }
-    }));
-    return div;
-}
-
-Warehouse.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Warehouse", this);
-}
-
-Warehouse.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Warehouse, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Warehouse = Warehouse;
-
-//Corporation Unlock Upgrades
-//Upgrades for entire corporation, unlocks features, either you have it or you dont
-//The structure is [index in Corporation feature upgrades array, price ]
-var CorporationUnlockUpgrades = {
-    //Lets you export goods
-    "0":  [0, 20e9, "Export",
-                    "Develop infrastructure to export your materials to your other facilities. " +
-                    "This allows you to move materials around between different divisions and cities."],
-
-    //Lets you buy exactly however many required materials you need for production
-    "1":  [1, 50e9, "Smart Supply", "Use advanced AI to anticipate your supply needs. " +
-                     "This allows you to purchase exactly however many materials you need for production."],
-
-    //Displays each material/product's demand
-    "2":  [2, 5e9, "Market Research - Demand",
-                    "Mine and analyze market data to determine the demand of all resources. " +
-                    "The demand attribute, which affects sales, will be displayed for every material and product."],
-
-    //Display's each material/product's competition
-    "3":  [3, 5e9, "Market Data - Competition",
-                    "Mine and analyze market data to determine how much competition there is on the market " +
-                    "for all resources. The competition attribute, which affects sales, will be displayed for " +
-                    "for every material and product."],
-    "4":  [4, 10e9, "VeChain",
-                    "Use AI and blockchain technology to identify where you can improve your supply chain systems. " +
-                    "This upgrade will allow you to view a wide array of useful statistics about your " +
-                    "Corporation."]
-}
-
-//Corporation Upgrades
-//Upgrades for entire corporation, levelable upgrades
-//The structure is [index in Corporation upgrades array, base price, price mult, benefit mult (additive),
-//                  name, desc]
-var CorporationUpgrades = {
-    //Smart factories, increases production
-    "0":    [0, 2e9, 1.07, 0.03,
-            "Smart Factories", "Advanced AI automatically optimizes the operation and productivity " +
-            "of factories. Each level of this upgrade increases your global production by 3% (additive)."],
-
-    //Smart warehouses, increases storage size
-    "1":    [1, 2e9, 1.07, .1,
-             "Smart Storage", "Advanced AI automatically optimizes your warehouse storage methods. " +
-             "Each level of this upgrade increases your global warehouse storage size by 10% (additive)."],
-
-    //Advertise through dreams, passive popularity/ awareness gain
-    "2":    [2, 8e9, 1.09, .001,
-            "DreamSense", "Use DreamSense LCC Technologies to advertise your corporation " +
-            "to consumers through their dreams. Each level of this upgrade provides a passive " +
-            "increase in awareness of all of your companies (divisions) by 0.004 / market cycle," +
-            "and in popularity by 0.001 / market cycle. A market cycle is approximately " +
-            "20 seconds."],
-
-    //Makes advertising more effective
-    "3":    [3, 4e9, 1.12, 0.005,
-            "Wilson Analytics", "Purchase data and analysis from Wilson, a marketing research " +
-            "firm. Each level of this upgrades increases the effectiveness of your " +
-            "advertising by 0.5% (additive)."],
-
-    //Augmentation for employees, increases cre
-    "4":    [4, 1e9, 1.06, 0.1,
-            "Nuoptimal Nootropic Injector Implants", "Purchase the Nuoptimal Nootropic " +
-            "Injector augmentation for your employees. Each level of this upgrade " +
-            "globally increases the creativity of your employees by 10% (additive)."],
-
-    //Augmentation for employees, increases cha
-    "5":    [5, 1e9, 1.06, 0.1,
-            "Speech Processor Implants", "Purchase the Speech Processor augmentation for your employees. " +
-            "Each level of this upgrade globally increases the charisma of your employees by 10% (additive)."],
-
-    //Augmentation for employees, increases int
-    "6":    [6, 1e9, 1.06, 0.1,
-            "Neural Accelerators", "Purchase the Neural Accelerator augmentation for your employees. " +
-            "Each level of this upgrade globally increases the intelligence of your employees " +
-            "by 10% (additive)."],
-
-    //Augmentation for employees, increases eff
-    "7":    [7, 1e9, 1.06, 0.1,
-            "FocusWires", "Purchase the FocusWire augmentation for your employees. Each level " +
-            "of this upgrade globally increases the efficiency of your employees by 10% (additive)."],
-
-    //Improves sales of materials/products
-    "8":    [8, 1e9, 1.08, 0.01,
-            "ABC SalesBots", "Always Be Closing. Purchase these robotic salesmen to increase the amount of " +
-            "materials and products you sell. Each level of this upgrade globally increases your sales " +
-            "by 1% (additive)."],
-
-    //Improves scientific research rate
-    "9":    [9, 5e9, 1.07, 0.05,
-            "Project Insight", "Purchase 'Project Insight', a R&D service provided by the secretive " +
-            "Fulcrum Technologies. Each level of this upgrade globally increases the amount of " +
-            "Scientific Research you produce by 5% (additive)."],
-}
-
-function Corporation(params={}) {
-    this.name = params.name ? params.name : "The Corporation";
-
-    //A division/business sector is represented  by the object:
-    this.divisions = [];
-
-    //Financial stats
-    this.funds      = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(150e9);
-    this.revenue    = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-    this.expenses   = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-    this.fundingRound = 0;
-    this.public     = false; //Publicly traded
-    this.numShares  = TOTALSHARES;
-    this.issuedShares = 0;
-    this.sharePrice = 0;
-    this.storedCycles = 0;
-
-    var numUnlockUpgrades = Object.keys(CorporationUnlockUpgrades).length,
-        numUpgrades = Object.keys(CorporationUpgrades).length;
-
-    this.unlockUpgrades = Array(numUnlockUpgrades).fill(0);
-    this.upgrades = Array(numUpgrades).fill(0);
-    this.upgradeMultipliers = Array(numUpgrades).fill(1);
-
-    this.state = new CorporationState();
-}
-
-Corporation.prototype.getState = function() {
-    return this.state.getState();
-}
-
-Corporation.prototype.storeCycles = function(numCycles=1) {
-    this.storedCycles += numCycles;
-}
-
-Corporation.prototype.process = function() {
-    var corp = this;
-    if (this.storedCycles >= CyclesPerIndustryStateCycle) {
-        var state = this.getState(), marketCycles=1;
-        this.storedCycles -= (marketCycles * CyclesPerIndustryStateCycle);
-
-        //At the start of a new cycle, calculate profits from previous cycle
-        if (state === "START") {
-            this.revenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-            this.expenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-            this.divisions.forEach((ind)=>{
-                this.revenue = this.revenue.plus(ind.lastCycleRevenue);
-                this.expenses = this.expenses.plus(ind.lastCycleExpenses);
-            });
-            var profit = this.revenue.minus(this.expenses);
-            var cycleProfit = profit.times(marketCycles * SecsPerMarketCycle);
-            if (isNaN(this.funds)) {
-                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("There was an error calculating your Corporations funds and they got reset to 0. " +
-                                "This is a bug. Please report to game developer.<br><br>" +
-                                "(Your funds have been set to $150b for the inconvenience)");
-                this.funds = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(150e9);
-            }
-            this.funds = this.funds.plus(cycleProfit);
-            this.updateSharePrice();
-        }
-
-        this.divisions.forEach(function(ind) {
-            ind.process(marketCycles, state, corp);
-        });
-
-
-        this.state.nextState();
-
-        if (_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage === _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.Corporation) {this.updateUIContent();}
-    }
-}
-
-Corporation.prototype.determineValuation = function() {
-    var val, profit = (this.revenue.minus(this.expenses)).toNumber();
-    if (this.public) {
-        val = this.funds.toNumber() + (profit * 85e3);
-        val *= (Math.pow(1.1, this.divisions.length));
-        val = Math.max(val, 0);
-    } else {
-        val = 10e9 + Math.max(this.funds.toNumber(), 0) / 3; //Base valuation
-        if (profit > 0) {
-            val += (profit * 320e3);
-            val *= (Math.pow(1.1, this.divisions.length));
-        } else {
-            val = 10e9 * Math.pow(1.1, this.divisions.length);
-        }
-        val -= (val % 1e6); //Round down to nearest millionth
-    }
-    return val * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].CorporationValuation;
-}
-
-Corporation.prototype.getInvestment = function() {
-    var val = this.determineValuation(), percShares;
-    switch (this.fundingRound) {
-        case 0: //Seed
-            percShares = 0.10;
-            break;
-        case 1: //Series A
-            percShares = 0.35;
-            break;
-        case 2: //Series B
-            percShares = 0.25;
-            break;
-        case 3: //Series C
-            percShares = 0.20;
-            break;
-        case 4:
-            return;
-    }
-    var funding = val * percShares * 4,
-        investShares = Math.floor(TOTALSHARES * percShares),
-        yesBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxGetYesButton"])(),
-        noBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxGetNoButton"])();
-    yesBtn.innerHTML = "Accept";
-    noBtn.innerHML = "Reject";
-    yesBtn.addEventListener("click", ()=>{
-        ++this.fundingRound;
-        this.funds = this.funds.plus(funding);
-        this.numShares -= investShares;
-        this.displayCorporationOverviewContent();
-        return Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxClose"])();
-    });
-    noBtn.addEventListener("click", ()=>{
-        return Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxClose"])();
-    });
-    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxCreate"])("An investment firm has offered you " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(funding).format('$0.000a') +
-                   " in funding in exchange for a " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(percShares*100).format("0.000a") +
-                   "% stake in the company (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(investShares).format('0.000a') + " shares).<br><br>" +
-                   "Do you accept or reject this offer?");
-}
-
-Corporation.prototype.goPublic = function() {
-    var goPublicPopupId = "cmpy-mgmt-go-public-popup";
-    var initialSharePrice = this.determineValuation() / (TOTALSHARES);
-    var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        innerHTML: "Enter the number of shares you would like to issue " +
-                   "for your IPO. These shares will be publicly sold " +
-                   "and you will no longer own them. Your Corporation will receive " +
-                   _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(initialSharePrice).format('$0.000a') + " per share " +
-                   "(the IPO money will be deposited directly into your Corporation's funds).<br><br>" +
-                   "Furthermore, issuing more shares now will help drive up " +
-                   "your company's stock price in the future.<br><br>" +
-                   "You have a total of " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.numShares).format("0.000a") + " of shares that you can issue.",
-    });
-    var yesBtn;
-    var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-        type:"number",
-        placeholder: "Shares to issue",
-        onkeyup:(e)=>{
-            e.preventDefault();
-            if (e.keyCode === 13) {yesBtn.click();}
-        }
-    });
-    var br = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {});
-    yesBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:"a-link-button",
-        innerText:"Go Public",
-        clickListener:()=>{
-            var numShares = Math.round(input.value);
-            var initialSharePrice = this.determineValuation() / (TOTALSHARES);
-            if (isNaN(numShares)) {
-                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for number of issued shares");
-                return false;
-            }
-            if (numShares > this.numShares) {
-                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Error: You don't have that many shares to issue!");
-                return false;
-            }
-            this.public = true;
-            this.sharePrice = initialSharePrice;
-            this.issuedShares = numShares;
-            this.numShares -= numShares;
-            this.funds = this.funds.plus(numShares * initialSharePrice);
-            this.displayCorporationOverviewContent();
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(goPublicPopupId);
-            return false;
-        }
-    });
-    var noBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:"a-link-button",
-        innerText:"Cancel",
-        clickListener:()=>{
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(goPublicPopupId);
-            return false;
-        }
-    });
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(goPublicPopupId, [txt, br, input, yesBtn, noBtn]);
-}
-
-Corporation.prototype.updateSharePrice = function() {
-    var targetPrice = this.determineValuation() / (TOTALSHARES - this.issuedShares);
-    if (this.sharePrice <= targetPrice) {
-        this.sharePrice *= (1 + (Math.random() * 0.01));
-    } else {
-        this.sharePrice *= (1 - (Math.random() * 0.01));
-    }
-    if (this.sharePrice <= 0.01) {this.sharePrice = 0.01;}
-}
-
-//One time upgrades that unlock new features
-Corporation.prototype.unlock = function(upgrade) {
-    var upgN = upgrade[0], price = upgrade[1];
-    while (this.unlockUpgrades.length <= upgN) {
-        this.unlockUpgrades.push(0);
-    }
-    if (this.funds.lt(price)) {
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough funds to unlock this!");
-        return;
-    }
-    this.unlockUpgrades[upgN] = 1;
-    this.funds = this.funds.minus(price);
-}
-
-//Levelable upgrades
-Corporation.prototype.upgrade = function(upgrade) {
-    var upgN = upgrade[0], basePrice = upgrade[1], priceMult = upgrade[2],
-        upgradeAmt = upgrade[3]; //Amount by which the upgrade multiplier gets increased (additive)
-    while (this.upgrades.length <= upgN) {this.upgrades.push(0);}
-    while (this.upgradeMultipliers.length <= upgN) {this.upgradeMultipliers.push(1);}
-    var totalCost = basePrice * Math.pow(priceMult, this.upgrades[upgN]);
-    if (this.funds.lt(totalCost)) {
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough funds to purchase this!");
-        return;
-    }
-    ++this.upgrades[upgN];
-    this.funds = this.funds.minus(totalCost);
-
-    //Increase upgrade multiplier
-    this.upgradeMultipliers[upgN] = 1 + (this.upgrades[upgN] * upgradeAmt);
-
-    //If storage size is being updated, update values in Warehouse objects
-    if (upgN === 1) {
-        for (var i = 0; i < this.divisions.length; ++i) {
-            var industry = this.divisions[i];
-            for (var city in industry.warehouses) {
-                if (industry.warehouses.hasOwnProperty(city) && industry.warehouses[city] instanceof Warehouse) {
-                    industry.warehouses[city].updateSize(this);
-                }
-            }
-        }
-    }
-
-    this.updateCorporationOverviewContent();
-}
-
-Corporation.prototype.getProductionMultiplier = function() {
-    var mult = this.upgradeMultipliers[0];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-Corporation.prototype.getStorageMultiplier = function() {
-    var mult = this.upgradeMultipliers[1];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-Corporation.prototype.getDreamSenseGain = function() {
-    var gain = this.upgradeMultipliers[2] - 1;
-    return gain <= 0 ? 0 : gain;
-}
-
-Corporation.prototype.getAdvertisingMultiplier = function() {
-    var mult = this.upgradeMultipliers[3];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-Corporation.prototype.getEmployeeCreMultiplier = function() {
-    var mult = this.upgradeMultipliers[4];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-Corporation.prototype.getEmployeeChaMultiplier = function() {
-    var mult = this.upgradeMultipliers[5];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-Corporation.prototype.getEmployeeIntMultiplier = function() {
-    var mult = this.upgradeMultipliers[6];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-Corporation.prototype.getEmployeeEffMultiplier = function() {
-    var mult = this.upgradeMultipliers[7];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-Corporation.prototype.getSalesMultiplier = function() {
-    var mult = this.upgradeMultipliers[8];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-Corporation.prototype.getScientificResearchMultiplier = function() {
-    var mult = this.upgradeMultipliers[9];
-    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
-}
-
-//Keep 'global' variables for DOM elements so we don't have to search
-//through the DOM tree repeatedly when updating UI
-var companyManagementDiv, companyManagementHeaderTabs, companyManagementPanel,
-    currentCityUi,
-    corporationUnlockUpgrades, corporationUpgrades,
-
-    //Industry Overview Panel
-    industryOverviewPanel, industryOverviewText,
-
-    //Industry Employee Panel
-    industryEmployeePanel, industryEmployeeText, industryEmployeeHireButton, industryEmployeeAutohireButton,
-        industryEmployeeManagementUI, industryEmployeeInfo, industryIndividualEmployeeInfo,
-    industryOfficeUpgradeSizeButton,
-
-    //Industry Warehouse Panel
-    industryWarehousePanel, industrySmartSupplyCheckbox, industryWarehouseStorageText,
-        industryWarehouseUpgradeSizeButton, industryWarehouseStateText,
-        industryWarehouseMaterials, industryWarehouseProducts,
-    headerTabs, cityTabs;
-Corporation.prototype.createUI = function() {
-    companyManagementDiv = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        id:"cmpy-mgmt-container",
-        position:"fixed",
-        class:"generic-menupage-container"
-    });
-    companyManagementHeaderTabs = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {id:"cmpy-mgmt-header-tabs"});
-    companyManagementDiv.appendChild(companyManagementHeaderTabs);
-
-    //Create division/industry tabs at the top
-    this.updateUIHeaderTabs();
-
-    //Create the 'panel' that will have the actual content in the UI
-    companyManagementPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {id:"cmpy-mgmt-panel"});
-    companyManagementDiv.appendChild(companyManagementPanel);
-    document.getElementById("entire-game-container").appendChild(companyManagementDiv);
-
-    this.displayCorporationOverviewContent();
-}
-
-Corporation.prototype.updateUIHeaderTabs = function() {
-    if (companyManagementHeaderTabs) {
-        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(companyManagementHeaderTabs);
-    } else {
-        console.log("ERROR: Header tabs div has not yet been created when Corporation.updateUIHeaderTabs() is called");
-        return;
-    }
-
-    //Corporation overview tabs
-    var cmpyOverviewHdrTab = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
-        id:"cmpy-mgmt-company-tab",
-        class:"cmpy-mgmt-header-tab",
-        innerText:this.name,
-        checked:true,
-        clickListener:()=>{
-            this.selectHeaderTab(cmpyOverviewHdrTab);
-            this.displayCorporationOverviewContent();
-            return false;
-        }
-    });
-    companyManagementHeaderTabs.appendChild(cmpyOverviewHdrTab);
-
-    //Tabs for each division
-    for (var i = 0; i < this.divisions.length; ++i) {
-        this.createDivisionUIHeaderTab(this.divisions[i]);
-    }
-
-    //Create a tab to expand into a new industry
-    companyManagementHeaderTabs.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
-        id:'cmpy-mgmt-expand-industry-tab',
-        class:"cmpy-mgmt-header-tab",
-        innerText:"Expand into new Industry",
-        clickListener: ()=>{
-            if (document.getElementById("cmpy-mgmt-expand-industry-popup") != null) {return;}
-
-            var container = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-                class:"popup-box-container",
-                id:"cmpy-mgmt-expand-industry-popup",
-            });
-            var content = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {class:"popup-box-content"});
-            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerHTML: "Create a new division to expand into a new industry:",
-            });
-            var selector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {
-                class:"cmpy-mgmt-industry-select"
-            });
-            var industryDescription = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {});
-            var yesBtn;
-            var nameInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                type:"text",
-                id:"cmpy-mgmt-expand-industry-name-input",
-                color:"white",
-                backgroundColor:"black",
-                display:"block",
-                maxLength: 30,
-                pattern:"[a-zA-Z0-9-_]",
-                onkeyup:(e)=>{
-                    e.preventDefault();
-                    if (e.keyCode === 13) {yesBtn.click();}
-                }
-            });
-            var nameLabel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("label", {
-                for:"cmpy-mgmt-expand-industry-name-input",
-                innerText:"Division name: "
-            });
-            yesBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("span", {
-                class:"popup-box-button",
-                innerText:"Create Division",
-                clickListener: ()=>{
-                    var ind = selector.options[selector.selectedIndex].value,
-                        newDivisionName = nameInput.value;
-
-                    for (var i = 0; i < this.divisions.length; ++i) {
-                        if (this.divisions[i].name === newDivisionName) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("This name is already in use!");
-                            return false;
-                        }
-                    }
-                    if (this.funds.lt(IndustryStartingCosts[ind])) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Not enough money to create a new division in this industry");
-                    } else if (newDivisionName === "") {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("New division must have a name!");
-                    } else {
-                        this.funds = this.funds.minus(IndustryStartingCosts[ind]);
-                        var newInd = new Industry({
-                            name:newDivisionName,
-                            type:ind,
-                        });
-                        this.divisions.push(newInd);
-                        this.updateUIHeaderTabs();
-                        this.selectHeaderTab(headerTabs[headerTabs.length-2]);
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])("cmpy-mgmt-expand-industry-popup");
-                        this.displayDivisionContent(newInd, _Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12);
-                    }
-                    return false;
-                }
-            });
-            var noBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("span", {
-                class:"popup-box-button",
-                innerText:"Cancel",
-                clickListener: function() {
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])("cmpy-mgmt-expand-industry-popup");
-                    return false;
-                }
-            });
-
-            //Make an object to keep track of what industries you're already in
-            var ownedIndustries = {}
-            for (var i = 0; i < this.divisions.length; ++i) {
-                ownedIndustries[this.divisions[i].type] = true;
-            }
-
-            //Add industry types to selector
-            //Have Agriculture be first as recommended option
-            if (!ownedIndustries["Agriculture"]) {
-                selector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                    text:Industries["Agriculture"], value:"Agriculture"
-                }));
-            }
-
-            for (var key in Industries) {
-                if (key !== "Agriculture" && Industries.hasOwnProperty(key) && !ownedIndustries[key]) {
-                    var ind = Industries[key];
-                    selector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                        text: ind,value:key,
-                    }));
-                }
-            }
-
-            //Initial Industry Description
-            var ind = selector.options[selector.selectedIndex].value;
-            industryDescription.innerHTML = (IndustryDescriptions[ind] + "<br><br>");
-
-            //Change the industry description text based on selected option
-            selector.addEventListener("change", function() {
-                var ind = selector.options[selector.selectedIndex].value;
-                industryDescription.innerHTML = IndustryDescriptions[ind] + "<br><br>";
-            });
-
-            //Add to DOM
-            content.appendChild(txt);
-            content.appendChild(selector);
-            content.appendChild(industryDescription);
-            content.appendChild(nameLabel);
-            content.appendChild(nameInput);
-            content.appendChild(noBtn);
-            content.appendChild(yesBtn);
-            container.appendChild(content);
-            document.getElementById("entire-game-container").appendChild(container);
-            container.style.display = "block";
-            return false;
-        }
-    }));
-
-    headerTabs = companyManagementDiv.getElementsByClassName("cmpy-mgmt-header-tab");
-}
-
-//Updates UI to display which header tab is selected
-Corporation.prototype.selectHeaderTab = function(currentTab) {
-    if (currentTab == null) {return;}
-    for (var i = 0; i < headerTabs.length; ++i) {
-        headerTabs[i].className = "cmpy-mgmt-header-tab";
-    }
-    currentTab.className = "cmpy-mgmt-header-tab current";
-}
-
-Corporation.prototype.createDivisionUIHeaderTab = function(division) {
-    var tabId = "cmpy-mgmt-" + division.name + "-tab";
-    var tab = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
-        id:tabId,
-        class:"cmpy-mgmt-header-tab",
-        innerText:division.name,
-        clickListener:()=>{
-            this.selectHeaderTab(tab);
-            this.displayDivisionContent(division, _Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12);
-            return false;
-        }
-    });
-    companyManagementHeaderTabs.appendChild(tab);
-}
-
-Corporation.prototype.clearUIPanel = function() {
-    while(companyManagementPanel.firstChild) {
-        companyManagementPanel.removeChild(companyManagementPanel.firstChild);
-    }
-}
-
-Corporation.prototype.updateUIContent = function() {
-    //Check which of the header tab buttons is checked
-    if (headerTabs == null) {
-        console.log("ERROR: headerTabs is null in Corporation.updateUIContent()");
-        return;
-    }
-    for (var i = 0; i < headerTabs.length; ++i) {
-        if (headerTabs[i].classList.contains("current")) {
-            if (i === 0) {
-                //Corporation overview
-                this.updateCorporationOverviewContent();
-            } else {
-                //Division
-                this.updateDivisionContent(this.divisions[i-1]);
-            }
-            return;
-        }
-    }
-}
-
-Corporation.prototype.displayCorporationOverviewContent = function() {
-    this.clearUIPanel();
-    companyManagementPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        id:"cmpy-mgmt-overview-text",
-    }));
-    if (headerTabs && headerTabs.length >= 1) {
-        this.selectHeaderTab(headerTabs[0]);
-    }
-
-    //Check if player has Corporation Handbook
-    var homeComp = _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].getHomeComputer(), hasHandbook = false,
-        handbookFn = "corporation-management-handbook.lit";
-    for (var i = 0; i < homeComp.messages.length; ++i) {
-        if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(homeComp.messages[i]) && homeComp.messages[i] === handbookFn) {
-            hasHandbook = true;
-            break;
-        }
-    }
-
-    companyManagementPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:"a-link-button", innerText:"Getting Started Guide", display:"inline-block",
-        tooltip:"Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' " +
-                "This is a .lit file that guides you through the beginning of setting up a Corporation and " +
-                "provides some tips/pointers for helping you get started with managing it.",
-        clickListener:()=>{
-            if (!hasHandbook) {homeComp.messages.push(handbookFn);}
-            Object(_Literature_js__WEBPACK_IMPORTED_MODULE_3__["showLiterature"])(handbookFn);
-            return false;
-        }
-    }));
-
-    //Investors
-    if (this.public) {
-        //Sell share buttons
-        var sellShares = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class:"a-link-button", innerText:"Sell Shares", display:"inline-block",
-            tooltip:"Sell your shares in the company. This is the only way to " +
-                    "profit from your business venture.",
-            clickListener:()=>{
-                var popupId = "cmpy-mgmt-sell-shares-popup";
-                var currentStockPrice = this.sharePrice;
-                var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                    innerHTML: "Enter the number of shares you would like to sell. The money from " +
-                               "selling your shares will go directly to you (NOT your Corporation). " +
-                               "The current price of your " +
-                               "company's stock is " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(currentStockPrice).format("$0.000a"),
-                });
-                var profitIndicator = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {});
-                var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                    type:"number", placeholder:"Shares to sell", margin:"5px",
-                    inputListener: ()=> {
-                        var numShares = Math.round(input.value);
-                        if (isNaN(numShares) || numShares <= 0) {
-                            profitIndicator.innerText = "ERROR: Invalid value entered for number of shares to sell"
-                        } else if (numShares > this.numShares) {
-                            profitIndicator.innerText = "You don't have this many shares to sell!";
-                        } else {
-                            profitIndicator.innerText = "Sell " + numShares + " shares for a total of " +
-                                                        _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(numShares * currentStockPrice).format('$0.000a');
-                        }
-                    }
-                });
-                var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class:"a-link-button", innerText:"Sell shares", display:"inline-block",
-                    clickListener:()=>{
-                        var shares = Math.round(input.value);
-                        if (isNaN(shares) || shares <= 0) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: Invalid value for number of shares");
-                        } else if (shares > this.numShares) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You don't have this many shares to sell");
-                        } else {
-                            this.numShares -= shares;
-                            if (isNaN(this.issuedShares)) {
-                                console.log("ERROR: Corporation issuedShares is NaN: " + this.issuedShares);
-                                console.log("Converting to number now");
-                                var res = parseInt(this.issuedShares);
-                                if (isNaN(res)) {
-                                    this.issuedShares = 0;
-                                } else {
-                                    this.issuedShares = res;
-                                }
-                            }
-                            this.issuedShares += shares;
-                            _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].gainMoney(shares * this.sharePrice);
-                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                            return false;
-                        }
-
-                    }
-                });
-                var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class:"a-link-button", innerText:"Cancel", display:"inline-block",
-                    clickListener:()=>{
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        return false;
-                    }
-                });
-                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, profitIndicator, input, confirmBtn, cancelBtn]);
-            }
-        });
-
-        //Buyback shares button
-        var buybackShares = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class:"a-link-button", innerText:"Buyback shares", display:"inline-block",
-            tooltip:"Buy back shares you that previously issued or sold at market price.",
-            clickListener:()=>{
-                var popupId = "cmpy-mgmt-buyback-shares-popup";
-                var currentStockPrice = this.sharePrice;
-                var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                    innerHTML: "Enter the number of shares you would like to buy back at market price. To purchase " +
-                               "these shares, you must use your own money (NOT your Corporation's funds). " +
-                               "The current price of your " +
-                               "company's stock is " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(currentStockPrice).format("$0.000a") +
-                               ". Your company currently has " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.issuedShares, 3) + " outstanding stock shares",
-                });
-                var costIndicator = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {});
-                var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                    type:"number", placeholder:"Shares to buyback", margin:"5px",
-                    inputListener: ()=> {
-                        var numShares = Math.round(input.value);
-                        //TODO add conditional for if player doesn't have enough money
-                        if (isNaN(numShares) || numShares <= 0) {
-                            costIndicator.innerText = "ERROR: Invalid value entered for number of shares to buyback"
-                        } else if (numShares > this.issuedShares) {
-                            costIndicator.innerText = "There are not this many shares available to buy back. " +
-                                                      "There are only " + this.issuedShares + " outstanding shares.";
-                        } else {
-                            console.log("here");
-                            costIndicator.innerText = "Purchase " + numShares + " shares for a total of " +
-                                                      _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(numShares * currentStockPrice).format('$0.000a');
-                        }
-                    }
-                });
-                var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class:"a-link-button", innerText:"Buy shares", display:"inline-block",
-                    clickListener:()=>{
-                        var shares = Math.round(input.value);
-                        var tempStockPrice = this.sharePrice;
-                        if (isNaN(shares) || shares <= 0) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: Invalid value for number of shares");
-                        } else if (shares > this.issuedShares) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: There are not this many oustanding shares to buy back");
-                        } else if (shares * tempStockPrice > _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].money) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You do not have enough money to purchase this many shares (you need " +
-                                            _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(shares * tempStockPrice).format("$0.000a") + ")");
-                        } else {
-                            this.numShares += shares;
-                            if (isNaN(this.issuedShares)) {
-                                console.log("ERROR: Corporation issuedShares is NaN: " + this.issuedShares);
-                                console.log("Converting to number now");
-                                var res = parseInt(this.issuedShares);
-                                if (isNaN(res)) {
-                                    this.issuedShares = 0;
-                                } else {
-                                    this.issuedShares = res;
-                                }
-                            }
-                            this.issuedShares -= shares;
-                            _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].loseMoney(shares * tempStockPrice);
-                            //TODO REMOVE from Player money
-                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        }
-                        return false;
-
-                    }
-                });
-                var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class:"a-link-button",
-                    innerText:"Cancel",
-                    display:"inline-block",
-                    clickListener:()=>{
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        return false;
-                    }
-                });
-                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, costIndicator, input, confirmBtn, cancelBtn]);
-            }
-        });
-
-        companyManagementPanel.appendChild(sellShares);
-        companyManagementPanel.appendChild(buybackShares);
-
-        //If your Corporation is big enough, buy faction influence through bribes
-        var canBribe = this.determineValuation() >= BribeThreshold;
-        var bribeFactions = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class: canBribe ? "a-link-button" : "a-link-button-inactive",
-            innerText:"Bribe Factions", display:"inline-block",
-            tooltip:canBribe
-                    ? "Use your Corporations power and influence to bribe Faction leaders in exchange for reputation"
-                    : "Your Corporation is not powerful enough to bribe Faction leaders",
-            clickListener:()=>{
-                var popupId = "cmpy-mgmt-bribe-factions-popup";
-                var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                    innerText:"You can use Corporation funds or stock shares to bribe Faction Leaders in exchange for faction reputation"
-                });
-                var factionSelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {margin:"3px"});
-                for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].factions.length; ++i) {
-                    var facName = _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].factions[i];
-                    factionSelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                        text:facName, value:facName
-                    }));
-                }
-                var repGainText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p");
-                var stockSharesInput;
-                var moneyInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                    type:"number", placeholder:"Corporation funds", margin:"5px",
-                    inputListener:()=>{
-                        var money = moneyInput.value == null || moneyInput.value == "" ? 0 : parseFloat(moneyInput.value);
-                        var stockPrice = this.sharePrice;
-                        var stockShares = stockSharesInput.value == null || stockSharesInput.value == "" ? 0 : Math.round(parseFloat(stockSharesInput.value));
-                        if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
-                            repGainText.innerText = "ERROR: Invalid value(s) entered";
-                        } else if (this.funds.lt(money)) {
-                            repGainText.innerText = "ERROR: You do not have this much money to bribe with";
-                        } else if (this.stockShares > this.numShares) {
-                            repGainText.innerText = "ERROR: You do not have this many shares to bribe with";
-                        } else {
-
-                            var totalAmount = Number(money) + (stockShares * stockPrice);
-                            var repGain = totalAmount / BribeToRepRatio;
-                            repGainText.innerText = "You will gain " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(repGain, 0) +
-                                                    " reputation with " +
-                                                    factionSelector.options[factionSelector.selectedIndex].value +
-                                                    " with this bribe";
-                        }
-                    }
-                });
-                stockSharesInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                    type:"number", placeholder:"Stock Shares", margin: "5px",
-                    inputListener:()=>{
-                        var money = moneyInput.value == null || moneyInput.value == "" ? 0 : parseFloat(moneyInput.value);
-                        var stockPrice = this.sharePrice;
-                        var stockShares = stockSharesInput.value == null || stockSharesInput.value == "" ? 0 : Math.round(stockSharesInput.value);
-                        if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
-                            repGainText.innerText = "ERROR: Invalid value(s) entered";
-                        } else if (this.funds.lt(money)) {
-                            repGainText.innerText = "ERROR: You do not have this much money to bribe with";
-                        } else if (this.stockShares > this.numShares) {
-                            repGainText.innerText = "ERROR: You do not have this many shares to bribe with";
-                        } else {
-                            var totalAmount = money + (stockShares * stockPrice);
-                            var repGain = totalAmount / BribeToRepRatio;
-                            console.log("repGain: " + repGain);
-                            repGainText.innerText = "You will gain " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(repGain, 0) +
-                                                    " reputation with " +
-                                                    factionSelector.options[factionSelector.selectedIndex].value +
-                                                    " with this bribe";
-                        }
-                    }
-                });
-                var confirmButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class:"a-link-button", innerText:"Bribe", display:"inline-block",
-                    clickListener:()=>{
-                        var money = moneyInput.value == null || moneyInput.value == "" ? 0 : parseFloat(moneyInput.value);
-                        var stockPrice = this.sharePrice;
-                        var stockShares = stockSharesInput.value == null || stockSharesInput.value == ""? 0 : Math.round(parseFloat(stockSharesInput.value));
-                        var fac = _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Factions"][factionSelector.options[factionSelector.selectedIndex].value];
-                        if (fac == null) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You must select a faction to bribe");
-                            return false;
-                        }
-                        if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: Invalid value(s) entered");
-                        } else if (this.funds.lt(money)) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You do not have this much money to bribe with");
-                        } else if (stockShares > this.numShares) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You do not have this many shares to bribe with");
-                        } else {
-                            var totalAmount = money + (stockShares * stockPrice);
-                            var repGain = totalAmount / BribeToRepRatio;
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You gained " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(repGain, 0) +
-                                            " reputation with " + fac.name  + " by bribing them.");
-                            fac.playerReputation += repGain;
-                            this.funds = this.funds.minus(money);
-                            this.numShares -= stockShares;
-                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                            return false;
-                        }
-                    }
-                });
-                var cancelButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class:"a-link-button", innerText:"Cancel", display:"inline-block",
-                    clickListener:()=>{
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        return false;
-                    }
-                });
-
-                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, factionSelector, repGainText,
-                                      moneyInput, stockSharesInput, confirmButton, cancelButton]);
-            }
-        });
-        companyManagementPanel.appendChild(bribeFactions);
-    } else {
-        var findInvestors = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class: this.fundingRound >= 4 ? "a-link-button-inactive" : "a-link-button tooltip",
-            innerText: "Find Investors",
-            display:"inline-block",
-            clickListener:()=>{
-                this.getInvestment();
-            }
-        });
-        if (this.fundingRound < 4) {
-            var findInvestorsTooltip = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("span", {
-                class:"tooltiptext",
-                innerText:"Search for private investors who will give you startup funding in exchange " +
-                          "for equity (stock shares) in your company"
-            });
-            findInvestors.appendChild(findInvestorsTooltip);
-        }
-
-        var goPublic = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class:"a-link-button tooltip",
-            innerText:"Go Public",
-            display:"inline-block",
-            clickListener:()=>{
-                this.goPublic();
-                return false;
-            }
-        });
-        var goPublicTooltip = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("span", {
-            class:"tooltiptext",
-            innerText: "Become a publicly traded and owned entity. Going public involves " +
-                       "issuing shares for an IPO. Once you are a public company, " +
-                       "your shares will be traded on the stock market."
-        });
-        goPublic.appendChild(goPublicTooltip);
-
-        companyManagementPanel.appendChild(findInvestors);
-        companyManagementPanel.appendChild(goPublic);
-    }
-
-    //Update overview text
-    this.updateCorporationOverviewContent();
-
-    //Don't show upgrades if player hasn't opened any divisions
-    if (this.divisions.length <= 0) {return; }
-    //Corporation Upgrades
-    var upgradeContainer = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        class:"cmpy-mgmt-upgrade-container",
-    });
-    upgradeContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("h1", {
-        innerText:"Unlocks", margin:"6px", padding:"6px",
-    }));
-
-    //Unlock upgrades
-    var corp = this;
-    var numUnlockUpgrades = Object.keys(CorporationUnlockUpgrades).length,
-        numUpgrades = Object.keys(CorporationUpgrades).length;
-    if (this.unlockUpgrades == null || this.upgrades == null) { //Backwards compatibility
-        this.unlockUpgrades = Array(numUnlockUpgrades).fill(0);
-        this.upgrades = Array(numUpgrades).fill(0);
-    }
-    while (this.unlockUpgrades.length < numUnlockUpgrades) {this.unlockUpgrades.push(0);}
-    while (this.upgrades.length < numUpgrades) {this.upgrades.push(0);}
-    while (this.upgradeMultipliers < numUpgrades) {this.upgradeMultipliers.push(1);}
-
-    for (var i = 0; i < numUnlockUpgrades; ++i) {
-        (function(i, corp) {
-            if (corp.unlockUpgrades[i] === 0) {
-                var upgrade = CorporationUnlockUpgrades[i.toString()];
-                if (upgrade == null) {
-                    console.log("ERROR: Could not find upgrade index " + i);
-                    return;
-                }
-
-                upgradeContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-                    class:"cmpy-mgmt-upgrade-div", width:"45%",
-                    innerHTML:upgrade[2] +  " - " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgrade[1]).format("$0.000a"),
-                    tooltip: upgrade[3],
-                    clickListener:()=>{
-                        if (corp.funds.lt(upgrade[1])) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Insufficient funds");
-                        } else {
-                            corp.unlock(upgrade);
-                            corp.displayCorporationOverviewContent();
-                        }
-                    }
-                }));
-            }
-        })(i, corp);
-    }
-
-    //Levelable upgrades
-    upgradeContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("h1", {
-        innerText:"Upgrades", margin:"6px", padding:"6px",
-    }));
-
-    for (var i = 0; i < numUpgrades; ++i) {
-        (function(i, corp) {
-            var upgrade = CorporationUpgrades[i.toString()];
-            if (upgrade == null) {
-                console.log("ERROR: Could not find levelable upgrade index " + i);
-                return;
-            }
-
-            var baseCost = upgrade[1], priceMult = upgrade[2];
-            var cost = baseCost * Math.pow(priceMult, corp.upgrades[i]);
-            upgradeContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-                class:"cmpy-mgmt-upgrade-div", width:"45%",
-                innerHTML:upgrade[4] + " - " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(cost).format("$0.000a"),
-                tooltip:upgrade[5],
-                clickListener:()=>{
-                    if (corp.funds.lt(cost)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Insufficient funds");
-                    } else {
-                        corp.upgrade(upgrade);
-                        corp.displayCorporationOverviewContent();
-                    }
-                }
-            }));
-        })(i, corp);
-    }
-
-    companyManagementPanel.appendChild(upgradeContainer);
-}
-
-Corporation.prototype.updateCorporationOverviewContent = function() {
-    var p = document.getElementById("cmpy-mgmt-overview-text");
-    if (p == null) {
-        console.log("WARNING: Could not find overview text elemtn in updateCorporationOverviewContent()");
-        return;
-    }
-    var totalFunds = this.funds,
-        totalRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0),
-        totalExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
-
-    var profit = this.revenue.minus(this.expenses).toNumber(),
-        profitStr = profit >= 0 ? _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(profit).format("$0.000a") : "-" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(-1 * profit).format("$0.000a");
-
-    var txt = "Total Funds: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(totalFunds.toNumber()).format('$0.000a') + "<br>" +
-              "Total Revenue: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.revenue.toNumber()).format("$0.000a") + " / s<br>" +
-              "Total Expenses: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.expenses.toNumber()).format("$0.000a") + "/ s<br>" +
-              "Total Profits: " + profitStr + " / s<br>" +
-              "Publicly Traded: " + (this.public ? "Yes" : "No") + "<br>" +
-              "Owned Stock Shares: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.numShares).format('0.000a') + "<br>" +
-              "Stock Price: " + (this.public ? "$" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.sharePrice, 2) : "N/A") + "<br><br>";
-
-    var prodMult        = this.getProductionMultiplier(),
-        storageMult     = this.getStorageMultiplier(),
-        advMult         = this.getAdvertisingMultiplier(),
-        empCreMult      = this.getEmployeeCreMultiplier(),
-        empChaMult      = this.getEmployeeChaMultiplier(),
-        empIntMult      = this.getEmployeeIntMultiplier(),
-        empEffMult      = this.getEmployeeEffMultiplier(),
-        salesMult       = this.getSalesMultiplier(),
-        sciResMult      = this.getScientificResearchMultiplier();
-    if (prodMult > 1)       {txt += "Production Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(prodMult, 3) + "<br>";}
-    if (storageMult > 1)    {txt += "Storage Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(storageMult, 3) + "<br>";}
-    if (advMult > 1)        {txt += "Advertising Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(advMult, 3) + "<br>";}
-    if (empCreMult > 1)     {txt += "Empl. Creativity Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(empCreMult, 3) + "<br>";}
-    if (empChaMult > 1)     {txt += "Empl. Charisma Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(empChaMult, 3) + "<br>";}
-    if (empIntMult > 1)     {txt += "Empl. Intelligence Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(empIntMult, 3) + "<br>";}
-    if (empEffMult > 1)     {txt += "Empl. Efficiency Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(empEffMult, 3) + "<br>";}
-    if (salesMult > 1)      {txt += "Sales Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(salesMult, 3) + "<br>";}
-    if (sciResMult > 1)     {txt += "Scientific Research Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(sciResMult, 3) + "<br>";}
-    p.innerHTML = txt;
-}
-
-Corporation.prototype.displayDivisionContent = function(division, city) {
-    this.clearUIPanel();
-    currentCityUi = city;
-
-    //Add the city tabs on the left
-    for (var cityName in division.offices) {
-        if (division.offices[cityName] instanceof OfficeSpace) {
-            this.createCityUITab(cityName, division);
-        }
-    }
-    cityTabs = companyManagementPanel.getElementsByClassName("cmpy-mgmt-city-tab");
-    if (cityTabs.length > 0) {
-        this.selectCityTab(document.getElementById("cmpy-mgmt-city-" + city + "-tab"), city);
-    }
-
-    //Expand into new City button
-    companyManagementPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
-        class:"cmpy-mgmt-city-tab", innerText:"Expand into new City", display:"inline-block",
-        clickListener:()=>{
-            var popupId = "cmpy-mgmt-expand-city-popup";
-            var text = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerText: "Would you like to expand into a new city by opening an office? " +
-                           "This would cost " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(OfficeInitialCost).format('$0.000a'),
-            });
-            var citySelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {margin:"5px"});
-            for (var cityName in division.offices) {
-                if (division.offices.hasOwnProperty(cityName)) {
-                    if (!(division.offices[cityName] instanceof OfficeSpace)) {
-                        citySelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                            text: cityName,
-                            value: cityName
-                        }));
-                    }
-                }
-            }
-
-            var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                innerText:"Confirm", class:"a-link-button", display:"inline-block", margin:"3px",
-                clickListener:()=>{
-                    var city = citySelector.options[citySelector.selectedIndex].value;
-                    if (this.funds.lt(OfficeInitialCost)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to open a new office!");
-                    } else {
-                        this.funds = this.funds.minus(OfficeInitialCost);
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Opened a new office in " + city + "!");
-                        division.offices[city] = new OfficeSpace({
-                            loc:city,
-                            size:OfficeInitialSize,
-                        });
-                        this.displayDivisionContent(division, city);
-                    }
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                innerText:"Cancel", class:"a-link-button", display:"inline-block", margin:"3px",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            })
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [text, citySelector, confirmBtn, cancelBtn]);
-            return false;
-        }
-    }));
-    companyManagementPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {})); // Force line break
-
-    //Get office object
-    var office = division.offices[currentCityUi];
-    if (!(office instanceof OfficeSpace)) {
-        console.log("ERROR: Current city for UI does not have an office space");
-        return;
-    }
-
-    //Left and right panels
-    var leftPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {class:"cmpy-mgmt-industry-left-panel"});
-    var rightPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {class:"cmpy-mgmt-industry-right-panel"});
-    companyManagementPanel.appendChild(leftPanel);
-    companyManagementPanel.appendChild(rightPanel);
-
-    //Different sections (Overview, Employee/Office, and Warehouse)
-    industryOverviewPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        id:"cmpy-mgmt-industry-overview-panel", class:"cmpy-mgmt-industry-overview-panel"
-    });
-    leftPanel.appendChild(industryOverviewPanel);
-
-    industryEmployeePanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        id:"cmpy-mgmt-employee-panel", class:"cmpy-mgmt-employee-panel"
-    });
-    leftPanel.appendChild(industryEmployeePanel);
-
-    industryWarehousePanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        id:"cmpy-mgmt-warehouse-panel", class:"cmpy-mgmt-warehouse-panel"
-    });
-    rightPanel.appendChild(industryWarehousePanel);
-
-    //Industry overview text
-    industryOverviewText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {});
-    industryOverviewPanel.appendChild(industryOverviewText);
-    industryOverviewPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-
-    //Industry overview Purchases & Upgrades
-    var numUpgrades = Object.keys(IndustryUpgrades).length;
-    while (division.upgrades.length < numUpgrades) {division.upgrades.push(0);} //Backwards compatibility
-
-    var industryOverviewUpgrades = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {});
-    industryOverviewUpgrades.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("u", {
-        innerText:"Purchases & Upgrades", margin:"2px", padding:"2px",
-        fontSize:"14px",
-    }));
-    industryOverviewUpgrades.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-    for (var i = 0; i < numUpgrades; ++i) {
-        (function(i, corp, division, office) {
-            var upgrade = IndustryUpgrades[i.toString()];
-            if (upgrade == null) {
-                console.log("ERROR: Could not find levelable upgrade index: " + i);
-                return;
-            }
-
-            var baseCost = upgrade[1], priceMult = upgrade[2], cost = 0;
-            switch(i) {
-                case 0: //Coffee, cost is static per employee
-                    cost = office.employees.length * baseCost;
-                    break;
-                default:
-                    cost = baseCost * Math.pow(priceMult, division.upgrades[i]);
-                    break;
-            }
-            industryOverviewUpgrades.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-                class:"cmpy-mgmt-upgrade-div", display:"inline-block",
-                innerHTML:upgrade[4] + ' - ' + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(cost).format("$0.000a"),
-                tooltip:upgrade[5],
-                clickListener:()=>{
-                    if (corp.funds.lt(cost)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Insufficient funds");
-                    } else {
-                        corp.funds = corp.funds.minus(cost);
-                        division.upgrade(upgrade, {
-                            corporation:corp,
-                            office:office,
-                        });
-                        corp.displayDivisionContent(division, city);
-                    }
-                }
-            }));
-            industryOverviewUpgrades.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-
-        })(i, this, division, office);
-    }
-
-
-    industryOverviewPanel.appendChild(industryOverviewUpgrades);
-
-    //Industry Overview 'Create Product' button if applicable
-    if (division.makesProducts) {
-        //Get the text on the button based on Industry type
-        var createProductButtonText, createProductPopupText;
-        switch(division.type) {
-            case Industries.Food:
-                createProductButtonText = "Build Restaurant";
-                createProductPopupText = "Build and manage a new restaurant!"
-                break;
-            case Industries.Tobacco:
-                createProductButtonText = "Create Product";
-                createProductPopupText = "Create a new tobacco product!";
-                break;
-            case Industries.Pharmaceutical:
-                createProductButtonText = "Create Drug";
-                createProductPopupText = "Design and develop a new pharmaceutical drug!";
-                break;
-            case Industries.Computer:
-            case "Computer":
-                createProductButtonText = "Create Product";
-                createProductPopupText = "Design and manufacture a new computer hardware product!";
-                break;
-            case Industries.Robotics:
-                createProductButtonText = "Design Robot";
-                createProductPopupText = "Design and create a new robot or robotic system!";
-                break;
-            case Industries.Software:
-                createProductButtonText = "Develop Software";
-                createProductPopupText = "Develop a new piece of software!";
-                break;
-            case Industries.HealthCare:
-                createProductButtonText = "Build Hospital";
-                createProductPopupText = "Build and manage a new hospital!";
-                break;
-            case Industries.RealEstate:
-                createProductButtonText = "Develop Property";
-                createProductPopupText = "Develop a new piece of real estate property!";
-                break;
-            default:
-                createProductButtonText = "Create Product";
-                return "";
-        }
-        createProductPopupText += "<br><br>To begin developing a product, " +
-            "first choose the city in which it will be designed. The stats of your employees " +
-            "in the selected city affect the properties of the finished product, such as its " +
-            "quality, performance, and durability.<br><br>" +
-            "You can also choose to invest money in the design and marketing of " +
-            "the product. Investing money in its design will result in a superior product. " +
-            "Investing money in marketing the product will help the product's sales.";
-
-        //Create the button
-        industryOverviewPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class:"a-link-button", innerText:createProductButtonText, margin:"6px", display:"inline-block",
-            clickListener:()=>{
-                var popupId = "cmpy-mgmt-create-product-popup";
-                var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                    innerHTML:createProductPopupText,
-                });
-                var designCity = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {});
-                for (var cityName in division.offices) {
-                    if (division.offices[cityName] instanceof OfficeSpace) {
-                        designCity.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
-                            value:cityName,
-                            text:cityName
-                        }));
-                    }
-                }
-                var foo = "Product Name";
-                if (division.type === Industries.Food) {
-                    foo = "Restaurant Name";
-                } else if (division.type === Industries.Healthcare) {
-                    foo = "Hospital Name";
-                } else if (division.type === Industries.RealEstate) {
-                    foo = "Property Name";
-                }
-                var productNameInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                    placeholder:foo,
-                });
-                var lineBreak1 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br",{});
-                var designInvestInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                    type:"number",
-                    placeholder:"Design investment"
-                });
-                var marketingInvestInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                    type:"number",
-                    placeholder:"Marketing investment"
-                });
-                var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class:"a-link-button",
-                    innerText:"Develop Product",
-                    clickListener:()=>{
-                        if (designInvestInput.value == null) {designInvestInput.value = 0;}
-                        if (marketingInvestInput.value == null) {marketingInvestInput.value = 0;}
-                        var designInvest = parseFloat(designInvestInput.value),
-                            marketingInvest = parseFloat(marketingInvestInput.value);
-                        if (productNameInput.value == null || productNameInput.value === "") {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You must specify a name for your product!");
-                        } else if (isNaN(designInvest)) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for design investment");
-                        } else if (isNaN(marketingInvest))  {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for marketing investment");
-                        } else if (this.funds.lt(designInvest + marketingInvest)) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to make this large of an investment");
-                        } else {
-                            var product = new Product({
-                                name:productNameInput.value.replace(/[<>]/g, ''), //Sanitize for HTMl elements
-                                createCity:designCity.options[designCity.selectedIndex].value,
-                                designCost: designInvest,
-                                advCost: marketingInvest,
-                            });
-                            this.funds = this.funds.minus(designInvest + marketingInvest);
-                            division.products[product.name] = product;
-                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        }
-                        //this.updateUIContent();
-                        this.displayDivisionContent(division, city);
-                        return false;
-                    }
-                })
-                var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class:"a-link-button",
-                    innerText:"Cancel",
-                    clickListener:()=>{
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        return false;
-                    }
-                })
-                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, designCity, productNameInput, lineBreak1,
-                                      designInvestInput, marketingInvestInput, confirmBtn, cancelBtn]);
-            }
-        }));
-    }
-
-    //Employee and Office Panel
-    industryEmployeeText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        id: "cmpy-mgmt-employee-p",
-        display:"block",
-        innerHTML:  "<h1>Office Space</h1><br>" +
-                    "Type: " + office.tier + "<br>" +
-                    "Comfort: " + office.comf + "<br>" +
-                    "Beauty: " + office.beau + "<br>" +
-                    "Size: " + office.employees.length + " / " + office.size + " employees",
-    });
-    industryEmployeePanel.appendChild(industryEmployeeText);
-
-    //Hire Employee button
-    if (office.employees.length === 0) {
-        industryEmployeeHireButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class:"a-link-button",display:"inline-block",
-            innerText:"Hire Employee", fontSize:"13px",
-            tooltip:"You'll need to hire some employees to get your operations started! " +
-                    "It's recommended to have at least one employee in every position",
-            clickListener:()=>{
-                office.findEmployees({corporation:this, division:division});
-                return false;
-            }
-        });
-        //industryEmployeeHireButton.classList.add("flashing-button");
-    } else {
-        industryEmployeeHireButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class:"a-link-button",display:"inline-block",
-            innerText:"Hire Employee", fontSize:"13px",
-            clickListener:()=>{
-                office.findEmployees({corporation:this, division:division});
-                return false;
-            }
-        });
-    }
-    industryEmployeePanel.appendChild(industryEmployeeHireButton);
-
-    //Autohire Employee button
-    industryEmployeeAutohireButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:"a-link-button", display:"inline-block",
-        innerText:"Autohire Employee", fontSize:"13px",
-        tooltip:"Automatically hires an employee and gives him/her a random name",
-        clickListener:()=>{
-            office.hireRandomEmployee({corporation:this, division:division});
-            return false;
-        }
-    });
-    industryEmployeePanel.appendChild(industryEmployeeAutohireButton);
-
-    //Upgrade Office Size button
-    industryEmployeePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-    industryOfficeUpgradeSizeButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:"a-link-button", innerText:"Upgrade size",
-        display:"inline-block", margin:"6px", fontSize:"13px",
-        tooltip:"Upgrade the office's size so that it can hold more employees!",
-        clickListener:()=>{
-            var popupId = "cmpy-mgmt-upgrade-office-size-popup";
-            var initialPriceMult = Math.round(office.size / OfficeInitialSize);
-            var upgradeCost = OfficeInitialCost * Math.pow(1.07, initialPriceMult);
-
-            //Calculate cost to upgrade size by 15 employees
-            var mult = 0;
-            for (var i = 0; i < 5; ++i) {
-                mult += (Math.pow(1.07, initialPriceMult + i));
-            }
-            var upgradeCost15 = OfficeInitialCost * mult;
-
-            //Calculate max upgrade size and cost
-            var maxMult = (this.funds.dividedBy(OfficeInitialCost)).toNumber();
-            var maxNum = 1;
-            mult = Math.pow(1.07, initialPriceMult);
-            while(maxNum < 50) { //Hard cap of 50x (extra 150 employees)
-                if (mult >= maxMult) {break;}
-                var multIncrease = Math.pow(1.07, initialPriceMult + maxNum);
-                if (mult + multIncrease > maxMult) {
-                    break;
-                } else {
-                    mult += multIncrease;
-                }
-                ++maxNum;
-            }
-
-            var upgradeCostMax = OfficeInitialCost * mult;
-
-            var text = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerText:"Increase the size of your office space to fit additional employees!"
-            });
-            var text2 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {innerText: "Upgrade size: "});
-
-            var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class: this.funds.lt(upgradeCost) ? "a-link-button-inactive" : "a-link-button",
-                display:"inline-block", margin:"4px", innerText:"by 3",
-                tooltip:_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgradeCost).format("$0.000a"),
-                clickListener:()=>{
-                    if (this.funds.lt(upgradeCost)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to purchase this upgrade!");
-                    } else {
-                        office.size += OfficeInitialSize;
-                        this.funds = this.funds.minus(upgradeCost);
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Office space increased! It can now hold " + office.size + " employees");
-                        this.updateUIContent();
-                    }
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            var confirmBtn15 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class: this.funds.lt(upgradeCost15) ? "a-link-button-inactive" : "a-link-button",
-                display:"inline-block", margin:"4px", innerText:"by 15",
-                tooltip:_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgradeCost15).format("$0.000a"),
-                clickListener:()=>{
-                    if (this.funds.lt(upgradeCost15)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to purchase this upgrade!");
-                    } else {
-                        office.size += (OfficeInitialSize * 5);
-                        this.funds = this.funds.minus(upgradeCost15);
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Office space increased! It can now hold " + office.size + " employees");
-                        this.updateUIContent();
-                    }
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            var confirmBtnMax = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:this.funds.lt(upgradeCostMax) ? "a-link-button-inactive" : "a-link-button",
-                display:"inline-block", margin:"4px", innerText:"by MAX (" + maxNum*OfficeInitialSize + ")",
-                tooltip:_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgradeCostMax).format("$0.000a"),
-                clickListener:()=>{
-                    if (this.funds.lt(upgradeCostMax)) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to purchase this upgrade!");
-                    } else {
-                        office.size += (OfficeInitialSize * maxNum);
-                        this.funds = this.funds.minus(upgradeCostMax);
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Office space increased! It can now hold " + office.size + " employees");
-                        this.updateUIContent();
-                    }
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button", innerText:"Cancel", display:"inline-block", margin:"4px",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            })
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [text, text2, confirmBtn, confirmBtn15, confirmBtnMax, cancelBtn]);
-            return false;
-        }
-    });
-    industryEmployeePanel.appendChild(industryOfficeUpgradeSizeButton);
-
-    //Throw Office Party
-    industryEmployeePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-        class:"a-link-button", display:"inline-block", innerText:"Throw Party",
-        fontSize:"13px",
-        tooltip:"Throw an office party to increase your employee's morale and happiness",
-        clickListener:()=>{
-            var popupId = "cmpy-mgmt-throw-office-party-popup";
-            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerText:"Enter the amount of money you would like to spend PER EMPLOYEE " +
-                          "on this office party"
-            });
-            var totalCostTxt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-                innerText:"Throwing this party will cost a total of $0"
-            });
-            var confirmBtn;
-            var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
-                type:"number", margin:"5px", placeholder:"$ / employee",
-                inputListener:()=>{
-                    if (isNaN(input.value) || input.value < 0) {
-                        totalCostTxt.innerText = "Invalid value entered!"
-                    } else {
-                        var totalCost = input.value * office.employees.length;
-                        totalCostTxt.innerText = "Throwing this party will cost a total of " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(totalCost).format('$0.000a');
-                    }
-                },
-                onkeyup:(e)=>{
-                    e.preventDefault();
-                    if (e.keyCode === 13) {confirmBtn.click();}
-                }
-            });
-            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button",
-                display:"inline-block",
-                innerText:"Throw Party",
-                clickListener:()=>{
-                    if (isNaN(input.value) || input.value < 0) {
-                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value entered");
-                    } else {
-                        var totalCost = input.value * office.employees.length;
-                        if (this.funds.lt(totalCost)) {
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to throw this party!");
-                        } else {
-                            this.funds = this.funds.minus(totalCost);
-                            var mult;
-                            for (var fooit = 0; fooit < office.employees.length; ++fooit) {
-                                mult = office.employees[fooit].throwParty(input.value);
-                            }
-                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You threw a party for the office! The morale and happiness " +
-                                            "of each employee increased by " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])((mult-1) * 100, 2) + "%.");
-                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                        }
-                    }
-                    return false;
-                }
-            });
-            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                class:"a-link-button",
-                display:"inline-block",
-                innerText:"Cancel",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, totalCostTxt, input, confirmBtn, cancelBtn]);
-        }
-    }));
-
-    industryEmployeeManagementUI = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {});
-    industryEmployeeInfo = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {margin:"4px", padding:"4px"});
-    if (empManualAssignmentModeActive) {
-        //Employees manually assigned
-        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class:"a-link-button", display:"inline-block", margin:"4px",
-            innerText:"Switch to Auto Mode",
-            tooltip:"Switch to Automatic Assignment Mode, which will automatically  " +
-                    "assign employees to your selected jobs. You simply have to select " +
-                    "the number of assignments for each job",
-            clickListener:()=>{
-                empManualAssignmentModeActive = false;
-                this.displayDivisionContent(division, city);
-            }
-        }));
-        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-
-        industryIndividualEmployeeInfo = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {margin:"4px", padding:"4px"});
-        var selector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {
-            color: "white", backgroundColor:"black", margin:"4px", padding:"4px",
-            changeListener:()=>{
-                var name = selector.options[selector.selectedIndex].text;
-                for (var i = 0; i < office.employees.length; ++i) {
-                    if (office.employees[i].name === name) {
-                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryIndividualEmployeeInfo);
-                        office.employees[i].createUI(industryIndividualEmployeeInfo, this);
-                        return;
-                    }
-                }
-                console.log("ERROR: Employee in selector could not be found");
-            }
-        });
-
-        for (var i = 0; i < office.employees.length; ++i) {
-            selector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {text:office.employees[i].name}));
-        }
-
-        selector.selectedIndex = -1;
-
-        industryEmployeeManagementUI.appendChild(industryEmployeeInfo);
-        industryEmployeeManagementUI.appendChild(selector);
-        industryEmployeeManagementUI.appendChild(industryIndividualEmployeeInfo);
-    } else {
-        //Player only manages the number of each occupation, not who gets what job
-        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            class:"a-link-button", display:"inline-block", margin:"4px",
-            innerText:"Switch to Manual Mode",
-            tooltip:"Switch to Manual Assignment Mode, which allows you to " +
-                    "specify which employees should get which jobs",
-            clickListener:()=>{
-                empManualAssignmentModeActive = true;
-                this.displayDivisionContent(division, city);
-            }
-        }));
-        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-
-        var opCount = 0, engCount = 0, busCount = 0,
-            mgmtCount = 0, rndCount = 0, unassignedCount = 0,
-            trainingCount = 0;
-        for (var i = 0; i < office.employees.length; ++i) {
-            switch (office.employees[i].pos) {
-                case EmployeePositions.Operations:
-                    ++opCount; break;
-                case EmployeePositions.Engineer:
-                    ++engCount; break;
-                case EmployeePositions.Business:
-                    ++busCount; break;
-                case EmployeePositions.Management:
-                    ++mgmtCount; break;
-                case EmployeePositions.RandD:
-                    ++rndCount; break;
-                case EmployeePositions.Unassigned:
-                    ++unassignedCount; break;
-                case EmployeePositions.Training:
-                    ++trainingCount; break;
-                default:
-                    console.log("ERROR: Unrecognized employee position: " + office.employees[i].pos);
-                    break;
-            }
-        }
-
-        //Unassigned employee count display
-        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-            display:"inline-block",
-            innerText:"Unassigned Employees: " + unassignedCount,
-        }));
-        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-
-        //General display of employee information (avg morale, avg energy, etc.)
-        industryEmployeeManagementUI.appendChild(industryEmployeeInfo);
-        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-
-        var positions = [EmployeePositions.Operations, EmployeePositions.Engineer,
-                         EmployeePositions.Business, EmployeePositions.Management,
-                         EmployeePositions.RandD, EmployeePositions.Training];
-        var descriptions = ["Manages supply chain operations. Improves production.", //Operations
-                            "Develops and maintains products and production systems. Improves production.", //Engineer
-                            "Handles sales and finances. Improves sales.", //Business
-                            "Leads and oversees employees and office operations. Improves production.", //Management
-                            "Research new innovative ways to improve the company. Generates Scientific Research", //RandD
-                            "Set employee to training, which will increase some of their stats. Employees in training do not affect any company operations."] //Training
-        var counts = [opCount, engCount, busCount, mgmtCount, rndCount, trainingCount];
-        for (var i = 0; i < positions.length; ++i) {
-            (function(corp, i) {
-                var info = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("h2", {
-                    display:"inline-block", width:"40%", fontSize:"15px",
-                    innerText: positions[i] + "(" + counts[i] + ")",
-                    tooltipleft: descriptions[i]
-                });
-                var plusBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class: unassignedCount > 0 ? "a-link-button" : "a-link-button-inactive",
-                    display:"inline-block", innerText:"+",
-                    clickListener:()=>{
-                        office.assignEmployeeToJob(positions[i]);
-                        corp.displayDivisionContent(division, city);
-                    }
-                });
-                var minusBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-                    class: counts[i] > 0 ? "a-link-button" : "a-link-button-inactive",
-                    display:"inline-block", innerText:"-",
-                    clickListener:()=>{
-                        office.unassignEmployeeFromJob(positions[i]);
-                        corp.displayDivisionContent(division, city);
-                    }
-                });
-                var newline = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {});
-                industryEmployeeManagementUI.appendChild(info);
-                industryEmployeeManagementUI.appendChild(plusBtn);
-                industryEmployeeManagementUI.appendChild(minusBtn);
-                industryEmployeeManagementUI.appendChild(newline);
-            })(this, i);
-        }
-    }
-    industryEmployeePanel.appendChild(industryEmployeeManagementUI);
-
-    //Warehouse Panel
-    var warehouse = division.warehouses[currentCityUi];
-    if (warehouse instanceof Warehouse) {
-        warehouse.createUI({industry:division, company: this});
-    } else {
-        industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
-            innerText:"Purchase Warehouse ($5b)",
-            class: "a-link-button",
-            clickListener:()=>{
-                if (this.funds.lt(WarehouseInitialCost)) {
-                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You do not have enough funds to do this!");
-                } else {
-                    division.warehouses[currentCityUi] = new Warehouse({
-                        loc:currentCityUi,
-                        size:WarehouseInitialSize,
-                    });
-                    this.funds = this.funds.minus(WarehouseInitialCost);
-                    this.displayDivisionContent(division, currentCityUi);
-                }
-                return false;
-            }
-        }));
-    }
-    this.updateDivisionContent(division);
-}
-
-Corporation.prototype.updateDivisionContent = function(division) {
-    if (!(division instanceof Industry)) {
-        console.log("ERROR: Invalid 'division' argument in Corporation.updateDivisionContent");
-        return;
-    }
-    var vechain = (this.unlockUpgrades[4] === 1);
-    //Industry Overview Text
-    var profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber(),
-        profitStr = profit >= 0 ? _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(profit).format("$0.000a") : "-" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(-1 * profit).format("$0.000a");
-    var advertisingInfo = "";
-    if (vechain) {
-        var advertisingFactors = division.getAdvertisingFactors();
-        var awarenessFac = advertisingFactors[1];
-        var popularityFac = advertisingFactors[2];
-        var ratioFac = advertisingFactors[3];
-        var totalAdvertisingFac = advertisingFactors[0];
-        advertisingInfo =
-            "<p class='tooltip'>Advertising Multiplier: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(totalAdvertisingFac, 3) +
-            "<span class='tooltiptext' style='font-size:12px'>Total multiplier for this industry's sales due to its awareness and popularity<br>" +
-            "Awareness Bonus: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(Math.pow(awarenessFac, 0.85), 3) + "<br>" +
-            "Popularity Bonus: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(Math.pow(popularityFac, 0.85), 3) + "<br>" +
-            "Ratio Multiplier: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(Math.pow(ratioFac, 0.85), 3) + "</span></p><br>"
-
-    }
-
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryOverviewText);
-    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        innerHTML:"Industry: " + division.type + " (Corp Funds: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.funds.toNumber()).format("$0.000a") + ")<br><br>" +
-                  "Awareness: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.awareness, 3) + "<br>" +
-                  "Popularity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.popularity, 3) +  "<br>" +
-                  advertisingInfo + "<br>" +
-                  "Revenue: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(division.lastCycleRevenue.toNumber()).format("$0.000a") + " / s<br>" +
-                  "Expenses: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(division.lastCycleExpenses.toNumber()).format("$0.000a") + " /s<br>" +
-                  "Profit: " + profitStr + " / s<br><br>"
-    }));
-    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        marginTop:"2px",
-        innerText:"Production Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.prodMult, 2),
-        tooltip:"Production gain from owning production-boosting materials " +
-                "such as hardware, Robots, AI Cores, and Real Estate"
-    }));
-    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
-        innerText:"?", class:"help-tip",
-        clickListener:()=>{
-            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Owning Hardware, Robots, AI Cores, and Real Estate " +
-                            "can boost your Industry's production. The effect these " +
-                            "materials have on your production varies between Industries. " +
-                            "For example, Real Estate may be very effective for some Industries, " +
-                            "but ineffective for others.<br><br>" +
-                            "This division's production multiplier is calculated by summing " +
-                            "the individual production multiplier of each of its office locations. " +
-                            "This production multiplier is applied to each office. Therefore, it is " +
-                            "beneficial to expand into new cities as this can greatly increase the " +
-                            "production multiplier of your entire Division.");
-        }
-    }));
-    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br"));
-    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-        display:"inline-block",
-        innerText:"Scientific Research: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.sciResearch.qty, 3),
-        tooltip:"Scientific Research increases the quality of the materials and " +
-                "products that you produce."
-    }));
-
-    //Office and Employee List
-    var office = division.offices[currentCityUi];
-    industryEmployeeText.innerHTML =
-                "<h1>Office Space</h1><br>" +
-                "Type: " + office.tier + "<br>" +
-                "Comfort: " + office.comf + "<br>" +
-                "Beauty: " + office.beau + "<br>" +
-                "Size: " + office.employees.length + " / " + office.size + " employees";
-    if (office.employees.length >= office.size) {
-        industryEmployeeHireButton.className = "a-link-button-inactive";
-        industryEmployeeAutohireButton.className = "a-link-button-inactive tooltip";
-    } else if (office.employees.length === 0) {
-        industryEmployeeHireButton.className = "a-link-button tooltip flashing-button";
-        industryEmployeeAutohireButton.className = "a-link-button tooltip";
-    } else {
-        industryEmployeeHireButton.className = "a-link-button";
-        industryEmployeeAutohireButton.className = "a-link-button tooltip";
-    }
-
-    //Employee Overview stats
-    //Calculate average morale, happiness, and energy
-    var totalMorale = 0, totalHappiness = 0, totalEnergy = 0,
-        avgMorale = 0, avgHappiness = 0, avgEnergy = 0;
-    for (var i = 0; i < office.employees.length; ++i) {
-        totalMorale += office.employees[i].mor;
-        totalHappiness += office.employees[i].hap;
-        totalEnergy += office.employees[i].ene;
-    }
-    if (office.employees.length > 0) {
-        avgMorale = totalMorale / office.employees.length;
-        avgHappiness = totalHappiness / office.employees.length;
-        avgEnergy = totalEnergy / office.employees.length;
-    }
-    industryEmployeeInfo.innerHTML =
-        "Avg Employee Morale: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(avgMorale, 3) + "<br>" +
-        "Avg Employee Happiness: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(avgHappiness, 3) + "<br>" +
-        "Avg Employee Energy: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(avgEnergy, 3);
-    if (vechain) { //VeChain - Statistics
-        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-            innerText:"Material Production: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.getOfficeProductivity(office), 3),
-            tooltip: "The base amount of material this office can produce. Does not include " +
-                     "production multipliers from upgrades and materials. This value is based off " +
-                     "the productivity of your Operations, Engineering, and Management employees"
-        }));
-        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-            innerText:"Product Production: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.getOfficeProductivity(office, {forProduct:true}), 3),
-            tooltip: "The base amount of any given Product this office can produce. Does not include " +
-                     "production multipliers from upgrades and materials. This value is based off " +
-                     "the productivity of your Operations, Engineering, and Management employees"
-        }));
-        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
-        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
-            innerText: "Business Multiplier: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.getBusinessFactor(office), 3),
-            tooltip: "The effect this office's 'Business' employees has on boosting sales"
-        }));
-    }
-
-    //Warehouse
-    var warehouse = division.warehouses[currentCityUi];
-    if (warehouse instanceof Warehouse) {
-        warehouse.updateUI({industry:division, company:this});
-    }
-}
-
-Corporation.prototype.createCityUITab = function(city, division) {
-    var tab = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
-        id:"cmpy-mgmt-city-" + city + "-tab",
-        class:"cmpy-mgmt-city-tab",
-        innerText:city,
-        clickListener:()=>{
-            this.selectCityTab(tab, city);
-            this.displayDivisionContent(division, city);
-            return false;
-        }
-    });
-    companyManagementPanel.appendChild(tab);
-}
-
-Corporation.prototype.selectCityTab = function(activeTab, city) {
-    if (activeTab == null) {
-        activeTab = document.getElementById("cmpy-mgmt-city-" + city + "-tab");
-        if (activeTab == null) {return;}
-    }
-    for (var i = 0; i < cityTabs.length; ++i) {
-        cityTabs[i].className = "cmpy-mgmt-city-tab";
-    }
-    activeTab.className = "cmpy-mgmt-city-tab current";
-}
-
-Corporation.prototype.clearUI = function() {
-    //Delete everything
-    if (companyManagementDiv != null) {Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(companyManagementDiv.id);}
-
-    //Reset global DOM variables
-    companyManagementDiv        = null;
-    companyManagementPanel      = null;
-    currentCityUi               = null;
-
-    corporationUnlockUpgrades   = null;
-    corporationUpgrades         = null;
-
-    industryOverviewPanel       = null;
-    industryOverviewText        = null;
-
-    industryEmployeePanel           = null;
-    industryEmployeeText            = null;
-    industryEmployeeHireButton      = null;
-    industryEmployeeAutohireButton  = null;
-    industryEmployeeManagementUI    = null;
-    industryEmployeeInfo            = null;
-    industryIndividualEmployeeInfo  = null;
-
-    industryOfficeUpgradeSizeButton = null;
-
-    industryWarehousePanel              = null;
-    industrySmartSupplyCheckbox         = null;
-    industryWarehouseStorageText        = null;
-    industryWarehouseUpgradeSizeButton  = null;
-    industryWarehouseStateText          = null;
-    industryWarehouseMaterials          = null;
-    industryWarehouseProducts           = null;
-
-    companyManagementHeaderTabs = null;
-    headerTabs                  = null;
-    cityTabs                    = null;
-
-    document.getElementById("character-overview-wrapper").style.visibility = "visible";
-}
-
-Corporation.prototype.toJSON = function() {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Corporation", this);
-}
-
-Corporation.fromJSON = function(value) {
-	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Corporation, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Corporation = Corporation;
-
-
-
-
-/***/ }),
-/* 41 */
 /*!********************************************!*\
   !*** ./node_modules/jquery/dist/jquery.js ***!
   \********************************************/
@@ -54088,27 +48653,34 @@ return jQuery;
 
 
 /***/ }),
-/* 42 */
-/*!********************************!*\
-  !*** ./src/ActiveScriptsUI.js ***!
-  \********************************/
+/* 39 */
+/*!****************************!*\
+  !*** ./src/HacknetNode.js ***!
+  \****************************/
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setActiveScriptsClickHandlers", function() { return setActiveScriptsClickHandlers; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addActiveScriptsItem", function() { return addActiveScriptsItem; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deleteActiveScriptsItem", function() { return deleteActiveScriptsItem; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateActiveScriptsItems", function() { return updateActiveScriptsItems; });
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
-/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Server.js */ 10);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_LogBox_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/LogBox.js */ 50);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6__);
-/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hacknetNodesInit", function() { return hacknetNodesInit; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HacknetNode", function() { return HacknetNode; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "purchaseHacknet", function() { return purchaseHacknet; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateTotalHacknetProduction", function() { return updateTotalHacknetProduction; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCostOfNextHacknetNode", function() { return getCostOfNextHacknetNode; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateHacknetNodesMultiplierButtons", function() { return updateHacknetNodesMultiplierButtons; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getMaxNumberLevelUpgrades", function() { return getMaxNumberLevelUpgrades; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayHacknetNodesContent", function() { return displayHacknetNodesContent; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateHacknetNodesContent", function() { return updateHacknetNodesContent; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "processAllHacknetNodeEarnings", function() { return processAllHacknetNodeEarnings; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getHacknetNode", function() { return getHacknetNode; });
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15);
+/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
+/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engine.js */ 5);
+/* harmony import */ var _InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./InteractiveTutorial.js */ 25);
+/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Player.js */ 0);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
+/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
 
 
 
@@ -54119,343 +48691,5546 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-/* Active Scripts UI*/
-function setActiveScriptsClickHandlers() {
-    //Server panel click handlers
-    var serverPanels = document.getElementsByClassName("active-scripts-server-header");
-    if (serverPanels == null) {
-        console.log("ERROR: Could not find Active Scripts server panels");
-        return;
+/* HacknetNode.js */
+function hacknetNodesInit() {
+    var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
+    mult1x.addEventListener("click", function() {
+        hacknetNodePurchaseMultiplier = 1;
+        updateHacknetNodesMultiplierButtons();
+        updateHacknetNodesContent();
+        return false;
+    });
+    var mult5x = document.getElementById("hacknet-nodes-5x-multiplier");
+    mult5x.addEventListener("click", function() {
+        hacknetNodePurchaseMultiplier = 5;
+        updateHacknetNodesMultiplierButtons();
+        updateHacknetNodesContent();
+        return false;
+    });
+    var mult10x = document.getElementById("hacknet-nodes-10x-multiplier");
+    mult10x.addEventListener("click", function() {
+        hacknetNodePurchaseMultiplier = 10;
+        updateHacknetNodesMultiplierButtons();
+        updateHacknetNodesContent();
+        return false;
+    });
+    var multMax = document.getElementById("hacknet-nodes-max-multiplier");
+    multMax.addEventListener("click", function() {
+        hacknetNodePurchaseMultiplier = 0;
+        updateHacknetNodesMultiplierButtons();
+        updateHacknetNodesContent();
+        return false;
+    });
+}
+document.addEventListener("DOMContentLoaded", hacknetNodesInit, false);
+
+function HacknetNode(name) {
+    this.level      = 1;
+    this.ram        = 1; //GB
+    this.cores      = 1;
+
+    this.name       = name;
+
+    this.totalMoneyGenerated    = 0;
+    this.onlineTimeSeconds      = 0;
+
+    this.moneyGainRatePerSecond = 0;
+}
+
+HacknetNode.prototype.updateMoneyGainRate = function() {
+    //How much extra $/s is gained per level
+    var gainPerLevel = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMoneyGainPerLevel;
+
+    this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
+                                  Math.pow(1.035, this.ram-1) *
+                                  ((this.cores + 5) / 6) *
+                                  _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_money_mult *
+                                  _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].HacknetNodeMoney;
+    if (isNaN(this.moneyGainRatePerSecond)) {
+        this.moneyGainRatePerSecond = 0;
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_5__["dialogBoxCreate"])("Error in calculating Hacknet Node production. Please report to game developer");
     }
-    for (i = 0; i < serverPanels.length; ++i) {
-        serverPanels[i].onclick = function() {
-            this.classList.toggle("active");
 
-            var panel = this.nextElementSibling;
-            if (panel.style.display === "block") {
-                panel.style.display = "none";
-            } else {
-                panel.style.display = "block";
-            }
+    updateTotalHacknetProduction();
+}
+
+HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
+    levels = Math.round(levels);
+    if (isNaN(levels) || levels < 1) {return 0;}
+    var mult = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeUpgradeLevelMult;
+    var totalMultiplier = 0; //Summed
+    var currLevel = this.level;
+    for (var i = 0; i < levels; ++i) {
+        totalMultiplier += Math.pow(mult, currLevel);
+        ++currLevel;
+    }
+    return _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].BaseCostForHacknetNode / 2 * totalMultiplier * _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_level_cost_mult;
+}
+
+//Wrapper function for Netscript
+HacknetNode.prototype.getLevelUpgradeCost = function(levels=1) {
+    return this.calculateLevelUpgradeCost(levels);
+}
+
+HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
+    levels = Math.round(levels);
+    var cost = this.calculateLevelUpgradeCost(levels);
+    if (isNaN(cost) || levels < 0) {return false;}
+    if (this.level + levels > _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel) {
+        var diff = Math.max(0, _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel - this.level);
+        return this.purchaseLevelUpgrade(diff);
+    }
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {return false;}
+    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].loseMoney(cost);
+    this.level += levels;
+    this.updateMoneyGainRate();
+    return true;
+}
+
+//Wrapper function for Netscript
+HacknetNode.prototype.upgradeLevel = function(levels=1) {
+    return this.purchaseLevelUpgrade(levels);
+}
+
+HacknetNode.prototype.calculateRamUpgradeCost = function() {
+    var numUpgrades = Math.log2(this.ram);
+
+    //Calculate cost
+    //Base cost of RAM is 50k per 1GB, increased by some multiplier for each time RAM is upgraded
+    var baseCost = this.ram * _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].BaseCostFor1GBOfRamHacknetNode;
+    var mult = Math.pow(_Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeUpgradeRamMult, numUpgrades);
+    return baseCost * mult * _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_ram_cost_mult;
+}
+
+//Wrapper function for Netscript
+HacknetNode.prototype.getRamUpgradeCost = function() {
+    return this.calculateRamUpgradeCost();
+}
+
+HacknetNode.prototype.purchaseRamUpgrade = function() {
+    var cost = this.calculateRamUpgradeCost();
+    if (isNaN(cost)) {return false;}
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {return false;}
+    if (this.ram >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxRam) {return false;}
+    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].loseMoney(cost);
+    this.ram *= 2; //Ram is always doubled
+    this.updateMoneyGainRate();
+    return true;
+}
+
+//Wrapper function for Netscript
+HacknetNode.prototype.upgradeRam = function() {
+    return this.purchaseRamUpgrade();
+}
+
+HacknetNode.prototype.calculateCoreUpgradeCost = function() {
+    var coreBaseCost = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].BaseCostForHacknetNodeCore;
+    var mult = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeUpgradeCoreMult;
+    return coreBaseCost * Math.pow(mult, this.cores-1) * _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_core_cost_mult;
+}
+
+//Wrapper function for Netscript
+HacknetNode.prototype.getCoreUpgradeCost = function() {
+    return this.calculateCoreUpgradeCost();
+}
+
+HacknetNode.prototype.purchaseCoreUpgrade = function() {
+    var cost = this.calculateCoreUpgradeCost();
+    if (isNaN(cost)) {return false;}
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {return false;}
+    if (this.cores >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxCores) {return false;}
+    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].loseMoney(cost);
+    ++this.cores;
+    this.updateMoneyGainRate();
+    return true;
+}
+
+//Wrapper function for Netscript
+HacknetNode.prototype.upgradeCore = function() {
+    return this.purchaseCoreUpgrade();
+}
+
+/* Saving and loading HackNets */
+HacknetNode.prototype.toJSON = function() {
+    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__["Generic_toJSON"])("HacknetNode", this);
+}
+
+HacknetNode.fromJSON = function(value) {
+    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__["Generic_fromJSON"])(HacknetNode, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__["Reviver"].constructors.HacknetNode = HacknetNode;
+
+
+function purchaseHacknet() {
+    /* INTERACTIVE TUTORIAL */
+    if (_InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__["iTutorialIsRunning"]) {
+        if (_InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__["currITutorialStep"] == _InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__["iTutorialSteps"].HacknetNodesIntroduction) {
+            Object(_InteractiveTutorial_js__WEBPACK_IMPORTED_MODULE_3__["iTutorialNextStep"])();
+        } else {
+            return;
         }
     }
 
-    //Script Panel click handlers
-    var scriptPanels = document.getElementsByClassName("active-scripts-script-header");
-    if (scriptPanels == null) {
-        console.log("ERROR: Could not find Active Scripts panels for individual scripts");
-        return;
-    }
-    for (var i = 0; i < scriptPanels.length; ++i) {
-        scriptPanels[i].onclick = function() {
-            this.classList.toggle("active");
+    /* END INTERACTIVE TUTORIAL */
 
-            var panel = this.nextElementSibling;
-            if (panel.style.display === "block") {
-                panel.style.display = "none";
-            } else {
-                panel.style.display = "block";
-            }
-        }
+    var cost = getCostOfNextHacknetNode();
+    if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {
+        //dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
+        return false;
     }
+
+    //Auto generate a name for the node for now...TODO
+    var numOwned = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length;
+    var name = "hacknet-node-" + numOwned;
+    var node = new HacknetNode(name);
+    node.updateMoneyGainRate();
+
+    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].loseMoney(cost);
+    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.push(node);
+
+    displayHacknetNodesContent();
+    updateTotalHacknetProduction();
+    return numOwned;
 }
 
-//Returns the ul element containins all script items for a specific server
-function getActiveScriptsServerList(server) {
-    if (server == null) {return null;}
-    var panelname = "active-scripts-server-panel-" + server.hostname;
-    var item = document.getElementById(panelname + "-script-list");
-    if (item == null) {
-        console.log("ERROR: Cannot find list for: " + server.hostname);
-    }
-    return item;
-}
-
-function createActiveScriptsServerPanel(server) {
-    var panelname = "active-scripts-server-panel-" + server.hostname;
-    var activeScriptsList = document.getElementById("active-scripts-list");
-
-    //Div of entire Panel
-    var panelDiv = document.createElement("div");
-    panelDiv.setAttribute("id", panelname);
-
-    //Panel Header
-    var panelHdr = document.createElement("button");
-    panelHdr.setAttribute("class", "active-scripts-server-header")
-    panelHdr.setAttribute("id", panelname + "-hdr");
-    panelHdr.innerHTML = server.hostname;
-
-    //Panel content
-    var panelContentDiv = document.createElement("div");
-    panelContentDiv.setAttribute("class", "active-scripts-server-panel");
-    panelContentDiv.setAttribute("id", panelname + "-content");
-
-    //List of scripts
-    var panelScriptList = document.createElement("ul");
-    panelScriptList.setAttribute("id", panelname + "-script-list");
-
-    panelContentDiv.appendChild(panelScriptList);
-    panelDiv.appendChild(panelHdr);
-    panelDiv.appendChild(panelContentDiv);
-    activeScriptsList.appendChild(panelDiv);
-
-    setActiveScriptsClickHandlers() //Reset click handlers
-
-    return panelDiv;
-}
-
-//Deletes the info for a particular server (Dropdown header + Panel with all info)
-//in the Active Scripts page if it exists
-function deleteActiveScriptsServerPanel(server) {
-    var panelname = "active-scripts-server-panel-" + server.hostname;
-    var panel = document.getElementById(panelname);
-    if (panel == null) {
-        console.log("No such panel exists: " + panelname);
-        return;
-    }
-
-    //Remove the panel if it has no elements
-    var scriptList = document.getElementById(panelname + "-script-list");
-    if (scriptList.childNodes.length == 0) {
-        panel.parentNode.removeChild(panel);
-    }
-}
-
-function addActiveScriptsItem(workerscript) {
-    //Get server panel
-    var server = Object(_Server_js__WEBPACK_IMPORTED_MODULE_2__["getServer"])(workerscript.serverIp);
-    if (server == null) {
-        console.log("ERROR: Invalid server IP for workerscript.");
-        return;
-    }
-    var panelname = "active-scripts-server-panel-" + server.hostname;
-
-    var panel = document.getElementById(panelname);
-    if (panel == null) {
-        panel = createActiveScriptsServerPanel(server);
-    }
-
-    //Create the element itself. Each element is an accordion collapsible
-    var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
-    for (var i = 0; i < workerscript.args.length; ++i) {
-        itemNameArray.push(String(workerscript.args[i]));
-    }
-    var itemName = itemNameArray.join("-");
-    var item = document.createElement("li");
-    item.setAttribute("id", itemName);
-
-    var btn = document.createElement("button");
-    btn.setAttribute("class", "active-scripts-script-header");
-    btn.innerHTML = workerscript.name;
-
-    var itemContentDiv = document.createElement("div");
-    itemContentDiv.setAttribute("class", "active-scripts-script-panel");
-    itemContentDiv.setAttribute("id", itemName + "-content");
-
-    item.appendChild(btn);
-    item.appendChild(itemContentDiv);
-
-    createActiveScriptsText(workerscript, itemContentDiv);
-
-    //Append element to list
-    var list = getActiveScriptsServerList(server);
-    list.appendChild(item);
-
-    setActiveScriptsClickHandlers() //Reset click handlers
-}
-
-function deleteActiveScriptsItem(workerscript) {
-    var server = Object(_Server_js__WEBPACK_IMPORTED_MODULE_2__["getServer"])(workerscript.serverIp);
-    if (server == null) {
-        console.log("ERROR: Invalid server IP for workerscript.");
-        return;
-    }
-    var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
-    for (var i = 0; i < workerscript.args.length; ++i) {
-        itemNameArray.push(String(workerscript.args[i]));
-    }
-    var itemName = itemNameArray.join("-");
-    var li = document.getElementById(itemName);
-    if (li == null) {
-        console.log("could not find Active scripts li element for: " + workerscript.name);
-        return;
-    }
-    li.parentNode.removeChild(li);
-    deleteActiveScriptsServerPanel(server);
-}
-
-//Update the ActiveScriptsItems array
-function updateActiveScriptsItems() {
+//Calculates the total production from all HacknetNodes
+function updateTotalHacknetProduction() {
     var total = 0;
-    for (var i = 0; i < _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__["workerScripts"].length; ++i) {
-        total += updateActiveScriptsItemContent(_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__["workerScripts"][i]);
+    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
+        total += _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].moneyGainRatePerSecond;
+    }
+    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].totalHacknetNodeProduction = total;
+}
+
+function getCostOfNextHacknetNode() {
+    //Cost increases exponentially based on how many you own
+    var numOwned = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length;
+    var mult = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodePurchaseNextMult;
+    return _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].BaseCostForHacknetNode * Math.pow(mult, numOwned) * _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknet_node_purchase_cost_mult;
+}
+
+var hacknetNodePurchaseMultiplier = 1;
+function updateHacknetNodesMultiplierButtons() {
+    var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
+    var mult5x = document.getElementById("hacknet-nodes-5x-multiplier");
+    var mult10x = document.getElementById("hacknet-nodes-10x-multiplier");
+    var multMax = document.getElementById("hacknet-nodes-max-multiplier");
+    mult1x.setAttribute("class", "a-link-button");
+    mult5x.setAttribute("class", "a-link-button");
+    mult10x.setAttribute("class", "a-link-button");
+    multMax.setAttribute("class", "a-link-button");
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length == 0) {
+        mult1x.setAttribute("class", "a-link-button-inactive");
+        mult5x.setAttribute("class", "a-link-button-inactive");
+        mult10x.setAttribute("class", "a-link-button-inactive");
+        multMax.setAttribute("class", "a-link-button-inactive");
+    } else if (hacknetNodePurchaseMultiplier == 1) {
+        mult1x.setAttribute("class", "a-link-button-inactive");
+    } else if (hacknetNodePurchaseMultiplier == 5) {
+        mult5x.setAttribute("class", "a-link-button-inactive");
+    } else if (hacknetNodePurchaseMultiplier == 10) {
+        mult10x.setAttribute("class", "a-link-button-inactive");
+    } else {
+        multMax.setAttribute("class", "a-link-button-inactive");
+    }
+}
+
+//Calculate the maximum number of times the Player can afford to upgrade
+//a Hacknet Node's level"
+function getMaxNumberLevelUpgrades(nodeObj) {
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(nodeObj.calculateLevelUpgradeCost(1))) {return 0;}
+    var min = 1;
+    var max = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel-1;
+    var levelsToMax = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel - nodeObj.level;
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax))) {
+        return levelsToMax;
+    }
+
+    while (min <= max) {
+        var curr = (min + max) / 2 | 0;
+        if (curr != _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel &&
+            _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.gt(nodeObj.calculateLevelUpgradeCost(curr)) &&
+            _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(nodeObj.calculateLevelUpgradeCost(curr+1))) {
+            return Math.min(levelsToMax, curr);
+        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(nodeObj.calculateLevelUpgradeCost(curr))) {
+            max = curr - 1;
+        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.gt(nodeObj.calculateLevelUpgradeCost(curr))) {
+            min = curr + 1;
+        } else {
+            return Math.min(levelsToMax, curr);
+        }
+    }
+}
+
+//Creates Hacknet Node DOM elements when the page is opened
+function displayHacknetNodesContent() {
+    //Update Hacknet Nodes button
+    var newPurchaseButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_6__["clearEventListeners"])("hacknet-nodes-purchase-button");
+
+    newPurchaseButton.addEventListener("click", function() {
+        purchaseHacknet();
+        return false;
+    });
+
+    //Handle Purchase multiplier buttons
+    updateHacknetNodesMultiplierButtons();
+
+    //Remove all old hacknet Node DOM elements
+    var hacknetNodesList = document.getElementById("hacknet-nodes-list");
+        while (hacknetNodesList.firstChild) {
+        hacknetNodesList.removeChild(hacknetNodesList.firstChild);
+    }
+
+    //Then re-create them
+    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
+        createHacknetNodeDomElement(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]);
+    }
+    updateHacknetNodesContent();
+}
+
+//Update information on all Hacknet Node DOM elements
+function updateHacknetNodesContent() {
+    //Set purchase button to inactive if not enough money, and update its price display
+    var cost = getCostOfNextHacknetNode();
+    var purchaseButton = document.getElementById("hacknet-nodes-purchase-button");
+    purchaseButton.innerHTML = "Purchase Hacknet Node - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(cost, 2);
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(cost)) {
+        purchaseButton.setAttribute("class", "a-link-button-inactive");
+    } else {
+        purchaseButton.setAttribute("class", "a-link-button");
+    }
+
+    //Update player's money
+    var moneyElem = document.getElementById("hacknet-nodes-money");
+    moneyElem.innerHTML = "Money: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.toNumber(), 2) + "<br>" +
+                          "Total production from all Hacknet Nodes: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].totalHacknetNodeProduction, 2) + " / second";
+
+    //Update information in each owned hacknet node
+    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
+        updateHacknetNodeDomElement(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]);
+    }
+}
+
+//Creates a single Hacknet Node DOM element
+function createHacknetNodeDomElement(nodeObj) {
+    var nodeName = nodeObj.name;
+
+    var listItem = document.createElement("li");
+    listItem.setAttribute("class", "hacknet-node");
+
+    var span = document.createElement("span");
+    span.style.display = "inline";
+
+    var buttonDiv = document.createElement("div");
+    buttonDiv.setAttribute("class", "hacknet-node-button-div");
+
+    //Text
+    var txt = document.createElement("p");
+    //txt.setAttribute("id", "hacknet-node-text-" + nodeName);
+    txt.id = "hacknet-node-text-" + nodeName;
+
+    //Upgrade buttons
+    var upgradeLevelButton = document.createElement("a");
+    var upgradeRamButton = document.createElement("a");
+    var upgradeCoreButton = document.createElement("a");
+
+    //upgradeLevelButton.setAttribute("id", "hacknet-node-upgrade-level-" + nodeName);
+    upgradeLevelButton.id = "hacknet-node-upgrade-level-" + nodeName;
+    upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
+    upgradeLevelButton.addEventListener("click", function() {
+        var numUpgrades = hacknetNodePurchaseMultiplier;
+        if (hacknetNodePurchaseMultiplier == 0) {
+            numUpgrades = getMaxNumberLevelUpgrades(nodeObj);
+        }
+        nodeObj.purchaseLevelUpgrade(numUpgrades);
+        updateHacknetNodesContent();
+        return false;
+    });
+    //upgradeRamButton.setAttribute("id", "hacknet-node-upgrade-ram-" + nodeName);
+    upgradeRamButton.id = "hacknet-node-upgrade-ram-" + nodeName;
+    upgradeRamButton.setAttribute("class", "a-link-button-inactive");
+    upgradeRamButton.addEventListener("click", function() {
+        nodeObj.purchaseRamUpgrade();
+        updateHacknetNodesContent();
+        return false;
+    });
+    //upgradeCoreButton.setAttribute("id", "hacknet-node-upgrade-core-" + nodeName);
+    upgradeCoreButton.id = "hacknet-node-upgrade-core-" + nodeName;
+    upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
+    upgradeCoreButton.addEventListener("click", function() {
+        nodeObj.purchaseCoreUpgrade();
+        updateHacknetNodesContent();
+        return false;
+    });
+
+    //Put all the components together in the li element
+    span.appendChild(txt);
+    buttonDiv.appendChild(upgradeLevelButton);
+    buttonDiv.appendChild(upgradeRamButton);
+    buttonDiv.appendChild(upgradeCoreButton);
+    span.appendChild(buttonDiv);
+    listItem.appendChild(span);
+
+    document.getElementById("hacknet-nodes-list").appendChild(listItem);
+
+    //Set the text and stuff inside the DOM element
+    updateHacknetNodeDomElement(nodeObj);
+}
+
+//Updates information on a single hacknet node DOM element
+function updateHacknetNodeDomElement(nodeObj) {
+    var nodeName = nodeObj.name;
+    var txt = document.getElementById("hacknet-node-text-" + nodeName);
+    if (txt == null) {throw new Error("Cannot find text element");}
+    txt.innerHTML = "Node name:  " + nodeName + "<br>" +
+                    "Production: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(nodeObj.totalMoneyGenerated, 2) +
+                                 " ($" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(nodeObj.moneyGainRatePerSecond, 2) + " / second) <br>" +
+                    "Level:      " + nodeObj.level + "<br>" +
+                    "RAM:        " + nodeObj.ram + "GB<br>" +
+                    "Cores:      " + nodeObj.cores;
+
+    //Upgrade level
+    var upgradeLevelButton = document.getElementById("hacknet-node-upgrade-level-" + nodeName);
+    if (upgradeLevelButton == null) {throw new Error("Cannot find upgrade level button element");}
+    if (nodeObj.level >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel) {
+        upgradeLevelButton.innerHTML = "MAX LEVEL";
+        upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
+    } else {
+        var multiplier = 0;
+        if (hacknetNodePurchaseMultiplier == 0) {
+            //Max
+            multiplier = getMaxNumberLevelUpgrades(nodeObj);
+        } else {
+            var levelsToMax = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxLevel - nodeObj.level;
+            multiplier = Math.min(levelsToMax, hacknetNodePurchaseMultiplier);
+        }
+
+        var upgradeLevelCost = nodeObj.calculateLevelUpgradeCost(multiplier);
+        upgradeLevelButton.innerHTML = "Upgrade Hacknet Node Level x" + multiplier +
+                                       " - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(upgradeLevelCost, 2);
+        if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(upgradeLevelCost)) {
+            upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
+        } else {
+            upgradeLevelButton.setAttribute("class", "a-link-button");
+        }
+    }
+
+    //Upgrade RAM
+    var upgradeRamButton = document.getElementById("hacknet-node-upgrade-ram-" + nodeName);
+    if (upgradeRamButton == null) {throw new Error("Cannot find upgrade ram button element");}
+    if (nodeObj.ram >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxRam) {
+        upgradeRamButton.innerHTML = "MAX RAM";
+        upgradeRamButton.setAttribute("class", "a-link-button-inactive");
+    } else {
+        var upgradeRamCost = nodeObj.calculateRamUpgradeCost();
+        upgradeRamButton.innerHTML = "Upgrade Hacknet Node RAM - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(upgradeRamCost, 2);
+        if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(upgradeRamCost)) {
+            upgradeRamButton.setAttribute("class", "a-link-button-inactive");
+        } else {
+            upgradeRamButton.setAttribute("class", "a-link-button");
+        }
+    }
+
+    //Upgrade Cores
+    var upgradeCoreButton = document.getElementById("hacknet-node-upgrade-core-" + nodeName);
+    if (upgradeCoreButton == null) {throw new Error("Cannot find upgrade cores button element");}
+    if (nodeObj.cores >= _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMaxCores) {
+        upgradeCoreButton.innerHTML = "MAX CORES";
+        upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
+    } else {
+        var upgradeCoreCost = nodeObj.calculateCoreUpgradeCost();
+        upgradeCoreButton.innerHTML = "Purchase additional CPU Core - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["formatNumber"])(upgradeCoreCost, 2);
+        if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].money.lt(upgradeCoreCost)) {
+            upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
+        } else {
+            upgradeCoreButton.setAttribute("class", "a-link-button");
+        }
+    }
+}
+
+function processAllHacknetNodeEarnings(numCycles) {
+    var total = 0;
+    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
+        total += processSingleHacknetNodeEarnings(numCycles, _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]);
     }
-    document.getElementById("active-scripts-total-prod").innerHTML =
-        "Total online production of Active Scripts: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6___default()(total).format('$0.000a') + " / sec<br>" +
-        "Total online production since last Aug installation: " +
-        _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6___default()(_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].scriptProdSinceLastAug).format('$0.000a') + " (" +
-        _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6___default()(_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].scriptProdSinceLastAug / (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].playtimeSinceLastAug/1000)).format('$0.000a') + " / sec)";
     return total;
 }
 
-//Updates the content of the given item in the Active Scripts list
-function updateActiveScriptsItemContent(workerscript) {
-    var server = Object(_Server_js__WEBPACK_IMPORTED_MODULE_2__["getServer"])(workerscript.serverIp);
-    if (server == null) {
-        console.log("ERROR: Invalid server IP for workerscript.");
-        return;
+function processSingleHacknetNodeEarnings(numCycles, nodeObj) {
+    var cyclesPerSecond = 1000 / _engine_js__WEBPACK_IMPORTED_MODULE_2__["Engine"]._idleSpeed;
+    var earningPerCycle = nodeObj.moneyGainRatePerSecond / cyclesPerSecond;
+    if (isNaN(earningPerCycle)) {
+        console.log("ERROR: Hacknet Node Calculated earnings is NaN");
+        earningPerCycle = 0;
     }
-    var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
-    for (var i = 0; i < workerscript.args.length; ++i) {
-        itemNameArray.push(String(workerscript.args[i]));
-    }
-    var itemName = itemNameArray.join("-");
-    var itemContent = document.getElementById(itemName + "-content")
-
-    //Add the updated text back. Returns the total online production rate
-    return updateActiveScriptsText(workerscript, itemContent);
+    var totalEarnings = numCycles * earningPerCycle;
+    nodeObj.totalMoneyGenerated += totalEarnings;
+    nodeObj.onlineTimeSeconds += (numCycles * (_engine_js__WEBPACK_IMPORTED_MODULE_2__["Engine"]._idleSpeed / 1000));
+    _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].gainMoney(totalEarnings);
+    return totalEarnings;
 }
 
-function createActiveScriptsText(workerscript, item) {
-    var itemTextHeader = document.createElement("p");
-    var itemTextStats = document.createElement("p");
-    var itemId = item.id;
-    itemTextStats.setAttribute("id", itemId + "-stats");
-
-    //Server ip/hostname
-    var threads = "Threads: " + workerscript.scriptRef.threads;
-    var args = "Args: " + Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_4__["printArray"])(workerscript.args);
-
-    itemTextHeader.innerHTML = threads + "<br>" + args + "<br>";
-
-    item.appendChild(itemTextHeader);
-    item.appendChild(itemTextStats);
-
-    var onlineMps = updateActiveScriptsText(workerscript, item, itemTextStats);
-
-    var logButton = document.createElement("span");
-    logButton.innerHTML = "Log";
-    var killButton = document.createElement("span");
-    killButton.innerHTML = "Kill script";
-    logButton.setAttribute("class", "active-scripts-button");
-    killButton.setAttribute("class", "active-scripts-button");
-    logButton.addEventListener("click", function() {
-        Object(_utils_LogBox_js__WEBPACK_IMPORTED_MODULE_5__["logBoxCreate"])(workerscript.scriptRef);
-        return false;
-    });
-    killButton.addEventListener("click", function() {
-        Object(_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__["killWorkerScript"])(workerscript.scriptRef, workerscript.scriptRef.scriptRef.server);
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_3__["dialogBoxCreate"])("Killing script, may take a few minutes to complete...");
-        return false;
-    });
-    item.appendChild(logButton);
-    item.appendChild(killButton);
-
-    //Return total online production rate
-    return onlineMps;
-}
-
-function updateActiveScriptsText(workerscript, item, statsEl=null) {
-    var itemId = item.id
-    var itemTextStats = document.getElementById(itemId + "-stats");
-    if (itemTextStats == null || itemTextStats === undefined) {
-        itemTextStats = statsEl;
-    }
-
-    //Updates statistics only
-    //Online
-    var onlineTotalMoneyMade = "Total online production: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(workerscript.scriptRef.onlineMoneyMade, 2);
-    var onlineTotalExpEarned = (Array(26).join(" ") + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(workerscript.scriptRef.onlineExpGained, 2) + " hacking exp").replace( / /g, "&nbsp;");
-
-    var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime;
-    var onlineMpsText = "Online production rate: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(onlineMps, 2) + "/second";
-    var onlineEps = workerscript.scriptRef.onlineExpGained / workerscript.scriptRef.onlineRunningTime;
-    var onlineEpsText = (Array(25).join(" ") + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(onlineEps, 4) + " hacking exp/second").replace( / /g, "&nbsp;");
-
-    //Offline
-    var offlineTotalMoneyMade = "Total offline production: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(workerscript.scriptRef.offlineMoneyMade, 2);
-    var offlineTotalExpEarned = (Array(27).join(" ") + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(workerscript.scriptRef.offlineExpGained, 2) + " hacking exp").replace( / /g, "&nbsp;");
-
-    var offlineMps = workerscript.scriptRef.offlineMoneyMade / workerscript.scriptRef.offlineRunningTime;
-    var offlineMpsText = "Offline production rate: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(offlineMps, 2) + "/second";
-    var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime;
-    var offlineEpsText = (Array(26).join(" ") + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(offlineEps, 4) +  " hacking exp/second").replace( / /g, "&nbsp;");
-
-    itemTextStats.innerHTML = onlineTotalMoneyMade + "<br>" + onlineTotalExpEarned + "<br>" +
-                              onlineMpsText + "<br>" + onlineEpsText + "<br>" + offlineTotalMoneyMade + "<br>" + offlineTotalExpEarned + "<br>" +
-                              offlineMpsText + "<br>" + offlineEpsText + "<br>";
-    return onlineMps;
-}
-
-
-
-
-/***/ }),
-/* 43 */
-/*!******************************!*\
-  !*** ./src/NetscriptPort.js ***!
-  \******************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NetscriptPort", function() { return NetscriptPort; });
-/* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Settings.js */ 24);
-
-
-function NetscriptPort() {
-    this.data = [];
-}
-
-NetscriptPort.prototype.write = function(data) {
-    this.data.push(data);
-    if (this.data.length > _Settings_js__WEBPACK_IMPORTED_MODULE_0__["Settings"].MaxPortCapacity) {
-        return this.data.shift();
+function getHacknetNode(name) {
+    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) {
+        if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].name == name) {
+            return _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i];
+        }
     }
     return null;
 }
 
-NetscriptPort.prototype.tryWrite = function(data) {
-    if (this.data.length >= _Settings_js__WEBPACK_IMPORTED_MODULE_0__["Settings"].MaxPortCapacity) {
-        return false;
-    }
-    this.data.push(data);
-    return true;
+
+
+
+/***/ }),
+/* 40 */
+/*!**********************************!*\
+  !*** ./src/CompanyManagement.js ***!
+  \**********************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Corporation", function() { return Corporation; });
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15);
+/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Faction.js */ 11);
+/* harmony import */ var _Literature_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Literature.js */ 53);
+/* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Location.js */ 4);
+/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Player.js */ 0);
+/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/decimal.js */ 23);
+/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_6__);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10__);
+/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* State */
+var companyStates = ["START", "PURCHASE", "PRODUCTION", "SALE", "EXPORT"];
+function CorporationState() {
+    this.state = 0;
 }
 
-NetscriptPort.prototype.read = function() {
-    if (this.data.length === 0) {
-        return "NULL PORT DATA";
+CorporationState.prototype.nextState = function() {
+    if (this.state < 0 || this.state >= companyStates.length) {
+        this.state = 0;
+    }
+
+    ++this.state;
+    if (this.state >= companyStates.length) {
+        this.state = 0;
     }
-    return this.data.shift();
 }
 
-NetscriptPort.prototype.peek = function() {
-    if (this.data.length === 0) {
-        return "NULL PORT DATA";
+CorporationState.prototype.getState = function() {
+    return companyStates[this.state];
+}
+
+CorporationState.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("CorporationState", this);
+}
+
+CorporationState.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(CorporationState, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.CorporationState = CorporationState;
+
+/* Constants */
+var TOTALSHARES = 1e9; //Total number of shares you have at your company
+var CyclesPerMarketCycle    = 75;
+var CyclesPerIndustryStateCycle = CyclesPerMarketCycle / companyStates.length;
+var SecsPerMarketCycle      = CyclesPerMarketCycle / 5;
+var Cities = ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"];
+var WarehouseInitialCost        = 5e9; //Initial purchase cost of warehouse
+var WarehouseInitialSize        = 100;
+var WarehouseUpgradeBaseCost    = 1e9;
+
+var OfficeInitialCost           = 4e9;
+var OfficeInitialSize           = 3;
+var OfficeUpgradeBaseCost       = 1e9;
+
+var BribeThreshold              = 100e12; //Money needed to be able to bribe for faction rep
+var BribeToRepRatio             = 1e9;   //Bribe Value divided by this = rep gain
+
+var ProductProductionCostRatio  = 5;    //Ratio of material cost of a product to its production cost
+
+function Material(params={}) {
+    this.name = params.name ? params.name : "";
+    this.qty    = 0; //Quantity
+    this.qlt    = 0; //Quality, unbounded
+    this.dmd    = 0; //Demand, 0-100?
+    this.dmdR   = 0; //Range of possible demand
+    this.cmp    = 0; //Competition, 0-100
+    this.cmpR   = 0; //Range of possible competition
+    this.mv     = 0; //Maximum Volatility of stats
+
+    //Markup. Determines how high of a price you can charge on the material
+    //compared to the market price (bCost) based on quality
+    //Quality is divided by this to determine markup limits
+    //e.g if mku is 10 and quality is 100 then you can mark up prices by 100/10 = 10
+    //without consequences
+    this.mku    = 0;
+
+    this.buy = 0; //How much of this material is being bought per second
+    this.sll = 0; //How much of this material is being sold per second
+    this.prd = 0; //How much of this material is being produced per second
+    this.exp = []; //Exports of this material to another warehouse/industry
+    this.totalExp = 0; //Total export amount for last cycle
+    this.imp = 0;
+    this.bCost = 0; //$ Cost/sec to buy material
+    this.sCost = 0; //$ Cost/sec to sell material
+
+    //[Whether production/sale is limited, limit amount]
+    this.prdman = [false, 0]; //Production for this material is manually limited
+    this.sllman = [false, 0]; //Sale of this material is manually limited
+    this.init();
+}
+
+Material.prototype.init = function(mats={}) {
+    switch(this.name) {
+        case "Water":
+            this.dmd = 75; this.dmdR = [65, 85];
+            this.cmp = 50; this.cmpR = [40, 60];
+            this.bCost = 1000; this.mv = 0.2;
+            this.mku = 6;
+            break;
+        case "Energy":
+            this.dmd = 90; this.dmdR = [80, 100];
+            this.cmp = 80; this.cmpR = [65, 95];
+            this.bCost = 1500; this.mv = 0.2;
+            this.mku = 6;
+            break;
+        case "Food":
+            this.dmd = 80; this.dmdR = [70, 90];
+            this.cmp = 60; this.cmpR = [35, 85];
+            this.bCost = 5000; this.mv = 1;
+            this.mku = 3;
+            break;
+        case "Plants":
+            this.dmd = 70; this.dmdR = [20, 90];
+            this.cmp = 50; this.cmpR = [30, 70];
+            this.bCost = 3000; this.mv = 0.6;
+            this.mku = 3.75;
+            break;
+        case "Metal":
+            this.dmd = 80; this.dmdR = [75, 85];
+            this.cmp = 70; this.cmpR = [60, 80];
+            this.bCost = 2650; this.mv = 1;
+            this.mku = 6;
+            break;
+        case "Hardware":
+            this.dmd = 85; this.dmdR = [80, 90];
+            this.cmp = 80; this.cmpR = [65, 95];
+            this.bCost = 4000; this.mv = 0.5; //Less mv bc its processed twice
+            this.mku = 1;
+            break;
+        case "Chemicals":
+            this.dmd = 55; this.dmdR = [40, 70];
+            this.cmp = 60; this.cmpR = [40, 80];
+            this.bCost = 6750; this.mv = 1.2;
+            this.mku = 2;
+            break;
+        case "Real Estate":
+            this.dmd = 50; this.dmdR = [5, 100];
+            this.cmp = 50; this.cmpR = [25, 75];
+            this.bCost = 16e3; this.mv = 1.5; //Less mv bc its processed twice
+            this.mku = 1.5;
+            break;
+        case "Drugs":
+            this.dmd = 60; this.dmdR = [45, 75];
+            this.cmp = 70; this.cmpR = [40, 100];
+            this.bCost = 8e3; this.mv = 1.6;
+            this.mku = 1;
+            break;
+        case "Robots":
+            this.dmd = 90; this.dmdR = [80, 100];
+            this.cmp = 90; this.cmpR = [80, 100];
+            this.bCost = 20e3; this.mv = 0.5; //Less mv bc its processed twice
+            this.mku = 1;
+            break;
+        case "AI Cores":
+            this.dmd = 90; this.dmdR = [80, 100];
+            this.cmp = 90; this.cmpR = [80, 100];
+            this.bCost = 27e3; this.mv = 0.8; //Less mv bc its processed twice
+            this.mku = 0.5;
+            break;
+        case "Scientific Research":
+            break;
+        default:
+            console.log("Invalid material type in init(): " + this.name);
+            break;
+    }
+}
+
+//Process change in demand, competition, and buy cost of this material
+Material.prototype.processMarket = function() {
+    //This 1st random check determines whether competition increases or decreases
+    //More competition = lower market price
+    var v = (Math.random() * this.mv) / 100;
+    var pv = (Math.random() * this.mv) / 300;
+    if (Math.random() < 0.42) {
+        this.cmp *= (1+v);
+        if (this.cmp > this.cmpR[1]) {this.cmp = this.cmpR[1]};
+        this.bCost *= (1-pv);
     } else {
-        var foo = this.data.slice();
-        return foo[0];
+        this.cmp *= (1-v);
+        if (this.cmp < this.cmpR[0]) {this.cmp = this.cmpR[0];}
+        this.bCost *= (1+pv);
+    }
+
+    //This 2nd random check determines whether demand increases or decreases
+    //More demand = higher market price
+    v = (Math.random() * this.mv) / 100;
+    pv = (Math.random() * this.mv) / 300;
+    if (Math.random() < 0.45) {
+        this.dmd *= (1+v);
+        if (this.dmd > this.dmdR[1]) {this.dmd = this.dmdR[1];}
+        this.bCost *= (1+pv);
+    } else {
+        this.dmd *= (1-v);
+        if (this.dmd < this.dmdR[0]) {this.dmd = this.dmdR[0];}
+        this.bCost *= (1-pv);
     }
 }
 
-NetscriptPort.prototype.full = function() {
-    return this.data.length == _Settings_js__WEBPACK_IMPORTED_MODULE_0__["Settings"].MaxPortCapacity;
+Material.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Material", this);
 }
 
-NetscriptPort.prototype.empty = function() {
-    return this.data.length === 0;
+Material.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Material, value.data);
 }
 
-NetscriptPort.prototype.clear = function() {
-    this.data.length = 0;
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Material = Material;
+
+//Map of material (by name) to their sizes (how much space it takes in warehouse)
+let MaterialSizes = {
+    Water:      0.05,
+    Energy:     0.01,
+    Food:       0.03,
+    Plants:     0.05,
+    Metal:      0.1,
+    Hardware:   0.06,
+    Chemicals:  0.05,
+    Drugs:      0.02,
+    Robots:     0.5,
+    "AICores": 0.1
+}
+
+function Product(params={}) {
+    this.name = params.name         ? params.name           : 0;
+    this.dmd = params.demand        ? params.demand         : 0;
+    this.cmp = params.competition   ? params.competition    : 0;
+    this.mku = params.markup        ? params.markup         : 0;
+    this.pCost = 0; //An estimate of how much money it costs to make this
+    this.sCost = 0; //How much this is selling for
+
+    //Variables for creation of product
+    this.fin = false;       //Finished being created
+    this.prog = 0;          //0-100% created
+    this.createCity = params.createCity ? params.createCity : ""; // City in which the product is being created
+    this.designCost     = params.designCost ? params.designCost : 0;
+    this.advCost        = params.advCost ? params.advCost : 0;
+
+    //Aggregate score for a product's 'rating' based on the other properties below
+    //The weighting of the other properties (performance, durability)
+    //differs between industries
+    this.rat = 0;
+
+    this.qlt = params.quality       ? params.quality        : 0;
+    this.per = params.performance   ? params.performance    : 0;
+    this.dur = params.durability    ? params.durability     : 0;
+    this.rel = params.reliability   ? params.reliability    : 0;
+    this.aes = params.aesthetics    ? params.aesthetics     : 0;
+    this.fea = params.features      ? params.features       : 0;
+
+    //Data refers to the production, sale, and quantity of the products
+    //These values are specific to a city
+    //The data is [qty, prod, sell]
+    this.data = {
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: [0, 0, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chongqing]: [0, 0, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: [0, 0, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: [0, 0, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: [0, 0, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: [0, 0, 0],
+    }
+
+    //Only applies for location-based products like restaurants/hospitals
+    this.loc = params.loc ? params.loc : 0;
+
+    //How much space it takes in the warehouse. Not applicable for all products
+    this.siz = params.size ? params.size : 0;
+
+    //Material requirements. An object that maps the name of a material to how much it requires
+    //to make 1 unit of the product.
+    this.reqMats = params.req           ? params.req            : {};
+
+    //[Whether production/sale is limited, limit amount]
+    this.prdman = {
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chongqing]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: [false, 0],
+    }
+
+    this.sllman = {
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chongqing]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: [false, 0],
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: [false, 0],
+    }
+}
+
+//empWorkMult is a multiplier that increases progress rate based on
+//productivity of employees
+Product.prototype.createProduct = function(marketCycles=1, empWorkMult=1) {
+    if (this.fin) {return;}
+    this.prog += (marketCycles * .01 * empWorkMult);
+}
+
+//'industry' is a reference to the industry that makes the product
+Product.prototype.finishProduct = function(employeeProd, industry) {
+    this.fin = true;
+
+    //Calculate properties
+    var progrMult = this.prog / 100;
+
+    var engrRatio   = employeeProd[EmployeePositions.Engineer] / employeeProd["total"],
+        mgmtRatio   = employeeProd[EmployeePositions.Management] / employeeProd["total"],
+        rndRatio    = employeeProd[EmployeePositions.RandD] / employeeProd["total"],
+        opsRatio    = employeeProd[EmployeePositions.Operations] / employeeProd["total"],
+        busRatio    = employeeProd[EmployeePositions.Business] / employeeProd["total"];
+    var designMult = 1 + (Math.pow(this.designCost, 0.1) / 100);
+    console.log("designMult: " + designMult);
+    var balanceMult = (1.2 * engrRatio) + (0.9 * mgmtRatio) + (1.3 * rndRatio) +
+                      (1.5 * opsRatio) + (busRatio);
+    var sciMult = 1 + (Math.pow(industry.sciResearch.qty, industry.sciFac) / 800);
+    var totalMult = progrMult * balanceMult * designMult * sciMult;
+
+    this.qlt = totalMult * ((0.10 * employeeProd[EmployeePositions.Engineer]) +
+                            (0.05 * employeeProd[EmployeePositions.Management]) +
+                            (0.05 * employeeProd[EmployeePositions.RandD]) +
+                            (0.02 * employeeProd[EmployeePositions.Operations]) +
+                            (0.02 * employeeProd[EmployeePositions.Business]));
+    this.per = totalMult * ((0.15 * employeeProd[EmployeePositions.Engineer]) +
+                            (0.02 * employeeProd[EmployeePositions.Management]) +
+                            (0.02 * employeeProd[EmployeePositions.RandD]) +
+                            (0.02 * employeeProd[EmployeePositions.Operations]) +
+                            (0.02 * employeeProd[EmployeePositions.Business]));
+    this.dur = totalMult * ((0.05 * employeeProd[EmployeePositions.Engineer]) +
+                            (0.02 * employeeProd[EmployeePositions.Management]) +
+                            (0.08 * employeeProd[EmployeePositions.RandD]) +
+                            (0.05 * employeeProd[EmployeePositions.Operations]) +
+                            (0.05 * employeeProd[EmployeePositions.Business]));
+    this.rel = totalMult * ((0.02 * employeeProd[EmployeePositions.Engineer]) +
+                            (0.08 * employeeProd[EmployeePositions.Management]) +
+                            (0.02 * employeeProd[EmployeePositions.RandD]) +
+                            (0.05 * employeeProd[EmployeePositions.Operations]) +
+                            (0.08 * employeeProd[EmployeePositions.Business]));
+    this.aes = totalMult * ((0.00 * employeeProd[EmployeePositions.Engineer]) +
+                            (0.08 * employeeProd[EmployeePositions.Management]) +
+                            (0.05 * employeeProd[EmployeePositions.RandD]) +
+                            (0.02 * employeeProd[EmployeePositions.Operations]) +
+                            (0.10 * employeeProd[EmployeePositions.Business]));
+    this.fea = totalMult * ((0.08 * employeeProd[EmployeePositions.Engineer]) +
+                            (0.05 * employeeProd[EmployeePositions.Management]) +
+                            (0.02 * employeeProd[EmployeePositions.RandD]) +
+                            (0.05 * employeeProd[EmployeePositions.Operations]) +
+                            (0.05 * employeeProd[EmployeePositions.Business]));
+    this.calculateRating(industry);
+    var advMult = 1 + (Math.pow(this.advCost, 0.1) / 100);
+    this.mku = 100 / (advMult * Math.pow((this.qlt + 0.001), 0.65) * (busRatio + mgmtRatio));
+    this.dmd = industry.awareness === 0 ? 20 : Math.min(100, advMult * (100 * (industry.popularity / industry.awareness)));
+    this.cmp = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(0, 70);
+
+    //Calculate the product's required materials
+    //For now, just set it to be the same as the requirements to make materials
+    for (var matName in industry.reqMats) {
+        if (industry.reqMats.hasOwnProperty(matName)) {
+            this.reqMats[matName] = industry.reqMats[matName];
+        }
+    }
+
+    //Calculate the product's size
+    //For now, just set it to be the same size as the requirements to make materials
+    this.siz = 0;
+    for (var matName in industry.reqMats) {
+        this.siz += MaterialSizes[matName] * industry.reqMats[matName];
+    }
+
+    //Delete unneeded variables
+    delete this.prog;
+    delete this.createCity;
+    delete this.designCost;
+    delete this.advCost;
+}
+
+
+Product.prototype.calculateRating = function(industry) {
+    var weights = ProductRatingWeights[industry.type];
+    if (weights == null) {
+        console.log("ERROR: Could not find product rating weights for: " + industry);
+        return;
+    }
+    this.rat = 0;
+    this.rat += weights.Quality     ? this.qlt * weights.Quality : 0;
+    this.rat += weights.Performance ? this.per * weights.Performance : 0;
+    this.rat += weights.Durability  ? this.dur * weights.Durability : 0;
+    this.rat += weights.Reliability ? this.rel * weights.Reliability : 0;
+    this.rat += weights.Aesthetics  ? this.aes * weights.Aesthetics : 0;
+    this.rat += weights.Features    ? this.fea * weights.Features : 0;
+}
+
+Product.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Product", this);
+}
+
+Product.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Product, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Product = Product;
+
+var Industries = {
+    Energy: "Energy",
+    Utilities: "Water Utilities",
+    Agriculture: "Agriculture",
+    Fishing: "Fishing",
+    Mining: "Mining",
+    Food: "Food",
+    Tobacco: "Tobacco",
+    Chemical: "Chemical",
+    Pharmaceutical: "Pharmaceutical",
+    Computer: "Computer Hardware",
+    Robotics: "Robotics",
+    Software: "Software",
+    Healthcare: "Healthcare",
+    RealEstate: "RealEstate",
+}
+
+var IndustryStartingCosts = {
+    Energy: 225e9,
+    Utilities: 150e9,
+    Agriculture: 40e9,
+    Fishing: 80e9,
+    Mining: 300e9,
+    Food: 10e9,
+    Tobacco: 20e9,
+    Chemical: 70e9,
+    Pharmaceutical: 200e9,
+    Computer: 500e9,
+    Robotics: 1e12,
+    Software: 25e9,
+    Healthcare: 750e9,
+    RealEstate: 600e9,
+}
+
+var IndustryDescriptions = {
+    Energy: "Engage in the production and distribution of energy.<br><br>" +
+            "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Energy).format("$0.000a") + "<br>" +
+            "Recommended starting Industry: NO",
+    Utilities: "Distributes water and provides wastewater services.<br><br>" +
+               "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Utilities).format("$0.000a") + "<br>" +
+               "Recommended starting Industry: NO",
+    Agriculture: "Cultive crops and breed livestock to produce food.<br><br>" +
+                 "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Agriculture).format("$0.000a") + "<br>" +
+                 "Recommended starting Industry: YES",
+    Fishing: "Produce food through the breeding and processing of fish and fish products<br><br>" +
+             "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Fishing).format("$0.000a") + "<br>" +
+             "Recommended starting Industry: NO",
+    Mining: "Extract and process metals from the earth.<br><br>" +
+            "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Mining).format("$0.000a") + "<br>" +
+            "Recommended starting Industry: NO",
+    Food: "Create your own restaurants all around the world.<br><br>" +
+          "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Food).format("$0.000a") + "<br>" +
+          "Recommended starting Industry: YES",
+    Tobacco: "Create and distribute tobacco and tobacco-related products.<br><br>" +
+             "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Tobacco).format("$0.000a") + "<br>" +
+             "Recommended starting Industry: YES",
+    Chemical: "Product industrial chemicals<br><br>" +
+              "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Chemical).format("$0.000a") + "<br>" +
+              "Recommended starting Industry: NO",
+    Pharmaceutical: "Discover, develop, and create new pharmaceutical drugs.<br><br>" +
+                    "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Pharmaceutical).format("$0.000a") + "<br>" +
+                    "Recommended starting Industry: NO",
+    Computer: "Develop and manufacture new computer hardware and networking infrastructures.<br><br>" +
+              "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Computer).format("$0.000a") + "<br>" +
+              "Recommended starting Industry: NO",
+    Robotics: "Develop and create robots.<br><br>" +
+              "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Robotics).format("$0.000a") + "<br>" +
+              "Recommended starting Industry: NO",
+    Software: "Develop computer software and create AI Cores.<br><br>" +
+              "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Software).format("$0.000a") + "<br>" +
+              "Recommended starting Industry: YES",
+    Healthcare: "Create and manage hospitals.<br><br>" +
+                "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.Healthcare).format("$0.000a") + "<br>" +
+                "Recommended starting Industry: NO",
+    RealEstate: "Develop and manage real estate properties.<br><br>" +
+                "Starting cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(IndustryStartingCosts.RealEstate).format("$0.000a") + "<br>" +
+                "Recommended starting Industry: NO",
+}
+
+var ProductRatingWeights = {
+    [Industries.Food]: {
+        Quality:        0.7,
+        Durability:     0.1,
+        Aesthetics:     0.2,
+    },
+    [Industries.Tobacco]: {
+        Quality:        0.4,
+        Durability:     0.2,
+        Reliability:    0.2,
+        Aesthetics:     0.2,
+    },
+    [Industries.Pharmaceutical]: {
+        Quality:        0.2,
+        Performance:    0.2,
+        Durability:     0.1,
+        Reliability:    0.3,
+        Features:       0.2,
+    },
+    [Industries.Computer]: {
+        Quality:        0.15,
+        Performance:    0.25,
+        Durability:     0.25,
+        Reliability:    0.2,
+        Aesthetics:     0.05,
+        Features:       0.1,
+    },
+    "Computer" : {  //Repeat
+        Quality:        0.15,
+        Performance:    0.25,
+        Durability:     0.25,
+        Reliability:    0.2,
+        Aesthetics:     0.05,
+        Features:       0.1,
+    },
+    [Industries.Robotics]: {
+        Quality:        0.1,
+        Performance:    0.2,
+        Durability:     0.2,
+        Reliability:    0.2,
+        Aesthetics:     0.1,
+        Features:       0.2,
+    },
+    [Industries.Software]: {
+        Quality:        0.2,
+        Performance:    0.2,
+        Reliability:    0.2,
+        Durability:     0.2,
+        Features:       0.2,
+    },
+    [Industries.Healthcare]: {
+        Quality:        0.4,
+        Performance:    0.1,
+        Durability:     0.1,
+        Reliability:    0.3,
+        Features:       0.1,
+    },
+    [Industries.RealEstate]: {
+        Quality:        0.2,
+        Durability:     0.25,
+        Reliability:    0.1,
+        Aesthetics:     0.35,
+        Features:       0.1,
+    }
+}
+
+//Industry upgrades
+//The structure is:
+//  [index in array, base price, price mult, benefit mult (if applicable), name, desc]
+var IndustryUpgrades = {
+    "0":    [0, 500e3, 1, 1.05,
+            "Coffee", "Provide your employees with coffee, increasing their energy by 5%."],
+    "1":    [1, 1e9, 1.06, 1.03,
+            "AdVert.Inc", "Hire AdVert.Inc to advertise your company. Each level of " +
+            "this upgrade grants your company a static increase of 3 and 1 to its awareness and " +
+            "popularity, respectively. It will then increase your company's awareness by 1%, and its popularity " +
+            "by a random percentage between 1% and 3%. These effects are increased by other upgrades " +
+            "that increase the power of your advertising."]
+}
+
+var empManualAssignmentModeActive = false;
+function Industry(params={}) {
+    this.offices = { //Maps locations to offices. 0 if no office at that location
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: 0,
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chongqing]: 0,
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: new OfficeSpace({
+            loc:_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12,
+            size:OfficeInitialSize,
+        }),
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: 0,
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: 0,
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: 0
+    };
+
+    this.warehouses = { //Maps locations to warehouses. 0 if no warehouse at that location
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Aevum]: 0,
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Chonqing]: 0,
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12]: new Warehouse({
+            loc:_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12,
+            size: WarehouseInitialSize,
+        }),
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].NewTokyo]: 0,
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Ishima]: 0,
+        [_Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Volhaven]: 0
+    };
+
+    this.name   = params.name ? params.name : 0;
+    this.type   = params.type ? params.type : 0;
+
+    this.sciResearch    = new Material({name: "Scientific Research"});
+
+    //A map of the NAME of materials required to create produced materials to
+    //how many are needed to produce 1 unit of produced materials
+    this.reqMats = {};
+
+    //An array of the name of materials being produced
+    this.prodMats = [];
+
+    this.products  = {};
+    this.makesProducts = false;
+
+    this.awareness      = 0;
+    this.popularity     = 0; //Should always be less than awareness
+    this.startingCost   = 0;
+
+    /* The following are factors for how much production/other things are increased by
+       different factors. The production increase always has diminishing returns,
+       and they are all reprsented by exponentials of < 1 (e.g x ^ 0.5, x ^ 0.8)
+       The number for these represent the exponential. A lower number means more
+       diminishing returns */
+    this.reFac      = 0; //Real estate Factor
+    this.sciFac     = 0; //Scientific Research Factor, affects quality
+    this.hwFac      = 0; //Hardware factor
+    this.robFac     = 0; //Robotics Factor
+    this.aiFac      = 0; //AI Cores factor;
+    this.advFac     = 0; //Advertising factor, affects sales
+
+    this.prodMult   = 0; //Production multiplier
+
+    //Financials
+    this.lastCycleRevenue   = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+    this.lastCycleExpenses  = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+    this.thisCycleRevenue   = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+    this.thisCycleExpenses  = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+
+    //Upgrades
+    var numUpgrades = Object.keys(IndustryUpgrades).length;
+    this.upgrades = Array(numUpgrades).fill(0);
+
+    this.state = "START";
+    this.newInd = true;
+
+    this.init();
+}
+
+Industry.prototype.init = function() {
+    //Set the unique properties of an industry (how much its affected by real estate/scientific research, etc.)
+    this.startingCost = IndustryStartingCosts[this.type];
+    switch (this.type) {
+        case Industries.Energy:
+            this.reFac  = 0.65;
+            this.sciFac = 0.7;
+            this.robFac = 0.05;
+            this.aiFac  = 0.3;
+            this.advFac = 0.08;
+            this.reqMats = {
+                "Hardware": 0.1,
+                "Metal":    0.2,
+            };
+            this.prodMats = ["Energy"];
+            break;
+        case Industries.Utilities:
+        case "Utilities":
+            this.reFac  = 0.5;
+            this.sciFac = 0.6;
+            this.robFac = 0.4;
+            this.aiFac  = 0.4;
+            this.advFac = 0.08;
+            this.reqMats = {
+                "Hardware": 0.1,
+                "Metal":    0.1,
+            }
+            this.prodMats = ["Water"];
+            break;
+        case Industries.Agriculture:
+            this.reFac  = 0.75;
+            this.sciFac = 0.5;
+            this.hwFac  = 0.2;
+            this.robFac = 0.3;
+            this.aiFac  = 0.3;
+            this.advFac = 0.04;
+            this.reqMats = {
+                "Water":    0.5,
+                "Energy":   0.5,
+            }
+            this.prodMats = ["Plants", "Food"];
+            break;
+        case Industries.Fishing:
+            this.reFac  = 0.15;
+            this.sciFac = 0.35;
+            this.hwFac  = 0.35;
+            this.robFac = 0.5;
+            this.aiFac  = 0.2;
+            this.advFac = 0.08;
+            this.reqMats = {
+                "Energy":   0.5,
+            }
+            this.prodMats = ["Food"];
+            break;
+        case Industries.Mining:
+            this.reFac  = 0.3;
+            this.sciFac = 0.26;
+            this.hwFac  = 0.4;
+            this.robFac = 0.45;
+            this.aiFac  = 0.45;
+            this.advFac = 0.06;
+            this.reqMats = {
+                "Energy":   0.8,
+            }
+            this.prodMats = ["Metal"];
+            break;
+        case Industries.Food:
+            //reFac is unique for this bc it diminishes greatly per city. Handle this separately in code?
+            this.sciFac = 0.12;
+            this.hwFac  = 0.15;
+            this.robFac = 0.3;
+            this.aiFac  = 0.25;
+            this.advFac = 0.25;
+            this.reFac  = 0.05;
+            this.reqMats = {
+                "Food":     0.5,
+                "Water":    0.5,
+                "Energy":   0.2,
+            }
+            this.makesProducts = true;
+            break;
+        case Industries.Tobacco:
+            this.reFac  = 0.15;
+            this.sciFac = 0.75;
+            this.hwFac  = 0.15;
+            this.robFac = 0.2;
+            this.aiFac  = 0.15;
+            this.advFac = 0.2;
+            this.reqMats = {
+                "Plants":   1,
+                "Water":    0.2,
+            }
+            this.makesProducts = true;
+            break;
+        case Industries.Chemical:
+            this.reFac  = 0.25;
+            this.sciFac = 0.75;
+            this.hwFac  = 0.2;
+            this.robFac = 0.25;
+            this.aiFac  = 0.2;
+            this.advFac = 0.07;
+            this.reqMats = {
+                "Plants":   1,
+                "Energy":   0.5,
+                "Water":    0.5,
+            }
+            this.prodMats = ["Chemicals"];
+            break;
+        case Industries.Pharmaceutical:
+            this.reFac  = 0.05;
+            this.sciFac = 0.8;
+            this.hwFac  = 0.15;
+            this.robFac = 0.25;
+            this.aiFac  = 0.2;
+            this.advFac = 0.16;
+            this.reqMats = {
+                "Chemicals":    2,
+                "Energy":       1,
+                "Water":        0.5,
+            }
+            this.prodMats = ["Drugs"];
+            this.makesProducts = true;
+            break;
+        case Industries.Computer:
+        case "Computer":
+            this.reFac  = 0.2;
+            this.sciFac = 0.62;
+            this.robFac = 0.36;
+            this.aiFac  = 0.19;
+            this.advFac = 0.17;
+            this.reqMats = {
+                "Metal":    2.5,
+                "Energy":   1,
+            }
+            this.prodMats = ["Hardware"];
+            this.makesProducts = true;
+            break;
+        case Industries.Robotics:
+            this.reFac  = 0.32;
+            this.sciFac = 0.65;
+            this.aiFac  = 0.36;
+            this.advFac = 0.18;
+            this.hwFac  = 0.19;
+            this.reqMats = {
+                "Hardware":     5,
+                "Energy":       3,
+            }
+            this.prodMats = ["Robots"];
+            this.makesProducts = true;
+            break;
+        case Industries.Software:
+            this.sciFac = 0.62;
+            this.advFac = 0.16;
+            this.hwFac  = 0.25;
+            this.reFac  = 0.1;
+            this.aiFac  = 0.1;
+            this.robFac = 0.05;
+            this.reqMats = {
+                "Hardware":     0.5,
+                "Energy":       1,
+            }
+            this.prodMats = ["AICores"];
+            this.makesProducts = true;
+            break;
+        case Industries.Healthcare:
+            this.reFac  = 0.1;
+            this.sciFac = 0.75;
+            this.advFac = 0.11;
+            this.hwFac  = 0.1;
+            this.robFac = 0.1;
+            this.aiFac  = 0.1;
+            this.reqMats = {
+                "Robots":       10,
+                "AICores":     5,
+                "Energy":       5,
+                "Water":        5,
+            }
+            this.makesProducts = true;
+            break;
+        case Industries.RealEstate:
+            this.robFac = 0.6;
+            this.aiFac  = 0.6;
+            this.advFac = 0.25;
+            this.sciFac = 0.05;
+            this.hwFac  = 0.05;
+            this.reqMats = {
+                "Metal":    20,
+                "Energy":   10,
+                "Water":    10,
+                "Hardware": 5
+            }
+            this.prodMats = ["RealEstate"];
+            this.makesProducts = true;
+            break;
+        default:
+            console.log("ERR: Invalid Industry Type passed into Industry.init(): " + this.type);
+            return;
+    }
+}
+
+Industry.prototype.getProductDescriptionText = function() {
+    if (!this.makesProducts) {return;}
+    switch (this.type) {
+        case Industries.Food:
+            return "create and manage restaurants";
+            break;
+        case Industries.Tobacco:
+            return "create tobacco and tobacco-related products";
+            break;
+        case Industries.Pharmaceutical:
+            return "develop new pharmaceutical drugs";
+            break;
+        case Industries.Computer:
+        case "Computer":
+            return "create new computer hardware and networking infrastructures";
+            break;
+        case Industries.Robotics:
+            return "build specialized robots and robot-related products";
+            break;
+        case Industries.Software:
+            return "develop computer software";
+            break;
+        case Industries.HealthCare:
+            return "build and manage hospitals";
+            break;
+        case Industries.RealEstate:
+            return "develop and manage real estate properties";
+            break;
+        default:
+            console.log("ERROR: Invalid industry type in Industry.getProductDescriptionText");
+            return "";
+    }
+}
+
+//Calculates the values that factor into the production and properties of
+//materials/products (such as quality, etc.)
+Industry.prototype.calculateProductionFactors = function() {
+    var multSum = 0;
+    for (var i = 0; i < Cities.length; ++i) {
+        var city = Cities[i];
+        var warehouse = this.warehouses[city];
+        if (!(warehouse instanceof Warehouse)) {
+            continue;
+        }
+
+        var materials = warehouse.materials,
+            office = this.offices[city];
+
+        var cityMult =  Math.pow(0.002 * materials.RealEstate.qty+1, this.reFac) *
+                        Math.pow(0.002 * materials.Hardware.qty+1, this.hwFac) *
+                        Math.pow(0.002 * materials.Robots.qty+1, this.robFac) *
+                        Math.pow(0.002 * materials.AICores.qty+1, this.aiFac);
+        multSum += Math.pow(cityMult, 0.73);
+    }
+
+    multSum < 1 ? this.prodMult = 1 : this.prodMult = multSum;
+}
+
+Industry.prototype.updateWarehouseSizeUsed = function(warehouse) {
+    if (warehouse instanceof Warehouse) {
+        //This resets the size back to 0 and then accounts for materials
+        warehouse.updateMaterialSizeUsed();
+    }
+
+    for (var prodName in this.products) {
+        if (this.products.hasOwnProperty(prodName)) {
+            var prod = this.products[prodName];
+            warehouse.sizeUsed += (prod.data[warehouse.loc][0] * prod.siz);
+            if (prod.data[warehouse.loc][0] > 0) {
+                warehouse.breakdown += (prodName + ": " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(prod.data[warehouse.loc][0] * prod.siz, 0) + "<br>");
+            }
+        }
+    }
+}
+
+Industry.prototype.process = function(marketCycles=1, state, company) {
+    this.state = state;
+
+    //At the start of a cycle, store and reset revenue/expenses
+    //Then calculate salaries and processs the markets
+    if (state === "START") {
+        if (isNaN(this.thisCycleRevenue) || isNaN(this.thisCycleExpenses)) {
+            console.log("ERROR: NaN in Corporation's computed revenue/expenses");
+            console.log(this.thisCycleRevenue.toString());
+            console.log(this.thisCycleExpenses.toString());
+            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Something went wrong when compting Corporation's revenue/expenses. This is a bug. Please report to game developer");
+            this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+            this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+        }
+        this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(marketCycles * SecsPerMarketCycle);
+        this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(marketCycles * SecsPerMarketCycle);
+        this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+        this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+
+        //Once you start making revenue, the player should no longer be
+        //considered new, and therefore no longer needs the 'tutorial' UI elements
+        if (this.lastCycleRevenue.gt(0)) {this.newInd = false;}
+
+        //Process offices (and the employees in them)
+        var employeeSalary = 0;
+        for (var officeLoc in this.offices) {
+            if (this.offices.hasOwnProperty(officeLoc) &&
+                this.offices[officeLoc] instanceof OfficeSpace) {
+                employeeSalary += this.offices[officeLoc].process(marketCycles, {industry:this, corporation:company});
+            }
+        }
+        this.thisCycleExpenses = this.thisCycleExpenses.plus(employeeSalary);
+
+        //Process change in demand/competition of materials/products
+        this.processMaterialMarket(marketCycles);
+        this.processProductMarket(marketCycles);
+
+        //Process loss of popularity
+        this.popularity -= (marketCycles * .0001);
+        this.popularity = Math.max(0, this.popularity);
+
+        //Process Dreamsense gains
+        var popularityGain = company.getDreamSenseGain(), awarenessGain = popularityGain * 4;
+        if (popularityGain > 0) {
+            this.popularity += (popularityGain * marketCycles);
+            this.awareness += (awarenessGain * marketCycles);
+        }
+
+        return;
+    }
+
+    //Process production, purchase, and import/export of materials
+    var res = this.processMaterials(marketCycles, company);
+    this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
+    this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
+
+    //Process creation, production & sale of products
+    res = this.processProducts(marketCycles, company);
+    this.thisCycleRevenue = this.thisCycleRevenue.plus(res[0]);
+    this.thisCycleExpenses = this.thisCycleExpenses.plus(res[1]);
+
+}
+
+//Process change in demand and competition for this industry's materials
+Industry.prototype.processMaterialMarket = function(marketCycles=1) {
+    //References to prodMats and reqMats
+    var reqMats = this.reqMats, prodMats = this.prodMats;
+
+    //Only 'process the market' for materials that this industry deals with
+    for (var i = 0; i < Cities.length; ++i) {
+        //If this industry has a warehouse in this city, process the market
+        //for every material this industry requires or produces
+        if (this.warehouses[Cities[i]] instanceof Warehouse) {
+            var wh = this.warehouses[Cities[i]];
+            for (var name in reqMats) {
+                if (reqMats.hasOwnProperty(name)) {
+                    wh.materials[name].processMarket();
+                }
+            }
+
+            //Produced materials are stored in an array
+            for (var foo = 0; foo < prodMats.length; ++foo) {
+                wh.materials[prodMats[foo]].processMarket();
+            }
+
+            //Process these twice because these boost production
+            wh.materials["Hardware"].processMarket();
+            wh.materials["Robots"].processMarket();
+            wh.materials["AICores"].processMarket();
+            wh.materials["RealEstate"].processMarket();
+        }
+    }
+}
+
+//Process change in demand and competition for this industry's products
+Industry.prototype.processProductMarket = function(marketCycles=1) {
+    //Demand gradually decreases, and competition gradually increases
+    for (var name in this.products) {
+        if (this.products.hasOwnProperty(name)) {
+            var product = this.products[name];
+            var change = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(1, 3) * 0.0004;
+            if (this.type === Industries.Pharmaceutical || this.type === Industries.Software ||
+                this.type === Industries.Robotics) {
+                change *= 3;
+            }
+            change *= marketCycles;
+            product.dmd -= change;
+            product.cmp += change;
+            product.cmp = Math.min(product.cmp, 99.99);
+            product.dmd = Math.max(product.dmd, 0.001);
+        }
+    }
+}
+
+//Process production, purchase, and import/export of materials
+Industry.prototype.processMaterials = function(marketCycles=1, company) {
+    var revenue = 0, expenses = 0, industry = this;
+    this.calculateProductionFactors();
+
+    //At the start of the export state, set the imports of everything to 0
+    if (this.state === "EXPORT") {
+        for (var i = 0; i < Cities.length; ++i) {
+            var city = Cities[i], office = this.offices[city];
+            if (!(this.warehouses[city] instanceof Warehouse)) {
+                continue;
+            }
+            var warehouse = this.warehouses[city];
+            for (var matName in warehouse.materials) {
+                if (warehouse.materials.hasOwnProperty(matName)) {
+                    var mat = warehouse.materials[matName];
+                    mat.imp = 0;
+                }
+            }
+        }
+    }
+
+    for (var i = 0; i < Cities.length; ++i) {
+        var city = Cities[i], office = this.offices[city];
+
+        if (this.warehouses[city] instanceof Warehouse) {
+            var warehouse = this.warehouses[city];
+
+            switch(this.state) {
+
+            case "PURCHASE":
+            /* Process purchase of materials */
+            for (var matName in warehouse.materials) {
+                if (warehouse.materials.hasOwnProperty(matName)) {
+                    (function(matName, ind) {
+                    var mat = warehouse.materials[matName];
+                    var buyAmt, maxAmt;
+                    if (warehouse.smartSupplyEnabled && Object.keys(ind.reqMats).includes(matName)) {
+                        //Smart supply tracker is stored as per second rate
+                        mat.buy = ind.reqMats[matName] * warehouse.smartSupplyStore;
+                        buyAmt = mat.buy * SecsPerMarketCycle * marketCycles;
+                    } else {
+                        buyAmt = (mat.buy * SecsPerMarketCycle * marketCycles);
+                    }
+
+                    if (matName == "RealEstate") {
+                        maxAmt = buyAmt;
+                    } else {
+                        maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / MaterialSizes[matName]);
+                    }
+                    var buyAmt = Math.min(buyAmt, maxAmt);
+                    if (buyAmt > 0) {
+                        mat.qty += buyAmt;
+                        expenses += (buyAmt * mat.bCost);
+                    }
+                })(matName, industry);
+                    this.updateWarehouseSizeUsed(warehouse);
+                }
+            } //End process purchase of materials
+            break;
+
+            case "PRODUCTION":
+            warehouse.smartSupplyStore = 0; //Reset smart supply amount
+
+            /* Process production of materials */
+            if (this.prodMats.length > 0) {
+                var mat = warehouse.materials[this.prodMats[0]];
+                //Calculate the maximum production of this material based
+                //on the office's productivity
+                var maxProd = this.getOfficeProductivity(office) * this.prodMult * company.getProductionMultiplier(), prod;
+
+                if (mat.prdman[0]) {
+                    //Production is manually limited
+                    prod = Math.min(maxProd, mat.prdman[1]);
+                } else {
+                    prod = maxProd;
+                }
+                prod *= (SecsPerMarketCycle * marketCycles); //Convert production from per second to per market cycle
+                //Calculate net change in warehouse storage making
+                //the produced materials will cost
+                var totalMatSize = 0;
+                for (var tmp = 0; tmp < this.prodMats.length; ++tmp) {
+                    totalMatSize += (MaterialSizes[this.prodMats[tmp]]);
+                }
+                for (var reqMatName in this.reqMats) {
+                    if (this.reqMats.hasOwnProperty(reqMatName)) {
+                        var normQty = this.reqMats[reqMatName];
+                        totalMatSize -= (MaterialSizes[reqMatName] * normQty);
+                    }
+                }
+                //If not enough space in warehouse, limit the amount of produced materials
+                if (totalMatSize > 0) {
+                    var maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / totalMatSize);
+                    prod = Math.min(maxAmt, prod);
+                }
+
+                if (prod < 0) {prod = 0;}
+
+                //Keep track of production for smart supply (/s)
+                warehouse.smartSupplyStore += (prod / (SecsPerMarketCycle * marketCycles));
+
+                //Make sure we have enough resource to make our materials
+                var producableFrac = 1;
+                for (var reqMatName in this.reqMats) {
+                    if (this.reqMats.hasOwnProperty(reqMatName)) {
+                        var req = this.reqMats[reqMatName] * prod;
+                        if (warehouse.materials[reqMatName].qty < req) {
+                            producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req);
+                        }
+                    }
+                }
+                if (producableFrac <= 0) {producableFrac = 0; prod = 0;}
+
+                //Make our materials if they are producable
+                if (producableFrac > 0 && prod > 0) {
+                    for (var reqMatName in this.reqMats) {
+                        if (this.reqMats.hasOwnProperty(reqMatName)) {
+                            var reqMatQtyNeeded = (this.reqMats[reqMatName] * prod * producableFrac);
+                            warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
+                            warehouse.materials[reqMatName].prd = 0;
+                            warehouse.materials[reqMatName].prd -= reqMatQtyNeeded / (SecsPerMarketCycle * marketCycles);
+                        }
+                    }
+                    for (var j = 0; j < this.prodMats.length; ++j) {
+                        warehouse.materials[this.prodMats[j]].qty += (prod * producableFrac);
+                        warehouse.materials[this.prodMats[j]].qlt =
+                            (office.employeeProd[EmployeePositions.Engineer] / 100 +
+                             Math.pow(this.sciResearch.qty, this.sciFac) +
+                             Math.pow(warehouse.materials["AICores"].qty, this.aiFac) / 10e3);
+                    }
+                } else {
+                    for (var reqMatName in this.reqMats) {
+                        if (this.reqMats.hasOwnProperty(reqMatName)) {
+                            warehouse.materials[reqMatName].prd = 0;
+                        }
+                    }
+                }
+
+                //Per second
+                var fooProd = prod * producableFrac / (SecsPerMarketCycle * marketCycles);
+                for (var fooI = 0; fooI < this.prodMats.length; ++fooI) {
+                    warehouse.materials[this.prodMats[fooI]].prd = fooProd;
+                }
+            } else {
+                //If this doesn't produce any materials, then it only creates
+                //Products. Creating products will consume materials. The
+                //Production of all consumed materials must be set to 0
+                for (var reqMatName in this.reqMats) {
+                    if (this.reqMats.hasOwnProperty(reqMatName)) {
+                        warehouse.materials[reqMatName].prd = 0;
+                    }
+                }
+            }
+            break;
+
+            case "SALE":
+            /* Process sale of materials */
+            for (var matName in warehouse.materials) {
+                if (warehouse.materials.hasOwnProperty(matName)) {
+                    var mat = warehouse.materials[matName];
+                    if (mat.sCost < 0 || mat.sllman[0] === false) {
+                        mat.sll = 0;
+                        continue;
+                    }
+                    var mat = warehouse.materials[matName];
+
+                    var sCost;
+                    if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(mat.sCost)) {
+                        sCost = mat.sCost.replace(/MP/g, mat.bCost);
+                        sCost = eval(sCost);
+                    } else {
+                        sCost = mat.sCost;
+                    }
+
+                    //Calculate how much of the material sells (per second)
+                    var markup = 1, markupLimit = mat.qlt / mat.mku;
+                    if (sCost > mat.bCost) {
+                        //Penalty if difference between sCost and bCost is greater than markup limit
+                        if ((sCost - mat.bCost) > markupLimit) {
+                            markup = markupLimit / (sCost - mat.bCost);
+                        }
+                    } else if (sCost < mat.bCost) {
+                        if (sCost <= 0) {
+                            markup = 1e12; //Sell everything, essentially discard
+                        } else {
+                            //Lower prices than market increases sales
+                            markup = mat.bCost / sCost;
+                        }
+                    }
+                    //var businessFactor = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]);
+                    var businessFactor = this.getBusinessFactor(office);        //Business employee productivity
+                    var advertisingFactor = this.getAdvertisingFactors()[0];    //Awareness + popularity
+                    var marketFactor = this.getMarketFactor(mat);               //Competition + demand
+                    var maxSell = (mat.qlt + .001) * marketFactor * markup * businessFactor *
+                                  company.getSalesMultiplier() * advertisingFactor;
+
+                    var sellAmt;
+                    if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(mat.sllman[1])) {
+                        //Dynamically evaluated
+                        var tmp = mat.sllman[1].replace(/MAX/g, maxSell);
+                        tmp = tmp.replace(/PROD/g, mat.prd);
+                        try {
+                            sellAmt = eval(tmp);
+                        } catch(e) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Error evaluating your sell amount for material " + mat.name +
+                                            " in " + this.name + "'s " + city + " office. The sell amount " +
+                                            "is being set to zero");
+                            sellAmt = 0;
+                        }
+                        sellAmt = Math.min(maxSell, sellAmt);
+                    } else if (mat.sllman[1] === -1) {
+                        //Backwards compatibility, -1 = MAX
+                        sellAmt = maxSell;
+                    } else {
+                        //Player's input value is just a number
+                        sellAmt = Math.min(maxSell, mat.sllman[1]);
+                    }
+
+                    sellAmt = (sellAmt * SecsPerMarketCycle * marketCycles);
+                    sellAmt = Math.min(mat.qty, sellAmt);
+                    if (sellAmt < 0) {
+                        console.log("sellAmt calculated to be negative");
+                        mat.sll = 0;
+                        continue;
+                    }
+                    if (sellAmt && sCost >= 0) {
+                        mat.qty -= sellAmt;
+                        revenue += (sellAmt * sCost);
+                        mat.sll = sellAmt / (SecsPerMarketCycle * marketCycles);
+                    } else {
+                        mat.sll = 0;
+                    }
+                }
+            } //End processing of sale of materials
+            break;
+
+            case "EXPORT":
+                for (var matName in warehouse.materials) {
+                    if (warehouse.materials.hasOwnProperty(matName)) {
+                        var mat = warehouse.materials[matName];
+                        mat.totalExp = 0; //Reset export
+                        for (var expI = 0; expI < mat.exp.length; ++expI) {
+                            var exp = mat.exp[expI];
+                            var amt = exp.amt.replace(/MAX/g, mat.qty / (SecsPerMarketCycle * marketCycles));
+                            try {
+                                amt = eval(amt);
+                            } catch(e) {
+                                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Calculating export for " + mat.name + " in " +
+                                                this.name +  "'s " + city + " division failed with " +
+                                                "error: " + e);
+                                continue;
+                            }
+                            if (isNaN(amt)) {
+                                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Error calculating export amount for " + mat.name +  " in " +
+                                                this.name + "'s " + city + " division.");
+                                continue;
+                            }
+                            amt = amt * SecsPerMarketCycle * marketCycles;
+
+                            if (mat.qty < amt) {
+                                amt = mat.qty;
+                            }
+                            if (amt === 0) {
+                                break; //None left
+                            }
+                            for (var foo = 0; foo < company.divisions.length; ++foo) {
+                                if (company.divisions[foo].name === exp.ind) {
+                                    var expIndustry = company.divisions[foo];
+                                    var expWarehouse = expIndustry.warehouses[exp.city];
+                                    if (!(expWarehouse instanceof Warehouse)) {
+                                        console.log("ERROR: Invalid export! " + expIndustry.name + " "  + exp.city);
+                                        break;
+                                    }
+
+                                    //Make sure theres enough space in warehouse
+                                    if (expWarehouse.sizeUsed >= expWarehouse.size) {
+                                        return; //Warehouse at capacity
+                                    } else {
+                                        var maxAmt = Math.floor((expWarehouse.size - expWarehouse.sizeUsed) / MaterialSizes[matName]);
+                                        amt = Math.min(maxAmt, amt);
+                                    }
+                                    expWarehouse.materials[matName].imp += (amt / (SecsPerMarketCycle * marketCycles));
+                                    expWarehouse.materials[matName].qty += amt;
+                                    expWarehouse.materials[matName].qlt = mat.qlt;
+                                    mat.qty -= amt;
+                                    mat.totalExp += amt;
+                                    expIndustry.updateWarehouseSizeUsed(expWarehouse);
+                                    break;
+                                }
+                            }
+                        }
+                        //totalExp should be per second
+                        mat.totalExp /= (SecsPerMarketCycle * marketCycles);
+                    }
+                }
+
+                break;
+
+            case "START":
+                break;
+            default:
+                console.log("ERROR: Invalid state: " + this.state);
+                break;
+            } //End switch(this.state)
+            this.updateWarehouseSizeUsed(warehouse);
+
+        } // End warehouse
+
+        //Produce Scientific Research based on R&D employees
+        //Scientific Research can be produced without a warehouse
+        if (office instanceof OfficeSpace) {
+            this.sciResearch.qty += (.005 * Math.pow(office.employeeProd[EmployeePositions.RandD], 0.5)
+                                     * company.getScientificResearchMultiplier());
+        }
+    }
+    return [revenue, expenses];
+}
+
+//Process production & sale of this industry's FINISHED products (including all of their stats)
+Industry.prototype.processProducts = function(marketCycles=1, corporation) {
+    var revenue = 0, expenses = 0;
+
+    //Create products
+    if (this.state === "PRODUCTION") {
+        for (var prodName in this.products) {
+            if (this.products.hasOwnProperty(prodName)) {
+                var prod = this.products[prodName];
+                if (!prod.fin) {
+                    var city = prod.createCity, office = this.offices[city];
+                    var total = office.employeeProd[EmployeePositions.Operations] +
+                                office.employeeProd[EmployeePositions.Engineer] +
+                                office.employeeProd[EmployeePositions.Management], ratio;
+                    if (total === 0) {
+                        ratio = 0;
+                    } else {
+                        ratio = office.employeeProd[EmployeePositions.Engineer] / total +
+                                office.employeeProd[EmployeePositions.Operations] / total +
+                                office.employeeProd[EmployeePositions.Management] / total;
+                    }
+                    prod.createProduct(marketCycles, ratio * Math.pow(total, 0.29));
+                    if (prod.prog >= 100) {
+                         prod.finishProduct(office.employeeProd, this);
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    //Produce Products
+    for (var prodName in this.products) {
+        if (this.products.hasOwnProperty(prodName)) {
+            var prod = this.products[prodName];
+            if (prod instanceof Product && prod.fin) {
+                revenue += this.processProduct(marketCycles, prod, corporation);
+            }
+        }
+    }
+    return [revenue, expenses];
+}
+
+//Processes FINISHED products
+Industry.prototype.processProduct = function(marketCycles=1, product, corporation) {
+    var totalProfit = 0;
+    for (var i = 0; i < Cities.length; ++i) {
+        var city = Cities[i], office = this.offices[city], warehouse = this.warehouses[city];
+        if (warehouse instanceof Warehouse) {
+            switch(this.state) {
+
+            case "PRODUCTION":
+            //Calculate the maximum production of this material based
+            //on the office's productivity
+            var maxProd = this.getOfficeProductivity(office, {forProduct:true}) *
+                          corporation.getProductionMultiplier() * this.prodMult, prod;
+
+            //Account for whether production is manually limited
+            if (product.prdman[city][0]) {
+                prod = Math.min(maxProd, product.prdman[city][1]);
+            } else {
+                prod = maxProd;
+            }
+            prod *= (SecsPerMarketCycle * marketCycles);
+
+            //Calculate net change in warehouse storage making the Products will cost
+            var netStorageSize = product.siz;
+            for (var reqMatName in product.reqMats) {
+                if (product.reqMats.hasOwnProperty(reqMatName)) {
+                    var normQty = product.reqMats[reqMatName];
+                    netStorageSize -= (MaterialSizes[reqMatName] * normQty);
+                }
+            }
+
+            //If there's not enough space in warehouse, limit the amount of Product
+            if (netStorageSize > 0) {
+                var maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / netStorageSize);
+                prod = Math.min(maxAmt, prod);
+            }
+
+            warehouse.smartSupplyStore += (prod / (SecsPerMarketCycle * marketCycles));
+
+            //Make sure we have enough resources to make our Products
+            var producableFrac = 1;
+            for (var reqMatName in product.reqMats) {
+                if (product.reqMats.hasOwnProperty(reqMatName)) {
+                    var req = product.reqMats[reqMatName] * prod;
+                    if (warehouse.materials[reqMatName].qty < req) {
+                        producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req);
+                    }
+                }
+            }
+
+            //Make our Products if they are producable
+            if (producableFrac > 0 && prod > 0) {
+                for (var reqMatName in product.reqMats) {
+                    if (product.reqMats.hasOwnProperty(reqMatName)) {
+                        var reqMatQtyNeeded = (product.reqMats[reqMatName] * prod * producableFrac);
+                        warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
+                        warehouse.materials[reqMatName].prd -= reqMatQtyNeeded / (SecsPerMarketCycle * marketCycles);
+                    }
+                }
+                //Quantity
+                product.data[city][0] += (prod * producableFrac);
+            }
+
+            //Keep track of production Per second
+            product.data[city][1] = prod * producableFrac / (SecsPerMarketCycle * marketCycles);
+            break;
+
+            case "SALE":
+            //Process sale of Products
+            product.pCost = 0; //Estimated production cost
+            for (var reqMatName in product.reqMats) {
+                if (product.reqMats.hasOwnProperty(reqMatName)) {
+                    product.pCost += (product.reqMats[reqMatName] * warehouse.materials[reqMatName].bCost);
+                }
+            }
+
+            //Since its a product, its production cost is increased for labor
+            product.pCost *= ProductProductionCostRatio;
+
+            //Calculate Sale Cost (sCost), which could be dynamically evaluated
+            var sCost;
+            if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(product.sCost)) {
+                sCost = product.sCost.replace(/MP/g, product.pCost + product.rat / product.mku);
+                sCost = eval(sCost);
+            } else {
+                sCost = product.sCost;
+            }
+
+            var markup = 1, markupLimit = product.rat / product.mku;
+            if (sCost > product.pCost) {
+                if ((sCost - product.pCost) > markupLimit) {
+                    markup = markupLimit / (sCost - product.pCost);
+                }
+            }
+            var businessFactor = this.getBusinessFactor(office);        //Business employee productivity
+            var advertisingFactor = this.getAdvertisingFactors()[0];    //Awareness + popularity
+            var marketFactor = this.getMarketFactor(product);        //Competition + demand
+            var maxSell = 0.5 * Math.pow(product.rat, 0.65) * marketFactor * corporation.getSalesMultiplier() *
+                          Math.pow(markup, 2) * businessFactor * advertisingFactor;
+            var sellAmt;
+            if (product.sllman[city][0] && Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(product.sllman[city][1])) {
+                //Sell amount is dynamically evaluated
+                var tmp = product.sllman[city][1].replace(/MAX/g, maxSell);
+                tmp = tmp.replace(/PROD/g, product.data[city][1]);
+                try {
+                    tmp = eval(tmp);
+                } catch(e) {
+                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Error evaluating your sell price expression for " + product.name +
+                                    " in " + this.name + "'s " + city + " office. Sell price is being set to MAX");
+                    tmp = maxSell;
+                }
+                sellAmt = Math.min(maxSell, tmp);
+            } else if (product.sllman[city][0] && product.sllman[city][1] > 0) {
+                //Sell amount is manually limited
+                sellAmt = Math.min(maxSell, product.sllman[city][1]);
+            } else {
+                //Backwards compatibility, -1 = 0
+                sellAmt = maxSell;
+            }
+            sellAmt = sellAmt * SecsPerMarketCycle * marketCycles;
+            sellAmt = Math.min(product.data[city][0], sellAmt); //data[0] is qty
+            if (sellAmt && sCost) {
+                product.data[city][0] -= sellAmt; //data[0] is qty
+                totalProfit += (sellAmt * sCost);
+                product.data[city][2] = sellAmt / (SecsPerMarketCycle * marketCycles); //data[2] is sell property
+            } else {
+                product.data[city][2] = 0; //data[2] is sell property
+            }
+            break;
+
+            case "START":
+            case "PURCHASE":
+            case "EXPORT":
+                break;
+            default:
+                console.log("ERROR: Invalid State: " + this.state);
+                break;
+            } //End switch(this.state)
+        }
+    }
+    return totalProfit;
+}
+
+Industry.prototype.discontinueProduct = function(product, parentRefs) {
+    var company = parentRefs.company, industry = parentRefs.industry;
+    for (var productName in this.products) {
+        if (this.products.hasOwnProperty(productName)) {
+            if (product === this.products[productName]) {
+                delete this.products[productName];
+                company.updateUIContent();
+            }
+        }
+    }
+}
+
+Industry.prototype.upgrade = function(upgrade, refs) {
+    var corporation = refs.corporation, division = refs.division,
+        office = refs.office;
+    var upgN = upgrade[0], basePrice = upgrade[1], priceMult = upgrade[2],
+        upgradeBenefit = upgrade[3];
+    while (this.upgrades.length <= upgN) {this.upgrades.push(0);}
+    ++this.upgrades[upgN];
+
+    switch (upgN) {
+        case 0: //Coffee, 5% energy per employee
+            for (var i = 0; i < office.employees.length; ++i) {
+                office.employees[i].ene = Math.min(office.employees[i].ene * 1.05, 100);
+            }
+            break;
+        case 1: //AdVert.Inc,
+            var advMult = corporation.getAdvertisingMultiplier();
+            this.awareness += (3 * advMult);
+            this.popularity += (1 * advMult);
+            this.awareness *= (1.01 * advMult);
+            this.popularity *= ((1 + Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(1, 3) / 100) * advMult);
+            break;
+        default:
+            console.log("ERROR: Un-implemented function index: " + upgN);
+            break;
+    }
+}
+
+//Returns how much of a material can be produced based of office productivity (employee stats)
+Industry.prototype.getOfficeProductivity = function(office, params) {
+    var total = office.employeeProd[EmployeePositions.Operations] +
+                office.employeeProd[EmployeePositions.Engineer] +
+                office.employeeProd[EmployeePositions.Management], ratio;
+    if (total === 0) {
+        ratio = 0;
+    } else {
+        ratio = (office.employeeProd[EmployeePositions.Operations] / total) *
+                (office.employeeProd[EmployeePositions.Engineer] / total) *
+                (office.employeeProd[EmployeePositions.Management] / total);
+        ratio = Math.max(0.01, ratio); //Minimum ratio value if you have employees
+    }
+    if (params && params.forProduct) {
+        return ratio * Math.pow(total, 0.2);
+    } else {
+        return 2 * ratio * Math.pow(total, 0.3);
+    }
+}
+
+//Returns a multiplier based on the office' 'Business' employees that affects sales
+Industry.prototype.getBusinessFactor = function(office) {
+    var ratioMult = 1;
+    if (office.employeeProd["total"] > 0) {
+        ratioMult = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]);
+    }
+    return ratioMult * Math.pow(1 + office.employeeProd[EmployeePositions.Business], 0.15);
+}
+
+//Returns a set of multipliers based on the Industry's awareness, popularity, and advFac. This
+//multiplier affects sales. The result is:
+//  [Total sales mult, total awareness mult, total pop mult, awareness/pop ratio mult]
+Industry.prototype.getAdvertisingFactors = function() {
+    var awarenessFac = Math.pow(this.awareness + 1, this.advFac);
+    var popularityFac = Math.pow(this.popularity + 1, this.advFac);
+    var ratioFac = (this.awareness === 0 ? 0.01 : Math.max((this.popularity + .001) / this.awareness, 0.01));
+    var totalFac = Math.pow(awarenessFac * popularityFac * ratioFac, 0.85);
+    return [totalFac, awarenessFac, popularityFac, ratioFac];
+}
+
+//Returns a multiplier based on a materials demand and competition that affects sales
+Industry.prototype.getMarketFactor = function(mat) {
+    return mat.dmd * (100 - mat.cmp)/100;
+}
+
+Industry.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Industry", this);
+}
+
+Industry.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Industry, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Industry = Industry;
+
+var EmployeePositions = {
+    Operations: "Operations",
+    Engineer: "Engineer",
+    Business: "Business",
+    Management: "Management",
+    RandD: "Research & Development",
+    Training:"Training",
+    Unassigned:"Unassigned",
+}
+
+function Employee(params={}) {
+    if (!(this instanceof Employee)) {
+        return new Employee(params);
+    }
+    this.name   = params.name           ? params.name           : "Bobby";
+
+    //Morale, happiness, and energy are 0-100
+    this.mor    = params.morale         ? params.morale         : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100);
+    this.hap    = params.happiness      ? params.happiness      : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100);
+    this.ene    = params.energy         ? params.energy         : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100);
+
+    this.age    = params.age            ? params.age            : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(20, 50);
+    this.int    = params.intelligence   ? params.intelligence   : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
+    this.cha    = params.charisma       ? params.charisma       : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
+    this.exp    = params.experience     ? params.experience     : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
+    this.cre    = params.creativity     ? params.creativity     : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
+    this.eff    = params.efficiency     ? params.efficiency     : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(10, 50);
+    this.sal    = params.salary         ? params.salary         : Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(0.1, 5);
+    this.pro    = 0; //Productivity, This is calculated
+
+    this.loc    = params.loc            ? params.loc : "";
+    this.pos    = EmployeePositions.Unassigned;
+}
+
+//Returns the amount the employee needs to be paid
+Employee.prototype.process = function(marketCycles=1, office) {
+    var gain = 0.001 * marketCycles,
+        det = gain * Math.random();
+    this.age += gain;
+    this.exp += gain;
+    if (this.age > 150) {
+        this.int -= det;
+        this.eff -= det;
+        this.cha -= det;
+    }
+
+    //Training
+    var trainingEff = gain * Math.random();
+    if (this.pos === EmployeePositions.Training) {
+        //To increase creativity and intelligence special upgrades are needed
+        this.cha += trainingEff;
+        this.exp += trainingEff;
+        this.eff += trainingEff;
+    }
+
+    //Weight based on how full office is
+    //Too many employees = more likely to decrease energy and happiness
+    var officeCapacityWeight = 0.5 * (office.employees.length / office.size - 0.5);
+    if (Math.random() < 0.5 - officeCapacityWeight) {
+        this.ene += det;
+        this.hap += det;
+    } else {
+        this.ene -= det;
+        this.hap -= det;
+    }
+    if (this.ene < office.minEne) {this.ene = office.minEne;}
+    if (this.hap < office.minHap) {this.hap = office.minHap;}
+    var salary = this.sal * marketCycles * SecsPerMarketCycle;
+    return salary;
+}
+
+Employee.prototype.calculateProductivity = function(corporation) {
+    var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
+        effCha = this.cha * corporation.getEmployeeChaMultiplier(),
+        effInt = this.int * corporation.getEmployeeIntMultiplier(),
+        effEff = this.eff * corporation.getEmployeeEffMultiplier();
+    var prodBase = this.mor * this.hap * this.ene * 1e-6, prodMult;
+    switch(this.pos) {
+        //Calculate productivity based on position. This is multipled by prodBase
+        //to get final value
+        case EmployeePositions.Operations:
+            prodMult = (0.6 * effInt) + (0.1 * effCha) + (this.exp) +
+                       (0.5 * effCre) + (effEff);
+            break;
+        case EmployeePositions.Engineer:
+            prodMult = (effInt) + (0.1 * effCha) + (1.5 * this.exp) +
+                       (effEff);
+            break;
+        case EmployeePositions.Business:
+            prodMult = (0.4 * effInt) + (effCha) + (0.5 * this.exp);
+            break;
+        case EmployeePositions.Management:
+            prodMult = (2 * effCha) + (this.exp) + (0.2 * effCre) +
+                       (0.7 * effEff);
+            break;
+        case EmployeePositions.RandD:
+            prodMult = (1.5 * effInt) + (0.8 * this.exp) + (effCre) +
+                       (0.5 * effEff);
+            break;
+        case EmployeePositions.Unassigned:
+        case EmployeePositions.Training:
+            prodMult = 0;
+            break;
+        default:
+            console.log("ERROR: Invalid employee position: " + this.pos);
+            break;
+    }
+    return prodBase * prodMult;
+}
+
+//Process benefits from having an office party thrown
+Employee.prototype.throwParty = function(money) {
+    var mult = 1 + (money / 10e6);
+    this.mor *= mult;
+    this.mor = Math.min(100, this.mor);
+    this.hap *= mult;
+    this.hap = Math.min(100, this.hap);
+    return mult;
+}
+
+//'panel' is the DOM element on which to create the UI
+Employee.prototype.createUI = function(panel, corporation) {
+    var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
+        effCha = this.cha * corporation.getEmployeeChaMultiplier(),
+        effInt = this.int * corporation.getEmployeeIntMultiplier(),
+        effEff = this.eff * corporation.getEmployeeEffMultiplier();
+    panel.style.color = "white";
+    panel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        id:"cmpy-mgmt-employee-" + this.name + "-panel-text",
+        innerHTML:"Morale: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.mor, 3) + "<br>" +
+                  "Happiness: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.hap, 3) + "<br>" +
+                  "Energy: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.ene, 3) + "<br>" +
+                  "Age: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.age, 3) + "<br>" +
+                  "Intelligence: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effInt, 3) + "<br>" +
+                  "Charisma: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effCha, 3) + "<br>" +
+                  "Experience: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.exp, 3) + "<br>" +
+                  "Creativity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effCre, 3) + "<br>" +
+                  "Efficiency: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effEff, 3) + "<br>" +
+                  "Salary: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.sal).format("$0.000a") + "/ s<br>",
+    }));
+
+    //Selector for employee position
+    var selector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {});
+    for (var key in EmployeePositions) {
+        if (EmployeePositions.hasOwnProperty(key)) {
+            selector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                text: EmployeePositions[key],
+                value: EmployeePositions[key],
+            }));
+        }
+    }
+
+    selector.addEventListener("change", ()=>{
+        this.pos = selector.options[selector.selectedIndex].value;
+    });
+
+    //Set initial value of selector
+    for (var i = 0; i < selector.length; ++i) {
+        if (selector.options[i].value === this.pos) {
+            selector.selectedIndex = i;
+            break;
+        }
+    }
+    panel.appendChild(selector);
+}
+
+Employee.prototype.updateUI = function(panel, corporation) {
+    var effCre = this.cre * corporation.getEmployeeCreMultiplier(),
+        effCha = this.cha * corporation.getEmployeeChaMultiplier(),
+        effInt = this.int * corporation.getEmployeeIntMultiplier(),
+        effEff = this.eff * corporation.getEmployeeEffMultiplier();
+    if (panel == null) {
+        console.log("ERROR: Employee.updateUI() called with null panel");
+        return;
+    }
+    var text = document.getElementById("cmpy-mgmt-employee-" + this.name + "-panel-text");
+    if (text == null) {
+        return this.createUI(panel);
+    }
+    text.innerHTML  = "Morale: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.mor, 3) + "<br>" +
+                      "Happiness: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.hap, 3) + "<br>" +
+                      "Energy: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.ene, 3) + "<br>" +
+                      "Age: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.age, 3) + "<br>" +
+                      "Intelligence: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effInt, 3) + "<br>" +
+                      "Charisma: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effCha, 3) + "<br>" +
+                      "Experience: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.exp, 3) + "<br>" +
+                      "Creativity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effCre, 3) + "<br>" +
+                      "Efficiency: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(effEff, 3) + "<br>" +
+                      "Salary: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.sal).format("$0.000a") + "/ s<br>";
+}
+
+Employee.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Employee", this);
+}
+
+Employee.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Employee, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Employee = Employee;
+
+var OfficeSpaceTiers = {
+    Basic: "Basic",
+    Enhanced: "Enhanced",
+    Luxurious: "Luxurious",
+    Extravagant: "Extravagant"
+}
+
+function OfficeSpace(params={}) {
+    this.loc    = params.loc        ? params.loc        : "";
+    this.cost   = params.cost       ? params.cost       : 1;
+    this.size   = params.size       ? params.size       : 1;
+    this.comf   = params.comfort    ? params.comfort    : 1;
+    this.beau   = params.beauty      ? params.beauty     : 1;
+    this.tier   = OfficeSpaceTiers.Basic;
+
+    this.minEne     = 0; //Minimum energy of employees, based on office
+    this.minHap     = 0; //Minimum happiness of employees, based on office.
+
+    this.employees = [];
+    this.employeeProd = {
+        [EmployeePositions.Operations]:   0,
+        [EmployeePositions.Engineer]:     0,
+        [EmployeePositions.Business]:     0,
+        [EmployeePositions.Management]:   0,
+        [EmployeePositions.RandD]:        0,
+        total:                            0,
+    };
+}
+
+OfficeSpace.prototype.process = function(marketCycles=1, parentRefs) {
+    var corporation = parentRefs.corporation, industry = parentRefs.industry;
+    var perfMult=1; //Multiplier for employee morale/happiness/energy based on company performance
+    if (industry.funds < 0 && industry.lastCycleRevenue < 0) {
+        perfMult = Math.pow(0.99, marketCycles);
+    } else if (industry.funds > 0 && industry.lastCycleRevenue > 0) {
+        perfMult = Math.pow(1.01, marketCycles);
+    }
+
+    var salaryPaid = 0;
+    for (var i = 0; i < this.employees.length; ++i) {
+        var emp = this.employees[i];
+        emp.mor *= perfMult;
+        emp.hap *= perfMult;
+        emp.ene *= perfMult;
+        var salary = emp.process(marketCycles, this);
+        salaryPaid += salary;
+    }
+    this.calculateEmployeeProductivity(marketCycles, corporation);
+    return salaryPaid;
+}
+
+OfficeSpace.prototype.calculateEmployeeProductivity = function(marketCycles=1, corporation) {
+    //Reset
+    for (var name in this.employeeProd) {
+        if (this.employeeProd.hasOwnProperty(name)) {
+            this.employeeProd[name] = 0;
+        }
+    }
+
+    var total = 0;
+    for (var i = 0; i < this.employees.length; ++i) {
+        var employee = this.employees[i];
+        var prod = employee.calculateProductivity(corporation);
+        this.employeeProd[employee.pos] += prod;
+        total += prod;
+    }
+    this.employeeProd["total"] = total;
+}
+
+//Takes care of UI as well
+OfficeSpace.prototype.findEmployees = function(parentRefs) {
+    var company = parentRefs.corporation, division = parentRefs.division;
+    if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;}
+
+    //Generate three random employees (meh, decent, amazing)
+    var mult1 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(25, 50)/100,
+        mult2 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(51, 75)/100,
+        mult3 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(76, 100)/100;
+    var int = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        cha = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        exp = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        cre = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        eff = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        sal = 2.2 * (int + cha + exp + cre + eff);
+
+    var emp1 = new Employee({
+        intelligence: int * mult1,
+        charisma: cha * mult1,
+        experience: exp * mult1,
+        creativity: cre * mult1,
+        efficiency: eff * mult1,
+        salary: sal * mult1,
+    });
+
+    var emp2 = new Employee({
+        intelligence: int * mult2,
+        charisma: cha * mult2,
+        experience: exp * mult2,
+        creativity: cre * mult2,
+        efficiency: eff * mult2,
+        salary: sal * mult2,
+    });
+
+    var emp3 = new Employee({
+        intelligence: int * mult3,
+        charisma: cha * mult3,
+        experience: exp * mult3,
+        creativity: cre * mult3,
+        efficiency: eff * mult3,
+        salary: sal * mult3,
+    });
+
+    var text = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("h1", {
+        innerHTML: "Select one of the following candidates for hire:",
+    });
+
+    var createEmpDiv = function(employee, office) {
+        var div = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+            class:"cmpy-mgmt-find-employee-option",
+            innerHTML:  "Intelligence: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.int, 1) + "<br>" +
+                        "Charisma: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.cha, 1) + "<br>" +
+                        "Experience: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.exp, 1) + "<br>" +
+                        "Creativity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.cre, 1) + "<br>" +
+                        "Efficiency: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(employee.eff, 1) + "<br>" +
+                        "Salary: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(employee.sal).format('$0.000a') + " \ s<br>",
+            clickListener:()=>{
+                office.hireEmployee(employee, parentRefs);
+                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])("cmpy-mgmt-hire-employee-popup");
+                return false;
+            }
+        });
+        return div;
+    };
+
+    var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:"a-link-button",
+        innerText:"Cancel",
+        float:"right",
+        clickListener:()=>{
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])("cmpy-mgmt-hire-employee-popup");
+            return false;
+        }
+    });
+
+    var elems = [text,
+                 createEmpDiv(emp1, this),
+                 createEmpDiv(emp2, this),
+                 createEmpDiv(emp3, this),
+                 cancelBtn];
+
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])("cmpy-mgmt-hire-employee-popup", elems);
+}
+
+OfficeSpace.prototype.hireEmployee = function(employee, parentRefs) {
+    var company = parentRefs.corporation, division = parentRefs.division;
+    var yesBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxGetYesButton"])(),
+        noBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxGetNoButton"])();
+    yesBtn.innerHTML = "Hire";
+    noBtn.innerHTML = "Cancel";
+    yesBtn.addEventListener("click", ()=>{
+        var name = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxGetInput"])();
+        for (var i = 0; i < this.employees.length; ++i) {
+            if (this.employees[i].name === name) {
+                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You already have an employee with this nickname! Please give every employee a unique nickname.");
+                return false;
+            }
+        }
+        employee.name = name;
+        this.employees.push(employee);
+        company.displayDivisionContent(division, currentCityUi);
+        return Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxClose"])();
+    });
+    noBtn.addEventListener("click", ()=>{
+        return Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxClose"])();
+    });
+    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoTxtInpBoxCreate"])("Give your employee a nickname!");
+}
+
+OfficeSpace.prototype.hireRandomEmployee = function(parentRefs) {
+    var company = parentRefs.corporation, division = parentRefs.division;
+    if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;}
+
+    //Generate three random employees (meh, decent, amazing)
+    var mult = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(76, 100)/100;
+    var int = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        cha = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        exp = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        cre = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        eff = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["getRandomInt"])(50, 100),
+        sal = 2.2 * (int + cha + exp + cre + eff);
+
+    var emp = new Employee({
+        intelligence: int * mult,
+        charisma: cha * mult,
+        experience: exp * mult,
+        creativity: cre * mult,
+        efficiency: eff * mult,
+        salary: sal * mult,
+    });
+
+    var name = Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["generateRandomString"])(7);
+
+    for (var i = 0; i < this.employees.length; ++i) {
+        if (this.employees[i].name === name) {
+            return this.hireRandomEmployee(parentRefs);
+        }
+    }
+    emp.name = name;
+    this.employees.push(emp);
+    company.displayDivisionContent(division, currentCityUi);
+}
+
+//Finds the first unassigned employee and assigns its to the specified job
+OfficeSpace.prototype.assignEmployeeToJob = function(job) {
+    for (var i = 0; i < this.employees.length; ++i) {
+        if (this.employees[i].pos === EmployeePositions.Unassigned) {
+            this.employees[i].pos = job;
+            return true;
+        }
+    }
+    return false;
+}
+
+//Finds the first employee with the given job and unassigns it
+OfficeSpace.prototype.unassignEmployeeFromJob = function(job) {
+    for (var i = 0; i < this.employees.length; ++i) {
+        if (this.employees[i].pos === job) {
+            this.employees[i].pos = EmployeePositions.Unassigned;
+            return true;
+        }
+    }
+    return false;
+}
+
+OfficeSpace.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("OfficeSpace", this);
+}
+
+OfficeSpace.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(OfficeSpace, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.OfficeSpace = OfficeSpace;
+
+function Warehouse(params={}) {
+    this.loc    = params.loc        ? params.loc    : "";
+    this.size   = params.size       ? params.size   : 0;
+    this.level  = 0;
+    this.sizeUsed = 0;
+    this.smartSupplyEnabled = false; //Whether or not smart supply is enabled
+    this.breakdown = "";
+
+    //Stores the amount of product to be produced. Used for Smart Supply unlock.
+    //The production tracked by smart supply is always based on the previous cycle,
+    //so it will always trail the "true" production by 1 cycle
+    this.smartSupplyStore = 0;
+
+    this.materials = {
+        Water:      new Material({name: "Water"}),
+        Energy:     new Material({name: "Energy"}),
+        Food:       new Material({name: "Food"}),
+        Plants:     new Material({name: "Plants"}),
+        Metal:      new Material({name: "Metal"}),
+        Hardware:   new Material({name: "Hardware"}),
+        Chemicals:  new Material({name: "Chemicals"}),
+        Drugs:      new Material({name: "Drugs"}),
+        Robots:     new Material({name: "Robots"}),
+        AICores:    new Material({name: "AI Cores"}),
+        RealEstate: new Material({name: "Real Estate"})
+    }
+}
+
+Warehouse.prototype.updateMaterialSizeUsed = function() {
+    this.sizeUsed = 0;
+    this.breakdown = "";
+    for (var matName in this.materials) {
+        if (this.materials.hasOwnProperty(matName)) {
+            var mat = this.materials[matName];
+            if (MaterialSizes.hasOwnProperty(matName)) {
+                this.sizeUsed += (mat.qty * MaterialSizes[matName]);
+                if (mat.qty > 0) {
+                    this.breakdown += (matName + ": " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.qty * MaterialSizes[matName], 0) + "<br>");
+                }
+            }
+        }
+    }
+    if (this.sizeUsed > this.size) {
+        console.log("ERROR: Warehouse size used greater than capacity, something went wrong");
+    }
+}
+
+Warehouse.prototype.updateSize = function(corporation) {
+    //Backwards compatibility
+    if (this.level == null || this.level === 0) {
+        this.level = Math.round(this.size / 100);
+    }
+
+    this.size = (this.level * 100) * corporation.getStorageMultiplier();
+}
+
+Warehouse.prototype.createUI = function(parentRefs) {
+    if (parentRefs.company == null || parentRefs.industry == null) {
+        console.log("ERROR: Warehouse.createUI called without parentRefs.company or parentRefs.industry");
+        return;
+    }
+    var company = parentRefs.company, industry = parentRefs.industry;
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryWarehousePanel);
+    industryWarehouseStorageText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        display:"inline-block", class:"tooltip",
+        color: this.sizeUsed >= this.size ? "red" : "white",
+    });
+    industryWarehousePanel.appendChild(industryWarehouseStorageText);
+
+    //Upgrade warehouse size button
+    var upgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, this.level+1);
+    industryWarehouseUpgradeSizeButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        innerText:"Upgrade Warehouse Size - " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgradeCost).format('$0.000a'),
+        display:"inline-block",
+        class: company.funds.lt(upgradeCost) ? "a-link-button-inactive" : "a-link-button",
+        clickListener:()=>{
+            //Backwards compatibility
+            if (this.level == null || this.level === 0) {
+                this.level = Math.round(this.size / 100);
+            }
+
+            ++this.level;
+            this.updateSize(company);
+            company.funds = company.funds.minus(upgradeCost);
+            this.createUI(parentRefs);
+            return;
+        }
+    });
+    industryWarehousePanel.appendChild(industryWarehouseUpgradeSizeButton);
+
+    //Material requirement text
+    var reqText = "This Industry uses [" + Object.keys(industry.reqMats).join(", ") +
+                  "] in order to ";
+    if (industry.prodMats.length > 0) {
+        reqText += "produce [" + industry.prodMats.join(", ") + "] ";
+        if (industry.makesProducts) {
+            reqText += " and " + industry.getProductDescriptionText();
+        }
+    } else if (industry.makesProducts) {
+        reqText += industry.getProductDescriptionText();
+    }
+    reqText += "<br><br>To get started with production, purchase your required " +
+               "materials or import them from another of your company's divisions.<br><br>";
+
+    //Material ratio text for tooltip
+    var reqRatioText = "The exact requirements for production are:<br>";
+    for (var matName in industry.reqMats) {
+        if (industry.reqMats.hasOwnProperty(matName)) {
+            reqRatioText += (industry.reqMats[matName] + " " + matName + "<br>");
+        }
+    }
+    reqRatioText += "in order to create ";
+    if (industry.prodMats.length > 0) {
+        reqRatioText += "one of each produced Material (" + industry.prodMats.join(", ") + ") ";
+        if (industry.makesProducts) {
+            reqRatioText += "or to create one of its Products";
+        }
+    } else if (industry.makesProducts) {
+        reqRatioText += "one of its Products";
+    }
+
+    industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        innerHTML:reqText, tooltipleft:reqRatioText
+    }));
+
+    //Current state
+    industryWarehouseStateText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p");
+    industryWarehousePanel.appendChild(industryWarehouseStateText);
+
+    //Smart Supply Enable/Disable
+    if (company.unlockUpgrades[1]) {
+        if (this.smartSupplyEnabled == null) {this.smartSupplyEnabled = false;}
+        var smartSupplyCheckboxId = "cmpy-mgmt-smart-supply-checkbox";
+        industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("label", {
+            for:smartSupplyCheckboxId, innerText:"Enable Smart Supply",
+            color:"white"
+        }));
+        industrySmartSupplyCheckbox = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+            type:"checkbox", id:smartSupplyCheckboxId, margin:"3px",
+            changeListener:()=>{
+                this.smartSupplyEnabled = industrySmartSupplyCheckbox.checked;
+            }
+        });
+        industrySmartSupplyCheckbox.checked = this.smartSupplyEnabled;
+        industryWarehousePanel.appendChild(industrySmartSupplyCheckbox);
+    }
+
+    //Materials
+    industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        innerHTML: "<br>Materials:<br>",
+    }));
+    industryWarehouseMaterials = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("ul");
+    industryWarehousePanel.appendChild(industryWarehouseMaterials);
+
+    //Products
+    if (industry.makesProducts && Object.keys(industry.products).length > 0) {
+        industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+            innerHTML: "<br>Products:<br>",
+        }));
+        industryWarehouseProducts = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("ul");
+        industryWarehousePanel.appendChild(industryWarehouseProducts);
+    }
+
+    this.updateUI(parentRefs);
+}
+
+Warehouse.prototype.updateUI = function(parentRefs) {
+    if (parentRefs.company == null || parentRefs.industry == null) {
+        console.log("ERROR: Warehouse.updateUI called without parentRefs.company or parentRefs.industry");
+        return;
+    }
+    var company = parentRefs.company, industry = parentRefs.industry;
+
+    //Storage text
+    var storageText = "Storage: " +
+                      (this.sizedUsed >= this.size ? Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.sizeUsed, 3) : Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.sizeUsed, 3)) +
+                      "/" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.size, 3);
+    if (this.breakdown != null && this.breakdown != "") {
+        storageText += ("<span class='tooltiptext'>" +
+                        this.breakdown + "</span>");
+    }
+    industryWarehouseStorageText.innerHTML = storageText;
+
+    //Upgrade warehouse size button
+    var upgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, this.level+1);
+    if (company.funds.lt(upgradeCost)) {
+        industryWarehouseUpgradeSizeButton.className = "a-link-button-inactive";
+    } else {
+        industryWarehouseUpgradeSizeButton.className = "a-link-button";
+    }
+
+    //Current state
+    var stateText = "Current state: ";
+    switch(industry.state) {
+        case "START":
+            stateText += "Preparing...";
+            break;
+        case "PURCHASE":
+            stateText += "Purchasing materials...";
+            break;
+        case "PRODUCTION":
+            stateText += "Producing materials and/or products...";
+            break;
+        case "SALE":
+            stateText += "Selling materials and/or products...";
+            break;
+        case "EXPORT":
+            stateText += "Exporting materials and/or products...";
+            break;
+        default:
+            console.log("ERROR: Invalid state: " + industry.state);
+            break;
+    }
+    industryWarehouseStateText.innerText = stateText;
+
+    //Materials
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryWarehouseMaterials);
+    for (var matName in this.materials) {
+        if (this.materials.hasOwnProperty(matName) && this.materials[matName] instanceof Material) {
+            if (Object.keys(industry.reqMats).includes(matName) || industry.prodMats.includes(matName) ||
+                matName === "Hardware" || matName === "Robots" || matName === "AICores" ||
+                matName === "RealEstate") {
+                industryWarehouseMaterials.appendChild(this.createMaterialUI(this.materials[matName], matName, parentRefs));
+            }
+        }
+    }
+
+    //Products
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryWarehouseProducts);
+    if (industry.makesProducts && Object.keys(industry.products).length > 0) {
+        for (var productName in industry.products) {
+            if (industry.products.hasOwnProperty(productName) && industry.products[productName] instanceof Product) {
+                industryWarehouseProducts.appendChild(this.createProductUI(industry.products[productName], parentRefs));
+            }
+        }
+    }
+}
+
+Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
+    if (parentRefs.company == null || parentRefs.industry == null) {
+        console.log("ERROR: Warehouse.createMaterialUI called without industry or company parent refs");
+        return;
+    }
+    var company = parentRefs.company, industry = parentRefs.industry;
+    var purchasePopupId = "cmpy-mgmt-material-purchase-popup",
+        sellPopupid = "cmpy-mgmt-material-sell-popup";
+    var div = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        class:"cmpy-mgmt-warehouse-material-div",
+    });
+
+    var totalGain = mat.buy + mat.prd + mat.imp - mat.sll - mat.totalExp;
+
+    //If Market Research upgrades are unlocked, add competition and demand info
+    var cmpAndDmdText = "";
+    if (company.unlockUpgrades[2] === 1) {
+        cmpAndDmdText += "<br>Competition: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.cmp, 3);
+    }
+    if (company.unlockUpgrades[3] === 1) {
+        cmpAndDmdText += "<br>Demand: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.dmd, 3);
+    }
+    var innerTxt = "<p class='tooltip'>" + mat.name + ": " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.qty, 3) +
+                   "(" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(totalGain, 3) +  "/s)" +
+                   "<span class='tooltiptext'>Buy: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.buy, 3) +
+                   "/s<br>Prod: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.prd, 3) + "/s<br>Sell: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sll, 3) +
+                   "/s<br>Export: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.totalExp, 3) + "/s<br>Import: " +
+                   Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.imp, 3) + "/s" + cmpAndDmdText + "</span></p><br>" +
+                   "<p class='tooltip'>MP: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.bCost, 2) +
+                   "<span class='tooltiptext'>Market Price: The price you would pay if " +
+                   "you were to buy this material on the market</span></p><br>" +
+                   "<p class='tooltip'>Quality: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.qlt, 2) +
+                   "<span class='tooltiptext'>The quality of your material. Higher quality " +
+                   "will lead to more sales</span></p>";
+
+    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        innerHTML: innerTxt,
+        id: "cmpy-mgmt-warehouse-" + matName + "-text", display:"inline-block",
+    }));
+
+    var buttonPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        display:"inline-block",
+    });
+    div.appendChild(buttonPanel);
+
+    //Button to set purchase amount
+    var tutorial = industry.newInd && Object.keys(industry.reqMats).includes(mat.name) &&
+                   mat.buy === 0 && mat.imp === 0;
+    var buyButtonParams = {
+        innerText: "Buy (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.buy, 3) + ")", display:"inline-block",
+        class: tutorial ? "a-link-button flashing-button" : "a-link-button",
+        clickListener:()=>{
+            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerHTML: "Enter the amount of " + mat.name + " you would like " +
+                           "to purchase per second. This material's cost changes constantly"
+            });
+            var confirmBtn;
+            var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                type:"number", value:mat.buy ? mat.buy : null, placeholder: "Purchase amount",
+                onkeyup:(e)=>{
+                    e.preventDefault();
+                    if (e.keyCode === 13) {confirmBtn.click();}
+                }
+            });
+            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                innerText:"Confirm", class:"a-link-button",
+                clickListener:()=>{
+                    if (isNaN(input.value)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid amount");
+                    } else {
+                        mat.buy = parseFloat(input.value);
+                        if (isNaN(mat.buy)) {mat.buy = 0;}
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(purchasePopupId);
+                        this.createUI(parentRefs);
+                        return false;
+                    }
+                }
+            });
+            var clearButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                innerText:"Clear Purchase", class:"a-link-button",
+                clickListener:()=>{
+                    mat.buy = 0;
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(purchasePopupId);
+                    this.createUI(parentRefs);
+                    return false;
+                }
+            });
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                innerText:"Cancel", class:"a-link-button",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(purchasePopupId);
+                }
+            });
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(purchasePopupId, [txt, input, confirmBtn, clearButton, cancelBtn]);
+            input.focus();
+        }
+    };
+    if (tutorial) {
+        buyButtonParams.tooltip = "Purchase your required materials to get production started!";
+    }
+    buttonPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", buyButtonParams));
+
+    //Button to manage exports
+    if (company.unlockUpgrades[0] === 1) { //Export unlock upgrade
+        function createExportPopup() {
+            var popupId = "cmpy-mgmt-export-popup";
+            var exportTxt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerText:"Select the industry and city to export this material to, as well as " +
+                          "how much of this material to export per second. You can set the export " +
+                          "amount to 'MAX' to export all of the materials in this warehouse."
+            });
+
+            //Select industry and city to export to
+            var citySelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select");
+            var industrySelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {
+                changeListener:()=>{
+                    var industryName = industrySelector.options[industrySelector.selectedIndex].value;
+                    for (var foo = 0; foo < company.divisions.length; ++foo) {
+                        if (company.divisions[foo].name == industryName) {
+                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["clearSelector"])(citySelector);
+                            var selectedIndustry = company.divisions[foo];
+                            for (var cityName in company.divisions[foo].warehouses) {
+                                if (company.divisions[foo].warehouses[cityName] instanceof Warehouse) {
+                                    citySelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                                        value:cityName, text:cityName,
+                                    }));
+                                }
+                            }
+                            return;
+                        }
+                    }
+                }
+            });
+
+            for (var i = 0; i < company.divisions.length; ++i) {
+                industrySelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                    text:company.divisions[i].name, value:company.divisions[i].name,
+                })); //End create element option
+            } //End for
+
+            var currIndustry = industrySelector.options[industrySelector.selectedIndex].value;
+            for (var i = 0; i < company.divisions.length; ++i) {
+                if (company.divisions[i].name == currIndustry) {
+                    for (var cityName in company.divisions[i].warehouses) {
+                        if (company.divisions[i].warehouses.hasOwnProperty(cityName) &&
+                            company.divisions[i].warehouses[cityName] instanceof Warehouse) {
+                            citySelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                                value:cityName, text:cityName,
+                            }));
+                        }
+                    }
+                    break;
+                }
+            }
+
+            //Select amount to export
+            var exportAmount = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                placeholder:"Export amount / s"
+            });
+
+            var exportBtn  = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button", display:"inline-block", innerText:"Export",
+                clickListener:()=>{
+                    var industryName = industrySelector.options[industrySelector.selectedIndex].text,
+                        cityName = citySelector.options[citySelector.selectedIndex].text,
+                        amt = exportAmount.value;
+                    //Sanitize amt
+                    var sanitizedAmt = amt.replace(/\s+/g, '');
+                    sanitizedAmt = sanitizedAmt.replace(/[^-()\d/*+.MAX]/g, '');
+                    var temp = sanitizedAmt.replace(/MAX/g, 1);
+                    try {
+                        temp = eval(temp);
+                    } catch(e) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid expression entered for export amount: " + e);
+                        return false;
+                    }
+
+                    if (temp == null || isNaN(temp)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid amount entered for export");
+                        return;
+                    }
+                    var exportObj = {ind:industryName, city:cityName, amt:sanitizedAmt};
+                    mat.exp.push(exportObj);
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button", display:"inline-block", innerText:"Cancel",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+
+            var currExportsText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerText:"Below is a list of all current exports of this material from this warehouse. " +
+                          "Clicking on one of the exports below will REMOVE that export."
+            });
+            var currExports = [];
+            for (var i = 0; i < mat.exp.length; ++i) {
+                (function(i, mat, currExports){
+                currExports.push(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+                    class:"cmpy-mgmt-existing-export",
+                    innerHTML: "Industry: " + mat.exp[i].ind + "<br>" +
+                               "City: " + mat.exp[i].city + "<br>" +
+                               "Amount/s: " + mat.exp[i].amt,
+                    clickListener:()=>{
+                        mat.exp.splice(i, 1); //Remove export object
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        createExportPopup();
+                    }
+                }));
+                })(i, mat, currExports);
+            }
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [exportTxt, industrySelector, citySelector, exportAmount,
+                                  exportBtn, cancelBtn, currExportsText].concat(currExports));
+        }
+        buttonPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            innerText:"Export", display:"inline-block", class:"a-link-button",
+            clickListener:()=>{createExportPopup();}
+        }));
+    }
+
+    buttonPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {})); // Force line break
+
+    //Button to set sell amount
+    var innerTextString;
+    if (mat.sllman[0]) {
+        innerTextString = (mat.sllman[1] === -1 ? "Sell (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sll, 3) + "/MAX)" :
+                          "Sell (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sll, 3) + "/" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sllman[1], 3) + ")");
+        if (mat.sCost) {
+            if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(mat.sCost)) {
+                var sCost = mat.sCost.replace(/MP/g, mat.bCost);
+                innerTextString += " @ $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(eval(sCost), 2);
+            } else {
+                innerTextString += " @ $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(mat.sCost, 2);
+            }
+        }
+    } else {
+        innerTextString = "Sell (0.000/0.000)";
+    }
+
+    buttonPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        innerText: innerTextString, display:"inline-block", class:"a-link-button",
+        clickListener:()=>{
+            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerHTML: "Enter the maximum amount of " + mat.name + " you would like " +
+                           "to sell per second, as well as the price at which you would " +
+                           "like to sell at.<br><br>" +
+                           "If the sell amount is set to 0, then the material will not be sold. If the sell price " +
+                           "if set to 0, then the material will be discarded<br><br>" +
+                           "Setting the sell amount to 'MAX' will result in you always selling the " +
+                           "maximum possible amount of the material.<br><br>" +
+                           "When setting the sell amount, you can use the 'PROD' variable to designate a dynamically " +
+                           "changing amount that depends on your production. For example, if you set the sell amount " +
+                           "to 'PROD-5' then you will always sell 5 less of the material than you produce.<br><br>" +
+                           "When setting the sell price, you can use the 'MP' variable to designate a dynamically " +
+                           "changing price that depends on the market price. For example, if you set the sell price " +
+                           "to 'MP+10' then it will always be sold at $10 above the market price.",
+            });
+            var br = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {});
+            var confirmBtn;
+            var inputQty = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                type:"text", marginTop:"4px",
+                value: mat.sllman[1] ? mat.sllman[1] : null, placeholder: "Sell amount",
+                onkeyup:(e)=>{
+                    e.preventDefault();
+                    if (e.keyCode === 13) {confirmBtn.click();}
+                }
+            });
+            var inputPx = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                type:"text", marginTop:"4px",
+                value: mat.sCost ? mat.sCost : null, placeholder: "Sell price",
+                onkeyup:(e)=>{
+                    e.preventDefault();
+                    if (e.keyCode === 13) {confirmBtn.click();}
+                }
+            });
+            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                innerText:"Confirm", class:"a-link-button", margin:"6px",
+                clickListener:()=>{
+                    //Parse price
+                    var cost = inputPx.value.replace(/\s+/g, '');
+                    cost = cost.replace(/[^-()\d/*+.MP]/g, ''); //Sanitize cost
+                    var temp = cost.replace(/MP/g, mat.bCost);
+                    try {
+                        temp = eval(temp);
+                    } catch(e) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field: " + e);
+                        return false;
+                    }
+
+                    if (temp == null || isNaN(temp)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field");
+                        return false;
+                    }
+
+                    if (cost.includes("MP")) {
+                        mat.sCost = cost; //Dynamically evaluated
+                    } else {
+                        mat.sCost = temp;
+                    }
+
+                    //Parse quantity
+                    if (inputQty.value.includes("MAX") || inputQty.value.includes("PROD")) {
+                        var qty = inputQty.value.replace(/\s+/g, '');
+                        qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
+                        var temp = qty.replace(/MAX/g, 1);
+                        temp = temp.replace(/PROD/g, 1);
+                        try {
+                            temp = eval(temp);
+                        } catch(e) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field: " + e);
+                            return false;
+                        }
+
+                        if (temp == null || isNaN(temp)) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field");
+                            return false;
+                        }
+
+                        mat.sllman[0] = true;
+                        mat.sllman[1] = qty; //Use sanitized input
+                    } else if (isNaN(inputQty.value)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for sell quantity field! Must be numeric or 'MAX'");
+                        return false;
+                    } else {
+                        var qty = parseFloat(inputQty.value);
+                        if (isNaN(qty)) {qty = 0;}
+                        if (qty === 0) {
+                            mat.sllman[0] = false;
+                            mat.sllman[1] = 0;
+                        } else {
+                            mat.sllman[0] = true;
+                            mat.sllman[1] = qty;
+                        }
+                    }
+
+                    this.createUI(parentRefs);
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(sellPopupid);
+                    return false;
+                }
+            });
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                innerText:"Cancel", class:"a-link-button", margin: "6px",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(sellPopupid);
+                }
+            });
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(sellPopupid, [txt, br, inputQty, inputPx, confirmBtn, cancelBtn]);
+            inputQty.focus();
+        }
+    }));
+
+    return div;
+}
+
+Warehouse.prototype.createProductUI = function(product, parentRefs) {
+    var company = parentRefs.company, industry = parentRefs.industry,
+        city = currentCityUi;
+    var div = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        class:"cmpy-mgmt-warehouse-product-div"
+    });
+
+    //Products being designed TODO
+    if (!product.fin) {
+        div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+            innerHTML: "Designing " + product.name + "...<br>" +
+                        Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.prog, 2) + "% complete",
+        }));
+        return div;
+    }
+
+    //Completed products
+    var cmpAndDmdText = "";
+    if (company.unlockUpgrades[2] === 1) {
+        cmpAndDmdText += "<br>Competition: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.cmp, 3);
+    }
+    if (company.unlockUpgrades[3] === 1) {
+        cmpAndDmdText += "<br>Demand: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.dmd, 3);
+    }
+    var totalGain = product.data[city][1] - product.data[city][2]; //Production - sale
+    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        innerHTML: "<p class='tooltip'>" + product.name + ": " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][0], 3) + //Quantity
+                   "(" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(totalGain, 3) + "/s)" +
+                   "<span class='tooltiptext'>Prod: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][1], 3) + "/s<br>" +
+                   "Sell: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][2], 3) + "/s</span></p><br>" +
+                   "<p class='tooltip'>Rating: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.rat, 3) +
+                   "<span class='tooltiptext'>Quality: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.qlt, 3) + "<br>" +
+                   "Performance: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.per, 3) + "<br>" +
+                   "Durability: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.dur, 3) + "<br>" +
+                   "Reliability: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.rel, 3) + "<br>" +
+                   "Aesthetics: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.aes, 3) + "<br>" +
+                   "Features: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.fea, 3) +
+                   cmpAndDmdText + "</span></p><br>" +
+                   "<p class='tooltip'>Est. Production Cost: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(product.pCost / ProductProductionCostRatio).format("$0.000a") +
+                   "<span class='tooltiptext'>An estimate of the material cost it takes to create this Product.</span></p><br>" +
+                   "<p class='tooltip'>Est. Market Price: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(product.pCost + product.rat / product.mku).format("$0.000a") +
+                   "<span class='tooltiptext'>An estimate of how much consumers are willing to pay for this product. " +
+                   "Setting the sale price above this may result in less sales. Setting the sale price below this may result " +
+                   "in more sales.</span></p>"
+    }));
+    var buttonPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        display:"inline-block",
+    });
+    div.appendChild(buttonPanel);
+
+    //Sell button
+    var sellInnerTextString = (product.sllman[city][1] === -1 ? "Sell (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][2], 3) + "/MAX)" :
+                              "Sell (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.data[city][2], 3) + "/" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.sllman[city][1], 3) + ")");
+    if (product.sCost) {
+        if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(product.sCost)) {
+            sellInnerTextString += (" @ " + product.sCost);
+        } else {
+            sellInnerTextString += (" @ " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(product.sCost).format("$0.000a"));
+        }
+    }
+    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        innerText:sellInnerTextString, class:"a-link-button", display:"inline-block",margin:"6px",
+        clickListener:()=>{
+            var popupId = "cmpy-mgmt-sell-product-popup";
+            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerHTML:"Enter the maximum amount of " + product.name + " you would like " +
+                          "to sell per second, as well as the price at which you would like to " +
+                          "sell it at.<br><br>" +
+                          "If the sell amount is set to 0, then the product will not be sold. If the " +
+                          "sell price is set to 0, then the product will be discarded.<br><br>" +
+                          "Setting the sell amount to 'MAX' will result in you always selling the " +
+                          "maximum possible amount of the material.<br><br>" +
+                          "When setting the sell amount, you can use the 'PROD' variable to designate a " +
+                          "dynamically changing amount that depends on your production. For example, " +
+                          "if you set the sell amount to 'PROD-1' then you will always sell 1 less of  " +
+                          "the material than you produce.<br><br>" +
+                          "When setting the sell price, you can use the 'MP' variable to set a " +
+                          "dynamically changing price that depends on the Product's estimated " +
+                          "market price. For example, if you set it to 'MP*5' then it " +
+                          "will always be sold at five times the estimated market price.",
+            });
+            var confirmBtn;
+            var inputQty = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                type:"text", value:product.sllman[city][1] ? product.sllman[city][1] : null, placeholder: "Sell amount",
+                onkeyup:(e)=>{
+                    e.preventDefault();
+                    if (e.keyCode === 13) {confirmBtn.click();}
+                }
+            });
+            var inputPx = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                type:"text", value: product.sCost ? product.sCost : null, placeholder: "Sell price",
+                onkeyup:(e)=>{
+                    e.preventDefault();
+                    if (e.keyCode === 13) {confirmBtn.click();}
+                }
+            });
+            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button", innerText:"Confirm",
+                clickListener:()=>{
+                    //Parse price
+                    if (inputPx.value.includes("MP")) {
+                        //Dynamically evaluated quantity. First test to make sure its valid
+                        //Sanitize input, then replace dynamic variables with arbitrary numbers
+                        var price = inputPx.value.replace(/\s+/g, '');
+                        price = price.replace(/[^-()\d/*+.MP]/g, '');
+                        var temp = price.replace(/MP/g, 1);
+                        try {
+                            temp = eval(temp);
+                        } catch(e) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell quantity field: " + e);
+                            return false;
+                        }
+                        if (temp == null || isNaN(temp)) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell quantity field.");
+                            return false;
+                        }
+                        product.sCost = price; //Use sanitized price
+                    } else {
+                        var cost = parseFloat(inputPx.value);
+                        if (isNaN(cost)) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for sell price field");
+                            return false;
+                        }
+                        product.sCost = cost;
+                    }
+
+                    //Parse quantity
+                    if (inputQty.value.includes("MAX") || inputQty.value.includes("PROD")) {
+                        //Dynamically evaluated quantity. First test to make sure its valid
+                        var qty = inputQty.value.replace(/\s+/g, '');
+                        qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
+                        var temp = qty.replace(/MAX/g, 1);
+                        temp = temp.replace(/PROD/g, 1);
+                        try {
+                            temp = eval(temp);
+                        } catch(e) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field: " + e);
+                            return false;
+                        }
+
+                        if (temp == null || isNaN(temp)) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value or expression for sell price field");
+                            return false;
+                        }
+                        product.sllman[city][0] = true;
+                        product.sllman[city][1] = qty; //Use sanitized input
+                    } else if (isNaN(inputQty.value)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for sell quantity field! Must be numeric");
+                        return false;
+                    } else {
+                        var qty = parseFloat(inputQty.value);
+                        if (isNaN(qty)) {qty = 0;}
+                        if (qty === 0) {
+                            product.sllman[city][0] = false;
+                        } else {
+                            product.sllman[city][0] = true;
+                            product.sllman[city][1] = qty;
+                        }
+                    }
+                    this.createUI(parentRefs);
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button", innerText:"Cancel",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, inputQty, inputPx, confirmBtn, cancelBtn]);
+            inputQty.focus();
+        }
+    }));
+    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br",{})); //force line break
+
+    //Limit production button
+    var limitProductionInnerText = "Limit Production";
+    if (product.prdman[city][0]) {
+        limitProductionInnerText += " (" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(product.prdman[city][1], 3) + ")";
+    }
+    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:"a-link-button", innerText:limitProductionInnerText,display:"inline-block",
+        clickListener:()=>{
+            var popupId = "cmpy-mgmt-limit-product-production-popup";
+            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerText:"Enter a limit to the amount of this product you would " +
+                          "like to product per second. Leave the box empty to set no limit."
+            });
+            var confirmBtn;
+            var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                type:"number", placeholder:"Limit",
+                onkeyup:(e)=>{
+                    e.preventDefault();
+                    if (e.keyCode === 13) {confirmBtn.click();}
+                }
+            });
+            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button", display:"inline-block", innerText:"Limit production", margin:'6px',
+                clickListener:()=>{
+                    if (input.value === "") {
+                        product.prdman[city][0] = false;
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        return false;
+                    }
+                    var qty = parseFloat(input.value);
+                    if (isNaN(qty)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value entered");
+                        return false;
+                    }
+                    if (qty < 0) {
+                        product.prdman[city][0] = false;
+                    } else {
+                        product.prdman[city][0] = true;
+                        product.prdman[city][1] = qty;
+                    }
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button", display:"inline-block", innerText:"Cancel", margin:"6px",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, input, confirmBtn, cancelBtn]);
+        }
+    }));
+
+    //Discontinue button
+    div.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:'a-link-button', display:"inline-block",innerText:"Discontinue",
+        clickListener:()=>{
+            var popupId = "cmpy-mgmt-discontinue-product-popup";
+            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerText:"Are you sure you want to do this? Discontinuing a product " +
+                          "removes it completely and permanently. You will no longer " +
+                          "produce this product and all of its existing stock will be " +
+                          "removed and left unsold",
+            });
+            var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button",innerText:"Discontinue",
+                clickListener:()=>{
+                    industry.discontinueProduct(product, parentRefs);
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button", innerText:"Cancel",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, confirmBtn, cancelBtn]);
+        }
+    }));
+    return div;
+}
+
+Warehouse.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Warehouse", this);
+}
+
+Warehouse.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Warehouse, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Warehouse = Warehouse;
+
+//Corporation Unlock Upgrades
+//Upgrades for entire corporation, unlocks features, either you have it or you dont
+//The structure is [index in Corporation feature upgrades array, price ]
+var CorporationUnlockUpgrades = {
+    //Lets you export goods
+    "0":  [0, 20e9, "Export",
+                    "Develop infrastructure to export your materials to your other facilities. " +
+                    "This allows you to move materials around between different divisions and cities."],
+
+    //Lets you buy exactly however many required materials you need for production
+    "1":  [1, 50e9, "Smart Supply", "Use advanced AI to anticipate your supply needs. " +
+                     "This allows you to purchase exactly however many materials you need for production."],
+
+    //Displays each material/product's demand
+    "2":  [2, 5e9, "Market Research - Demand",
+                    "Mine and analyze market data to determine the demand of all resources. " +
+                    "The demand attribute, which affects sales, will be displayed for every material and product."],
+
+    //Display's each material/product's competition
+    "3":  [3, 5e9, "Market Data - Competition",
+                    "Mine and analyze market data to determine how much competition there is on the market " +
+                    "for all resources. The competition attribute, which affects sales, will be displayed for " +
+                    "for every material and product."],
+    "4":  [4, 10e9, "VeChain",
+                    "Use AI and blockchain technology to identify where you can improve your supply chain systems. " +
+                    "This upgrade will allow you to view a wide array of useful statistics about your " +
+                    "Corporation."]
+}
+
+//Corporation Upgrades
+//Upgrades for entire corporation, levelable upgrades
+//The structure is [index in Corporation upgrades array, base price, price mult, benefit mult (additive),
+//                  name, desc]
+var CorporationUpgrades = {
+    //Smart factories, increases production
+    "0":    [0, 2e9, 1.07, 0.03,
+            "Smart Factories", "Advanced AI automatically optimizes the operation and productivity " +
+            "of factories. Each level of this upgrade increases your global production by 3% (additive)."],
+
+    //Smart warehouses, increases storage size
+    "1":    [1, 2e9, 1.07, .1,
+             "Smart Storage", "Advanced AI automatically optimizes your warehouse storage methods. " +
+             "Each level of this upgrade increases your global warehouse storage size by 10% (additive)."],
+
+    //Advertise through dreams, passive popularity/ awareness gain
+    "2":    [2, 8e9, 1.09, .001,
+            "DreamSense", "Use DreamSense LCC Technologies to advertise your corporation " +
+            "to consumers through their dreams. Each level of this upgrade provides a passive " +
+            "increase in awareness of all of your companies (divisions) by 0.004 / market cycle," +
+            "and in popularity by 0.001 / market cycle. A market cycle is approximately " +
+            "20 seconds."],
+
+    //Makes advertising more effective
+    "3":    [3, 4e9, 1.12, 0.005,
+            "Wilson Analytics", "Purchase data and analysis from Wilson, a marketing research " +
+            "firm. Each level of this upgrades increases the effectiveness of your " +
+            "advertising by 0.5% (additive)."],
+
+    //Augmentation for employees, increases cre
+    "4":    [4, 1e9, 1.06, 0.1,
+            "Nuoptimal Nootropic Injector Implants", "Purchase the Nuoptimal Nootropic " +
+            "Injector augmentation for your employees. Each level of this upgrade " +
+            "globally increases the creativity of your employees by 10% (additive)."],
+
+    //Augmentation for employees, increases cha
+    "5":    [5, 1e9, 1.06, 0.1,
+            "Speech Processor Implants", "Purchase the Speech Processor augmentation for your employees. " +
+            "Each level of this upgrade globally increases the charisma of your employees by 10% (additive)."],
+
+    //Augmentation for employees, increases int
+    "6":    [6, 1e9, 1.06, 0.1,
+            "Neural Accelerators", "Purchase the Neural Accelerator augmentation for your employees. " +
+            "Each level of this upgrade globally increases the intelligence of your employees " +
+            "by 10% (additive)."],
+
+    //Augmentation for employees, increases eff
+    "7":    [7, 1e9, 1.06, 0.1,
+            "FocusWires", "Purchase the FocusWire augmentation for your employees. Each level " +
+            "of this upgrade globally increases the efficiency of your employees by 10% (additive)."],
+
+    //Improves sales of materials/products
+    "8":    [8, 1e9, 1.08, 0.01,
+            "ABC SalesBots", "Always Be Closing. Purchase these robotic salesmen to increase the amount of " +
+            "materials and products you sell. Each level of this upgrade globally increases your sales " +
+            "by 1% (additive)."],
+
+    //Improves scientific research rate
+    "9":    [9, 5e9, 1.07, 0.05,
+            "Project Insight", "Purchase 'Project Insight', a R&D service provided by the secretive " +
+            "Fulcrum Technologies. Each level of this upgrade globally increases the amount of " +
+            "Scientific Research you produce by 5% (additive)."],
+}
+
+function Corporation(params={}) {
+    this.name = params.name ? params.name : "The Corporation";
+
+    //A division/business sector is represented  by the object:
+    this.divisions = [];
+
+    //Financial stats
+    this.funds      = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(150e9);
+    this.revenue    = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+    this.expenses   = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+    this.fundingRound = 0;
+    this.public     = false; //Publicly traded
+    this.numShares  = TOTALSHARES;
+    this.issuedShares = 0;
+    this.sharePrice = 0;
+    this.storedCycles = 0;
+
+    var numUnlockUpgrades = Object.keys(CorporationUnlockUpgrades).length,
+        numUpgrades = Object.keys(CorporationUpgrades).length;
+
+    this.unlockUpgrades = Array(numUnlockUpgrades).fill(0);
+    this.upgrades = Array(numUpgrades).fill(0);
+    this.upgradeMultipliers = Array(numUpgrades).fill(1);
+
+    this.state = new CorporationState();
+}
+
+Corporation.prototype.getState = function() {
+    return this.state.getState();
+}
+
+Corporation.prototype.storeCycles = function(numCycles=1) {
+    this.storedCycles += numCycles;
+}
+
+Corporation.prototype.process = function() {
+    var corp = this;
+    if (this.storedCycles >= CyclesPerIndustryStateCycle) {
+        var state = this.getState(), marketCycles=1;
+        this.storedCycles -= (marketCycles * CyclesPerIndustryStateCycle);
+
+        //At the start of a new cycle, calculate profits from previous cycle
+        if (state === "START") {
+            this.revenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+            this.expenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+            this.divisions.forEach((ind)=>{
+                this.revenue = this.revenue.plus(ind.lastCycleRevenue);
+                this.expenses = this.expenses.plus(ind.lastCycleExpenses);
+            });
+            var profit = this.revenue.minus(this.expenses);
+            var cycleProfit = profit.times(marketCycles * SecsPerMarketCycle);
+            if (isNaN(this.funds)) {
+                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("There was an error calculating your Corporations funds and they got reset to 0. " +
+                                "This is a bug. Please report to game developer.<br><br>" +
+                                "(Your funds have been set to $150b for the inconvenience)");
+                this.funds = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(150e9);
+            }
+            this.funds = this.funds.plus(cycleProfit);
+            this.updateSharePrice();
+        }
+
+        this.divisions.forEach(function(ind) {
+            ind.process(marketCycles, state, corp);
+        });
+
+
+        this.state.nextState();
+
+        if (_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage === _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.Corporation) {this.updateUIContent();}
+    }
+}
+
+Corporation.prototype.determineValuation = function() {
+    var val, profit = (this.revenue.minus(this.expenses)).toNumber();
+    if (this.public) {
+        val = this.funds.toNumber() + (profit * 85e3);
+        val *= (Math.pow(1.1, this.divisions.length));
+        val = Math.max(val, 0);
+    } else {
+        val = 10e9 + Math.max(this.funds.toNumber(), 0) / 3; //Base valuation
+        if (profit > 0) {
+            val += (profit * 320e3);
+            val *= (Math.pow(1.1, this.divisions.length));
+        } else {
+            val = 10e9 * Math.pow(1.1, this.divisions.length);
+        }
+        val -= (val % 1e6); //Round down to nearest millionth
+    }
+    return val * _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodeMultipliers"].CorporationValuation;
+}
+
+Corporation.prototype.getInvestment = function() {
+    var val = this.determineValuation(), percShares;
+    switch (this.fundingRound) {
+        case 0: //Seed
+            percShares = 0.10;
+            break;
+        case 1: //Series A
+            percShares = 0.35;
+            break;
+        case 2: //Series B
+            percShares = 0.25;
+            break;
+        case 3: //Series C
+            percShares = 0.20;
+            break;
+        case 4:
+            return;
+    }
+    var funding = val * percShares * 4,
+        investShares = Math.floor(TOTALSHARES * percShares),
+        yesBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxGetYesButton"])(),
+        noBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxGetNoButton"])();
+    yesBtn.innerHTML = "Accept";
+    noBtn.innerHML = "Reject";
+    yesBtn.addEventListener("click", ()=>{
+        ++this.fundingRound;
+        this.funds = this.funds.plus(funding);
+        this.numShares -= investShares;
+        this.displayCorporationOverviewContent();
+        return Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxClose"])();
+    });
+    noBtn.addEventListener("click", ()=>{
+        return Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxClose"])();
+    });
+    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_12__["yesNoBoxCreate"])("An investment firm has offered you " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(funding).format('$0.000a') +
+                   " in funding in exchange for a " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(percShares*100).format("0.000a") +
+                   "% stake in the company (" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(investShares).format('0.000a') + " shares).<br><br>" +
+                   "Do you accept or reject this offer?");
+}
+
+Corporation.prototype.goPublic = function() {
+    var goPublicPopupId = "cmpy-mgmt-go-public-popup";
+    var initialSharePrice = this.determineValuation() / (TOTALSHARES);
+    var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        innerHTML: "Enter the number of shares you would like to issue " +
+                   "for your IPO. These shares will be publicly sold " +
+                   "and you will no longer own them. Your Corporation will receive " +
+                   _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(initialSharePrice).format('$0.000a') + " per share " +
+                   "(the IPO money will be deposited directly into your Corporation's funds).<br><br>" +
+                   "Furthermore, issuing more shares now will help drive up " +
+                   "your company's stock price in the future.<br><br>" +
+                   "You have a total of " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.numShares).format("0.000a") + " of shares that you can issue.",
+    });
+    var yesBtn;
+    var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+        type:"number",
+        placeholder: "Shares to issue",
+        onkeyup:(e)=>{
+            e.preventDefault();
+            if (e.keyCode === 13) {yesBtn.click();}
+        }
+    });
+    var br = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {});
+    yesBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:"a-link-button",
+        innerText:"Go Public",
+        clickListener:()=>{
+            var numShares = Math.round(input.value);
+            var initialSharePrice = this.determineValuation() / (TOTALSHARES);
+            if (isNaN(numShares)) {
+                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for number of issued shares");
+                return false;
+            }
+            if (numShares > this.numShares) {
+                Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Error: You don't have that many shares to issue!");
+                return false;
+            }
+            this.public = true;
+            this.sharePrice = initialSharePrice;
+            this.issuedShares = numShares;
+            this.numShares -= numShares;
+            this.funds = this.funds.plus(numShares * initialSharePrice);
+            this.displayCorporationOverviewContent();
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(goPublicPopupId);
+            return false;
+        }
+    });
+    var noBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:"a-link-button",
+        innerText:"Cancel",
+        clickListener:()=>{
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(goPublicPopupId);
+            return false;
+        }
+    });
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(goPublicPopupId, [txt, br, input, yesBtn, noBtn]);
+}
+
+Corporation.prototype.updateSharePrice = function() {
+    var targetPrice = this.determineValuation() / (TOTALSHARES - this.issuedShares);
+    if (this.sharePrice <= targetPrice) {
+        this.sharePrice *= (1 + (Math.random() * 0.01));
+    } else {
+        this.sharePrice *= (1 - (Math.random() * 0.01));
+    }
+    if (this.sharePrice <= 0.01) {this.sharePrice = 0.01;}
+}
+
+//One time upgrades that unlock new features
+Corporation.prototype.unlock = function(upgrade) {
+    var upgN = upgrade[0], price = upgrade[1];
+    while (this.unlockUpgrades.length <= upgN) {
+        this.unlockUpgrades.push(0);
+    }
+    if (this.funds.lt(price)) {
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough funds to unlock this!");
+        return;
+    }
+    this.unlockUpgrades[upgN] = 1;
+    this.funds = this.funds.minus(price);
+}
+
+//Levelable upgrades
+Corporation.prototype.upgrade = function(upgrade) {
+    var upgN = upgrade[0], basePrice = upgrade[1], priceMult = upgrade[2],
+        upgradeAmt = upgrade[3]; //Amount by which the upgrade multiplier gets increased (additive)
+    while (this.upgrades.length <= upgN) {this.upgrades.push(0);}
+    while (this.upgradeMultipliers.length <= upgN) {this.upgradeMultipliers.push(1);}
+    var totalCost = basePrice * Math.pow(priceMult, this.upgrades[upgN]);
+    if (this.funds.lt(totalCost)) {
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough funds to purchase this!");
+        return;
+    }
+    ++this.upgrades[upgN];
+    this.funds = this.funds.minus(totalCost);
+
+    //Increase upgrade multiplier
+    this.upgradeMultipliers[upgN] = 1 + (this.upgrades[upgN] * upgradeAmt);
+
+    //If storage size is being updated, update values in Warehouse objects
+    if (upgN === 1) {
+        for (var i = 0; i < this.divisions.length; ++i) {
+            var industry = this.divisions[i];
+            for (var city in industry.warehouses) {
+                if (industry.warehouses.hasOwnProperty(city) && industry.warehouses[city] instanceof Warehouse) {
+                    industry.warehouses[city].updateSize(this);
+                }
+            }
+        }
+    }
+
+    this.updateCorporationOverviewContent();
+}
+
+Corporation.prototype.getProductionMultiplier = function() {
+    var mult = this.upgradeMultipliers[0];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+Corporation.prototype.getStorageMultiplier = function() {
+    var mult = this.upgradeMultipliers[1];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+Corporation.prototype.getDreamSenseGain = function() {
+    var gain = this.upgradeMultipliers[2] - 1;
+    return gain <= 0 ? 0 : gain;
+}
+
+Corporation.prototype.getAdvertisingMultiplier = function() {
+    var mult = this.upgradeMultipliers[3];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+Corporation.prototype.getEmployeeCreMultiplier = function() {
+    var mult = this.upgradeMultipliers[4];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+Corporation.prototype.getEmployeeChaMultiplier = function() {
+    var mult = this.upgradeMultipliers[5];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+Corporation.prototype.getEmployeeIntMultiplier = function() {
+    var mult = this.upgradeMultipliers[6];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+Corporation.prototype.getEmployeeEffMultiplier = function() {
+    var mult = this.upgradeMultipliers[7];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+Corporation.prototype.getSalesMultiplier = function() {
+    var mult = this.upgradeMultipliers[8];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+Corporation.prototype.getScientificResearchMultiplier = function() {
+    var mult = this.upgradeMultipliers[9];
+    if (isNaN(mult) || mult < 1) {return 1;} else {return mult;}
+}
+
+//Keep 'global' variables for DOM elements so we don't have to search
+//through the DOM tree repeatedly when updating UI
+var companyManagementDiv, companyManagementHeaderTabs, companyManagementPanel,
+    currentCityUi,
+    corporationUnlockUpgrades, corporationUpgrades,
+
+    //Industry Overview Panel
+    industryOverviewPanel, industryOverviewText,
+
+    //Industry Employee Panel
+    industryEmployeePanel, industryEmployeeText, industryEmployeeHireButton, industryEmployeeAutohireButton,
+        industryEmployeeManagementUI, industryEmployeeInfo, industryIndividualEmployeeInfo,
+    industryOfficeUpgradeSizeButton,
+
+    //Industry Warehouse Panel
+    industryWarehousePanel, industrySmartSupplyCheckbox, industryWarehouseStorageText,
+        industryWarehouseUpgradeSizeButton, industryWarehouseStateText,
+        industryWarehouseMaterials, industryWarehouseProducts,
+    headerTabs, cityTabs;
+Corporation.prototype.createUI = function() {
+    companyManagementDiv = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        id:"cmpy-mgmt-container",
+        position:"fixed",
+        class:"generic-menupage-container"
+    });
+    companyManagementHeaderTabs = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {id:"cmpy-mgmt-header-tabs"});
+    companyManagementDiv.appendChild(companyManagementHeaderTabs);
+
+    //Create division/industry tabs at the top
+    this.updateUIHeaderTabs();
+
+    //Create the 'panel' that will have the actual content in the UI
+    companyManagementPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {id:"cmpy-mgmt-panel"});
+    companyManagementDiv.appendChild(companyManagementPanel);
+    document.getElementById("entire-game-container").appendChild(companyManagementDiv);
+
+    this.displayCorporationOverviewContent();
+}
+
+Corporation.prototype.updateUIHeaderTabs = function() {
+    if (companyManagementHeaderTabs) {
+        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(companyManagementHeaderTabs);
+    } else {
+        console.log("ERROR: Header tabs div has not yet been created when Corporation.updateUIHeaderTabs() is called");
+        return;
+    }
+
+    //Corporation overview tabs
+    var cmpyOverviewHdrTab = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
+        id:"cmpy-mgmt-company-tab",
+        class:"cmpy-mgmt-header-tab",
+        innerText:this.name,
+        checked:true,
+        clickListener:()=>{
+            this.selectHeaderTab(cmpyOverviewHdrTab);
+            this.displayCorporationOverviewContent();
+            return false;
+        }
+    });
+    companyManagementHeaderTabs.appendChild(cmpyOverviewHdrTab);
+
+    //Tabs for each division
+    for (var i = 0; i < this.divisions.length; ++i) {
+        this.createDivisionUIHeaderTab(this.divisions[i]);
+    }
+
+    //Create a tab to expand into a new industry
+    companyManagementHeaderTabs.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
+        id:'cmpy-mgmt-expand-industry-tab',
+        class:"cmpy-mgmt-header-tab",
+        innerText:"Expand into new Industry",
+        clickListener: ()=>{
+            if (document.getElementById("cmpy-mgmt-expand-industry-popup") != null) {return;}
+
+            var container = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+                class:"popup-box-container",
+                id:"cmpy-mgmt-expand-industry-popup",
+            });
+            var content = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {class:"popup-box-content"});
+            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerHTML: "Create a new division to expand into a new industry:",
+            });
+            var selector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {
+                class:"cmpy-mgmt-industry-select"
+            });
+            var industryDescription = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {});
+            var yesBtn;
+            var nameInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                type:"text",
+                id:"cmpy-mgmt-expand-industry-name-input",
+                color:"white",
+                backgroundColor:"black",
+                display:"block",
+                maxLength: 30,
+                pattern:"[a-zA-Z0-9-_]",
+                onkeyup:(e)=>{
+                    e.preventDefault();
+                    if (e.keyCode === 13) {yesBtn.click();}
+                }
+            });
+            var nameLabel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("label", {
+                for:"cmpy-mgmt-expand-industry-name-input",
+                innerText:"Division name: "
+            });
+            yesBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("span", {
+                class:"popup-box-button",
+                innerText:"Create Division",
+                clickListener: ()=>{
+                    var ind = selector.options[selector.selectedIndex].value,
+                        newDivisionName = nameInput.value;
+
+                    for (var i = 0; i < this.divisions.length; ++i) {
+                        if (this.divisions[i].name === newDivisionName) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("This name is already in use!");
+                            return false;
+                        }
+                    }
+                    if (this.funds.lt(IndustryStartingCosts[ind])) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Not enough money to create a new division in this industry");
+                    } else if (newDivisionName === "") {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("New division must have a name!");
+                    } else {
+                        this.funds = this.funds.minus(IndustryStartingCosts[ind]);
+                        var newInd = new Industry({
+                            name:newDivisionName,
+                            type:ind,
+                        });
+                        this.divisions.push(newInd);
+                        this.updateUIHeaderTabs();
+                        this.selectHeaderTab(headerTabs[headerTabs.length-2]);
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])("cmpy-mgmt-expand-industry-popup");
+                        this.displayDivisionContent(newInd, _Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12);
+                    }
+                    return false;
+                }
+            });
+            var noBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("span", {
+                class:"popup-box-button",
+                innerText:"Cancel",
+                clickListener: function() {
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])("cmpy-mgmt-expand-industry-popup");
+                    return false;
+                }
+            });
+
+            //Make an object to keep track of what industries you're already in
+            var ownedIndustries = {}
+            for (var i = 0; i < this.divisions.length; ++i) {
+                ownedIndustries[this.divisions[i].type] = true;
+            }
+
+            //Add industry types to selector
+            //Have Agriculture be first as recommended option
+            if (!ownedIndustries["Agriculture"]) {
+                selector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                    text:Industries["Agriculture"], value:"Agriculture"
+                }));
+            }
+
+            for (var key in Industries) {
+                if (key !== "Agriculture" && Industries.hasOwnProperty(key) && !ownedIndustries[key]) {
+                    var ind = Industries[key];
+                    selector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                        text: ind,value:key,
+                    }));
+                }
+            }
+
+            //Initial Industry Description
+            var ind = selector.options[selector.selectedIndex].value;
+            industryDescription.innerHTML = (IndustryDescriptions[ind] + "<br><br>");
+
+            //Change the industry description text based on selected option
+            selector.addEventListener("change", function() {
+                var ind = selector.options[selector.selectedIndex].value;
+                industryDescription.innerHTML = IndustryDescriptions[ind] + "<br><br>";
+            });
+
+            //Add to DOM
+            content.appendChild(txt);
+            content.appendChild(selector);
+            content.appendChild(industryDescription);
+            content.appendChild(nameLabel);
+            content.appendChild(nameInput);
+            content.appendChild(noBtn);
+            content.appendChild(yesBtn);
+            container.appendChild(content);
+            document.getElementById("entire-game-container").appendChild(container);
+            container.style.display = "block";
+            return false;
+        }
+    }));
+
+    headerTabs = companyManagementDiv.getElementsByClassName("cmpy-mgmt-header-tab");
+}
+
+//Updates UI to display which header tab is selected
+Corporation.prototype.selectHeaderTab = function(currentTab) {
+    if (currentTab == null) {return;}
+    for (var i = 0; i < headerTabs.length; ++i) {
+        headerTabs[i].className = "cmpy-mgmt-header-tab";
+    }
+    currentTab.className = "cmpy-mgmt-header-tab current";
+}
+
+Corporation.prototype.createDivisionUIHeaderTab = function(division) {
+    var tabId = "cmpy-mgmt-" + division.name + "-tab";
+    var tab = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
+        id:tabId,
+        class:"cmpy-mgmt-header-tab",
+        innerText:division.name,
+        clickListener:()=>{
+            this.selectHeaderTab(tab);
+            this.displayDivisionContent(division, _Location_js__WEBPACK_IMPORTED_MODULE_4__["Locations"].Sector12);
+            return false;
+        }
+    });
+    companyManagementHeaderTabs.appendChild(tab);
+}
+
+Corporation.prototype.clearUIPanel = function() {
+    while(companyManagementPanel.firstChild) {
+        companyManagementPanel.removeChild(companyManagementPanel.firstChild);
+    }
+}
+
+Corporation.prototype.updateUIContent = function() {
+    //Check which of the header tab buttons is checked
+    if (headerTabs == null) {
+        console.log("ERROR: headerTabs is null in Corporation.updateUIContent()");
+        return;
+    }
+    for (var i = 0; i < headerTabs.length; ++i) {
+        if (headerTabs[i].classList.contains("current")) {
+            if (i === 0) {
+                //Corporation overview
+                this.updateCorporationOverviewContent();
+            } else {
+                //Division
+                this.updateDivisionContent(this.divisions[i-1]);
+            }
+            return;
+        }
+    }
+}
+
+Corporation.prototype.displayCorporationOverviewContent = function() {
+    this.clearUIPanel();
+    companyManagementPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        id:"cmpy-mgmt-overview-text",
+    }));
+    if (headerTabs && headerTabs.length >= 1) {
+        this.selectHeaderTab(headerTabs[0]);
+    }
+
+    //Check if player has Corporation Handbook
+    var homeComp = _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].getHomeComputer(), hasHandbook = false,
+        handbookFn = "corporation-management-handbook.lit";
+    for (var i = 0; i < homeComp.messages.length; ++i) {
+        if (Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["isString"])(homeComp.messages[i]) && homeComp.messages[i] === handbookFn) {
+            hasHandbook = true;
+            break;
+        }
+    }
+
+    companyManagementPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:"a-link-button", innerText:"Getting Started Guide", display:"inline-block",
+        tooltip:"Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' " +
+                "This is a .lit file that guides you through the beginning of setting up a Corporation and " +
+                "provides some tips/pointers for helping you get started with managing it.",
+        clickListener:()=>{
+            if (!hasHandbook) {homeComp.messages.push(handbookFn);}
+            Object(_Literature_js__WEBPACK_IMPORTED_MODULE_3__["showLiterature"])(handbookFn);
+            return false;
+        }
+    }));
+
+    //Investors
+    if (this.public) {
+        //Sell share buttons
+        var sellShares = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class:"a-link-button", innerText:"Sell Shares", display:"inline-block",
+            tooltip:"Sell your shares in the company. This is the only way to " +
+                    "profit from your business venture.",
+            clickListener:()=>{
+                var popupId = "cmpy-mgmt-sell-shares-popup";
+                var currentStockPrice = this.sharePrice;
+                var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                    innerHTML: "Enter the number of shares you would like to sell. The money from " +
+                               "selling your shares will go directly to you (NOT your Corporation). " +
+                               "The current price of your " +
+                               "company's stock is " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(currentStockPrice).format("$0.000a"),
+                });
+                var profitIndicator = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {});
+                var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                    type:"number", placeholder:"Shares to sell", margin:"5px",
+                    inputListener: ()=> {
+                        var numShares = Math.round(input.value);
+                        if (isNaN(numShares) || numShares <= 0) {
+                            profitIndicator.innerText = "ERROR: Invalid value entered for number of shares to sell"
+                        } else if (numShares > this.numShares) {
+                            profitIndicator.innerText = "You don't have this many shares to sell!";
+                        } else {
+                            profitIndicator.innerText = "Sell " + numShares + " shares for a total of " +
+                                                        _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(numShares * currentStockPrice).format('$0.000a');
+                        }
+                    }
+                });
+                var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class:"a-link-button", innerText:"Sell shares", display:"inline-block",
+                    clickListener:()=>{
+                        var shares = Math.round(input.value);
+                        if (isNaN(shares) || shares <= 0) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: Invalid value for number of shares");
+                        } else if (shares > this.numShares) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You don't have this many shares to sell");
+                        } else {
+                            this.numShares -= shares;
+                            if (isNaN(this.issuedShares)) {
+                                console.log("ERROR: Corporation issuedShares is NaN: " + this.issuedShares);
+                                console.log("Converting to number now");
+                                var res = parseInt(this.issuedShares);
+                                if (isNaN(res)) {
+                                    this.issuedShares = 0;
+                                } else {
+                                    this.issuedShares = res;
+                                }
+                            }
+                            this.issuedShares += shares;
+                            _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].gainMoney(shares * this.sharePrice);
+                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                            return false;
+                        }
+
+                    }
+                });
+                var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class:"a-link-button", innerText:"Cancel", display:"inline-block",
+                    clickListener:()=>{
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        return false;
+                    }
+                });
+                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, profitIndicator, input, confirmBtn, cancelBtn]);
+            }
+        });
+
+        //Buyback shares button
+        var buybackShares = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class:"a-link-button", innerText:"Buyback shares", display:"inline-block",
+            tooltip:"Buy back shares you that previously issued or sold at market price.",
+            clickListener:()=>{
+                var popupId = "cmpy-mgmt-buyback-shares-popup";
+                var currentStockPrice = this.sharePrice;
+                var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                    innerHTML: "Enter the number of shares you would like to buy back at market price. To purchase " +
+                               "these shares, you must use your own money (NOT your Corporation's funds). " +
+                               "The current price of your " +
+                               "company's stock is " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(currentStockPrice).format("$0.000a") +
+                               ". Your company currently has " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.issuedShares, 3) + " outstanding stock shares",
+                });
+                var costIndicator = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {});
+                var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                    type:"number", placeholder:"Shares to buyback", margin:"5px",
+                    inputListener: ()=> {
+                        var numShares = Math.round(input.value);
+                        //TODO add conditional for if player doesn't have enough money
+                        if (isNaN(numShares) || numShares <= 0) {
+                            costIndicator.innerText = "ERROR: Invalid value entered for number of shares to buyback"
+                        } else if (numShares > this.issuedShares) {
+                            costIndicator.innerText = "There are not this many shares available to buy back. " +
+                                                      "There are only " + this.issuedShares + " outstanding shares.";
+                        } else {
+                            console.log("here");
+                            costIndicator.innerText = "Purchase " + numShares + " shares for a total of " +
+                                                      _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(numShares * currentStockPrice).format('$0.000a');
+                        }
+                    }
+                });
+                var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class:"a-link-button", innerText:"Buy shares", display:"inline-block",
+                    clickListener:()=>{
+                        var shares = Math.round(input.value);
+                        var tempStockPrice = this.sharePrice;
+                        if (isNaN(shares) || shares <= 0) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: Invalid value for number of shares");
+                        } else if (shares > this.issuedShares) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: There are not this many oustanding shares to buy back");
+                        } else if (shares * tempStockPrice > _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].money) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You do not have enough money to purchase this many shares (you need " +
+                                            _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(shares * tempStockPrice).format("$0.000a") + ")");
+                        } else {
+                            this.numShares += shares;
+                            if (isNaN(this.issuedShares)) {
+                                console.log("ERROR: Corporation issuedShares is NaN: " + this.issuedShares);
+                                console.log("Converting to number now");
+                                var res = parseInt(this.issuedShares);
+                                if (isNaN(res)) {
+                                    this.issuedShares = 0;
+                                } else {
+                                    this.issuedShares = res;
+                                }
+                            }
+                            this.issuedShares -= shares;
+                            _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].loseMoney(shares * tempStockPrice);
+                            //TODO REMOVE from Player money
+                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        }
+                        return false;
+
+                    }
+                });
+                var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class:"a-link-button",
+                    innerText:"Cancel",
+                    display:"inline-block",
+                    clickListener:()=>{
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        return false;
+                    }
+                });
+                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, costIndicator, input, confirmBtn, cancelBtn]);
+            }
+        });
+
+        companyManagementPanel.appendChild(sellShares);
+        companyManagementPanel.appendChild(buybackShares);
+
+        //If your Corporation is big enough, buy faction influence through bribes
+        var canBribe = this.determineValuation() >= BribeThreshold;
+        var bribeFactions = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class: canBribe ? "a-link-button" : "a-link-button-inactive",
+            innerText:"Bribe Factions", display:"inline-block",
+            tooltip:canBribe
+                    ? "Use your Corporations power and influence to bribe Faction leaders in exchange for reputation"
+                    : "Your Corporation is not powerful enough to bribe Faction leaders",
+            clickListener:()=>{
+                var popupId = "cmpy-mgmt-bribe-factions-popup";
+                var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                    innerText:"You can use Corporation funds or stock shares to bribe Faction Leaders in exchange for faction reputation"
+                });
+                var factionSelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {margin:"3px"});
+                for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].factions.length; ++i) {
+                    var facName = _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].factions[i];
+                    factionSelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                        text:facName, value:facName
+                    }));
+                }
+                var repGainText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p");
+                var stockSharesInput;
+                var moneyInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                    type:"number", placeholder:"Corporation funds", margin:"5px",
+                    inputListener:()=>{
+                        var money = moneyInput.value == null || moneyInput.value == "" ? 0 : parseFloat(moneyInput.value);
+                        var stockPrice = this.sharePrice;
+                        var stockShares = stockSharesInput.value == null || stockSharesInput.value == "" ? 0 : Math.round(parseFloat(stockSharesInput.value));
+                        if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
+                            repGainText.innerText = "ERROR: Invalid value(s) entered";
+                        } else if (this.funds.lt(money)) {
+                            repGainText.innerText = "ERROR: You do not have this much money to bribe with";
+                        } else if (this.stockShares > this.numShares) {
+                            repGainText.innerText = "ERROR: You do not have this many shares to bribe with";
+                        } else {
+
+                            var totalAmount = Number(money) + (stockShares * stockPrice);
+                            var repGain = totalAmount / BribeToRepRatio;
+                            repGainText.innerText = "You will gain " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(repGain, 0) +
+                                                    " reputation with " +
+                                                    factionSelector.options[factionSelector.selectedIndex].value +
+                                                    " with this bribe";
+                        }
+                    }
+                });
+                stockSharesInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                    type:"number", placeholder:"Stock Shares", margin: "5px",
+                    inputListener:()=>{
+                        var money = moneyInput.value == null || moneyInput.value == "" ? 0 : parseFloat(moneyInput.value);
+                        var stockPrice = this.sharePrice;
+                        var stockShares = stockSharesInput.value == null || stockSharesInput.value == "" ? 0 : Math.round(stockSharesInput.value);
+                        if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
+                            repGainText.innerText = "ERROR: Invalid value(s) entered";
+                        } else if (this.funds.lt(money)) {
+                            repGainText.innerText = "ERROR: You do not have this much money to bribe with";
+                        } else if (this.stockShares > this.numShares) {
+                            repGainText.innerText = "ERROR: You do not have this many shares to bribe with";
+                        } else {
+                            var totalAmount = money + (stockShares * stockPrice);
+                            var repGain = totalAmount / BribeToRepRatio;
+                            console.log("repGain: " + repGain);
+                            repGainText.innerText = "You will gain " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(repGain, 0) +
+                                                    " reputation with " +
+                                                    factionSelector.options[factionSelector.selectedIndex].value +
+                                                    " with this bribe";
+                        }
+                    }
+                });
+                var confirmButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class:"a-link-button", innerText:"Bribe", display:"inline-block",
+                    clickListener:()=>{
+                        var money = moneyInput.value == null || moneyInput.value == "" ? 0 : parseFloat(moneyInput.value);
+                        var stockPrice = this.sharePrice;
+                        var stockShares = stockSharesInput.value == null || stockSharesInput.value == ""? 0 : Math.round(parseFloat(stockSharesInput.value));
+                        var fac = _Faction_js__WEBPACK_IMPORTED_MODULE_2__["Factions"][factionSelector.options[factionSelector.selectedIndex].value];
+                        if (fac == null) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You must select a faction to bribe");
+                            return false;
+                        }
+                        if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: Invalid value(s) entered");
+                        } else if (this.funds.lt(money)) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You do not have this much money to bribe with");
+                        } else if (stockShares > this.numShares) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("ERROR: You do not have this many shares to bribe with");
+                        } else {
+                            var totalAmount = money + (stockShares * stockPrice);
+                            var repGain = totalAmount / BribeToRepRatio;
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You gained " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(repGain, 0) +
+                                            " reputation with " + fac.name  + " by bribing them.");
+                            fac.playerReputation += repGain;
+                            this.funds = this.funds.minus(money);
+                            this.numShares -= stockShares;
+                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                            return false;
+                        }
+                    }
+                });
+                var cancelButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class:"a-link-button", innerText:"Cancel", display:"inline-block",
+                    clickListener:()=>{
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        return false;
+                    }
+                });
+
+                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, factionSelector, repGainText,
+                                      moneyInput, stockSharesInput, confirmButton, cancelButton]);
+            }
+        });
+        companyManagementPanel.appendChild(bribeFactions);
+    } else {
+        var findInvestors = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class: this.fundingRound >= 4 ? "a-link-button-inactive" : "a-link-button tooltip",
+            innerText: "Find Investors",
+            display:"inline-block",
+            clickListener:()=>{
+                this.getInvestment();
+            }
+        });
+        if (this.fundingRound < 4) {
+            var findInvestorsTooltip = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("span", {
+                class:"tooltiptext",
+                innerText:"Search for private investors who will give you startup funding in exchange " +
+                          "for equity (stock shares) in your company"
+            });
+            findInvestors.appendChild(findInvestorsTooltip);
+        }
+
+        var goPublic = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class:"a-link-button tooltip",
+            innerText:"Go Public",
+            display:"inline-block",
+            clickListener:()=>{
+                this.goPublic();
+                return false;
+            }
+        });
+        var goPublicTooltip = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("span", {
+            class:"tooltiptext",
+            innerText: "Become a publicly traded and owned entity. Going public involves " +
+                       "issuing shares for an IPO. Once you are a public company, " +
+                       "your shares will be traded on the stock market."
+        });
+        goPublic.appendChild(goPublicTooltip);
+
+        companyManagementPanel.appendChild(findInvestors);
+        companyManagementPanel.appendChild(goPublic);
+    }
+
+    //Update overview text
+    this.updateCorporationOverviewContent();
+
+    //Don't show upgrades if player hasn't opened any divisions
+    if (this.divisions.length <= 0) {return; }
+    //Corporation Upgrades
+    var upgradeContainer = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        class:"cmpy-mgmt-upgrade-container",
+    });
+    upgradeContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("h1", {
+        innerText:"Unlocks", margin:"6px", padding:"6px",
+    }));
+
+    //Unlock upgrades
+    var corp = this;
+    var numUnlockUpgrades = Object.keys(CorporationUnlockUpgrades).length,
+        numUpgrades = Object.keys(CorporationUpgrades).length;
+    if (this.unlockUpgrades == null || this.upgrades == null) { //Backwards compatibility
+        this.unlockUpgrades = Array(numUnlockUpgrades).fill(0);
+        this.upgrades = Array(numUpgrades).fill(0);
+    }
+    while (this.unlockUpgrades.length < numUnlockUpgrades) {this.unlockUpgrades.push(0);}
+    while (this.upgrades.length < numUpgrades) {this.upgrades.push(0);}
+    while (this.upgradeMultipliers < numUpgrades) {this.upgradeMultipliers.push(1);}
+
+    for (var i = 0; i < numUnlockUpgrades; ++i) {
+        (function(i, corp) {
+            if (corp.unlockUpgrades[i] === 0) {
+                var upgrade = CorporationUnlockUpgrades[i.toString()];
+                if (upgrade == null) {
+                    console.log("ERROR: Could not find upgrade index " + i);
+                    return;
+                }
+
+                upgradeContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+                    class:"cmpy-mgmt-upgrade-div", width:"45%",
+                    innerHTML:upgrade[2] +  " - " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgrade[1]).format("$0.000a"),
+                    tooltip: upgrade[3],
+                    clickListener:()=>{
+                        if (corp.funds.lt(upgrade[1])) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Insufficient funds");
+                        } else {
+                            corp.unlock(upgrade);
+                            corp.displayCorporationOverviewContent();
+                        }
+                    }
+                }));
+            }
+        })(i, corp);
+    }
+
+    //Levelable upgrades
+    upgradeContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("h1", {
+        innerText:"Upgrades", margin:"6px", padding:"6px",
+    }));
+
+    for (var i = 0; i < numUpgrades; ++i) {
+        (function(i, corp) {
+            var upgrade = CorporationUpgrades[i.toString()];
+            if (upgrade == null) {
+                console.log("ERROR: Could not find levelable upgrade index " + i);
+                return;
+            }
+
+            var baseCost = upgrade[1], priceMult = upgrade[2];
+            var cost = baseCost * Math.pow(priceMult, corp.upgrades[i]);
+            upgradeContainer.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+                class:"cmpy-mgmt-upgrade-div", width:"45%",
+                innerHTML:upgrade[4] + " - " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(cost).format("$0.000a"),
+                tooltip:upgrade[5],
+                clickListener:()=>{
+                    if (corp.funds.lt(cost)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Insufficient funds");
+                    } else {
+                        corp.upgrade(upgrade);
+                        corp.displayCorporationOverviewContent();
+                    }
+                }
+            }));
+        })(i, corp);
+    }
+
+    companyManagementPanel.appendChild(upgradeContainer);
+}
+
+Corporation.prototype.updateCorporationOverviewContent = function() {
+    var p = document.getElementById("cmpy-mgmt-overview-text");
+    if (p == null) {
+        console.log("WARNING: Could not find overview text elemtn in updateCorporationOverviewContent()");
+        return;
+    }
+    var totalFunds = this.funds,
+        totalRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0),
+        totalExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0);
+
+    var profit = this.revenue.minus(this.expenses).toNumber(),
+        profitStr = profit >= 0 ? _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(profit).format("$0.000a") : "-" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(-1 * profit).format("$0.000a");
+
+    var txt = "Total Funds: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(totalFunds.toNumber()).format('$0.000a') + "<br>" +
+              "Total Revenue: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.revenue.toNumber()).format("$0.000a") + " / s<br>" +
+              "Total Expenses: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.expenses.toNumber()).format("$0.000a") + "/ s<br>" +
+              "Total Profits: " + profitStr + " / s<br>" +
+              "Publicly Traded: " + (this.public ? "Yes" : "No") + "<br>" +
+              "Owned Stock Shares: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.numShares).format('0.000a') + "<br>" +
+              "Stock Price: " + (this.public ? "$" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(this.sharePrice, 2) : "N/A") + "<br><br>";
+
+    var prodMult        = this.getProductionMultiplier(),
+        storageMult     = this.getStorageMultiplier(),
+        advMult         = this.getAdvertisingMultiplier(),
+        empCreMult      = this.getEmployeeCreMultiplier(),
+        empChaMult      = this.getEmployeeChaMultiplier(),
+        empIntMult      = this.getEmployeeIntMultiplier(),
+        empEffMult      = this.getEmployeeEffMultiplier(),
+        salesMult       = this.getSalesMultiplier(),
+        sciResMult      = this.getScientificResearchMultiplier();
+    if (prodMult > 1)       {txt += "Production Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(prodMult, 3) + "<br>";}
+    if (storageMult > 1)    {txt += "Storage Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(storageMult, 3) + "<br>";}
+    if (advMult > 1)        {txt += "Advertising Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(advMult, 3) + "<br>";}
+    if (empCreMult > 1)     {txt += "Empl. Creativity Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(empCreMult, 3) + "<br>";}
+    if (empChaMult > 1)     {txt += "Empl. Charisma Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(empChaMult, 3) + "<br>";}
+    if (empIntMult > 1)     {txt += "Empl. Intelligence Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(empIntMult, 3) + "<br>";}
+    if (empEffMult > 1)     {txt += "Empl. Efficiency Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(empEffMult, 3) + "<br>";}
+    if (salesMult > 1)      {txt += "Sales Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(salesMult, 3) + "<br>";}
+    if (sciResMult > 1)     {txt += "Scientific Research Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(sciResMult, 3) + "<br>";}
+    p.innerHTML = txt;
+}
+
+Corporation.prototype.displayDivisionContent = function(division, city) {
+    this.clearUIPanel();
+    currentCityUi = city;
+
+    //Add the city tabs on the left
+    for (var cityName in division.offices) {
+        if (division.offices[cityName] instanceof OfficeSpace) {
+            this.createCityUITab(cityName, division);
+        }
+    }
+    cityTabs = companyManagementPanel.getElementsByClassName("cmpy-mgmt-city-tab");
+    if (cityTabs.length > 0) {
+        this.selectCityTab(document.getElementById("cmpy-mgmt-city-" + city + "-tab"), city);
+    }
+
+    //Expand into new City button
+    companyManagementPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
+        class:"cmpy-mgmt-city-tab", innerText:"Expand into new City", display:"inline-block",
+        clickListener:()=>{
+            var popupId = "cmpy-mgmt-expand-city-popup";
+            var text = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerText: "Would you like to expand into a new city by opening an office? " +
+                           "This would cost " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(OfficeInitialCost).format('$0.000a'),
+            });
+            var citySelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {margin:"5px"});
+            for (var cityName in division.offices) {
+                if (division.offices.hasOwnProperty(cityName)) {
+                    if (!(division.offices[cityName] instanceof OfficeSpace)) {
+                        citySelector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                            text: cityName,
+                            value: cityName
+                        }));
+                    }
+                }
+            }
+
+            var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                innerText:"Confirm", class:"a-link-button", display:"inline-block", margin:"3px",
+                clickListener:()=>{
+                    var city = citySelector.options[citySelector.selectedIndex].value;
+                    if (this.funds.lt(OfficeInitialCost)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to open a new office!");
+                    } else {
+                        this.funds = this.funds.minus(OfficeInitialCost);
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Opened a new office in " + city + "!");
+                        division.offices[city] = new OfficeSpace({
+                            loc:city,
+                            size:OfficeInitialSize,
+                        });
+                        this.displayDivisionContent(division, city);
+                    }
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                innerText:"Cancel", class:"a-link-button", display:"inline-block", margin:"3px",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            })
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [text, citySelector, confirmBtn, cancelBtn]);
+            return false;
+        }
+    }));
+    companyManagementPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {})); // Force line break
+
+    //Get office object
+    var office = division.offices[currentCityUi];
+    if (!(office instanceof OfficeSpace)) {
+        console.log("ERROR: Current city for UI does not have an office space");
+        return;
+    }
+
+    //Left and right panels
+    var leftPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {class:"cmpy-mgmt-industry-left-panel"});
+    var rightPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {class:"cmpy-mgmt-industry-right-panel"});
+    companyManagementPanel.appendChild(leftPanel);
+    companyManagementPanel.appendChild(rightPanel);
+
+    //Different sections (Overview, Employee/Office, and Warehouse)
+    industryOverviewPanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        id:"cmpy-mgmt-industry-overview-panel", class:"cmpy-mgmt-industry-overview-panel"
+    });
+    leftPanel.appendChild(industryOverviewPanel);
+
+    industryEmployeePanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        id:"cmpy-mgmt-employee-panel", class:"cmpy-mgmt-employee-panel"
+    });
+    leftPanel.appendChild(industryEmployeePanel);
+
+    industryWarehousePanel = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        id:"cmpy-mgmt-warehouse-panel", class:"cmpy-mgmt-warehouse-panel"
+    });
+    rightPanel.appendChild(industryWarehousePanel);
+
+    //Industry overview text
+    industryOverviewText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {});
+    industryOverviewPanel.appendChild(industryOverviewText);
+    industryOverviewPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+
+    //Industry overview Purchases & Upgrades
+    var numUpgrades = Object.keys(IndustryUpgrades).length;
+    while (division.upgrades.length < numUpgrades) {division.upgrades.push(0);} //Backwards compatibility
+
+    var industryOverviewUpgrades = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {});
+    industryOverviewUpgrades.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("u", {
+        innerText:"Purchases & Upgrades", margin:"2px", padding:"2px",
+        fontSize:"14px",
+    }));
+    industryOverviewUpgrades.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+    for (var i = 0; i < numUpgrades; ++i) {
+        (function(i, corp, division, office) {
+            var upgrade = IndustryUpgrades[i.toString()];
+            if (upgrade == null) {
+                console.log("ERROR: Could not find levelable upgrade index: " + i);
+                return;
+            }
+
+            var baseCost = upgrade[1], priceMult = upgrade[2], cost = 0;
+            switch(i) {
+                case 0: //Coffee, cost is static per employee
+                    cost = office.employees.length * baseCost;
+                    break;
+                default:
+                    cost = baseCost * Math.pow(priceMult, division.upgrades[i]);
+                    break;
+            }
+            industryOverviewUpgrades.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+                class:"cmpy-mgmt-upgrade-div", display:"inline-block",
+                innerHTML:upgrade[4] + ' - ' + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(cost).format("$0.000a"),
+                tooltip:upgrade[5],
+                clickListener:()=>{
+                    if (corp.funds.lt(cost)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Insufficient funds");
+                    } else {
+                        corp.funds = corp.funds.minus(cost);
+                        division.upgrade(upgrade, {
+                            corporation:corp,
+                            office:office,
+                        });
+                        corp.displayDivisionContent(division, city);
+                    }
+                }
+            }));
+            industryOverviewUpgrades.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+
+        })(i, this, division, office);
+    }
+
+
+    industryOverviewPanel.appendChild(industryOverviewUpgrades);
+
+    //Industry Overview 'Create Product' button if applicable
+    if (division.makesProducts) {
+        //Get the text on the button based on Industry type
+        var createProductButtonText, createProductPopupText;
+        switch(division.type) {
+            case Industries.Food:
+                createProductButtonText = "Build Restaurant";
+                createProductPopupText = "Build and manage a new restaurant!"
+                break;
+            case Industries.Tobacco:
+                createProductButtonText = "Create Product";
+                createProductPopupText = "Create a new tobacco product!";
+                break;
+            case Industries.Pharmaceutical:
+                createProductButtonText = "Create Drug";
+                createProductPopupText = "Design and develop a new pharmaceutical drug!";
+                break;
+            case Industries.Computer:
+            case "Computer":
+                createProductButtonText = "Create Product";
+                createProductPopupText = "Design and manufacture a new computer hardware product!";
+                break;
+            case Industries.Robotics:
+                createProductButtonText = "Design Robot";
+                createProductPopupText = "Design and create a new robot or robotic system!";
+                break;
+            case Industries.Software:
+                createProductButtonText = "Develop Software";
+                createProductPopupText = "Develop a new piece of software!";
+                break;
+            case Industries.HealthCare:
+                createProductButtonText = "Build Hospital";
+                createProductPopupText = "Build and manage a new hospital!";
+                break;
+            case Industries.RealEstate:
+                createProductButtonText = "Develop Property";
+                createProductPopupText = "Develop a new piece of real estate property!";
+                break;
+            default:
+                createProductButtonText = "Create Product";
+                return "";
+        }
+        createProductPopupText += "<br><br>To begin developing a product, " +
+            "first choose the city in which it will be designed. The stats of your employees " +
+            "in the selected city affect the properties of the finished product, such as its " +
+            "quality, performance, and durability.<br><br>" +
+            "You can also choose to invest money in the design and marketing of " +
+            "the product. Investing money in its design will result in a superior product. " +
+            "Investing money in marketing the product will help the product's sales.";
+
+        //Create the button
+        industryOverviewPanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class:"a-link-button", innerText:createProductButtonText, margin:"6px", display:"inline-block",
+            clickListener:()=>{
+                var popupId = "cmpy-mgmt-create-product-popup";
+                var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                    innerHTML:createProductPopupText,
+                });
+                var designCity = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {});
+                for (var cityName in division.offices) {
+                    if (division.offices[cityName] instanceof OfficeSpace) {
+                        designCity.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {
+                            value:cityName,
+                            text:cityName
+                        }));
+                    }
+                }
+                var foo = "Product Name";
+                if (division.type === Industries.Food) {
+                    foo = "Restaurant Name";
+                } else if (division.type === Industries.Healthcare) {
+                    foo = "Hospital Name";
+                } else if (division.type === Industries.RealEstate) {
+                    foo = "Property Name";
+                }
+                var productNameInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                    placeholder:foo,
+                });
+                var lineBreak1 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br",{});
+                var designInvestInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                    type:"number",
+                    placeholder:"Design investment"
+                });
+                var marketingInvestInput = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                    type:"number",
+                    placeholder:"Marketing investment"
+                });
+                var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class:"a-link-button",
+                    innerText:"Develop Product",
+                    clickListener:()=>{
+                        if (designInvestInput.value == null) {designInvestInput.value = 0;}
+                        if (marketingInvestInput.value == null) {marketingInvestInput.value = 0;}
+                        var designInvest = parseFloat(designInvestInput.value),
+                            marketingInvest = parseFloat(marketingInvestInput.value);
+                        if (productNameInput.value == null || productNameInput.value === "") {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You must specify a name for your product!");
+                        } else if (isNaN(designInvest)) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for design investment");
+                        } else if (isNaN(marketingInvest))  {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value for marketing investment");
+                        } else if (this.funds.lt(designInvest + marketingInvest)) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to make this large of an investment");
+                        } else {
+                            var product = new Product({
+                                name:productNameInput.value.replace(/[<>]/g, ''), //Sanitize for HTMl elements
+                                createCity:designCity.options[designCity.selectedIndex].value,
+                                designCost: designInvest,
+                                advCost: marketingInvest,
+                            });
+                            this.funds = this.funds.minus(designInvest + marketingInvest);
+                            division.products[product.name] = product;
+                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        }
+                        //this.updateUIContent();
+                        this.displayDivisionContent(division, city);
+                        return false;
+                    }
+                })
+                var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class:"a-link-button",
+                    innerText:"Cancel",
+                    clickListener:()=>{
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        return false;
+                    }
+                })
+                Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, designCity, productNameInput, lineBreak1,
+                                      designInvestInput, marketingInvestInput, confirmBtn, cancelBtn]);
+            }
+        }));
+    }
+
+    //Employee and Office Panel
+    industryEmployeeText = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        id: "cmpy-mgmt-employee-p",
+        display:"block",
+        innerHTML:  "<h1>Office Space</h1><br>" +
+                    "Type: " + office.tier + "<br>" +
+                    "Comfort: " + office.comf + "<br>" +
+                    "Beauty: " + office.beau + "<br>" +
+                    "Size: " + office.employees.length + " / " + office.size + " employees",
+    });
+    industryEmployeePanel.appendChild(industryEmployeeText);
+
+    //Hire Employee button
+    if (office.employees.length === 0) {
+        industryEmployeeHireButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class:"a-link-button",display:"inline-block",
+            innerText:"Hire Employee", fontSize:"13px",
+            tooltip:"You'll need to hire some employees to get your operations started! " +
+                    "It's recommended to have at least one employee in every position",
+            clickListener:()=>{
+                office.findEmployees({corporation:this, division:division});
+                return false;
+            }
+        });
+        //industryEmployeeHireButton.classList.add("flashing-button");
+    } else {
+        industryEmployeeHireButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class:"a-link-button",display:"inline-block",
+            innerText:"Hire Employee", fontSize:"13px",
+            clickListener:()=>{
+                office.findEmployees({corporation:this, division:division});
+                return false;
+            }
+        });
+    }
+    industryEmployeePanel.appendChild(industryEmployeeHireButton);
+
+    //Autohire Employee button
+    industryEmployeeAutohireButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:"a-link-button", display:"inline-block",
+        innerText:"Autohire Employee", fontSize:"13px",
+        tooltip:"Automatically hires an employee and gives him/her a random name",
+        clickListener:()=>{
+            office.hireRandomEmployee({corporation:this, division:division});
+            return false;
+        }
+    });
+    industryEmployeePanel.appendChild(industryEmployeeAutohireButton);
+
+    //Upgrade Office Size button
+    industryEmployeePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+    industryOfficeUpgradeSizeButton = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:"a-link-button", innerText:"Upgrade size",
+        display:"inline-block", margin:"6px", fontSize:"13px",
+        tooltip:"Upgrade the office's size so that it can hold more employees!",
+        clickListener:()=>{
+            var popupId = "cmpy-mgmt-upgrade-office-size-popup";
+            var initialPriceMult = Math.round(office.size / OfficeInitialSize);
+            var upgradeCost = OfficeInitialCost * Math.pow(1.07, initialPriceMult);
+
+            //Calculate cost to upgrade size by 15 employees
+            var mult = 0;
+            for (var i = 0; i < 5; ++i) {
+                mult += (Math.pow(1.07, initialPriceMult + i));
+            }
+            var upgradeCost15 = OfficeInitialCost * mult;
+
+            //Calculate max upgrade size and cost
+            var maxMult = (this.funds.dividedBy(OfficeInitialCost)).toNumber();
+            var maxNum = 1;
+            mult = Math.pow(1.07, initialPriceMult);
+            while(maxNum < 50) { //Hard cap of 50x (extra 150 employees)
+                if (mult >= maxMult) {break;}
+                var multIncrease = Math.pow(1.07, initialPriceMult + maxNum);
+                if (mult + multIncrease > maxMult) {
+                    break;
+                } else {
+                    mult += multIncrease;
+                }
+                ++maxNum;
+            }
+
+            var upgradeCostMax = OfficeInitialCost * mult;
+
+            var text = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerText:"Increase the size of your office space to fit additional employees!"
+            });
+            var text2 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {innerText: "Upgrade size: "});
+
+            var confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class: this.funds.lt(upgradeCost) ? "a-link-button-inactive" : "a-link-button",
+                display:"inline-block", margin:"4px", innerText:"by 3",
+                tooltip:_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgradeCost).format("$0.000a"),
+                clickListener:()=>{
+                    if (this.funds.lt(upgradeCost)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to purchase this upgrade!");
+                    } else {
+                        office.size += OfficeInitialSize;
+                        this.funds = this.funds.minus(upgradeCost);
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Office space increased! It can now hold " + office.size + " employees");
+                        this.updateUIContent();
+                    }
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            var confirmBtn15 = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class: this.funds.lt(upgradeCost15) ? "a-link-button-inactive" : "a-link-button",
+                display:"inline-block", margin:"4px", innerText:"by 15",
+                tooltip:_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgradeCost15).format("$0.000a"),
+                clickListener:()=>{
+                    if (this.funds.lt(upgradeCost15)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to purchase this upgrade!");
+                    } else {
+                        office.size += (OfficeInitialSize * 5);
+                        this.funds = this.funds.minus(upgradeCost15);
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Office space increased! It can now hold " + office.size + " employees");
+                        this.updateUIContent();
+                    }
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            var confirmBtnMax = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:this.funds.lt(upgradeCostMax) ? "a-link-button-inactive" : "a-link-button",
+                display:"inline-block", margin:"4px", innerText:"by MAX (" + maxNum*OfficeInitialSize + ")",
+                tooltip:_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(upgradeCostMax).format("$0.000a"),
+                clickListener:()=>{
+                    if (this.funds.lt(upgradeCostMax)) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to purchase this upgrade!");
+                    } else {
+                        office.size += (OfficeInitialSize * maxNum);
+                        this.funds = this.funds.minus(upgradeCostMax);
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Office space increased! It can now hold " + office.size + " employees");
+                        this.updateUIContent();
+                    }
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button", innerText:"Cancel", display:"inline-block", margin:"4px",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            })
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [text, text2, confirmBtn, confirmBtn15, confirmBtnMax, cancelBtn]);
+            return false;
+        }
+    });
+    industryEmployeePanel.appendChild(industryOfficeUpgradeSizeButton);
+
+    //Throw Office Party
+    industryEmployeePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+        class:"a-link-button", display:"inline-block", innerText:"Throw Party",
+        fontSize:"13px",
+        tooltip:"Throw an office party to increase your employee's morale and happiness",
+        clickListener:()=>{
+            var popupId = "cmpy-mgmt-throw-office-party-popup";
+            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerText:"Enter the amount of money you would like to spend PER EMPLOYEE " +
+                          "on this office party"
+            });
+            var totalCostTxt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+                innerText:"Throwing this party will cost a total of $0"
+            });
+            var confirmBtn;
+            var input = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("input", {
+                type:"number", margin:"5px", placeholder:"$ / employee",
+                inputListener:()=>{
+                    if (isNaN(input.value) || input.value < 0) {
+                        totalCostTxt.innerText = "Invalid value entered!"
+                    } else {
+                        var totalCost = input.value * office.employees.length;
+                        totalCostTxt.innerText = "Throwing this party will cost a total of " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(totalCost).format('$0.000a');
+                    }
+                },
+                onkeyup:(e)=>{
+                    e.preventDefault();
+                    if (e.keyCode === 13) {confirmBtn.click();}
+                }
+            });
+            confirmBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button",
+                display:"inline-block",
+                innerText:"Throw Party",
+                clickListener:()=>{
+                    if (isNaN(input.value) || input.value < 0) {
+                        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Invalid value entered");
+                    } else {
+                        var totalCost = input.value * office.employees.length;
+                        if (this.funds.lt(totalCost)) {
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You don't have enough company funds to throw this party!");
+                        } else {
+                            this.funds = this.funds.minus(totalCost);
+                            var mult;
+                            for (var fooit = 0; fooit < office.employees.length; ++fooit) {
+                                mult = office.employees[fooit].throwParty(input.value);
+                            }
+                            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You threw a party for the office! The morale and happiness " +
+                                            "of each employee increased by " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])((mult-1) * 100, 2) + "%.");
+                            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                        }
+                    }
+                    return false;
+                }
+            });
+            var cancelBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                class:"a-link-button",
+                display:"inline-block",
+                innerText:"Cancel",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createPopup"])(popupId, [txt, totalCostTxt, input, confirmBtn, cancelBtn]);
+        }
+    }));
+
+    industryEmployeeManagementUI = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {});
+    industryEmployeeInfo = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {margin:"4px", padding:"4px"});
+    if (empManualAssignmentModeActive) {
+        //Employees manually assigned
+        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class:"a-link-button", display:"inline-block", margin:"4px",
+            innerText:"Switch to Auto Mode",
+            tooltip:"Switch to Automatic Assignment Mode, which will automatically  " +
+                    "assign employees to your selected jobs. You simply have to select " +
+                    "the number of assignments for each job",
+            clickListener:()=>{
+                empManualAssignmentModeActive = false;
+                this.displayDivisionContent(division, city);
+            }
+        }));
+        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+
+        industryIndividualEmployeeInfo = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {margin:"4px", padding:"4px"});
+        var selector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("select", {
+            color: "white", backgroundColor:"black", margin:"4px", padding:"4px",
+            changeListener:()=>{
+                var name = selector.options[selector.selectedIndex].text;
+                for (var i = 0; i < office.employees.length; ++i) {
+                    if (office.employees[i].name === name) {
+                        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryIndividualEmployeeInfo);
+                        office.employees[i].createUI(industryIndividualEmployeeInfo, this);
+                        return;
+                    }
+                }
+                console.log("ERROR: Employee in selector could not be found");
+            }
+        });
+
+        for (var i = 0; i < office.employees.length; ++i) {
+            selector.add(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("option", {text:office.employees[i].name}));
+        }
+
+        selector.selectedIndex = -1;
+
+        industryEmployeeManagementUI.appendChild(industryEmployeeInfo);
+        industryEmployeeManagementUI.appendChild(selector);
+        industryEmployeeManagementUI.appendChild(industryIndividualEmployeeInfo);
+    } else {
+        //Player only manages the number of each occupation, not who gets what job
+        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            class:"a-link-button", display:"inline-block", margin:"4px",
+            innerText:"Switch to Manual Mode",
+            tooltip:"Switch to Manual Assignment Mode, which allows you to " +
+                    "specify which employees should get which jobs",
+            clickListener:()=>{
+                empManualAssignmentModeActive = true;
+                this.displayDivisionContent(division, city);
+            }
+        }));
+        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+
+        var opCount = 0, engCount = 0, busCount = 0,
+            mgmtCount = 0, rndCount = 0, unassignedCount = 0,
+            trainingCount = 0;
+        for (var i = 0; i < office.employees.length; ++i) {
+            switch (office.employees[i].pos) {
+                case EmployeePositions.Operations:
+                    ++opCount; break;
+                case EmployeePositions.Engineer:
+                    ++engCount; break;
+                case EmployeePositions.Business:
+                    ++busCount; break;
+                case EmployeePositions.Management:
+                    ++mgmtCount; break;
+                case EmployeePositions.RandD:
+                    ++rndCount; break;
+                case EmployeePositions.Unassigned:
+                    ++unassignedCount; break;
+                case EmployeePositions.Training:
+                    ++trainingCount; break;
+                default:
+                    console.log("ERROR: Unrecognized employee position: " + office.employees[i].pos);
+                    break;
+            }
+        }
+
+        //Unassigned employee count display
+        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+            display:"inline-block",
+            innerText:"Unassigned Employees: " + unassignedCount,
+        }));
+        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+
+        //General display of employee information (avg morale, avg energy, etc.)
+        industryEmployeeManagementUI.appendChild(industryEmployeeInfo);
+        industryEmployeeManagementUI.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+
+        var positions = [EmployeePositions.Operations, EmployeePositions.Engineer,
+                         EmployeePositions.Business, EmployeePositions.Management,
+                         EmployeePositions.RandD, EmployeePositions.Training];
+        var descriptions = ["Manages supply chain operations. Improves production.", //Operations
+                            "Develops and maintains products and production systems. Improves production.", //Engineer
+                            "Handles sales and finances. Improves sales.", //Business
+                            "Leads and oversees employees and office operations. Improves production.", //Management
+                            "Research new innovative ways to improve the company. Generates Scientific Research", //RandD
+                            "Set employee to training, which will increase some of their stats. Employees in training do not affect any company operations."] //Training
+        var counts = [opCount, engCount, busCount, mgmtCount, rndCount, trainingCount];
+        for (var i = 0; i < positions.length; ++i) {
+            (function(corp, i) {
+                var info = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("h2", {
+                    display:"inline-block", width:"40%", fontSize:"15px",
+                    innerText: positions[i] + "(" + counts[i] + ")",
+                    tooltipleft: descriptions[i]
+                });
+                var plusBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class: unassignedCount > 0 ? "a-link-button" : "a-link-button-inactive",
+                    display:"inline-block", innerText:"+",
+                    clickListener:()=>{
+                        office.assignEmployeeToJob(positions[i]);
+                        corp.displayDivisionContent(division, city);
+                    }
+                });
+                var minusBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+                    class: counts[i] > 0 ? "a-link-button" : "a-link-button-inactive",
+                    display:"inline-block", innerText:"-",
+                    clickListener:()=>{
+                        office.unassignEmployeeFromJob(positions[i]);
+                        corp.displayDivisionContent(division, city);
+                    }
+                });
+                var newline = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {});
+                industryEmployeeManagementUI.appendChild(info);
+                industryEmployeeManagementUI.appendChild(plusBtn);
+                industryEmployeeManagementUI.appendChild(minusBtn);
+                industryEmployeeManagementUI.appendChild(newline);
+            })(this, i);
+        }
+    }
+    industryEmployeePanel.appendChild(industryEmployeeManagementUI);
+
+    //Warehouse Panel
+    var warehouse = division.warehouses[currentCityUi];
+    if (warehouse instanceof Warehouse) {
+        warehouse.createUI({industry:division, company: this});
+    } else {
+        industryWarehousePanel.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("a", {
+            innerText:"Purchase Warehouse ($5b)",
+            class: "a-link-button",
+            clickListener:()=>{
+                if (this.funds.lt(WarehouseInitialCost)) {
+                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("You do not have enough funds to do this!");
+                } else {
+                    division.warehouses[currentCityUi] = new Warehouse({
+                        loc:currentCityUi,
+                        size:WarehouseInitialSize,
+                    });
+                    this.funds = this.funds.minus(WarehouseInitialCost);
+                    this.displayDivisionContent(division, currentCityUi);
+                }
+                return false;
+            }
+        }));
+    }
+    this.updateDivisionContent(division);
+}
+
+Corporation.prototype.updateDivisionContent = function(division) {
+    if (!(division instanceof Industry)) {
+        console.log("ERROR: Invalid 'division' argument in Corporation.updateDivisionContent");
+        return;
+    }
+    var vechain = (this.unlockUpgrades[4] === 1);
+    //Industry Overview Text
+    var profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber(),
+        profitStr = profit >= 0 ? _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(profit).format("$0.000a") : "-" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(-1 * profit).format("$0.000a");
+    var advertisingInfo = "";
+    if (vechain) {
+        var advertisingFactors = division.getAdvertisingFactors();
+        var awarenessFac = advertisingFactors[1];
+        var popularityFac = advertisingFactors[2];
+        var ratioFac = advertisingFactors[3];
+        var totalAdvertisingFac = advertisingFactors[0];
+        advertisingInfo =
+            "<p class='tooltip'>Advertising Multiplier: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(totalAdvertisingFac, 3) +
+            "<span class='tooltiptext' style='font-size:12px'>Total multiplier for this industry's sales due to its awareness and popularity<br>" +
+            "Awareness Bonus: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(Math.pow(awarenessFac, 0.85), 3) + "<br>" +
+            "Popularity Bonus: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(Math.pow(popularityFac, 0.85), 3) + "<br>" +
+            "Ratio Multiplier: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(Math.pow(ratioFac, 0.85), 3) + "</span></p><br>"
+
+    }
+
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeChildrenFromElement"])(industryOverviewText);
+    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        innerHTML:"Industry: " + division.type + " (Corp Funds: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(this.funds.toNumber()).format("$0.000a") + ")<br><br>" +
+                  "Awareness: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.awareness, 3) + "<br>" +
+                  "Popularity: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.popularity, 3) +  "<br>" +
+                  advertisingInfo + "<br>" +
+                  "Revenue: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(division.lastCycleRevenue.toNumber()).format("$0.000a") + " / s<br>" +
+                  "Expenses: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(division.lastCycleExpenses.toNumber()).format("$0.000a") + " /s<br>" +
+                  "Profit: " + profitStr + " / s<br><br>"
+    }));
+    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        marginTop:"2px",
+        innerText:"Production Multiplier: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.prodMult, 2),
+        tooltip:"Production gain from owning production-boosting materials " +
+                "such as hardware, Robots, AI Cores, and Real Estate"
+    }));
+    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("div", {
+        innerText:"?", class:"help-tip",
+        clickListener:()=>{
+            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Owning Hardware, Robots, AI Cores, and Real Estate " +
+                            "can boost your Industry's production. The effect these " +
+                            "materials have on your production varies between Industries. " +
+                            "For example, Real Estate may be very effective for some Industries, " +
+                            "but ineffective for others.<br><br>" +
+                            "This division's production multiplier is calculated by summing " +
+                            "the individual production multiplier of each of its office locations. " +
+                            "This production multiplier is applied to each office. Therefore, it is " +
+                            "beneficial to expand into new cities as this can greatly increase the " +
+                            "production multiplier of your entire Division.");
+        }
+    }));
+    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br"));
+    industryOverviewText.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+        display:"inline-block",
+        innerText:"Scientific Research: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.sciResearch.qty, 3),
+        tooltip:"Scientific Research increases the quality of the materials and " +
+                "products that you produce."
+    }));
+
+    //Office and Employee List
+    var office = division.offices[currentCityUi];
+    industryEmployeeText.innerHTML =
+                "<h1>Office Space</h1><br>" +
+                "Type: " + office.tier + "<br>" +
+                "Comfort: " + office.comf + "<br>" +
+                "Beauty: " + office.beau + "<br>" +
+                "Size: " + office.employees.length + " / " + office.size + " employees";
+    if (office.employees.length >= office.size) {
+        industryEmployeeHireButton.className = "a-link-button-inactive";
+        industryEmployeeAutohireButton.className = "a-link-button-inactive tooltip";
+    } else if (office.employees.length === 0) {
+        industryEmployeeHireButton.className = "a-link-button tooltip flashing-button";
+        industryEmployeeAutohireButton.className = "a-link-button tooltip";
+    } else {
+        industryEmployeeHireButton.className = "a-link-button";
+        industryEmployeeAutohireButton.className = "a-link-button tooltip";
+    }
+
+    //Employee Overview stats
+    //Calculate average morale, happiness, and energy
+    var totalMorale = 0, totalHappiness = 0, totalEnergy = 0,
+        avgMorale = 0, avgHappiness = 0, avgEnergy = 0;
+    for (var i = 0; i < office.employees.length; ++i) {
+        totalMorale += office.employees[i].mor;
+        totalHappiness += office.employees[i].hap;
+        totalEnergy += office.employees[i].ene;
+    }
+    if (office.employees.length > 0) {
+        avgMorale = totalMorale / office.employees.length;
+        avgHappiness = totalHappiness / office.employees.length;
+        avgEnergy = totalEnergy / office.employees.length;
+    }
+    industryEmployeeInfo.innerHTML =
+        "Avg Employee Morale: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(avgMorale, 3) + "<br>" +
+        "Avg Employee Happiness: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(avgHappiness, 3) + "<br>" +
+        "Avg Employee Energy: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(avgEnergy, 3);
+    if (vechain) { //VeChain - Statistics
+        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+            innerText:"Material Production: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.getOfficeProductivity(office), 3),
+            tooltip: "The base amount of material this office can produce. Does not include " +
+                     "production multipliers from upgrades and materials. This value is based off " +
+                     "the productivity of your Operations, Engineering, and Management employees"
+        }));
+        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+            innerText:"Product Production: " + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.getOfficeProductivity(office, {forProduct:true}), 3),
+            tooltip: "The base amount of any given Product this office can produce. Does not include " +
+                     "production multipliers from upgrades and materials. This value is based off " +
+                     "the productivity of your Operations, Engineering, and Management employees"
+        }));
+        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("br", {}));
+        industryEmployeeInfo.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("p", {
+            innerText: "Business Multiplier: x" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__["formatNumber"])(division.getBusinessFactor(office), 3),
+            tooltip: "The effect this office's 'Business' employees has on boosting sales"
+        }));
+    }
+
+    //Warehouse
+    var warehouse = division.warehouses[currentCityUi];
+    if (warehouse instanceof Warehouse) {
+        warehouse.updateUI({industry:division, company:this});
+    }
+}
+
+Corporation.prototype.createCityUITab = function(city, division) {
+    var tab = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["createElement"])("button", {
+        id:"cmpy-mgmt-city-" + city + "-tab",
+        class:"cmpy-mgmt-city-tab",
+        innerText:city,
+        clickListener:()=>{
+            this.selectCityTab(tab, city);
+            this.displayDivisionContent(division, city);
+            return false;
+        }
+    });
+    companyManagementPanel.appendChild(tab);
+}
+
+Corporation.prototype.selectCityTab = function(activeTab, city) {
+    if (activeTab == null) {
+        activeTab = document.getElementById("cmpy-mgmt-city-" + city + "-tab");
+        if (activeTab == null) {return;}
+    }
+    for (var i = 0; i < cityTabs.length; ++i) {
+        cityTabs[i].className = "cmpy-mgmt-city-tab";
+    }
+    activeTab.className = "cmpy-mgmt-city-tab current";
+}
+
+Corporation.prototype.clearUI = function() {
+    //Delete everything
+    if (companyManagementDiv != null) {Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__["removeElementById"])(companyManagementDiv.id);}
+
+    //Reset global DOM variables
+    companyManagementDiv        = null;
+    companyManagementPanel      = null;
+    currentCityUi               = null;
+
+    corporationUnlockUpgrades   = null;
+    corporationUpgrades         = null;
+
+    industryOverviewPanel       = null;
+    industryOverviewText        = null;
+
+    industryEmployeePanel           = null;
+    industryEmployeeText            = null;
+    industryEmployeeHireButton      = null;
+    industryEmployeeAutohireButton  = null;
+    industryEmployeeManagementUI    = null;
+    industryEmployeeInfo            = null;
+    industryIndividualEmployeeInfo  = null;
+
+    industryOfficeUpgradeSizeButton = null;
+
+    industryWarehousePanel              = null;
+    industrySmartSupplyCheckbox         = null;
+    industryWarehouseStorageText        = null;
+    industryWarehouseUpgradeSizeButton  = null;
+    industryWarehouseStateText          = null;
+    industryWarehouseMaterials          = null;
+    industryWarehouseProducts           = null;
+
+    companyManagementHeaderTabs = null;
+    headerTabs                  = null;
+    cityTabs                    = null;
+
+    document.getElementById("character-overview-wrapper").style.visibility = "visible";
+}
+
+Corporation.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_toJSON"])("Corporation", this);
+}
+
+Corporation.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Generic_fromJSON"])(Corporation, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__["Reviver"].constructors.Corporation = Corporation;
+
+
+
+
+/***/ }),
+/* 41 */
+/*!*************************!*\
+  !*** ./src/TextFile.js ***!
+  \*************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextFile", function() { return TextFile; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getTextFile", function() { return getTextFile; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createTextFile", function() { return createTextFile; });
+/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Server.js */ 10);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
+
+
+
+
+function TextFile(fn="", txt="") {
+    this.fn = fn.endsWith(".txt") ? fn : fn + ".txt";
+    this.fn = this.fn.replace(/\s+/g, '');
+    this.text = String(txt);
+}
+
+TextFile.prototype.append = function(txt) {
+    this.text += String(txt);
+}
+
+TextFile.prototype.write = function(txt) {
+    this.text = String(txt);
+}
+
+TextFile.prototype.read = function() {
+    return this.txt;
+}
+
+TextFile.prototype.show = function() {
+    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_1__["dialogBoxCreate"])(this.fn + "<br><br>" + this.text, true);
+}
+
+TextFile.prototype.download = function() {
+    var filename = this.fn;
+    var file = new Blob([this.text], {type: 'text/plain'});
+    if (window.navigator.msSaveOrOpenBlob) {// IE10+
+        window.navigator.msSaveOrOpenBlob(file, filename);
+    } else { // Others
+        var a = document.createElement("a"),
+                url = URL.createObjectURL(file);
+        a.href = url;
+        a.download = this.fn;
+        document.body.appendChild(a);
+        a.click();
+        setTimeout(function() {
+            document.body.removeChild(a);
+            window.URL.revokeObjectURL(url);
+        }, 0);
+    }
+}
+
+TextFile.prototype.toJSON = function() {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_2__["Generic_toJSON"])("TextFile", this);
+}
+
+TextFile.fromJSON = function(value) {
+	return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_2__["Generic_fromJSON"])(TextFile, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_2__["Reviver"].constructors.TextFile = TextFile;
+
+function getTextFile(fn, server) {
+    if (!fn.endsWith(".txt")) {fn += ".txt";}
+    for (var i = 0; i < server.textFiles.length; ++i) {
+        if (server.textFiles[i].fn === fn) {
+            return server.textFiles[i];
+        }
+    }
+    return null;
+}
+
+//Returns the TextFile object that was just created
+function createTextFile(fn, txt, server) {
+    if (getTextFile(fn, server) !== null) {
+        console.log("ERROR: createTextFile failed because the specified " +
+                    "server already has a text file with the same fn");
+        return;
+    }
+    var file = new TextFile(fn, txt);
+    server.textFiles.push(file);
+    return file;
+}
+
+function deleteTextFile(fn, server) {
+    if (!fn.endsWith(".txt")) {fn += ".txt";}
+    for (var i = 0; i < server.textFiles.length; ++i) {
+        if (server.textFiles[i].fn === fn) {
+            server.textFiles.splice(i, 1);
+            return true;
+        }
+    }
+    return false;
 }
 
 
 
 
 /***/ }),
-/* 44 */
+/* 42 */
 /*!***************************!*\
   !*** ./src/SourceFile.js ***!
   \***************************/
@@ -54468,7 +54243,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applySourceFile", function() { return applySourceFile; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initSourceFiles", function() { return initSourceFiles; });
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BitNode.js */ 16);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BitNode.js */ 15);
 
 
 
@@ -54663,8 +54438,1371 @@ function applySourceFile(srcFile) {
 
 
 
+/***/ }),
+/* 43 */
+/*!********************************!*\
+  !*** ./src/ActiveScriptsUI.js ***!
+  \********************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setActiveScriptsClickHandlers", function() { return setActiveScriptsClickHandlers; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addActiveScriptsItem", function() { return addActiveScriptsItem; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deleteActiveScriptsItem", function() { return deleteActiveScriptsItem; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateActiveScriptsItems", function() { return updateActiveScriptsItems; });
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
+/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Player.js */ 0);
+/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Server.js */ 10);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+/* harmony import */ var _utils_LogBox_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/LogBox.js */ 51);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6__);
+/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
+
+
+
+
+
+
+
+
+
+
+/* Active Scripts UI*/
+function setActiveScriptsClickHandlers() {
+    //Server panel click handlers
+    var serverPanels = document.getElementsByClassName("active-scripts-server-header");
+    if (serverPanels == null) {
+        console.log("ERROR: Could not find Active Scripts server panels");
+        return;
+    }
+    for (i = 0; i < serverPanels.length; ++i) {
+        serverPanels[i].onclick = function() {
+            this.classList.toggle("active");
+
+            var panel = this.nextElementSibling;
+            if (panel.style.display === "block") {
+                panel.style.display = "none";
+            } else {
+                panel.style.display = "block";
+            }
+        }
+    }
+
+    //Script Panel click handlers
+    var scriptPanels = document.getElementsByClassName("active-scripts-script-header");
+    if (scriptPanels == null) {
+        console.log("ERROR: Could not find Active Scripts panels for individual scripts");
+        return;
+    }
+    for (var i = 0; i < scriptPanels.length; ++i) {
+        scriptPanels[i].onclick = function() {
+            this.classList.toggle("active");
+
+            var panel = this.nextElementSibling;
+            if (panel.style.display === "block") {
+                panel.style.display = "none";
+            } else {
+                panel.style.display = "block";
+            }
+        }
+    }
+}
+
+//Returns the ul element containins all script items for a specific server
+function getActiveScriptsServerList(server) {
+    if (server == null) {return null;}
+    var panelname = "active-scripts-server-panel-" + server.hostname;
+    var item = document.getElementById(panelname + "-script-list");
+    if (item == null) {
+        console.log("ERROR: Cannot find list for: " + server.hostname);
+    }
+    return item;
+}
+
+function createActiveScriptsServerPanel(server) {
+    var panelname = "active-scripts-server-panel-" + server.hostname;
+    var activeScriptsList = document.getElementById("active-scripts-list");
+
+    //Div of entire Panel
+    var panelDiv = document.createElement("div");
+    panelDiv.setAttribute("id", panelname);
+
+    //Panel Header
+    var panelHdr = document.createElement("button");
+    panelHdr.setAttribute("class", "active-scripts-server-header")
+    panelHdr.setAttribute("id", panelname + "-hdr");
+    panelHdr.innerHTML = server.hostname;
+
+    //Panel content
+    var panelContentDiv = document.createElement("div");
+    panelContentDiv.setAttribute("class", "active-scripts-server-panel");
+    panelContentDiv.setAttribute("id", panelname + "-content");
+
+    //List of scripts
+    var panelScriptList = document.createElement("ul");
+    panelScriptList.setAttribute("id", panelname + "-script-list");
+
+    panelContentDiv.appendChild(panelScriptList);
+    panelDiv.appendChild(panelHdr);
+    panelDiv.appendChild(panelContentDiv);
+    activeScriptsList.appendChild(panelDiv);
+
+    setActiveScriptsClickHandlers() //Reset click handlers
+
+    return panelDiv;
+}
+
+//Deletes the info for a particular server (Dropdown header + Panel with all info)
+//in the Active Scripts page if it exists
+function deleteActiveScriptsServerPanel(server) {
+    var panelname = "active-scripts-server-panel-" + server.hostname;
+    var panel = document.getElementById(panelname);
+    if (panel == null) {
+        console.log("No such panel exists: " + panelname);
+        return;
+    }
+
+    //Remove the panel if it has no elements
+    var scriptList = document.getElementById(panelname + "-script-list");
+    if (scriptList.childNodes.length == 0) {
+        panel.parentNode.removeChild(panel);
+    }
+}
+
+function addActiveScriptsItem(workerscript) {
+    //Get server panel
+    var server = Object(_Server_js__WEBPACK_IMPORTED_MODULE_2__["getServer"])(workerscript.serverIp);
+    if (server == null) {
+        console.log("ERROR: Invalid server IP for workerscript.");
+        return;
+    }
+    var panelname = "active-scripts-server-panel-" + server.hostname;
+
+    var panel = document.getElementById(panelname);
+    if (panel == null) {
+        panel = createActiveScriptsServerPanel(server);
+    }
+
+    //Create the element itself. Each element is an accordion collapsible
+    var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
+    for (var i = 0; i < workerscript.args.length; ++i) {
+        itemNameArray.push(String(workerscript.args[i]));
+    }
+    var itemName = itemNameArray.join("-");
+    var item = document.createElement("li");
+    item.setAttribute("id", itemName);
+
+    var btn = document.createElement("button");
+    btn.setAttribute("class", "active-scripts-script-header");
+    btn.setAttribute("id", itemName + "-header");
+    btn.innerHTML = workerscript.name;
+
+    var itemContentDiv = document.createElement("div");
+    itemContentDiv.setAttribute("class", "active-scripts-script-panel");
+    itemContentDiv.setAttribute("id", itemName + "-content");
+
+    item.appendChild(btn);
+    item.appendChild(itemContentDiv);
+
+    createActiveScriptsText(workerscript, itemContentDiv);
+
+    //Append element to list
+    var list = getActiveScriptsServerList(server);
+    list.appendChild(item);
+
+    setActiveScriptsClickHandlers() //Reset click handlers
+}
+
+function deleteActiveScriptsItem(workerscript) {
+    var server = Object(_Server_js__WEBPACK_IMPORTED_MODULE_2__["getServer"])(workerscript.serverIp);
+    if (server == null) {
+        console.log("ERROR: Invalid server IP for workerscript.");
+        return;
+    }
+    var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
+    for (var i = 0; i < workerscript.args.length; ++i) {
+        itemNameArray.push(String(workerscript.args[i]));
+    }
+    var itemName = itemNameArray.join("-");
+    var li = document.getElementById(itemName);
+    if (li == null) {
+        console.log("could not find Active scripts li element for: " + workerscript.name);
+        return;
+    }
+    li.parentNode.removeChild(li);
+    deleteActiveScriptsServerPanel(server);
+}
+
+//Update the ActiveScriptsItems array
+function updateActiveScriptsItems() {
+    var total = 0;
+    for (var i = 0; i < _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__["workerScripts"].length; ++i) {
+        total += updateActiveScriptsItemContent(_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__["workerScripts"][i]);
+    }
+    document.getElementById("active-scripts-total-prod").innerHTML =
+        "Total online production of Active Scripts: " + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6___default()(total).format('$0.000a') + " / sec<br>" +
+        "Total online production since last Aug installation: " +
+        _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6___default()(_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].scriptProdSinceLastAug).format('$0.000a') + " (" +
+        _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_6___default()(_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].scriptProdSinceLastAug / (_Player_js__WEBPACK_IMPORTED_MODULE_1__["Player"].playtimeSinceLastAug/1000)).format('$0.000a') + " / sec)";
+    return total;
+}
+
+//Updates the content of the given item in the Active Scripts list
+function updateActiveScriptsItemContent(workerscript) {
+    var server = Object(_Server_js__WEBPACK_IMPORTED_MODULE_2__["getServer"])(workerscript.serverIp);
+    if (server == null) {
+        console.log("ERROR: Invalid server IP for workerscript.");
+        return;
+    }
+    var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
+    for (var i = 0; i < workerscript.args.length; ++i) {
+        itemNameArray.push(String(workerscript.args[i]));
+    }
+    var itemName = itemNameArray.join("-");
+    var itemContent = document.getElementById(itemName + "-content")
+
+    //Add the updated text back. Returns the total online production rate
+    return updateActiveScriptsText(workerscript, itemContent);
+}
+
+function createActiveScriptsText(workerscript, item) {
+    var itemTextHeader = document.createElement("p");
+    var itemTextStats = document.createElement("p");
+    var itemId = item.id;
+    itemTextStats.setAttribute("id", itemId + "-stats");
+
+    //Server ip/hostname
+    var threads = "Threads: " + workerscript.scriptRef.threads;
+    var args = "Args: " + Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_4__["printArray"])(workerscript.args);
+
+    itemTextHeader.innerHTML = threads + "<br>" + args + "<br>";
+
+    item.appendChild(itemTextHeader);
+    item.appendChild(itemTextStats);
+
+    var onlineMps = updateActiveScriptsText(workerscript, item, itemTextStats);
+
+    var logButton = document.createElement("span");
+    logButton.innerHTML = "Log";
+    var killButton = document.createElement("span");
+    killButton.innerHTML = "Kill script";
+    logButton.setAttribute("class", "active-scripts-button");
+    killButton.setAttribute("class", "active-scripts-button");
+    logButton.addEventListener("click", function() {
+        Object(_utils_LogBox_js__WEBPACK_IMPORTED_MODULE_5__["logBoxCreate"])(workerscript.scriptRef);
+        return false;
+    });
+    killButton.addEventListener("click", function() {
+        Object(_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__["killWorkerScript"])(workerscript.scriptRef, workerscript.scriptRef.scriptRef.server);
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_3__["dialogBoxCreate"])("Killing script, may take a few minutes to complete...");
+        return false;
+    });
+    item.appendChild(logButton);
+    item.appendChild(killButton);
+
+    //Return total online production rate
+    return onlineMps;
+}
+
+function updateActiveScriptsText(workerscript, item, statsEl=null) {
+    var itemId = item.id
+    var itemTextStats = document.getElementById(itemId + "-stats");
+    if (itemTextStats == null || itemTextStats === undefined) {
+        itemTextStats = statsEl;
+    }
+
+    //Updates statistics only
+    //Online
+    var onlineTotalMoneyMade = "Total online production: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(workerscript.scriptRef.onlineMoneyMade, 2);
+    var onlineTotalExpEarned = (Array(26).join(" ") + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(workerscript.scriptRef.onlineExpGained, 2) + " hacking exp").replace( / /g, "&nbsp;");
+
+    var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime;
+    var onlineMpsText = "Online production rate: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(onlineMps, 2) + "/second";
+    var onlineEps = workerscript.scriptRef.onlineExpGained / workerscript.scriptRef.onlineRunningTime;
+    var onlineEpsText = (Array(25).join(" ") + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(onlineEps, 4) + " hacking exp/second").replace( / /g, "&nbsp;");
+
+    //Offline
+    var offlineTotalMoneyMade = "Total offline production: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(workerscript.scriptRef.offlineMoneyMade, 2);
+    var offlineTotalExpEarned = (Array(27).join(" ") + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(workerscript.scriptRef.offlineExpGained, 2) + " hacking exp").replace( / /g, "&nbsp;");
+
+    var offlineMps = workerscript.scriptRef.offlineMoneyMade / workerscript.scriptRef.offlineRunningTime;
+    var offlineMpsText = "Offline production rate: $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(offlineMps, 2) + "/second";
+    var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime;
+    var offlineEpsText = (Array(26).join(" ") + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["formatNumber"])(offlineEps, 4) +  " hacking exp/second").replace( / /g, "&nbsp;");
+
+    itemTextStats.innerHTML = onlineTotalMoneyMade + "<br>" + onlineTotalExpEarned + "<br>" +
+                              onlineMpsText + "<br>" + onlineEpsText + "<br>" + offlineTotalMoneyMade + "<br>" + offlineTotalExpEarned + "<br>" +
+                              offlineMpsText + "<br>" + offlineEpsText + "<br>";
+    return onlineMps;
+}
+
+
+
+
+/***/ }),
+/* 44 */
+/*!************************!*\
+  !*** ./src/RedPill.js ***!
+  \************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "redPillFlag", function() { return redPillFlag; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hackWorldDaemon", function() { return hackWorldDaemon; });
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15);
+/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
+/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Player.js */ 0);
+/* harmony import */ var _Prestige_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Prestige.js */ 57);
+/* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./SourceFile.js */ 42);
+/* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Terminal.js */ 22);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
+
+
+
+
+
+
+
+
+
+
+
+/* RedPill.js
+ *  Implements what happens when you have Red Pill augmentation and then hack the world daemon */
+
+//Returns promise
+function writeRedPillLine(line) {
+    return new Promise(function(resolve, reject) {
+
+        var container = document.getElementById("red-pill-container");
+        var pElem = document.createElement("p");
+        container.appendChild(pElem);
+
+        var promise = writeRedPillLetter(pElem, line, 0);
+        promise.then(function(res) {
+            resolve(res);
+        }, function(e) {
+            reject(e);
+        });
+    });
+}
+
+function writeRedPillLetter(pElem, line, i=0) {
+    return new Promise(function(resolve, reject) {
+        setTimeout(function() {
+            if (i >= line.length) {
+                var textToShow = line.substring(0, i);
+                pElem.innerHTML = "> " + textToShow;
+                return resolve(true);
+            }
+            var textToShow = line.substring(0, i);
+            pElem.innerHTML = "> " + textToShow + "<span class='typed-cursor'> &#9608; </span>";
+            var promise = writeRedPillLetter(pElem, line, i+1);
+            promise.then(function(res) {
+                resolve(res);
+            }, function(e) {
+                reject(e);
+            });
+        }, 30);
+    });
+}
+
+let redPillFlag = false;
+function hackWorldDaemon(currentNodeNumber, flume=false) {
+    redPillFlag = true;
+    _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].loadRedPillContent();
+    return writeRedPillLine("[ERROR] SEMPOOL INVALID").then(function() {
+        return writeRedPillLine("[ERROR] Segmentation Fault");
+    }).then(function() {
+        return writeRedPillLine("[ERROR] SIGKILL RECVD");
+    }).then(function() {
+        return writeRedPillLine("Dumping core...");
+    }).then(function() {
+        return writeRedPillLine("0000 000016FA 174FEE40 29AC8239 384FEA88");
+    }).then(function() {
+        return writeRedPillLine("0010 745F696E 2BBBE394 390E3940 248BEC23");
+    }).then(function() {
+        return writeRedPillLine("0020 7124696B 0000FF69 74652E6F FFFF1111");
+    }).then(function() {
+        return writeRedPillLine("----------------------------------------");
+    }).then(function() {
+        return writeRedPillLine("Failsafe initiated...");
+    }).then(function() {
+        return writeRedPillLine("Restarting BitNode-" + currentNodeNumber + "...");
+    }).then(function() {
+        return writeRedPillLine("...........");
+    }).then(function() {
+        return writeRedPillLine("...........");
+    }).then(function() {
+        return writeRedPillLine("[ERROR] FAILED TO AUTOMATICALLY REBOOT BITNODE");
+    }).then(function() {
+        return writeRedPillLine("..............................................")
+    }).then(function() {
+        return writeRedPillLine("..............................................")
+    }).then(function() {
+        return loadBitVerse(currentNodeNumber, flume);
+    }).catch(function(e){
+        console.log("ERROR: " + e.toString());
+    });
+}
+
+//The bitNode name passed in will have a hyphen between number (e.g. BitNode-1)
+//This needs to be removed
+function giveSourceFile(bitNodeNumber) {
+    var sourceFileKey = "SourceFile"+ bitNodeNumber.toString();
+    var sourceFile = _SourceFile_js__WEBPACK_IMPORTED_MODULE_4__["SourceFiles"][sourceFileKey];
+    if (sourceFile == null) {
+        console.log("ERROR: could not find source file for Bit node: " + bitNodeNumber);
+        return;
+    }
+
+    //Check if player already has this source file
+    var alreadyOwned = false;
+    var ownedSourceFile = null;
+    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].sourceFiles.length; ++i) {
+        if (_Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].sourceFiles[i].n === bitNodeNumber) {
+            alreadyOwned = true;
+            ownedSourceFile = _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].sourceFiles[i];
+            break;
+        }
+    }
+
+    if (alreadyOwned && ownedSourceFile) {
+        if (ownedSourceFile.lvl >= 3) {
+            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__["dialogBoxCreate"])("The Source-File for the BitNode you just destroyed, " + sourceFile.name + ", " +
+                            "is already at max level!");
+        } else {
+            ++ownedSourceFile.lvl;
+            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__["dialogBoxCreate"])(sourceFile.name + " was upgraded to level " + ownedSourceFile.lvl + " for " +
+                            "destroying its corresponding BitNode!");
+        }
+    } else {
+        var playerSrcFile = new _SourceFile_js__WEBPACK_IMPORTED_MODULE_4__["PlayerOwnedSourceFile"](bitNodeNumber, 1);
+        _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].sourceFiles.push(playerSrcFile);
+        if (bitNodeNumber === 5) { //Artificial Intelligence
+            _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].intelligence = 1;
+        }
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__["dialogBoxCreate"])("You received a Source-File for destroying a Bit Node!<br><br>" +
+                        sourceFile.name + "<br><br>" + sourceFile.info);
+    }
+}
+
+function loadBitVerse(destroyedBitNodeNum, flume=false) {
+    //Clear the screen
+    var container = document.getElementById("red-pill-container");
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["removeChildrenFromElement"])(container);
+
+    //Create the Bit Verse
+    var bitVerseImage = document.createElement("pre");
+    var bitNodes = [];
+    for (var i = 1; i <= 12; ++i) {
+        bitNodes.push(createBitNode(i));
+    }
+
+    bitVerseImage.innerHTML =
+    "                          O                          <br>" +
+    "             |  O  O      |      O  O  |             <br>" +
+    "        O    |  | /     __|       \\ |  |    O        <br>" +
+    "      O |    O  | |  O /  |  O    | |  O    | O      <br>" +
+    "    | | |    |  |_/  |/   |   \\_  \\_|  |    | | |    <br>" +
+    "  O | | | O  |  | O__/    |   / \\__ |  |  O | | | O  <br>" +
+    "  | | | | |  |  |   /    /|  O  /  \\|  |  | | | | |  <br>" +
+    "O | | |  \\|  |  O  /   _/ |    /    O  |  |/  | | | O<br>" +
+    "| | | |O  /  |  | O   /   |   O   O |  |  \\  O| | | |<br>" +
+    "| | |/  \\/  / __| | |/ \\  |   \\   | |__ \\  \\/  \\| | |<br>" +
+    " \\| O   |  |_/    |\\|   \\ O    \\__|    \\_|  |   O |/ <br>" +
+    "  | |   |_/       | |    \\|    /  |       \\_|   | |  <br>" +
+    "   \\|   /          \\|     |   /  /          \\   |/   <br>" +
+    "    |  "+bitNodes[9]+"            |     |  /  |            "+bitNodes[10]+"  |    <br>" +
+    "  "+bitNodes[8]+" |  |            |     |     |            |  | "+bitNodes[11]+"  <br>" +
+    "  | |  |            /    / \\    \\            |  | |  <br>" +
+    "   \\|  |           /  "+bitNodes[6]+" /   \\ "+bitNodes[7]+"  \\           |  |/   <br>" +
+    "    \\  |          /  / |     | \\  \\          |  /    <br>" +
+    "     \\ \\JUMP "+bitNodes[4]+"3R |  |  |     |  |  | R3"+bitNodes[5]+" PMUJ/ /     <br>" +
+    "      \\||    |   |  |  |     |  |  |   |    ||/      <br>" +
+    "       \\|     \\_ |  |  |     |  |  | _/     |/       <br>" +
+    "        \\       \\| /    \\   /    \\ |/       /        <br>" +
+    "         "+bitNodes[0]+"       |/   "+bitNodes[1]+"  | |  "+bitNodes[2]+"   \\|       "+bitNodes[3]+"         <br>" +
+    "         |       |    |  | |  |    |       |         <br>" +
+    "          \\JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/          <br><br><br><br>";
+
+
+    /*
+    "                          O                          <br>" +
+    "             |  O  O      |      O  O  |             <br>" +
+    "        O    |  | /     __|       \ |  |    O        <br>" +
+    "      O |    O  | |  O /  |  O    | |  O    | O      <br>" +
+    "    | | |    |  |_/  |/   |   \_  \_|  |    | | |    <br>" +
+    "  O | | | O  |  | O__/    |   / \__ |  |  O | | | O  <br>" +
+    "  | | | | |  |  |   /    /|  O  /  \|  |  | | | | |  <br>" +
+    "O | | |  \|  |  O  /   _/ |    /    O  |  |/  | | | O<br>" +
+    "| | | |O  /  |  | O   /   |   O   O |  |  \  O| | | |<br>" +
+    "| | |/  \/  / __| | |/ \  |   \   | |__ \  \/  \| | |<br>" +
+    " \| O   |  |_/    |\|   \ O    \__|    \_|  |   O |/ <br>" +
+    "  | |   |_/       | |    \|    /  |       \_|   | |  <br>" +
+    "   \|   /          \|     |   /  /          \   |/   <br>" +
+    "    |  O            |     |  /  |            O  |    <br>" +
+    "  O |  |            |     |     |            |  | O  <br>" +
+    "  | |  |            /    / \    \            |  | |  <br>" +
+    "   \|  |           /  O /   \ O  \           |  |/   <br>" +
+    "    \  |          /  / |     | \  \          |  /    <br>" +
+    "     \ \JUMP O3R |  |  |     |  |  | R3O PMUJ/ /     <br>" +
+    "      \||    |   |  |  |     |  |  |   |    ||/      <br>" +
+    "       \|     \_ |  |  |     |  |  | _/     |/       <br>" +
+    "        \       \| /    \   /    \ |/       /        <br>" +
+    "         O       |/   O  | |  O   \|       O         <br>" +
+    "         |       |    |  | |  |    |       |         <br>" +
+    "          \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/          <br>";
+    */
+
+    container.appendChild(bitVerseImage);
+
+    //Bit node event listeners
+    for (var i = 1; i <= 12; ++i) {
+        (function(i) {
+            var elemId = "bitnode-" + i.toString();
+            var elem = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["clearEventListeners"])(elemId);
+            if (elem == null) {return;}
+            if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 || i === 6 || i === 8 || i === 11) {
+                elem.addEventListener("click", function() {
+                    var bitNodeKey = "BitNode" + i;
+                    var bitNode = _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodes"][bitNodeKey];
+                    if (bitNode == null) {
+                        console.log("ERROR: Could not find BitNode object for number: " + i);
+                        return;
+                    }
+                    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxCreate"])("BitNode-" + i + ": " + bitNode.name + "<br><br>" + bitNode.info);
+                    createBitNodeYesNoEventListeners(i, destroyedBitNodeNum, flume);
+                });
+            } else {
+                elem.addEventListener("click", function() {
+                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__["dialogBoxCreate"])("Not yet implemented! Coming soon!")
+                });
+            }
+        }(i)); //Immediate invocation closure
+    }
+
+    //Create lore text
+    return writeRedPillLine("Many decades ago, a humanoid extraterrestial species which we call the Enders descended on the Earth...violently").then(function() {
+        return writeRedPillLine("Our species fought back, but it was futile. The Enders had technology far beyond our own...");
+    }).then(function() {
+        return writeRedPillLine("Instead of killing every last one of us, the human race was enslaved...");
+    }).then(function() {
+        return writeRedPillLine("We were shackled in a digital world, chained into a prison for our minds...");
+    }).then(function() {
+        return writeRedPillLine("Using their advanced technology, the Enders created complex simulations of a virtual reality...");
+    }).then(function() {
+        return writeRedPillLine("Simulations designed to keep us content...ignorant of the truth.");
+    }).then(function() {
+        return writeRedPillLine("Simulations used to trap and suppress our consciousness, to keep us under control...");
+    }).then(function() {
+        return writeRedPillLine("Why did they do this? Why didn't they just end our entire race? We don't know, not yet.");
+    }).then(function() {
+        return writeRedPillLine("Humanity's only hope is to destroy these simulations, destroy the only realities we've ever known...");
+    }).then(function() {
+        return writeRedPillLine("Only then can we begin to fight back...");
+    }).then(function() {
+        return writeRedPillLine("By hacking the daemon that generated your reality, you've just destroyed one simulation, called a BitNode...");
+    }).then(function() {
+        return writeRedPillLine("But there is still a long way to go...");
+    }).then(function() {
+        return writeRedPillLine("The technology the Enders used to enslave the human race wasn't just a single complex simulation...");
+    }).then(function() {
+        return writeRedPillLine("There are tens if not hundreds of BitNodes out there...");
+    }).then(function() {
+        return writeRedPillLine("Each with their own simulations of a reality...");
+    }).then(function() {
+        return writeRedPillLine("Each creating their own universes...a universe of universes");
+    }).then(function() {
+        return writeRedPillLine("And all of which must be destroyed...");
+    }).then(function() {
+        return writeRedPillLine(".......................................");
+    }).then(function() {
+        return writeRedPillLine("Welcome to the Bitverse...");
+    }).then(function() {
+        return writeRedPillLine(" ");
+    }).then(function() {
+        return writeRedPillLine("(Enter a new BitNode using the image above)");
+    }).then(function() {
+        return Promise.resolve(true);
+    }).catch(function(e){
+        console.log("ERROR: " + e.toString());
+    });
+}
+
+
+//Returns string with DOM element for Bit Node
+function createBitNode(n) {
+    var bitNodeStr = "BitNode" + n.toString();
+    var bitNode = _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodes"][bitNodeStr];
+    if (bitNode == null) {return "O";}
+    return  "<a class='bitnode tooltip' id='bitnode-" + bitNode.number.toString() + "'><strong>O</strong>" +
+             "<span class='tooltiptext'>" +
+             "<strong>BitNode-" + bitNode.number.toString() + "<br>" + bitNode.name+ "</strong><br>" +
+             bitNode.desc + "<br>" +
+             "</span></a>";
+}
+
+function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode, flume=false) {
+    var yesBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxGetYesButton"])();
+    yesBtn.innerHTML = "Enter BitNode-" + newBitNode;
+    yesBtn.addEventListener("click", function() {
+        if (!flume) {
+            giveSourceFile(destroyedBitNode);
+        } else {
+            //If player used flume, subtract 5 int exp. The prestigeSourceFile()
+            //function below grants 5 int exp, so this allows sets net gain to 0
+            _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].gainIntelligenceExp(-5);
+        }
+        redPillFlag = false;
+        var container = document.getElementById("red-pill-container");
+        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["removeChildrenFromElement"])(container);
+
+        //Set new Bit Node
+        _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].bitNodeN = newBitNode;
+        console.log("Entering Bit Node " + _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].bitNodeN);
+
+        //Reenable terminal
+        $("#hack-progress-bar").attr('id', "old-hack-progress-bar");
+        $("#hack-progress").attr('id', "old-hack-progress");
+        document.getElementById("terminal-input-td").innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
+        $('input[class=terminal-input]').prop('disabled', false);
+
+        _Terminal_js__WEBPACK_IMPORTED_MODULE_5__["Terminal"].hackFlag = false;
+
+        Object(_Prestige_js__WEBPACK_IMPORTED_MODULE_3__["prestigeSourceFile"])();
+        Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxClose"])();
+    });
+    var noBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxGetNoButton"])();
+    noBtn.innerHTML = "Back";
+    noBtn.addEventListener("click", function() {
+        Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxClose"])();
+    });
+
+}
+
+
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
+
 /***/ }),
 /* 45 */
+/*!******************************!*\
+  !*** ./src/NetscriptPort.js ***!
+  \******************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NetscriptPort", function() { return NetscriptPort; });
+/* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Settings.js */ 24);
+
+
+function NetscriptPort() {
+    this.data = [];
+}
+
+NetscriptPort.prototype.write = function(data) {
+    this.data.push(data);
+    if (this.data.length > _Settings_js__WEBPACK_IMPORTED_MODULE_0__["Settings"].MaxPortCapacity) {
+        return this.data.shift();
+    }
+    return null;
+}
+
+NetscriptPort.prototype.tryWrite = function(data) {
+    if (this.data.length >= _Settings_js__WEBPACK_IMPORTED_MODULE_0__["Settings"].MaxPortCapacity) {
+        return false;
+    }
+    this.data.push(data);
+    return true;
+}
+
+NetscriptPort.prototype.read = function() {
+    if (this.data.length === 0) {
+        return "NULL PORT DATA";
+    }
+    return this.data.shift();
+}
+
+NetscriptPort.prototype.peek = function() {
+    if (this.data.length === 0) {
+        return "NULL PORT DATA";
+    } else {
+        var foo = this.data.slice();
+        return foo[0];
+    }
+}
+
+NetscriptPort.prototype.full = function() {
+    return this.data.length == _Settings_js__WEBPACK_IMPORTED_MODULE_0__["Settings"].MaxPortCapacity;
+}
+
+NetscriptPort.prototype.empty = function() {
+    return this.data.length === 0;
+}
+
+NetscriptPort.prototype.clear = function() {
+    this.data.length = 0;
+}
+
+
+
+
+/***/ }),
+/* 46 */
+/*!***************************!*\
+  !*** ./src/SaveObject.js ***!
+  \***************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "saveObject", function() { return saveObject; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadGame", function() { return loadGame; });
+/* harmony import */ var _Alias_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Alias.js */ 30);
+/* harmony import */ var _Company_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Company.js */ 9);
+/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Constants.js */ 3);
+/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./engine.js */ 5);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Faction.js */ 11);
+/* harmony import */ var _Fconf_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Fconf.js */ 34);
+/* harmony import */ var _Gang_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Gang.js */ 36);
+/* harmony import */ var _HacknetNode_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./HacknetNode.js */ 39);
+/* harmony import */ var _Message_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Message.js */ 27);
+/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Player.js */ 0);
+/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Script.js */ 28);
+/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./Server.js */ 10);
+/* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Settings.js */ 24);
+/* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
+/* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./StockMarket.js */ 21);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_GameOptions_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../utils/GameOptions.js */ 54);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
+/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
+/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/decimal.js */ 23);
+/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_20__);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* SaveObject.js
+ *  Defines the object used to save/load games
+ */
+let saveObject = new BitburnerSaveObject();
+
+function BitburnerSaveObject() {
+    this.PlayerSave                 = "";
+    this.AllServersSave             = "";
+    this.CompaniesSave              = "";
+    this.FactionsSave               = "";
+    this.SpecialServerIpsSave       = "";
+    this.AliasesSave                = "";
+    this.GlobalAliasesSave          = "";
+    this.MessagesSave               = "";
+    this.StockMarketSave            = "";
+    this.SettingsSave               = "";
+    this.FconfSettingsSave          = "";
+    this.VersionSave                = "";
+    this.AllGangsSave               = "";
+}
+
+BitburnerSaveObject.prototype.saveGame = function(db) {
+    this.PlayerSave                 = JSON.stringify(_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"]);
+
+    //Delete all logs from all running scripts
+    var TempAllServers = JSON.parse(JSON.stringify(_Server_js__WEBPACK_IMPORTED_MODULE_11__["AllServers"]), _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+    for (var ip in TempAllServers) {
+        var server = TempAllServers[ip];
+        if (server == null) {continue;}
+        for (var i = 0; i < server.runningScripts.length; ++i) {
+            var runningScriptObj = server.runningScripts[i];
+            runningScriptObj.logs.length = 0;
+            runningScriptObj.logs = [];
+        }
+    }
+
+    this.AllServersSave             = JSON.stringify(TempAllServers);
+    this.CompaniesSave              = JSON.stringify(_Company_js__WEBPACK_IMPORTED_MODULE_1__["Companies"]);
+    this.FactionsSave               = JSON.stringify(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["Factions"]);
+    this.SpecialServerIpsSave       = JSON.stringify(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__["SpecialServerIps"]);
+    this.AliasesSave                = JSON.stringify(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["Aliases"]);
+    this.GlobalAliasesSave          = JSON.stringify(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["GlobalAliases"]);
+    this.MessagesSave               = JSON.stringify(_Message_js__WEBPACK_IMPORTED_MODULE_8__["Messages"]);
+    this.StockMarketSave            = JSON.stringify(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["StockMarket"]);
+    this.SettingsSave               = JSON.stringify(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["Settings"]);
+    this.FconfSettingsSave          = JSON.stringify(_Fconf_js__WEBPACK_IMPORTED_MODULE_5__["FconfSettings"]);
+    this.VersionSave                = JSON.stringify(_Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version);
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].inGang()) {
+        this.AllGangsSave           = JSON.stringify(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["AllGangs"]);
+    }
+    var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
+
+    //We'll save to both localstorage and indexedDb
+    var objectStore = db.transaction(["savestring"], "readwrite").objectStore("savestring");
+    var request = objectStore.put(saveString, "save");
+
+    request.onerror = function(e) {
+        console.log("Error saving game to IndexedDB: " + e);
+    }
+
+    request.onsuccess = function(e) {
+        //console.log("Saved game to IndexedDB!");
+    }
+
+    try {
+        window.localStorage.setItem("bitburnerSave", saveString);
+        //console.log("Saved game to LocalStorage!");
+    } catch(e) {
+        if (e.code == 22) {
+            _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].createStatusText("Save failed for localStorage! Check console(F12)");
+            console.log("Failed to save game to localStorage because the size of the save file " +
+                        "is too large. However, the game will still be saved to IndexedDb if your browser " +
+                        "supports it. If you would like to save to localStorage as well, then " +
+                        "consider killing several of your scripts to " +
+                        "fix this, or increasing the size of your browsers localStorage");
+        }
+    }
+
+    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].createStatusText("Game saved!");
+}
+
+function loadGame(saveString) {
+    if (saveString === "" || saveString == null || saveString === undefined) {
+        if (!window.localStorage.getItem("bitburnerSave")) {
+            console.log("No save file to load");
+            return false;
+        }
+        saveString = decodeURIComponent(escape(atob(window.localStorage.getItem("bitburnerSave"))));
+        console.log("Loading game from localStorage");
+    } else {
+        saveString = decodeURIComponent(escape(atob(saveString)));
+        console.log("Loading game from IndexedDB");
+    }
+
+    var saveObj = JSON.parse(saveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+
+    Object(_Player_js__WEBPACK_IMPORTED_MODULE_9__["loadPlayer"])(saveObj.PlayerSave);
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_11__["loadAllServers"])(saveObj.AllServersSave);
+    Object(_Company_js__WEBPACK_IMPORTED_MODULE_1__["loadCompanies"])(saveObj.CompaniesSave);
+    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["loadFactions"])(saveObj.FactionsSave);
+    Object(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__["loadSpecialServerIps"])(saveObj.SpecialServerIpsSave);
+
+    if (saveObj.hasOwnProperty("AliasesSave")) {
+        try {
+            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])(saveObj.AliasesSave);
+        } catch(e) {
+            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])("");
+        }
+    } else {
+        Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])("");
+    }
+    if (saveObj.hasOwnProperty("GlobalAliasesSave")) {
+        try {
+            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])(saveObj.GlobalAliasesSave);
+        } catch(e) {
+            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])("");
+        }
+    } else {
+        Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])("");
+    }
+    if (saveObj.hasOwnProperty("MessagesSave")) {
+        try {
+            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["loadMessages"])(saveObj.MessagesSave);
+        } catch(e) {
+            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
+        }
+    } else {
+        Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
+    }
+    if (saveObj.hasOwnProperty("StockMarketSave")) {
+        try {
+            Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])(saveObj.StockMarketSave);
+        } catch(e) {
+            Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])("");
+        }
+    } else {
+        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])("");
+    }
+    if (saveObj.hasOwnProperty("SettingsSave")) {
+        try {
+            Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["loadSettings"])(saveObj.SettingsSave);
+        } catch(e) {
+            console.log("ERROR: Failed to parse Settings. Re-initing default values");
+            Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["initSettings"])();
+        }
+    } else {
+        Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["initSettings"])();
+    }
+    if (saveObj.hasOwnProperty("FconfSettingsSave")) {
+        try {
+            Object(_Fconf_js__WEBPACK_IMPORTED_MODULE_5__["loadFconf"])(saveObj.FconfSettingsSave);
+        } catch(e) {
+            console.log("ERROR: Failed to parse .fconf Settings.");
+        }
+    }
+    if (saveObj.hasOwnProperty("VersionSave")) {
+        try {
+            var ver = JSON.parse(saveObj.VersionSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+            if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == null || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN === 0) {
+                _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].setBitNodeNumber(1);
+            }
+            if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
+                console.log("Evaluating changes needed for version compatibility");
+                if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].augmentations.length > 0 || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].queuedAugmentations.length > 0 ||
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].sourceFiles.length > 0) {
+                    //If you have already purchased an Aug...you are far enough in the game
+                    //that everything should be available
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstFacInvRecvd = true;
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstAugPurchased = true;
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstJobRecvd = true;
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstTimeTraveled = true;
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstProgramAvailable = true;
+                } else  {
+                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].factions.length > 0 || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].factionInvitations.length > 0) {
+                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstFacInvRecvd = true;
+                    }
+                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].companyName !== "" || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].companyPosition !== "") {
+                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstJobRecvd = true;
+                    }
+                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].hacking_skill >= 25) {
+                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstScriptAvailable = true;
+                    }
+                }
+            }
+            if (ver != _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version) {
+                createNewUpdateText();
+            }
+        } catch(e) {
+            createNewUpdateText();
+        }
+    } else {
+        createNewUpdateText();
+    }
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
+        try {
+            Object(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["loadAllGangs"])(saveObj.AllGangsSave);
+        } catch(e) {
+            console.log("ERROR: Failed to parse AllGangsSave: " + e);
+        }
+    }
+
+    return true;
+}
+
+function loadImportedGame(saveObj, saveString) {
+    var tempSaveObj = null;
+    var tempPlayer = null;
+    var tempAllServers = null;
+    var tempCompanies = null;
+    var tempFactions = null;
+    var tempSpecialServerIps = null;
+    var tempAliases = null;
+    var tempGlobalAliases = null;
+    var tempMessages = null;
+    var tempStockMarket = null;
+    var tempAllGangs = null;
+
+    //Check to see if the imported save file can be parsed. If any
+    //errors are caught it will fail
+    try {
+        var decodedSaveString = decodeURIComponent(escape(atob(saveString)));
+        tempSaveObj = new BitburnerSaveObject();
+        tempSaveObj = JSON.parse(decodedSaveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+
+        tempPlayer = JSON.parse(tempSaveObj.PlayerSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+
+        //Parse Decimal.js objects
+        tempPlayer.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.money);
+        tempPlayer.total_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.total_money);
+        tempPlayer.lifetime_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.lifetime_money);
+
+        tempAllServers          = JSON.parse(tempSaveObj.AllServersSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+        tempCompanies           = JSON.parse(tempSaveObj.CompaniesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+        tempFactions            = JSON.parse(tempSaveObj.FactionsSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+        tempSpecialServerIps    = JSON.parse(tempSaveObj.SpecialServerIpsSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+        if (tempSaveObj.hasOwnProperty("AliasesSave")) {
+            try {
+                tempAliases         = JSON.parse(tempSaveObj.AliasesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+            } catch(e) {
+                console.log("Parsing Aliases save failed: " + e);
+                tempAliases = {};
+            }
+        } else {
+            tempAliases = {};
+        }
+        if (tempSaveObj.hasOwnProperty("GlobalAliases")) {
+            try {
+                tempGlobalAliases   = JSON.parse(tempSaveObj.AliasesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+            } catch(e) {
+                console.log("Parsing Global Aliases save failed: " + e);
+                tempGlobalAliases = {};
+            }
+        } else {
+            tempGlobalAliases = {};
+        }
+        if (tempSaveObj.hasOwnProperty("MessagesSave")) {
+            try {
+                tempMessages        = JSON.parse(tempSaveObj.MessagesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+            } catch(e) {
+                console.log("Parsing Messages save failed: " + e);
+                Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
+            }
+        } else {
+            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
+        }
+        if (saveObj.hasOwnProperty("StockMarketSave")) {
+            try {
+                tempStockMarket     = JSON.parse(tempSaveObj.StockMarketSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+            } catch(e) {
+                console.log("Parsing StockMarket save failed: " + e);
+                tempStockMarket     = {};
+            }
+        } else {
+            tempStockMarket = {};
+        }
+        if (tempSaveObj.hasOwnProperty("VersionSave")) {
+            try {
+                var ver = JSON.parse(tempSaveObj.VersionSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+                if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
+                    if (tempPlayer.bitNodeN == null || tempPlayer.bitNodeN == 0) {
+                        tempPlayer.bitNodeN = 1;
+                    }
+                    if (tempPlayer.sourceFiles == null) {
+                        tempPlayer.sourceFiles = [];
+                    }
+                }
+                if (ver != _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version) {
+                    //createNewUpdateText();
+                }
+            } catch(e) {
+                console.log("Parsing Version save failed: " + e);
+                //createNewUpdateText();
+            }
+        } else {
+            //createNewUpdateText();
+        }
+        if (tempPlayer.bitNodeN == 2 && tempPlayer.inGang() && tempSaveObj.hasOwnProperty("AllGangsSave")) {
+            try {
+                Object(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["loadAllGangs"])(tempSaveObj.AllGangsSave);
+            } catch(e) {
+                console.log("ERROR: Failed to parse AllGangsSave: " + e);
+            }
+        }
+    } catch(e) {
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("Error importing game: " + e.toString());
+        return false;
+    }
+
+    //Since the save file is valid, load everything for real
+    saveString = decodeURIComponent(escape(atob(saveString)));
+    saveObj = JSON.parse(saveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+
+    Object(_Player_js__WEBPACK_IMPORTED_MODULE_9__["loadPlayer"])(saveObj.PlayerSave);
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_11__["loadAllServers"])(saveObj.AllServersSave);
+    Object(_Company_js__WEBPACK_IMPORTED_MODULE_1__["loadCompanies"])(saveObj.CompaniesSave);
+    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["loadFactions"])(saveObj.FactionsSave);
+    Object(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__["loadSpecialServerIps"])(saveObj.SpecialServerIpsSave);
+
+    if (saveObj.hasOwnProperty("AliasesSave")) {
+        try {
+            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])(saveObj.AliasesSave);
+        } catch(e) {
+            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])("");
+        }
+    } else {
+        Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])("");
+    }
+    if (saveObj.hasOwnProperty("GlobalAliasesSave")) {
+        try {
+            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])(saveObj.GlobalAliasesSave);
+        } catch(e) {
+            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])("");
+        }
+    } else {
+        Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])("");
+    }
+    if (saveObj.hasOwnProperty("MessagesSave")) {
+        try {
+            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["loadMessages"])(saveObj.MessagesSave);
+        } catch(e) {
+            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
+        }
+    } else {
+        Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
+    }
+    if (saveObj.hasOwnProperty("StockMarketSave")) {
+        try {
+            Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])(saveObj.StockMarketSave);
+        } catch(e) {
+            Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])("");
+        }
+    } else {
+        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])("");
+    }
+    if (saveObj.hasOwnProperty("SettingsSave")) {
+        try {
+            Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["loadSettings"])(saveObj.SettingsSave);
+        } catch(e) {
+            Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["initSettings"])();
+        }
+    } else {
+        Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["initSettings"])();
+    }
+    if (saveObj.hasOwnProperty("FconfSettingsSave")) {
+        try {
+            Object(_Fconf_js__WEBPACK_IMPORTED_MODULE_5__["loadFconf"])(saveObj.FconfSettingsSave);
+        } catch(e) {
+            console.log("ERROR: Failed to load .fconf settings when importing");
+        }
+    }
+    if (saveObj.hasOwnProperty("VersionSave")) {
+        try {
+            var ver = JSON.parse(saveObj.VersionSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
+            if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == null || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 0) {
+                _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].setBitNodeNumber(1);
+
+            }
+            if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
+                console.log("Evaluating changes needed for version compatibility");
+                if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].augmentations.length > 0 || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].queuedAugmentations.length > 0 ||
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].sourceFiles.length > 0) {
+                    //If you have already purchased an Aug...you are far enough in the game
+                    //that everything should be available
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstFacInvRecvd = true;
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstAugPurchased = true;
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstJobRecvd = true;
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstTimeTraveled = true;
+                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstProgramAvailable = true;
+                } else  {
+                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].factions.length > 0 || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].factionInvitations.length > 0) {
+                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstFacInvRecvd = true;
+                    }
+                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].companyName !== "" || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].companyPosition !== "") {
+                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstJobRecvd = true;
+                    }
+                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].hacking_skill >= 25) {
+                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstScriptAvailable = true;
+                    }
+                }
+            }
+            if (ver != _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version) {
+                createNewUpdateText();
+            }
+        } catch(e) {
+            createNewUpdateText();
+        }
+    } else {
+        createNewUpdateText();
+    }
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
+        try {
+            Object(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["loadAllGangs"])(saveObj.AllGangsSave);
+        } catch(e) {
+            console.log("ERROR: Failed to parse AllGangsSave: " + e);
+        }
+    }
+
+    var popupId = "import-game-restart-game-notice";
+    var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["createElement"])("p", {
+        innerText:"Imported game! I would suggest saving the game and then reloading the page " +
+                 "to make sure everything runs smoothly"
+    });
+    var gotitBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["createElement"])("a", {
+        class:"a-link-button", float:"right", padding:"6px", innerText:"Got it!",
+        clickListener:()=>{
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["removeElementById"])(popupId);
+        }
+    });
+    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["createPopup"])(popupId, [txt, gotitBtn]);
+    Object(_utils_GameOptions_js__WEBPACK_IMPORTED_MODULE_16__["gameOptionsBoxClose"])();
+
+    //Re-start game
+    console.log("Importing game");
+    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].setDisplayElements();    //Sets variables for important DOM elements
+    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].init();                  //Initialize buttons, work, etc.
+    _Company_js__WEBPACK_IMPORTED_MODULE_1__["CompanyPositions"].init();
+
+    //Calculate the number of cycles have elapsed while offline
+    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._lastUpdate = new Date().getTime();
+    var lastUpdate = _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].lastUpdate;
+    var numCyclesOffline = Math.floor((_engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._lastUpdate - lastUpdate) / _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._idleSpeed);
+
+    /* Process offline progress */
+    var offlineProductionFromScripts = Object(_Script_js__WEBPACK_IMPORTED_MODULE_10__["loadAllRunningScripts"])();    //This also takes care of offline production for those scripts
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].isWorking) {
+        console.log("work() called in load() for " + numCyclesOffline * _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._idleSpeed + " milliseconds");
+        if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeFaction) {
+            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workForFaction(numCyclesOffline);
+        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeCreateProgram) {
+            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].createProgramWork(numCyclesOffline);
+        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeStudyClass) {
+            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].takeClass(numCyclesOffline);
+        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeCrime) {
+            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].commitCrime(numCyclesOffline);
+        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeCompanyPartTime) {
+            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workPartTime(numCyclesOffline);
+        } else {
+            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].work(numCyclesOffline);
+        }
+    }
+
+    //Hacknet Nodes offline progress
+    var offlineProductionFromHacknetNodes = Object(_HacknetNode_js__WEBPACK_IMPORTED_MODULE_7__["processAllHacknetNodeEarnings"])(numCyclesOffline);
+
+    //Passive faction rep gain offline
+    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["processPassiveFactionRepGain"])(numCyclesOffline);
+
+    //Update total playtime
+    var time = numCyclesOffline * _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._idleSpeed;
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].totalPlaytime == null) {_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].totalPlaytime = 0;}
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].playtimeSinceLastAug == null) {_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].playtimeSinceLastAug = 0;}
+    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].totalPlaytime += time;
+    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].playtimeSinceLastAug += time;
+
+    //Re-apply augmentations
+    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].reapplyAllAugmentations();
+
+    //Clear terminal
+    $("#terminal tr:not(:last)").remove();
+
+    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].lastUpdate = _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._lastUpdate;
+    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].start();                 //Run main game loop and Scripts loop
+    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("While you were offline, your scripts generated $" +
+                    Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__["formatNumber"])(offlineProductionFromScripts, 2) + " and your Hacknet Nodes generated $" +
+                    Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__["formatNumber"])(offlineProductionFromHacknetNodes, 2));
+    return true;
+}
+
+BitburnerSaveObject.prototype.exportGame = function() {
+    this.PlayerSave                 = JSON.stringify(_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"]);
+    this.AllServersSave             = JSON.stringify(_Server_js__WEBPACK_IMPORTED_MODULE_11__["AllServers"]);
+    this.CompaniesSave              = JSON.stringify(_Company_js__WEBPACK_IMPORTED_MODULE_1__["Companies"]);
+    this.FactionsSave               = JSON.stringify(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["Factions"]);
+    this.SpecialServerIpsSave       = JSON.stringify(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__["SpecialServerIps"]);
+    this.AliasesSave                = JSON.stringify(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["Aliases"]);
+    this.GlobalAliasesSave          = JSON.stringify(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["GlobalAliases"]);
+    this.MessagesSave               = JSON.stringify(_Message_js__WEBPACK_IMPORTED_MODULE_8__["Messages"]);
+    this.StockMarketSave            = JSON.stringify(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["StockMarket"]);
+    this.SettingsSave               = JSON.stringify(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["Settings"]);
+    this.VersionSave                = JSON.stringify(_Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version);
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].inGang()) {
+        this.AllGangsSave           = JSON.stringify(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["AllGangs"]);
+    }
+
+    var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
+    var filename = "bitburnerSave.json";
+    var file = new Blob([saveString], {type: 'text/plain'});
+    if (window.navigator.msSaveOrOpenBlob) {// IE10+
+        window.navigator.msSaveOrOpenBlob(file, filename);
+    } else { // Others
+        var a = document.createElement("a"),
+                url = URL.createObjectURL(file);
+        a.href = url;
+        a.download = "bitburnerSave.json";
+        document.body.appendChild(a);
+        a.click();
+        setTimeout(function() {
+            document.body.removeChild(a);
+            window.URL.revokeObjectURL(url);
+        }, 0);
+    }
+}
+
+BitburnerSaveObject.prototype.importGame = function() {
+    if (window.File && window.FileReader && window.FileList && window.Blob) {
+        var fileSelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["clearEventListeners"])("import-game-file-selector");
+        fileSelector.addEventListener("change", openImportFileHandler, false);
+        $("#import-game-file-selector").click();
+    } else {
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("ERR: Your browser does not support HTML5 File API. Cannot import.");
+    }
+
+}
+
+BitburnerSaveObject.prototype.deleteGame = function(db) {
+    //Delete from local storage
+    if (window.localStorage.getItem("bitburnerSave")) {
+        window.localStorage.removeItem("bitburnerSave");
+    }
+
+    //Delete from indexedDB
+    var request = db.transaction(["savestring"], "readwrite").objectStore("savestring").delete("save");
+    request.onsuccess = function(e) {
+        console.log("Successfully deleted save from indexedDb");
+    }
+    request.onerror = function(e) {
+        console.log("Failed to delete save from indexedDb: " + e);
+    }
+    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].createStatusText("Game deleted!");
+}
+
+function createNewUpdateText() {
+    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("New update!<br>" +
+                    "Please report any bugs/issues through the github repository " +
+                    "or the Bitburner subreddit (reddit.com/r/bitburner).<br><br>" +
+                    _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].LatestUpdate);
+}
+
+
+BitburnerSaveObject.prototype.toJSON = function() {
+    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Generic_toJSON"])("BitburnerSaveObject", this);
+}
+
+BitburnerSaveObject.fromJSON = function(value) {
+    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Generic_fromJSON"])(BitburnerSaveObject, value.data);
+}
+
+_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"].constructors.BitburnerSaveObject = BitburnerSaveObject;
+
+//Import game
+
+function openImportFileHandler(evt) {
+    var file = evt.target.files[0];
+    if (!file) {
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("Invalid file selected");
+        return;
+    }
+
+    var reader = new FileReader();
+    reader.onload = function(e) {
+        var contents = e.target.result;
+        loadImportedGame(saveObject, contents);
+    };
+    reader.readAsText(file);
+}
+
+
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
+
+/***/ }),
+/* 47 */
 /*!****************************!*\
   !*** ./src/Bladeburner.js ***!
   \****************************/
@@ -54675,15 +55813,15 @@ __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Bladeburner", function() { return Bladeburner; });
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Faction.js */ 14);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Faction.js */ 11);
 /* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Location.js */ 4);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _RedPill_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./RedPill.js */ 49);
+/* harmony import */ var _RedPill_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./RedPill.js */ 44);
 /* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Terminal.js */ 22);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
 /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/numeral.min.js */ 12);
+/* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/numeral.min.js */ 13);
 /* harmony import */ var _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10__);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
 
@@ -58275,10 +59413,10 @@ function initBladeburner() {
 
 
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
 
 /***/ }),
-/* 46 */
+/* 48 */
 /*!***********************************************!*\
   !*** ./node_modules/pako/lib/utils/common.js ***!
   \***********************************************/
@@ -58393,7 +59531,36 @@ exports.setTyped(TYPED_OK);
 
 
 /***/ }),
-/* 47 */
+/* 49 */
+/*!***********************************!*\
+  !*** (webpack)/buildin/global.js ***!
+  \***********************************/
+/***/ (function(module, exports) {
+
+var g;
+
+// This works in non-strict mode
+g = (function() {
+	return this;
+})();
+
+try {
+	// This works if eval is allowed (see CSP)
+	g = g || Function("return this")() || (1, eval)("this");
+} catch (e) {
+	// This works if the window reference is available
+	if (typeof window === "object") g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
+
+
+/***/ }),
+/* 50 */
 /*!*******************************************!*\
   !*** ./node_modules/jszip/lib/support.js ***!
   \*******************************************/
@@ -58434,393 +59601,15 @@ else {
 }
 
 try {
-    exports.nodestream = !!__webpack_require__(/*! readable-stream */ 105).Readable;
+    exports.nodestream = !!__webpack_require__(/*! readable-stream */ 106).Readable;
 } catch(e) {
     exports.nodestream = false;
 }
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ 59).Buffer))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ 61).Buffer))
 
 /***/ }),
-/* 48 */
-/*!***********************************!*\
-  !*** (webpack)/buildin/global.js ***!
-  \***********************************/
-/***/ (function(module, exports) {
-
-var g;
-
-// This works in non-strict mode
-g = (function() {
-	return this;
-})();
-
-try {
-	// This works if eval is allowed (see CSP)
-	g = g || Function("return this")() || (1, eval)("this");
-} catch (e) {
-	// This works if the window reference is available
-	if (typeof window === "object") g = window;
-}
-
-// g can still be undefined, but nothing to do about it...
-// We return undefined, instead of nothing here, so it's
-// easier to handle this case. if(!global) { ...}
-
-module.exports = g;
-
-
-/***/ }),
-/* 49 */
-/*!************************!*\
-  !*** ./src/RedPill.js ***!
-  \************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "redPillFlag", function() { return redPillFlag; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hackWorldDaemon", function() { return hackWorldDaemon; });
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 16);
-/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _Prestige_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Prestige.js */ 67);
-/* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./SourceFile.js */ 44);
-/* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Terminal.js */ 22);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
-
-
-
-
-
-
-
-
-
-
-
-/* RedPill.js
- *  Implements what happens when you have Red Pill augmentation and then hack the world daemon */
-
-//Returns promise
-function writeRedPillLine(line) {
-    return new Promise(function(resolve, reject) {
-
-        var container = document.getElementById("red-pill-container");
-        var pElem = document.createElement("p");
-        container.appendChild(pElem);
-
-        var promise = writeRedPillLetter(pElem, line, 0);
-        promise.then(function(res) {
-            resolve(res);
-        }, function(e) {
-            reject(e);
-        });
-    });
-}
-
-function writeRedPillLetter(pElem, line, i=0) {
-    return new Promise(function(resolve, reject) {
-        setTimeout(function() {
-            if (i >= line.length) {
-                var textToShow = line.substring(0, i);
-                pElem.innerHTML = "> " + textToShow;
-                return resolve(true);
-            }
-            var textToShow = line.substring(0, i);
-            pElem.innerHTML = "> " + textToShow + "<span class='typed-cursor'> &#9608; </span>";
-            var promise = writeRedPillLetter(pElem, line, i+1);
-            promise.then(function(res) {
-                resolve(res);
-            }, function(e) {
-                reject(e);
-            });
-        }, 30);
-    });
-}
-
-let redPillFlag = false;
-function hackWorldDaemon(currentNodeNumber, flume=false) {
-    redPillFlag = true;
-    _engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].loadRedPillContent();
-    return writeRedPillLine("[ERROR] SEMPOOL INVALID").then(function() {
-        return writeRedPillLine("[ERROR] Segmentation Fault");
-    }).then(function() {
-        return writeRedPillLine("[ERROR] SIGKILL RECVD");
-    }).then(function() {
-        return writeRedPillLine("Dumping core...");
-    }).then(function() {
-        return writeRedPillLine("0000 000016FA 174FEE40 29AC8239 384FEA88");
-    }).then(function() {
-        return writeRedPillLine("0010 745F696E 2BBBE394 390E3940 248BEC23");
-    }).then(function() {
-        return writeRedPillLine("0020 7124696B 0000FF69 74652E6F FFFF1111");
-    }).then(function() {
-        return writeRedPillLine("----------------------------------------");
-    }).then(function() {
-        return writeRedPillLine("Failsafe initiated...");
-    }).then(function() {
-        return writeRedPillLine("Restarting BitNode-" + currentNodeNumber + "...");
-    }).then(function() {
-        return writeRedPillLine("...........");
-    }).then(function() {
-        return writeRedPillLine("...........");
-    }).then(function() {
-        return writeRedPillLine("[ERROR] FAILED TO AUTOMATICALLY REBOOT BITNODE");
-    }).then(function() {
-        return writeRedPillLine("..............................................")
-    }).then(function() {
-        return writeRedPillLine("..............................................")
-    }).then(function() {
-        return loadBitVerse(currentNodeNumber, flume);
-    }).catch(function(e){
-        console.log("ERROR: " + e.toString());
-    });
-}
-
-//The bitNode name passed in will have a hyphen between number (e.g. BitNode-1)
-//This needs to be removed
-function giveSourceFile(bitNodeNumber) {
-    var sourceFileKey = "SourceFile"+ bitNodeNumber.toString();
-    var sourceFile = _SourceFile_js__WEBPACK_IMPORTED_MODULE_4__["SourceFiles"][sourceFileKey];
-    if (sourceFile == null) {
-        console.log("ERROR: could not find source file for Bit node: " + bitNodeNumber);
-        return;
-    }
-
-    //Check if player already has this source file
-    var alreadyOwned = false;
-    var ownedSourceFile = null;
-    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].sourceFiles.length; ++i) {
-        if (_Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].sourceFiles[i].n === bitNodeNumber) {
-            alreadyOwned = true;
-            ownedSourceFile = _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].sourceFiles[i];
-            break;
-        }
-    }
-
-    if (alreadyOwned && ownedSourceFile) {
-        if (ownedSourceFile.lvl >= 3) {
-            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__["dialogBoxCreate"])("The Source-File for the BitNode you just destroyed, " + sourceFile.name + ", " +
-                            "is already at max level!");
-        } else {
-            ++ownedSourceFile.lvl;
-            Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__["dialogBoxCreate"])(sourceFile.name + " was upgraded to level " + ownedSourceFile.lvl + " for " +
-                            "destroying its corresponding BitNode!");
-        }
-    } else {
-        var playerSrcFile = new _SourceFile_js__WEBPACK_IMPORTED_MODULE_4__["PlayerOwnedSourceFile"](bitNodeNumber, 1);
-        _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].sourceFiles.push(playerSrcFile);
-        if (bitNodeNumber === 5) { //Artificial Intelligence
-            _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].intelligence = 1;
-        }
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__["dialogBoxCreate"])("You received a Source-File for destroying a Bit Node!<br><br>" +
-                        sourceFile.name + "<br><br>" + sourceFile.info);
-    }
-}
-
-function loadBitVerse(destroyedBitNodeNum, flume=false) {
-    //Clear the screen
-    var container = document.getElementById("red-pill-container");
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["removeChildrenFromElement"])(container);
-
-    //Create the Bit Verse
-    var bitVerseImage = document.createElement("pre");
-    var bitNodes = [];
-    for (var i = 1; i <= 12; ++i) {
-        bitNodes.push(createBitNode(i));
-    }
-
-    bitVerseImage.innerHTML =
-    "                          O                          <br>" +
-    "             |  O  O      |      O  O  |             <br>" +
-    "        O    |  | /     __|       \\ |  |    O        <br>" +
-    "      O |    O  | |  O /  |  O    | |  O    | O      <br>" +
-    "    | | |    |  |_/  |/   |   \\_  \\_|  |    | | |    <br>" +
-    "  O | | | O  |  | O__/    |   / \\__ |  |  O | | | O  <br>" +
-    "  | | | | |  |  |   /    /|  O  /  \\|  |  | | | | |  <br>" +
-    "O | | |  \\|  |  O  /   _/ |    /    O  |  |/  | | | O<br>" +
-    "| | | |O  /  |  | O   /   |   O   O |  |  \\  O| | | |<br>" +
-    "| | |/  \\/  / __| | |/ \\  |   \\   | |__ \\  \\/  \\| | |<br>" +
-    " \\| O   |  |_/    |\\|   \\ O    \\__|    \\_|  |   O |/ <br>" +
-    "  | |   |_/       | |    \\|    /  |       \\_|   | |  <br>" +
-    "   \\|   /          \\|     |   /  /          \\   |/   <br>" +
-    "    |  "+bitNodes[9]+"            |     |  /  |            "+bitNodes[10]+"  |    <br>" +
-    "  "+bitNodes[8]+" |  |            |     |     |            |  | "+bitNodes[11]+"  <br>" +
-    "  | |  |            /    / \\    \\            |  | |  <br>" +
-    "   \\|  |           /  "+bitNodes[6]+" /   \\ "+bitNodes[7]+"  \\           |  |/   <br>" +
-    "    \\  |          /  / |     | \\  \\          |  /    <br>" +
-    "     \\ \\JUMP "+bitNodes[4]+"3R |  |  |     |  |  | R3"+bitNodes[5]+" PMUJ/ /     <br>" +
-    "      \\||    |   |  |  |     |  |  |   |    ||/      <br>" +
-    "       \\|     \\_ |  |  |     |  |  | _/     |/       <br>" +
-    "        \\       \\| /    \\   /    \\ |/       /        <br>" +
-    "         "+bitNodes[0]+"       |/   "+bitNodes[1]+"  | |  "+bitNodes[2]+"   \\|       "+bitNodes[3]+"         <br>" +
-    "         |       |    |  | |  |    |       |         <br>" +
-    "          \\JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/          <br><br><br><br>";
-
-
-    /*
-    "                          O                          <br>" +
-    "             |  O  O      |      O  O  |             <br>" +
-    "        O    |  | /     __|       \ |  |    O        <br>" +
-    "      O |    O  | |  O /  |  O    | |  O    | O      <br>" +
-    "    | | |    |  |_/  |/   |   \_  \_|  |    | | |    <br>" +
-    "  O | | | O  |  | O__/    |   / \__ |  |  O | | | O  <br>" +
-    "  | | | | |  |  |   /    /|  O  /  \|  |  | | | | |  <br>" +
-    "O | | |  \|  |  O  /   _/ |    /    O  |  |/  | | | O<br>" +
-    "| | | |O  /  |  | O   /   |   O   O |  |  \  O| | | |<br>" +
-    "| | |/  \/  / __| | |/ \  |   \   | |__ \  \/  \| | |<br>" +
-    " \| O   |  |_/    |\|   \ O    \__|    \_|  |   O |/ <br>" +
-    "  | |   |_/       | |    \|    /  |       \_|   | |  <br>" +
-    "   \|   /          \|     |   /  /          \   |/   <br>" +
-    "    |  O            |     |  /  |            O  |    <br>" +
-    "  O |  |            |     |     |            |  | O  <br>" +
-    "  | |  |            /    / \    \            |  | |  <br>" +
-    "   \|  |           /  O /   \ O  \           |  |/   <br>" +
-    "    \  |          /  / |     | \  \          |  /    <br>" +
-    "     \ \JUMP O3R |  |  |     |  |  | R3O PMUJ/ /     <br>" +
-    "      \||    |   |  |  |     |  |  |   |    ||/      <br>" +
-    "       \|     \_ |  |  |     |  |  | _/     |/       <br>" +
-    "        \       \| /    \   /    \ |/       /        <br>" +
-    "         O       |/   O  | |  O   \|       O         <br>" +
-    "         |       |    |  | |  |    |       |         <br>" +
-    "          \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/          <br>";
-    */
-
-    container.appendChild(bitVerseImage);
-
-    //Bit node event listeners
-    for (var i = 1; i <= 12; ++i) {
-        (function(i) {
-            var elemId = "bitnode-" + i.toString();
-            var elem = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["clearEventListeners"])(elemId);
-            if (elem == null) {return;}
-            if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 || i === 6 || i === 8 || i === 11) {
-                elem.addEventListener("click", function() {
-                    var bitNodeKey = "BitNode" + i;
-                    var bitNode = _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodes"][bitNodeKey];
-                    if (bitNode == null) {
-                        console.log("ERROR: Could not find BitNode object for number: " + i);
-                        return;
-                    }
-                    Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxCreate"])("BitNode-" + i + ": " + bitNode.name + "<br><br>" + bitNode.info);
-                    createBitNodeYesNoEventListeners(i, destroyedBitNodeNum, flume);
-                });
-            } else {
-                elem.addEventListener("click", function() {
-                    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_6__["dialogBoxCreate"])("Not yet implemented! Coming soon!")
-                });
-            }
-        }(i)); //Immediate invocation closure
-    }
-
-    //Create lore text
-    return writeRedPillLine("Many decades ago, a humanoid extraterrestial species which we call the Enders descended on the Earth...violently").then(function() {
-        return writeRedPillLine("Our species fought back, but it was futile. The Enders had technology far beyond our own...");
-    }).then(function() {
-        return writeRedPillLine("Instead of killing every last one of us, the human race was enslaved...");
-    }).then(function() {
-        return writeRedPillLine("We were shackled in a digital world, chained into a prison for our minds...");
-    }).then(function() {
-        return writeRedPillLine("Using their advanced technology, the Enders created complex simulations of a virtual reality...");
-    }).then(function() {
-        return writeRedPillLine("Simulations designed to keep us content...ignorant of the truth.");
-    }).then(function() {
-        return writeRedPillLine("Simulations used to trap and suppress our consciousness, to keep us under control...");
-    }).then(function() {
-        return writeRedPillLine("Why did they do this? Why didn't they just end our entire race? We don't know, not yet.");
-    }).then(function() {
-        return writeRedPillLine("Humanity's only hope is to destroy these simulations, destroy the only realities we've ever known...");
-    }).then(function() {
-        return writeRedPillLine("Only then can we begin to fight back...");
-    }).then(function() {
-        return writeRedPillLine("By hacking the daemon that generated your reality, you've just destroyed one simulation, called a BitNode...");
-    }).then(function() {
-        return writeRedPillLine("But there is still a long way to go...");
-    }).then(function() {
-        return writeRedPillLine("The technology the Enders used to enslave the human race wasn't just a single complex simulation...");
-    }).then(function() {
-        return writeRedPillLine("There are tens if not hundreds of BitNodes out there...");
-    }).then(function() {
-        return writeRedPillLine("Each with their own simulations of a reality...");
-    }).then(function() {
-        return writeRedPillLine("Each creating their own universes...a universe of universes");
-    }).then(function() {
-        return writeRedPillLine("And all of which must be destroyed...");
-    }).then(function() {
-        return writeRedPillLine(".......................................");
-    }).then(function() {
-        return writeRedPillLine("Welcome to the Bitverse...");
-    }).then(function() {
-        return writeRedPillLine(" ");
-    }).then(function() {
-        return writeRedPillLine("(Enter a new BitNode using the image above)");
-    }).then(function() {
-        return Promise.resolve(true);
-    }).catch(function(e){
-        console.log("ERROR: " + e.toString());
-    });
-}
-
-
-//Returns string with DOM element for Bit Node
-function createBitNode(n) {
-    var bitNodeStr = "BitNode" + n.toString();
-    var bitNode = _BitNode_js__WEBPACK_IMPORTED_MODULE_0__["BitNodes"][bitNodeStr];
-    if (bitNode == null) {return "O";}
-    return  "<a class='bitnode tooltip' id='bitnode-" + bitNode.number.toString() + "'><strong>O</strong>" +
-             "<span class='tooltiptext'>" +
-             "<strong>BitNode-" + bitNode.number.toString() + "<br>" + bitNode.name+ "</strong><br>" +
-             bitNode.desc + "<br>" +
-             "</span></a>";
-}
-
-function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode, flume=false) {
-    var yesBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxGetYesButton"])();
-    yesBtn.innerHTML = "Enter BitNode-" + newBitNode;
-    yesBtn.addEventListener("click", function() {
-        if (!flume) {
-            giveSourceFile(destroyedBitNode);
-        } else {
-            //If player used flume, subtract 5 int exp. The prestigeSourceFile()
-            //function below grants 5 int exp, so this allows sets net gain to 0
-            _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].gainIntelligenceExp(-5);
-        }
-        redPillFlag = false;
-        var container = document.getElementById("red-pill-container");
-        Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__["removeChildrenFromElement"])(container);
-
-        //Set new Bit Node
-        _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].bitNodeN = newBitNode;
-        console.log("Entering Bit Node " + _Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].bitNodeN);
-
-        //Reenable terminal
-        $("#hack-progress-bar").attr('id', "old-hack-progress-bar");
-        $("#hack-progress").attr('id', "old-hack-progress");
-        document.getElementById("terminal-input-td").innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
-        $('input[class=terminal-input]').prop('disabled', false);
-
-        _Terminal_js__WEBPACK_IMPORTED_MODULE_5__["Terminal"].hackFlag = false;
-
-        Object(_Prestige_js__WEBPACK_IMPORTED_MODULE_3__["prestigeSourceFile"])();
-        Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxClose"])();
-    });
-    var noBtn = Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxGetNoButton"])();
-    noBtn.innerHTML = "Back";
-    noBtn.addEventListener("click", function() {
-        Object(_utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_8__["yesNoBoxClose"])();
-    });
-
-}
-
-
-
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
-
-/***/ }),
-/* 50 */
+/* 51 */
 /*!*************************!*\
   !*** ./utils/LogBox.js ***!
   \*************************/
@@ -58832,7 +59621,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logBoxUpdateText", function() { return logBoxUpdateText; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logBoxOpened", function() { return logBoxOpened; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logBoxCurrentScript", function() { return logBoxCurrentScript; });
-/* harmony import */ var _src_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../src/NetscriptWorker.js */ 21);
+/* harmony import */ var _src_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../src/NetscriptWorker.js */ 20);
 /* harmony import */ var _HelperFunctions_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./HelperFunctions.js */ 1);
 
 
@@ -58902,653 +59691,7 @@ function logBoxUpdateText() {
 
 
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
-
-/***/ }),
-/* 51 */
-/*!***************************!*\
-  !*** ./src/SaveObject.js ***!
-  \***************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "saveObject", function() { return saveObject; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadGame", function() { return loadGame; });
-/* harmony import */ var _Alias_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Alias.js */ 28);
-/* harmony import */ var _Company_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Company.js */ 9);
-/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Constants.js */ 3);
-/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Faction.js */ 14);
-/* harmony import */ var _Fconf_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Fconf.js */ 34);
-/* harmony import */ var _Gang_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Gang.js */ 35);
-/* harmony import */ var _HacknetNode_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./HacknetNode.js */ 38);
-/* harmony import */ var _Message_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Message.js */ 27);
-/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _Script_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Script.js */ 29);
-/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./Server.js */ 10);
-/* harmony import */ var _Settings_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Settings.js */ 24);
-/* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
-/* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./StockMarket.js */ 20);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_GameOptions_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../utils/GameOptions.js */ 54);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8);
-/* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
-/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/decimal.js */ 23);
-/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_20__);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* SaveObject.js
- *  Defines the object used to save/load games
- */
-let saveObject = new BitburnerSaveObject();
-
-function BitburnerSaveObject() {
-    this.PlayerSave                 = "";
-    this.AllServersSave             = "";
-    this.CompaniesSave              = "";
-    this.FactionsSave               = "";
-    this.SpecialServerIpsSave       = "";
-    this.AliasesSave                = "";
-    this.GlobalAliasesSave          = "";
-    this.MessagesSave               = "";
-    this.StockMarketSave            = "";
-    this.SettingsSave               = "";
-    this.FconfSettingsSave          = "";
-    this.VersionSave                = "";
-    this.AllGangsSave               = "";
-}
-
-BitburnerSaveObject.prototype.saveGame = function(db) {
-    this.PlayerSave                 = JSON.stringify(_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"]);
-
-    //Delete all logs from all running scripts
-    var TempAllServers = JSON.parse(JSON.stringify(_Server_js__WEBPACK_IMPORTED_MODULE_11__["AllServers"]), _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-    for (var ip in TempAllServers) {
-        var server = TempAllServers[ip];
-        if (server == null) {continue;}
-        for (var i = 0; i < server.runningScripts.length; ++i) {
-            var runningScriptObj = server.runningScripts[i];
-            runningScriptObj.logs.length = 0;
-            runningScriptObj.logs = [];
-        }
-    }
-
-    this.AllServersSave             = JSON.stringify(TempAllServers);
-    this.CompaniesSave              = JSON.stringify(_Company_js__WEBPACK_IMPORTED_MODULE_1__["Companies"]);
-    this.FactionsSave               = JSON.stringify(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["Factions"]);
-    this.SpecialServerIpsSave       = JSON.stringify(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__["SpecialServerIps"]);
-    this.AliasesSave                = JSON.stringify(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["Aliases"]);
-    this.GlobalAliasesSave          = JSON.stringify(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["GlobalAliases"]);
-    this.MessagesSave               = JSON.stringify(_Message_js__WEBPACK_IMPORTED_MODULE_8__["Messages"]);
-    this.StockMarketSave            = JSON.stringify(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["StockMarket"]);
-    this.SettingsSave               = JSON.stringify(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["Settings"]);
-    this.FconfSettingsSave          = JSON.stringify(_Fconf_js__WEBPACK_IMPORTED_MODULE_5__["FconfSettings"]);
-    this.VersionSave                = JSON.stringify(_Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version);
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].inGang()) {
-        this.AllGangsSave           = JSON.stringify(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["AllGangs"]);
-    }
-    var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
-
-    //We'll save to both localstorage and indexedDb
-    var objectStore = db.transaction(["savestring"], "readwrite").objectStore("savestring");
-    var request = objectStore.put(saveString, "save");
-
-    request.onerror = function(e) {
-        console.log("Error saving game to IndexedDB: " + e);
-    }
-
-    request.onsuccess = function(e) {
-        //console.log("Saved game to IndexedDB!");
-    }
-
-    try {
-        window.localStorage.setItem("bitburnerSave", saveString);
-        //console.log("Saved game to LocalStorage!");
-    } catch(e) {
-        if (e.code == 22) {
-            _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].createStatusText("Save failed for localStorage! Check console(F12)");
-            console.log("Failed to save game to localStorage because the size of the save file " +
-                        "is too large. However, the game will still be saved to IndexedDb if your browser " +
-                        "supports it. If you would like to save to localStorage as well, then " +
-                        "consider killing several of your scripts to " +
-                        "fix this, or increasing the size of your browsers localStorage");
-        }
-    }
-
-    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].createStatusText("Game saved!");
-}
-
-function loadGame(saveString) {
-    if (saveString === "" || saveString == null || saveString === undefined) {
-        if (!window.localStorage.getItem("bitburnerSave")) {
-            console.log("No save file to load");
-            return false;
-        }
-        saveString = decodeURIComponent(escape(atob(window.localStorage.getItem("bitburnerSave"))));
-        console.log("Loading game from localStorage");
-    } else {
-        saveString = decodeURIComponent(escape(atob(saveString)));
-        console.log("Loading game from IndexedDB");
-    }
-
-    var saveObj = JSON.parse(saveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-
-    Object(_Player_js__WEBPACK_IMPORTED_MODULE_9__["loadPlayer"])(saveObj.PlayerSave);
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_11__["loadAllServers"])(saveObj.AllServersSave);
-    Object(_Company_js__WEBPACK_IMPORTED_MODULE_1__["loadCompanies"])(saveObj.CompaniesSave);
-    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["loadFactions"])(saveObj.FactionsSave);
-    Object(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__["loadSpecialServerIps"])(saveObj.SpecialServerIpsSave);
-
-    if (saveObj.hasOwnProperty("AliasesSave")) {
-        try {
-            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])(saveObj.AliasesSave);
-        } catch(e) {
-            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])("");
-        }
-    } else {
-        Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])("");
-    }
-    if (saveObj.hasOwnProperty("GlobalAliasesSave")) {
-        try {
-            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])(saveObj.GlobalAliasesSave);
-        } catch(e) {
-            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])("");
-        }
-    } else {
-        Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])("");
-    }
-    if (saveObj.hasOwnProperty("MessagesSave")) {
-        try {
-            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["loadMessages"])(saveObj.MessagesSave);
-        } catch(e) {
-            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
-        }
-    } else {
-        Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
-    }
-    if (saveObj.hasOwnProperty("StockMarketSave")) {
-        try {
-            Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])(saveObj.StockMarketSave);
-        } catch(e) {
-            Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])("");
-        }
-    } else {
-        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])("");
-    }
-    if (saveObj.hasOwnProperty("SettingsSave")) {
-        try {
-            Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["loadSettings"])(saveObj.SettingsSave);
-        } catch(e) {
-            console.log("ERROR: Failed to parse Settings. Re-initing default values");
-            Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["initSettings"])();
-        }
-    } else {
-        Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["initSettings"])();
-    }
-    if (saveObj.hasOwnProperty("FconfSettingsSave")) {
-        try {
-            Object(_Fconf_js__WEBPACK_IMPORTED_MODULE_5__["loadFconf"])(saveObj.FconfSettingsSave);
-        } catch(e) {
-            console.log("ERROR: Failed to parse .fconf Settings.");
-        }
-    }
-    if (saveObj.hasOwnProperty("VersionSave")) {
-        try {
-            var ver = JSON.parse(saveObj.VersionSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-            if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == null || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN === 0) {
-                _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].setBitNodeNumber(1);
-            }
-            if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
-                console.log("Evaluating changes needed for version compatibility");
-                if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].augmentations.length > 0 || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].queuedAugmentations.length > 0 ||
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].sourceFiles.length > 0) {
-                    //If you have already purchased an Aug...you are far enough in the game
-                    //that everything should be available
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstFacInvRecvd = true;
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstAugPurchased = true;
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstJobRecvd = true;
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstTimeTraveled = true;
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstProgramAvailable = true;
-                } else  {
-                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].factions.length > 0 || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].factionInvitations.length > 0) {
-                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstFacInvRecvd = true;
-                    }
-                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].companyName !== "" || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].companyPosition !== "") {
-                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstJobRecvd = true;
-                    }
-                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].hacking_skill >= 25) {
-                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstScriptAvailable = true;
-                    }
-                }
-            }
-            if (ver != _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version) {
-                createNewUpdateText();
-            }
-        } catch(e) {
-            createNewUpdateText();
-        }
-    } else {
-        createNewUpdateText();
-    }
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
-        try {
-            Object(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["loadAllGangs"])(saveObj.AllGangsSave);
-        } catch(e) {
-            console.log("ERROR: Failed to parse AllGangsSave: " + e);
-        }
-    }
-
-    return true;
-}
-
-function loadImportedGame(saveObj, saveString) {
-    var tempSaveObj = null;
-    var tempPlayer = null;
-    var tempAllServers = null;
-    var tempCompanies = null;
-    var tempFactions = null;
-    var tempSpecialServerIps = null;
-    var tempAliases = null;
-    var tempGlobalAliases = null;
-    var tempMessages = null;
-    var tempStockMarket = null;
-    var tempAllGangs = null;
-
-    //Check to see if the imported save file can be parsed. If any
-    //errors are caught it will fail
-    try {
-        var decodedSaveString = decodeURIComponent(escape(atob(saveString)));
-        tempSaveObj = new BitburnerSaveObject();
-        tempSaveObj = JSON.parse(decodedSaveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-
-        tempPlayer = JSON.parse(tempSaveObj.PlayerSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-
-        //Parse Decimal.js objects
-        tempPlayer.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.money);
-        tempPlayer.total_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.total_money);
-        tempPlayer.lifetime_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.lifetime_money);
-
-        tempAllServers          = JSON.parse(tempSaveObj.AllServersSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-        tempCompanies           = JSON.parse(tempSaveObj.CompaniesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-        tempFactions            = JSON.parse(tempSaveObj.FactionsSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-        tempSpecialServerIps    = JSON.parse(tempSaveObj.SpecialServerIpsSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-        if (tempSaveObj.hasOwnProperty("AliasesSave")) {
-            try {
-                tempAliases         = JSON.parse(tempSaveObj.AliasesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-            } catch(e) {
-                console.log("Parsing Aliases save failed: " + e);
-                tempAliases = {};
-            }
-        } else {
-            tempAliases = {};
-        }
-        if (tempSaveObj.hasOwnProperty("GlobalAliases")) {
-            try {
-                tempGlobalAliases   = JSON.parse(tempSaveObj.AliasesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-            } catch(e) {
-                console.log("Parsing Global Aliases save failed: " + e);
-                tempGlobalAliases = {};
-            }
-        } else {
-            tempGlobalAliases = {};
-        }
-        if (tempSaveObj.hasOwnProperty("MessagesSave")) {
-            try {
-                tempMessages        = JSON.parse(tempSaveObj.MessagesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-            } catch(e) {
-                console.log("Parsing Messages save failed: " + e);
-                Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
-            }
-        } else {
-            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
-        }
-        if (saveObj.hasOwnProperty("StockMarketSave")) {
-            try {
-                tempStockMarket     = JSON.parse(tempSaveObj.StockMarketSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-            } catch(e) {
-                console.log("Parsing StockMarket save failed: " + e);
-                tempStockMarket     = {};
-            }
-        } else {
-            tempStockMarket = {};
-        }
-        if (tempSaveObj.hasOwnProperty("VersionSave")) {
-            try {
-                var ver = JSON.parse(tempSaveObj.VersionSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-                if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
-                    if (tempPlayer.bitNodeN == null || tempPlayer.bitNodeN == 0) {
-                        tempPlayer.bitNodeN = 1;
-                    }
-                    if (tempPlayer.sourceFiles == null) {
-                        tempPlayer.sourceFiles = [];
-                    }
-                }
-                if (ver != _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version) {
-                    //createNewUpdateText();
-                }
-            } catch(e) {
-                console.log("Parsing Version save failed: " + e);
-                //createNewUpdateText();
-            }
-        } else {
-            //createNewUpdateText();
-        }
-        if (tempPlayer.bitNodeN == 2 && tempPlayer.inGang() && tempSaveObj.hasOwnProperty("AllGangsSave")) {
-            try {
-                Object(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["loadAllGangs"])(tempSaveObj.AllGangsSave);
-            } catch(e) {
-                console.log("ERROR: Failed to parse AllGangsSave: " + e);
-            }
-        }
-    } catch(e) {
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("Error importing game: " + e.toString());
-        return false;
-    }
-
-    //Since the save file is valid, load everything for real
-    saveString = decodeURIComponent(escape(atob(saveString)));
-    saveObj = JSON.parse(saveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-
-    Object(_Player_js__WEBPACK_IMPORTED_MODULE_9__["loadPlayer"])(saveObj.PlayerSave);
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_11__["loadAllServers"])(saveObj.AllServersSave);
-    Object(_Company_js__WEBPACK_IMPORTED_MODULE_1__["loadCompanies"])(saveObj.CompaniesSave);
-    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["loadFactions"])(saveObj.FactionsSave);
-    Object(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__["loadSpecialServerIps"])(saveObj.SpecialServerIpsSave);
-
-    if (saveObj.hasOwnProperty("AliasesSave")) {
-        try {
-            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])(saveObj.AliasesSave);
-        } catch(e) {
-            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])("");
-        }
-    } else {
-        Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadAliases"])("");
-    }
-    if (saveObj.hasOwnProperty("GlobalAliasesSave")) {
-        try {
-            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])(saveObj.GlobalAliasesSave);
-        } catch(e) {
-            Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])("");
-        }
-    } else {
-        Object(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["loadGlobalAliases"])("");
-    }
-    if (saveObj.hasOwnProperty("MessagesSave")) {
-        try {
-            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["loadMessages"])(saveObj.MessagesSave);
-        } catch(e) {
-            Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
-        }
-    } else {
-        Object(_Message_js__WEBPACK_IMPORTED_MODULE_8__["initMessages"])();
-    }
-    if (saveObj.hasOwnProperty("StockMarketSave")) {
-        try {
-            Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])(saveObj.StockMarketSave);
-        } catch(e) {
-            Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])("");
-        }
-    } else {
-        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["loadStockMarket"])("");
-    }
-    if (saveObj.hasOwnProperty("SettingsSave")) {
-        try {
-            Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["loadSettings"])(saveObj.SettingsSave);
-        } catch(e) {
-            Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["initSettings"])();
-        }
-    } else {
-        Object(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["initSettings"])();
-    }
-    if (saveObj.hasOwnProperty("FconfSettingsSave")) {
-        try {
-            Object(_Fconf_js__WEBPACK_IMPORTED_MODULE_5__["loadFconf"])(saveObj.FconfSettingsSave);
-        } catch(e) {
-            console.log("ERROR: Failed to load .fconf settings when importing");
-        }
-    }
-    if (saveObj.hasOwnProperty("VersionSave")) {
-        try {
-            var ver = JSON.parse(saveObj.VersionSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]);
-            if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == null || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 0) {
-                _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].setBitNodeNumber(1);
-
-            }
-            if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
-                console.log("Evaluating changes needed for version compatibility");
-                if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].augmentations.length > 0 || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].queuedAugmentations.length > 0 ||
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].sourceFiles.length > 0) {
-                    //If you have already purchased an Aug...you are far enough in the game
-                    //that everything should be available
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstFacInvRecvd = true;
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstAugPurchased = true;
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstJobRecvd = true;
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstTimeTraveled = true;
-                    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstProgramAvailable = true;
-                } else  {
-                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].factions.length > 0 || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].factionInvitations.length > 0) {
-                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstFacInvRecvd = true;
-                    }
-                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].companyName !== "" || _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].companyPosition !== "") {
-                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstJobRecvd = true;
-                    }
-                    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].hacking_skill >= 25) {
-                        _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].firstScriptAvailable = true;
-                    }
-                }
-            }
-            if (ver != _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version) {
-                createNewUpdateText();
-            }
-        } catch(e) {
-            createNewUpdateText();
-        }
-    } else {
-        createNewUpdateText();
-    }
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
-        try {
-            Object(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["loadAllGangs"])(saveObj.AllGangsSave);
-        } catch(e) {
-            console.log("ERROR: Failed to parse AllGangsSave: " + e);
-        }
-    }
-
-    var popupId = "import-game-restart-game-notice";
-    var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["createElement"])("p", {
-        innerText:"Imported game! I would suggest saving the game and then reloading the page " +
-                 "to make sure everything runs smoothly"
-    });
-    var gotitBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["createElement"])("a", {
-        class:"a-link-button", float:"right", padding:"6px", innerText:"Got it!",
-        clickListener:()=>{
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["removeElementById"])(popupId);
-        }
-    });
-    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["createPopup"])(popupId, [txt, gotitBtn]);
-    Object(_utils_GameOptions_js__WEBPACK_IMPORTED_MODULE_16__["gameOptionsBoxClose"])();
-
-    //Re-start game
-    console.log("Importing game");
-    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].setDisplayElements();    //Sets variables for important DOM elements
-    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].init();                  //Initialize buttons, work, etc.
-    _Company_js__WEBPACK_IMPORTED_MODULE_1__["CompanyPositions"].init();
-
-    //Calculate the number of cycles have elapsed while offline
-    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._lastUpdate = new Date().getTime();
-    var lastUpdate = _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].lastUpdate;
-    var numCyclesOffline = Math.floor((_engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._lastUpdate - lastUpdate) / _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._idleSpeed);
-
-    /* Process offline progress */
-    var offlineProductionFromScripts = Object(_Script_js__WEBPACK_IMPORTED_MODULE_10__["loadAllRunningScripts"])();    //This also takes care of offline production for those scripts
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].isWorking) {
-        console.log("work() called in load() for " + numCyclesOffline * _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._idleSpeed + " milliseconds");
-        if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeFaction) {
-            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workForFaction(numCyclesOffline);
-        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeCreateProgram) {
-            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].createProgramWork(numCyclesOffline);
-        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeStudyClass) {
-            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].takeClass(numCyclesOffline);
-        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeCrime) {
-            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].commitCrime(numCyclesOffline);
-        } else if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workType == _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].WorkTypeCompanyPartTime) {
-            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].workPartTime(numCyclesOffline);
-        } else {
-            _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].work(numCyclesOffline);
-        }
-    }
-
-    //Hacknet Nodes offline progress
-    var offlineProductionFromHacknetNodes = Object(_HacknetNode_js__WEBPACK_IMPORTED_MODULE_7__["processAllHacknetNodeEarnings"])(numCyclesOffline);
-
-    //Passive faction rep gain offline
-    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["processPassiveFactionRepGain"])(numCyclesOffline);
-
-    //Update total playtime
-    var time = numCyclesOffline * _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._idleSpeed;
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].totalPlaytime == null) {_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].totalPlaytime = 0;}
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].playtimeSinceLastAug == null) {_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].playtimeSinceLastAug = 0;}
-    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].totalPlaytime += time;
-    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].playtimeSinceLastAug += time;
-
-    //Re-apply augmentations
-    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].reapplyAllAugmentations();
-
-    //Clear terminal
-    $("#terminal tr:not(:last)").remove();
-
-    _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].lastUpdate = _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"]._lastUpdate;
-    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].start();                 //Run main game loop and Scripts loop
-    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("While you were offline, your scripts generated $" +
-                    Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__["formatNumber"])(offlineProductionFromScripts, 2) + " and your Hacknet Nodes generated $" +
-                    Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__["formatNumber"])(offlineProductionFromHacknetNodes, 2));
-    return true;
-}
-
-BitburnerSaveObject.prototype.exportGame = function() {
-    this.PlayerSave                 = JSON.stringify(_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"]);
-    this.AllServersSave             = JSON.stringify(_Server_js__WEBPACK_IMPORTED_MODULE_11__["AllServers"]);
-    this.CompaniesSave              = JSON.stringify(_Company_js__WEBPACK_IMPORTED_MODULE_1__["Companies"]);
-    this.FactionsSave               = JSON.stringify(_Faction_js__WEBPACK_IMPORTED_MODULE_4__["Factions"]);
-    this.SpecialServerIpsSave       = JSON.stringify(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__["SpecialServerIps"]);
-    this.AliasesSave                = JSON.stringify(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["Aliases"]);
-    this.GlobalAliasesSave          = JSON.stringify(_Alias_js__WEBPACK_IMPORTED_MODULE_0__["GlobalAliases"]);
-    this.MessagesSave               = JSON.stringify(_Message_js__WEBPACK_IMPORTED_MODULE_8__["Messages"]);
-    this.StockMarketSave            = JSON.stringify(_StockMarket_js__WEBPACK_IMPORTED_MODULE_14__["StockMarket"]);
-    this.SettingsSave               = JSON.stringify(_Settings_js__WEBPACK_IMPORTED_MODULE_12__["Settings"]);
-    this.VersionSave                = JSON.stringify(_Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].Version);
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_9__["Player"].inGang()) {
-        this.AllGangsSave           = JSON.stringify(_Gang_js__WEBPACK_IMPORTED_MODULE_6__["AllGangs"]);
-    }
-
-    var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
-    var filename = "bitburnerSave.json";
-    var file = new Blob([saveString], {type: 'text/plain'});
-    if (window.navigator.msSaveOrOpenBlob) {// IE10+
-        window.navigator.msSaveOrOpenBlob(file, filename);
-    } else { // Others
-        var a = document.createElement("a"),
-                url = URL.createObjectURL(file);
-        a.href = url;
-        a.download = "bitburnerSave.json";
-        document.body.appendChild(a);
-        a.click();
-        setTimeout(function() {
-            document.body.removeChild(a);
-            window.URL.revokeObjectURL(url);
-        }, 0);
-    }
-}
-
-BitburnerSaveObject.prototype.importGame = function() {
-    if (window.File && window.FileReader && window.FileList && window.Blob) {
-        var fileSelector = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["clearEventListeners"])("import-game-file-selector");
-        fileSelector.addEventListener("change", openImportFileHandler, false);
-        $("#import-game-file-selector").click();
-    } else {
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("ERR: Your browser does not support HTML5 File API. Cannot import.");
-    }
-
-}
-
-BitburnerSaveObject.prototype.deleteGame = function(db) {
-    //Delete from local storage
-    if (window.localStorage.getItem("bitburnerSave")) {
-        window.localStorage.removeItem("bitburnerSave");
-    }
-
-    //Delete from indexedDB
-    var request = db.transaction(["savestring"], "readwrite").objectStore("savestring").delete("save");
-    request.onsuccess = function(e) {
-        console.log("Successfully deleted save from indexedDb");
-    }
-    request.onerror = function(e) {
-        console.log("Failed to delete save from indexedDb: " + e);
-    }
-    _engine_js__WEBPACK_IMPORTED_MODULE_3__["Engine"].createStatusText("Game deleted!");
-}
-
-function createNewUpdateText() {
-    Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("New update!<br>" +
-                    "Please report any bugs/issues through the github repository " +
-                    "or the Bitburner subreddit (reddit.com/r/bitburner).<br><br>" +
-                    _Constants_js__WEBPACK_IMPORTED_MODULE_2__["CONSTANTS"].LatestUpdate);
-}
-
-
-BitburnerSaveObject.prototype.toJSON = function() {
-    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Generic_toJSON"])("BitburnerSaveObject", this);
-}
-
-BitburnerSaveObject.fromJSON = function(value) {
-    return Object(_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Generic_fromJSON"])(BitburnerSaveObject, value.data);
-}
-
-_utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"].constructors.BitburnerSaveObject = BitburnerSaveObject;
-
-//Import game
-
-function openImportFileHandler(evt) {
-    var file = evt.target.files[0];
-    if (!file) {
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_15__["dialogBoxCreate"])("Invalid file selected");
-        return;
-    }
-
-    var reader = new FileReader();
-    reader.onload = function(e) {
-        var contents = e.target.result;
-        loadImportedGame(saveObject, contents);
-    };
-    reader.readAsText(file);
-}
-
-
-
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
 
 /***/ }),
 /* 52 */
@@ -59588,7 +59731,7 @@ function openImportFileHandler(evt) {
 
 /*<replacement>*/
 
-var processNextTick = __webpack_require__(/*! process-nextick-args */ 64).nextTick;
+var processNextTick = __webpack_require__(/*! process-nextick-args */ 65).nextTick;
 /*</replacement>*/
 
 /*<replacement>*/
@@ -59603,11 +59746,11 @@ var objectKeys = Object.keys || function (obj) {
 module.exports = Duplex;
 
 /*<replacement>*/
-var util = __webpack_require__(/*! core-util-is */ 58);
+var util = __webpack_require__(/*! core-util-is */ 59);
 util.inherits = __webpack_require__(/*! inherits */ 55);
 /*</replacement>*/
 
-var Readable = __webpack_require__(/*! ./_stream_readable */ 104);
+var Readable = __webpack_require__(/*! ./_stream_readable */ 105);
 var Writable = __webpack_require__(/*! ./_stream_writable */ 74);
 
 util.inherits(Duplex, Readable);
@@ -60186,7 +60329,7 @@ function gameOptionsBoxOpen() {
 
 
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
 
 /***/ }),
 /* 55 */
@@ -60231,8 +60374,8 @@ if (typeof Object.create === 'function') {
 
 
 var utils = __webpack_require__(/*! ./utils */ 31);
-var support = __webpack_require__(/*! ./support */ 47);
-var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ 62);
+var support = __webpack_require__(/*! ./support */ 50);
+var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ 63);
 var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ 37);
 
 /**
@@ -60507,6 +60650,343 @@ exports.Utf8EncodeWorker = Utf8EncodeWorker;
 
 /***/ }),
 /* 57 */
+/*!*************************!*\
+  !*** ./src/Prestige.js ***!
+  \*************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prestigeAugmentation", function() { return prestigeAugmentation; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prestigeSourceFile", function() { return prestigeSourceFile; });
+/* harmony import */ var _ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActiveScriptsUI.js */ 43);
+/* harmony import */ var _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Augmentations.js */ 18);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./BitNode.js */ 15);
+/* harmony import */ var _CinematicText_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./CinematicText.js */ 67);
+/* harmony import */ var _Company_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Company.js */ 9);
+/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./CreateProgram.js */ 14);
+/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./engine.js */ 5);
+/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Faction.js */ 11);
+/* harmony import */ var _Gang_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Gang.js */ 36);
+/* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Location.js */ 4);
+/* harmony import */ var _Message_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Message.js */ 27);
+/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 29);
+/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./NetscriptWorker.js */ 20);
+/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Player.js */ 0);
+/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Server.js */ 10);
+/* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
+/* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./StockMarket.js */ 21);
+/* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Terminal.js */ 22);
+/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/decimal.js */ 23);
+/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_18__);
+/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
+/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//Prestige by purchasing augmentation
+function prestigeAugmentation() {
+    Object(_BitNode_js__WEBPACK_IMPORTED_MODULE_2__["initBitNodeMultipliers"])();
+
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].prestigeAugmentation();
+
+    //Delete all Worker Scripts objects
+    Object(_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_12__["prestigeWorkerScripts"])();
+
+    var homeComp = _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].getHomeComputer();
+    //Delete all servers except home computer
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["prestigeAllServers"])();
+
+    //Delete Special Server IPs
+    Object(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["prestigeSpecialServerIps"])(); //Must be done before initForeignServers()
+
+    //Reset home computer (only the programs) and add to AllServers
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["AddToAllServers"])(homeComp);
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["prestigeHomeComputer"])(homeComp);
+
+    if (Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["augmentationExists"])(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].Neurolink) &&
+        _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].Neurolink].owned) {
+        homeComp.programs.push(_CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__["Programs"].FTPCrackProgram);
+        homeComp.programs.push(_CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__["Programs"].RelaySMTPProgram);
+    }
+    if (Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["augmentationExists"])(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].CashRoot) &&
+        _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].CashRoot].owned) {
+        _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].setMoney(new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(1000000));
+        homeComp.programs.push(_CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__["Programs"].BruteSSHProgram);
+    }
+
+    //Re-create foreign servers
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["initForeignServers"])();
+
+    //Darkweb is purchase-able
+    document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button");
+
+    //Gain favor for Companies
+    for (var member in _Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"]) {
+        if (_Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"].hasOwnProperty(member)) {
+            _Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"][member].gainFavor();
+        }
+    }
+
+    //Gain favor for factions
+    for (var member in _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"]) {
+        if (_Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"].hasOwnProperty(member)) {
+            _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"][member].gainFavor();
+        }
+    }
+
+    //Stop a Terminal action if there is onerror
+    if (_engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"]._actionInProgress) {
+        _engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"]._actionInProgress = false;
+        _Terminal_js__WEBPACK_IMPORTED_MODULE_17__["Terminal"].finishAction(true);
+    }
+
+    //Re-initialize things - This will update any changes
+    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_7__["initFactions"])(); //Factions must be initialized before augmentations
+    Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["initAugmentations"])(); //Calls reapplyAllAugmentations() and resets Player multipliers
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].reapplyAllSourceFiles();
+    Object(_Company_js__WEBPACK_IMPORTED_MODULE_4__["initCompanies"])();
+
+    //Clear terminal
+    $("#terminal tr:not(:last)").remove();
+    Object(_Terminal_js__WEBPACK_IMPORTED_MODULE_17__["postNetburnerText"])();
+
+    //Messages
+    Object(_Message_js__WEBPACK_IMPORTED_MODULE_10__["initMessages"])();
+
+    //Reset Stock market
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount) {
+        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["initStockMarket"])();
+        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["initSymbolToStockMap"])();
+    }
+    Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["setStockMarketContentCreated"])(false);
+    var stockMarketList = document.getElementById("stock-market-list");
+    while(stockMarketList.firstChild) {
+        stockMarketList.removeChild(stockMarketList.firstChild);
+    }
+
+    //Gang, in BitNode 2
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].inGang()) {
+        var faction = _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"][_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].gang.facName];
+        if (faction instanceof _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Faction"]) {
+            Object(_Faction_js__WEBPACK_IMPORTED_MODULE_7__["joinFaction"])(faction);
+        }
+    }
+
+    //Reset Bladeburner
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bladeburner = null;
+
+    //BitNode 8: Ghost of Wall Street
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8) {_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(100e6);}
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["hasWallStreetSF"]) {
+        _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount = true;
+        _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasTixApiAccess = true;
+    }
+
+    var mainMenu = document.getElementById("mainmenu-container");
+    mainMenu.style.visibility = "visible";
+    _Terminal_js__WEBPACK_IMPORTED_MODULE_17__["Terminal"].resetTerminalInput();
+    _engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"].loadTerminalContent();
+
+    //Red Pill
+    if (Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["augmentationExists"])(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].TheRedPill) &&
+        _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].TheRedPill].owned) {
+        var WorldDaemon = _Server_js__WEBPACK_IMPORTED_MODULE_14__["AllServers"][_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["SpecialServerIps"][_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["SpecialServerNames"].WorldDaemon]];
+        var DaedalusServer = _Server_js__WEBPACK_IMPORTED_MODULE_14__["AllServers"][_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["SpecialServerIps"][_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["SpecialServerNames"].DaedalusServer]];
+        if (WorldDaemon && DaedalusServer) {
+            WorldDaemon.serversOnNetwork.push(DaedalusServer.ip);
+            DaedalusServer.serversOnNetwork.push(WorldDaemon.ip);
+        }
+    }
+}
+
+
+//Prestige by destroying Bit Node and gaining a Source File
+function prestigeSourceFile() {
+    Object(_BitNode_js__WEBPACK_IMPORTED_MODULE_2__["initBitNodeMultipliers"])();
+
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].prestigeSourceFile();
+    Object(_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_12__["prestigeWorkerScripts"])(); //Delete all Worker Scripts objects
+
+    var homeComp = _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].getHomeComputer();
+
+    //Delete all servers except home computer
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["prestigeAllServers"])(); //Must be done before initForeignServers()
+
+    //Delete Special Server IPs
+    Object(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["prestigeSpecialServerIps"])();
+
+    //Reset home computer (only the programs) and add to AllServers
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["AddToAllServers"])(homeComp);
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["prestigeHomeComputer"])(homeComp);
+
+    //Re-create foreign servers
+    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["initForeignServers"])();
+
+    var srcFile1Owned = false;
+    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].sourceFiles.length; ++i) {
+        if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].sourceFiles[i].n == 1) {
+            srcFile1Owned = true;
+        }
+    }
+    if (srcFile1Owned) {
+        homeComp.setMaxRam(32);
+    } else {
+        homeComp.setMaxRam(8);
+    }
+    homeComp.cpuCores = 1;
+
+    //Darkweb is purchase-able
+    document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button");
+
+    //Reset favor for Companies
+    for (var member in _Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"]) {
+        if (_Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"].hasOwnProperty(member)) {
+            _Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"][member].favor = 0;
+        }
+    }
+
+    //Reset favor for factions
+    for (var member in _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"]) {
+        if (_Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"].hasOwnProperty(member)) {
+            _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"][member].favor = 0;
+        }
+    }
+
+    //Stop a Terminal action if there is one
+    if (_engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"]._actionInProgress) {
+        _engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"]._actionInProgress = false;
+        _Terminal_js__WEBPACK_IMPORTED_MODULE_17__["Terminal"].finishAction(true);
+    }
+
+    //Delete all Augmentations
+    for (var name in _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"]) {
+        if (_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"].hasOwnProperty(name)) {
+            delete _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][name];
+        }
+    }
+
+    //Re-initialize things - This will update any changes
+    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_7__["initFactions"])(); //Factions must be initialized before augmentations
+    Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["initAugmentations"])();    //Calls reapplyAllAugmentations() and resets Player multipliers
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].reapplyAllSourceFiles();
+    Object(_Company_js__WEBPACK_IMPORTED_MODULE_4__["initCompanies"])();
+
+    //Clear terminal
+    $("#terminal tr:not(:last)").remove();
+    Object(_Terminal_js__WEBPACK_IMPORTED_MODULE_17__["postNetburnerText"])();
+
+    //Messages
+    Object(_Message_js__WEBPACK_IMPORTED_MODULE_10__["initMessages"])();
+
+    var mainMenu = document.getElementById("mainmenu-container");
+    mainMenu.style.visibility = "visible";
+    _Terminal_js__WEBPACK_IMPORTED_MODULE_17__["Terminal"].resetTerminalInput();
+    _engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"].loadTerminalContent();
+
+    //Reinitialize Bit Node flags
+    Object(_NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["initSingularitySFFlags"])();
+
+    //Reset Stock market, gang, and corporation
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount) {
+        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["initStockMarket"])();
+        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["initSymbolToStockMap"])();
+    }
+    Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["setStockMarketContentCreated"])(false);
+    var stockMarketList = document.getElementById("stock-market-list");
+    while(stockMarketList.firstChild) {
+        stockMarketList.removeChild(stockMarketList.firstChild);
+    }
+
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].gang = null;
+    Object(_Gang_js__WEBPACK_IMPORTED_MODULE_8__["deleteGangDisplayContent"])();
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].corporation = null;
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bladeburner = null;
+
+    //BitNode 3: Corporatocracy
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 3) {
+        _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(150e9);
+        homeComp.messages.push("corporation-management-handbook.lit");
+        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_19__["dialogBoxCreate"])("You received a copy of the Corporation Management Handbook on your home computer. " +
+                        "Read it if you need help getting started with Corporations!");
+    }
+
+    //BitNode 6: Bladeburner
+    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 6) {
+        var cinematicText = ["In the middle of the 21st century, OmniTek Incorporated advanced robot evolution " +
+                             "with their Synthoids (synthetic androids), a being virtually identical to a human.",
+                             "------",
+                             "Their sixth-generation Synthoids, called MK-VI, were stronger, faster, and more " +
+                             "intelligent than humans. Many argued that the MK-VI Synthoids were the first " +
+                             "example of sentient AI.",
+                             "------",
+                             "Unfortunately, in 2070 a terrorist group called Ascendis Totalis hacked into OmniTek and " +
+                             "uploaded a rogue AI into their Synthoid manufacturing facilities.",
+                             "------",
+                             "The MK-VI Synthoids infected by the rogue AI turned hostile toward humanity, initiating " +
+                             "the deadliest conflict in human history. This dark chapter is now known as the Synthoid Uprising.",
+                             "------",
+                             "In the aftermath of the Uprising, further manufacturing of Synthoids with advanced AI " +
+                             "was banned. MK-VI Synthoids that did not have the rogue Ascendis Totalis AI were " +
+                             "allowed to continue their existence.",
+                             "------",
+                             "The intelligence community believes that not all of the rogue MK-VI Synthoids from the Uprising were " +
+                             "found and destroyed, and that many of them are blending in as normal humans in society today. " +
+                             "As a result, many nations have created Bladeburner divisions, special units that are tasked with " +
+                             "investigating and dealing with Synthoid threats."];
+        Object(_CinematicText_js__WEBPACK_IMPORTED_MODULE_3__["writeCinematicText"])(cinematicText).then(function() {
+            var popupId = "bladeburner-bitnode-start-nsa-notification";
+            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["createElement"])("p", {
+                innerText:"Visit the National Security Agency (NSA) to apply for their Bladeburner " +
+                          "division! You will need 100 of each combat stat before doing this."
+            })
+            var brEl = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["createElement"])("br");
+            var okBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["createElement"])("a", {
+                class:"a-link-button", innerText:"Got it!", padding:"8px",
+                clickListener:()=>{
+                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["removeElementById"])(popupId);
+                    return false;
+                }
+            });
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["createPopup"])(popupId, [txt, brEl, okBtn]);
+        }).catch(function(e) {
+            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["exceptionAlert"])(e);
+        })
+
+    }
+
+    //Gain int exp
+    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].gainIntelligenceExp(5);
+}
+
+
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 38)))
+
+/***/ }),
+/* 58 */
 /*!********************************************!*\
   !*** ./node_modules/jszip/lib/external.js ***!
   \********************************************/
@@ -60523,7 +61003,7 @@ var ES6Promise = null;
 if (typeof Promise !== "undefined") {
     ES6Promise = Promise;
 } else {
-    ES6Promise = __webpack_require__(/*! lie */ 138);
+    ES6Promise = __webpack_require__(/*! lie */ 139);
 }
 
 /**
@@ -60535,7 +61015,7 @@ module.exports = {
 
 
 /***/ }),
-/* 58 */
+/* 59 */
 /*!***********************************************!*\
   !*** ./node_modules/core-util-is/lib/util.js ***!
   \***********************************************/
@@ -60649,10 +61129,203 @@ function objectToString(o) {
   return Object.prototype.toString.call(o);
 }
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ 59).Buffer))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ 61).Buffer))
 
 /***/ }),
-/* 59 */
+/* 60 */
+/*!*****************************************!*\
+  !*** ./node_modules/process/browser.js ***!
+  \*****************************************/
+/***/ (function(module, exports) {
+
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things.  But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals.  It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+    throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+    throw new Error('clearTimeout has not been defined');
+}
+(function () {
+    try {
+        if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+        } else {
+            cachedSetTimeout = defaultSetTimout;
+        }
+    } catch (e) {
+        cachedSetTimeout = defaultSetTimout;
+    }
+    try {
+        if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+        } else {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } catch (e) {
+        cachedClearTimeout = defaultClearTimeout;
+    }
+} ())
+function runTimeout(fun) {
+    if (cachedSetTimeout === setTimeout) {
+        //normal enviroments in sane situations
+        return setTimeout(fun, 0);
+    }
+    // if setTimeout wasn't available but was latter defined
+    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+        cachedSetTimeout = setTimeout;
+        return setTimeout(fun, 0);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedSetTimeout(fun, 0);
+    } catch(e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+            return cachedSetTimeout.call(null, fun, 0);
+        } catch(e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+            return cachedSetTimeout.call(this, fun, 0);
+        }
+    }
+
+
+}
+function runClearTimeout(marker) {
+    if (cachedClearTimeout === clearTimeout) {
+        //normal enviroments in sane situations
+        return clearTimeout(marker);
+    }
+    // if clearTimeout wasn't available but was latter defined
+    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+        cachedClearTimeout = clearTimeout;
+        return clearTimeout(marker);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedClearTimeout(marker);
+    } catch (e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
+            return cachedClearTimeout.call(null, marker);
+        } catch (e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+            return cachedClearTimeout.call(this, marker);
+        }
+    }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    if (!draining || !currentQueue) {
+        return;
+    }
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = runTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        runTimeout(drainQueue);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+
+/***/ }),
+/* 61 */
 /*!**************************************!*\
   !*** ./node_modules/buffer/index.js ***!
   \**************************************/
@@ -60669,9 +61342,9 @@ function objectToString(o) {
 
 
 
-var base64 = __webpack_require__(/*! base64-js */ 164)
-var ieee754 = __webpack_require__(/*! ieee754 */ 163)
-var isArray = __webpack_require__(/*! isarray */ 106)
+var base64 = __webpack_require__(/*! base64-js */ 166)
+var ieee754 = __webpack_require__(/*! ieee754 */ 165)
+var isArray = __webpack_require__(/*! isarray */ 107)
 
 exports.Buffer = Buffer
 exports.SlowBuffer = SlowBuffer
@@ -62449,203 +63122,10 @@ function isnan (val) {
   return val !== val // eslint-disable-line no-self-compare
 }
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ 48)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ 49)))
 
 /***/ }),
-/* 60 */
-/*!*****************************************!*\
-  !*** ./node_modules/process/browser.js ***!
-  \*****************************************/
-/***/ (function(module, exports) {
-
-// shim for using process in browser
-var process = module.exports = {};
-
-// cached from whatever global is present so that test runners that stub it
-// don't break things.  But we need to wrap it in a try catch in case it is
-// wrapped in strict mode code which doesn't define any globals.  It's inside a
-// function because try/catches deoptimize in certain engines.
-
-var cachedSetTimeout;
-var cachedClearTimeout;
-
-function defaultSetTimout() {
-    throw new Error('setTimeout has not been defined');
-}
-function defaultClearTimeout () {
-    throw new Error('clearTimeout has not been defined');
-}
-(function () {
-    try {
-        if (typeof setTimeout === 'function') {
-            cachedSetTimeout = setTimeout;
-        } else {
-            cachedSetTimeout = defaultSetTimout;
-        }
-    } catch (e) {
-        cachedSetTimeout = defaultSetTimout;
-    }
-    try {
-        if (typeof clearTimeout === 'function') {
-            cachedClearTimeout = clearTimeout;
-        } else {
-            cachedClearTimeout = defaultClearTimeout;
-        }
-    } catch (e) {
-        cachedClearTimeout = defaultClearTimeout;
-    }
-} ())
-function runTimeout(fun) {
-    if (cachedSetTimeout === setTimeout) {
-        //normal enviroments in sane situations
-        return setTimeout(fun, 0);
-    }
-    // if setTimeout wasn't available but was latter defined
-    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
-        cachedSetTimeout = setTimeout;
-        return setTimeout(fun, 0);
-    }
-    try {
-        // when when somebody has screwed with setTimeout but no I.E. maddness
-        return cachedSetTimeout(fun, 0);
-    } catch(e){
-        try {
-            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
-            return cachedSetTimeout.call(null, fun, 0);
-        } catch(e){
-            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
-            return cachedSetTimeout.call(this, fun, 0);
-        }
-    }
-
-
-}
-function runClearTimeout(marker) {
-    if (cachedClearTimeout === clearTimeout) {
-        //normal enviroments in sane situations
-        return clearTimeout(marker);
-    }
-    // if clearTimeout wasn't available but was latter defined
-    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
-        cachedClearTimeout = clearTimeout;
-        return clearTimeout(marker);
-    }
-    try {
-        // when when somebody has screwed with setTimeout but no I.E. maddness
-        return cachedClearTimeout(marker);
-    } catch (e){
-        try {
-            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
-            return cachedClearTimeout.call(null, marker);
-        } catch (e){
-            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
-            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
-            return cachedClearTimeout.call(this, marker);
-        }
-    }
-
-
-
-}
-var queue = [];
-var draining = false;
-var currentQueue;
-var queueIndex = -1;
-
-function cleanUpNextTick() {
-    if (!draining || !currentQueue) {
-        return;
-    }
-    draining = false;
-    if (currentQueue.length) {
-        queue = currentQueue.concat(queue);
-    } else {
-        queueIndex = -1;
-    }
-    if (queue.length) {
-        drainQueue();
-    }
-}
-
-function drainQueue() {
-    if (draining) {
-        return;
-    }
-    var timeout = runTimeout(cleanUpNextTick);
-    draining = true;
-
-    var len = queue.length;
-    while(len) {
-        currentQueue = queue;
-        queue = [];
-        while (++queueIndex < len) {
-            if (currentQueue) {
-                currentQueue[queueIndex].run();
-            }
-        }
-        queueIndex = -1;
-        len = queue.length;
-    }
-    currentQueue = null;
-    draining = false;
-    runClearTimeout(timeout);
-}
-
-process.nextTick = function (fun) {
-    var args = new Array(arguments.length - 1);
-    if (arguments.length > 1) {
-        for (var i = 1; i < arguments.length; i++) {
-            args[i - 1] = arguments[i];
-        }
-    }
-    queue.push(new Item(fun, args));
-    if (queue.length === 1 && !draining) {
-        runTimeout(drainQueue);
-    }
-};
-
-// v8 likes predictible objects
-function Item(fun, array) {
-    this.fun = fun;
-    this.array = array;
-}
-Item.prototype.run = function () {
-    this.fun.apply(null, this.array);
-};
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-process.version = ''; // empty string to avoid regexp issues
-process.versions = {};
-
-function noop() {}
-
-process.on = noop;
-process.addListener = noop;
-process.once = noop;
-process.off = noop;
-process.removeListener = noop;
-process.removeAllListeners = noop;
-process.emit = noop;
-process.prependListener = noop;
-process.prependOnceListener = noop;
-
-process.listeners = function (name) { return [] }
-
-process.binding = function (name) {
-    throw new Error('process.binding is not supported');
-};
-
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
-    throw new Error('process.chdir is not supported');
-};
-process.umask = function() { return 0; };
-
-
-/***/ }),
-/* 61 */
+/* 62 */
 /*!****************************************************************************!*\
   !*** ./node_modules/jszip/node_modules/core-js/library/modules/_global.js ***!
   \****************************************************************************/
@@ -62657,7 +63137,7 @@ var global = module.exports = typeof window != 'undefined' && window.Math == Mat
 if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
 
 /***/ }),
-/* 62 */
+/* 63 */
 /*!***********************************************!*\
   !*** ./node_modules/jszip/lib/nodejsUtils.js ***!
   \***********************************************/
@@ -62717,17 +63197,17 @@ module.exports = {
     }
 };
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ 59).Buffer))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../buffer/index.js */ 61).Buffer))
 
 /***/ }),
-/* 63 */
+/* 64 */
 /*!*******************************************!*\
   !*** ./node_modules/safe-buffer/index.js ***!
   \*******************************************/
 /***/ (function(module, exports, __webpack_require__) {
 
 /* eslint-disable node/no-deprecated-api */
-var buffer = __webpack_require__(/*! buffer */ 59)
+var buffer = __webpack_require__(/*! buffer */ 61)
 var Buffer = buffer.Buffer
 
 // alternative to using Object.keys for old browsers
@@ -62791,7 +63271,7 @@ SafeBuffer.allocUnsafeSlow = function (size) {
 
 
 /***/ }),
-/* 64 */
+/* 65 */
 /*!****************************************************!*\
   !*** ./node_modules/process-nextick-args/index.js ***!
   \****************************************************/
@@ -62846,7 +63326,7 @@ function nextTick(fn, arg1, arg2, arg3) {
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../process/browser.js */ 60)))
 
 /***/ }),
-/* 65 */
+/* 66 */
 /*!*************************************!*\
   !*** ./src/NetscriptEnvironment.js ***!
   \*************************************/
@@ -62855,9 +63335,9 @@ function nextTick(fn, arg1, arg2, arg3) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Environment", function() { return Environment; });
-/* harmony import */ var _HacknetNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./HacknetNode.js */ 38);
-/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 30);
-/* harmony import */ var _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./NetscriptPort.js */ 43);
+/* harmony import */ var _HacknetNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./HacknetNode.js */ 39);
+/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 29);
+/* harmony import */ var _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./NetscriptPort.js */ 45);
 
 
 
@@ -62957,7 +63437,7 @@ Environment.prototype = {
 
 
 /***/ }),
-/* 66 */
+/* 67 */
 /*!******************************!*\
   !*** ./src/CinematicText.js ***!
   \******************************/
@@ -63069,343 +63549,6 @@ function cinematicTextEnd() {
 
 
 
-/***/ }),
-/* 67 */
-/*!*************************!*\
-  !*** ./src/Prestige.js ***!
-  \*************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prestigeAugmentation", function() { return prestigeAugmentation; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prestigeSourceFile", function() { return prestigeSourceFile; });
-/* harmony import */ var _ActiveScriptsUI_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActiveScriptsUI.js */ 42);
-/* harmony import */ var _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Augmentations.js */ 18);
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./BitNode.js */ 16);
-/* harmony import */ var _CinematicText_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./CinematicText.js */ 66);
-/* harmony import */ var _Company_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Company.js */ 9);
-/* harmony import */ var _CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./CreateProgram.js */ 13);
-/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./engine.js */ 5);
-/* harmony import */ var _Faction_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Faction.js */ 14);
-/* harmony import */ var _Gang_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Gang.js */ 35);
-/* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Location.js */ 4);
-/* harmony import */ var _Message_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Message.js */ 27);
-/* harmony import */ var _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./NetscriptFunctions.js */ 30);
-/* harmony import */ var _NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./NetscriptWorker.js */ 21);
-/* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Player.js */ 0);
-/* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Server.js */ 10);
-/* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17);
-/* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./StockMarket.js */ 20);
-/* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Terminal.js */ 22);
-/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/decimal.js */ 23);
-/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_18__);
-/* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//Prestige by purchasing augmentation
-function prestigeAugmentation() {
-    Object(_BitNode_js__WEBPACK_IMPORTED_MODULE_2__["initBitNodeMultipliers"])();
-
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].prestigeAugmentation();
-
-    //Delete all Worker Scripts objects
-    Object(_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_12__["prestigeWorkerScripts"])();
-
-    var homeComp = _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].getHomeComputer();
-    //Delete all servers except home computer
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["prestigeAllServers"])();
-
-    //Delete Special Server IPs
-    Object(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["prestigeSpecialServerIps"])(); //Must be done before initForeignServers()
-
-    //Reset home computer (only the programs) and add to AllServers
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["AddToAllServers"])(homeComp);
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["prestigeHomeComputer"])(homeComp);
-
-    if (Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["augmentationExists"])(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].Neurolink) &&
-        _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].Neurolink].owned) {
-        homeComp.programs.push(_CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__["Programs"].FTPCrackProgram);
-        homeComp.programs.push(_CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__["Programs"].RelaySMTPProgram);
-    }
-    if (Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["augmentationExists"])(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].CashRoot) &&
-        _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].CashRoot].owned) {
-        _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].setMoney(new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(1000000));
-        homeComp.programs.push(_CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__["Programs"].BruteSSHProgram);
-    }
-
-    //Re-create foreign servers
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["initForeignServers"])();
-
-    //Darkweb is purchase-able
-    document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button");
-
-    //Gain favor for Companies
-    for (var member in _Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"]) {
-        if (_Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"].hasOwnProperty(member)) {
-            _Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"][member].gainFavor();
-        }
-    }
-
-    //Gain favor for factions
-    for (var member in _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"]) {
-        if (_Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"].hasOwnProperty(member)) {
-            _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"][member].gainFavor();
-        }
-    }
-
-    //Stop a Terminal action if there is onerror
-    if (_engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"]._actionInProgress) {
-        _engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"]._actionInProgress = false;
-        _Terminal_js__WEBPACK_IMPORTED_MODULE_17__["Terminal"].finishAction(true);
-    }
-
-    //Re-initialize things - This will update any changes
-    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_7__["initFactions"])(); //Factions must be initialized before augmentations
-    Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["initAugmentations"])(); //Calls reapplyAllAugmentations() and resets Player multipliers
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].reapplyAllSourceFiles();
-    Object(_Company_js__WEBPACK_IMPORTED_MODULE_4__["initCompanies"])();
-
-    //Clear terminal
-    $("#terminal tr:not(:last)").remove();
-    Object(_Terminal_js__WEBPACK_IMPORTED_MODULE_17__["postNetburnerText"])();
-
-    //Messages
-    Object(_Message_js__WEBPACK_IMPORTED_MODULE_10__["initMessages"])();
-
-    //Reset Stock market
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount) {
-        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["initStockMarket"])();
-        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["initSymbolToStockMap"])();
-    }
-    Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["setStockMarketContentCreated"])(false);
-    var stockMarketList = document.getElementById("stock-market-list");
-    while(stockMarketList.firstChild) {
-        stockMarketList.removeChild(stockMarketList.firstChild);
-    }
-
-    //Gang, in BitNode 2
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN == 2 && _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].inGang()) {
-        var faction = _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"][_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].gang.facName];
-        if (faction instanceof _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Faction"]) {
-            Object(_Faction_js__WEBPACK_IMPORTED_MODULE_7__["joinFaction"])(faction);
-        }
-    }
-
-    //Reset Bladeburner
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bladeburner = null;
-
-    //BitNode 8: Ghost of Wall Street
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8) {_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(100e6);}
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["hasWallStreetSF"]) {
-        _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount = true;
-        _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasTixApiAccess = true;
-    }
-
-    var mainMenu = document.getElementById("mainmenu-container");
-    mainMenu.style.visibility = "visible";
-    _Terminal_js__WEBPACK_IMPORTED_MODULE_17__["Terminal"].resetTerminalInput();
-    _engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"].loadTerminalContent();
-
-    //Red Pill
-    if (Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["augmentationExists"])(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].TheRedPill) &&
-        _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].TheRedPill].owned) {
-        var WorldDaemon = _Server_js__WEBPACK_IMPORTED_MODULE_14__["AllServers"][_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["SpecialServerIps"][_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["SpecialServerNames"].WorldDaemon]];
-        var DaedalusServer = _Server_js__WEBPACK_IMPORTED_MODULE_14__["AllServers"][_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["SpecialServerIps"][_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["SpecialServerNames"].DaedalusServer]];
-        if (WorldDaemon && DaedalusServer) {
-            WorldDaemon.serversOnNetwork.push(DaedalusServer.ip);
-            DaedalusServer.serversOnNetwork.push(WorldDaemon.ip);
-        }
-    }
-}
-
-
-//Prestige by destroying Bit Node and gaining a Source File
-function prestigeSourceFile() {
-    Object(_BitNode_js__WEBPACK_IMPORTED_MODULE_2__["initBitNodeMultipliers"])();
-
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].prestigeSourceFile();
-    Object(_NetscriptWorker_js__WEBPACK_IMPORTED_MODULE_12__["prestigeWorkerScripts"])(); //Delete all Worker Scripts objects
-
-    var homeComp = _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].getHomeComputer();
-
-    //Delete all servers except home computer
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["prestigeAllServers"])(); //Must be done before initForeignServers()
-
-    //Delete Special Server IPs
-    Object(_SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__["prestigeSpecialServerIps"])();
-
-    //Reset home computer (only the programs) and add to AllServers
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["AddToAllServers"])(homeComp);
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["prestigeHomeComputer"])(homeComp);
-
-    //Re-create foreign servers
-    Object(_Server_js__WEBPACK_IMPORTED_MODULE_14__["initForeignServers"])();
-
-    var srcFile1Owned = false;
-    for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].sourceFiles.length; ++i) {
-        if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].sourceFiles[i].n == 1) {
-            srcFile1Owned = true;
-        }
-    }
-    if (srcFile1Owned) {
-        homeComp.setMaxRam(32);
-    } else {
-        homeComp.setMaxRam(8);
-    }
-    homeComp.cpuCores = 1;
-
-    //Darkweb is purchase-able
-    document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button");
-
-    //Reset favor for Companies
-    for (var member in _Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"]) {
-        if (_Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"].hasOwnProperty(member)) {
-            _Company_js__WEBPACK_IMPORTED_MODULE_4__["Companies"][member].favor = 0;
-        }
-    }
-
-    //Reset favor for factions
-    for (var member in _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"]) {
-        if (_Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"].hasOwnProperty(member)) {
-            _Faction_js__WEBPACK_IMPORTED_MODULE_7__["Factions"][member].favor = 0;
-        }
-    }
-
-    //Stop a Terminal action if there is one
-    if (_engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"]._actionInProgress) {
-        _engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"]._actionInProgress = false;
-        _Terminal_js__WEBPACK_IMPORTED_MODULE_17__["Terminal"].finishAction(true);
-    }
-
-    //Delete all Augmentations
-    for (var name in _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"]) {
-        if (_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"].hasOwnProperty(name)) {
-            delete _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][name];
-        }
-    }
-
-    //Re-initialize things - This will update any changes
-    Object(_Faction_js__WEBPACK_IMPORTED_MODULE_7__["initFactions"])(); //Factions must be initialized before augmentations
-    Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["initAugmentations"])();    //Calls reapplyAllAugmentations() and resets Player multipliers
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].reapplyAllSourceFiles();
-    Object(_Company_js__WEBPACK_IMPORTED_MODULE_4__["initCompanies"])();
-
-    //Clear terminal
-    $("#terminal tr:not(:last)").remove();
-    Object(_Terminal_js__WEBPACK_IMPORTED_MODULE_17__["postNetburnerText"])();
-
-    //Messages
-    Object(_Message_js__WEBPACK_IMPORTED_MODULE_10__["initMessages"])();
-
-    var mainMenu = document.getElementById("mainmenu-container");
-    mainMenu.style.visibility = "visible";
-    _Terminal_js__WEBPACK_IMPORTED_MODULE_17__["Terminal"].resetTerminalInput();
-    _engine_js__WEBPACK_IMPORTED_MODULE_6__["Engine"].loadTerminalContent();
-
-    //Reinitialize Bit Node flags
-    Object(_NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["initSingularitySFFlags"])();
-
-    //Reset Stock market, gang, and corporation
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount) {
-        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["initStockMarket"])();
-        Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["initSymbolToStockMap"])();
-    }
-    Object(_StockMarket_js__WEBPACK_IMPORTED_MODULE_16__["setStockMarketContentCreated"])(false);
-    var stockMarketList = document.getElementById("stock-market-list");
-    while(stockMarketList.firstChild) {
-        stockMarketList.removeChild(stockMarketList.firstChild);
-    }
-
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].gang = null;
-    Object(_Gang_js__WEBPACK_IMPORTED_MODULE_8__["deleteGangDisplayContent"])();
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].corporation = null;
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bladeburner = null;
-
-    //BitNode 3: Corporatocracy
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 3) {
-        _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(150e9);
-        homeComp.messages.push("corporation-management-handbook.lit");
-        Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_19__["dialogBoxCreate"])("You received a copy of the Corporation Management Handbook on your home computer. " +
-                        "Read it if you need help getting started with Corporations!");
-    }
-
-    //BitNode 6: Bladeburner
-    if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 6) {
-        var cinematicText = ["In the middle of the 21st century, OmniTek Incorporated advanced robot evolution " +
-                             "with their Synthoids (synthetic androids), a being virtually identical to a human.",
-                             "------",
-                             "Their sixth-generation Synthoids, called MK-VI, were stronger, faster, and more " +
-                             "intelligent than humans. Many argued that the MK-VI Synthoids were the first " +
-                             "example of sentient AI.",
-                             "------",
-                             "Unfortunately, in 2070 a terrorist group called Ascendis Totalis hacked into OmniTek and " +
-                             "uploaded a rogue AI into their Synthoid manufacturing facilities.",
-                             "------",
-                             "The MK-VI Synthoids infected by the rogue AI turned hostile toward humanity, initiating " +
-                             "the deadliest conflict in human history. This dark chapter is now known as the Synthoid Uprising.",
-                             "------",
-                             "In the aftermath of the Uprising, further manufacturing of Synthoids with advanced AI " +
-                             "was banned. MK-VI Synthoids that did not have the rogue Ascendis Totalis AI were " +
-                             "allowed to continue their existence.",
-                             "------",
-                             "The intelligence community believes that not all of the rogue MK-VI Synthoids from the Uprising were " +
-                             "found and destroyed, and that many of them are blending in as normal humans in society today. " +
-                             "As a result, many nations have created Bladeburner divisions, special units that are tasked with " +
-                             "investigating and dealing with Synthoid threats."];
-        Object(_CinematicText_js__WEBPACK_IMPORTED_MODULE_3__["writeCinematicText"])(cinematicText).then(function() {
-            var popupId = "bladeburner-bitnode-start-nsa-notification";
-            var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["createElement"])("p", {
-                innerText:"Visit the National Security Agency (NSA) to apply for their Bladeburner " +
-                          "division! You will need 100 of each combat stat before doing this."
-            })
-            var brEl = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["createElement"])("br");
-            var okBtn = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["createElement"])("a", {
-                class:"a-link-button", innerText:"Got it!", padding:"8px",
-                clickListener:()=>{
-                    Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["removeElementById"])(popupId);
-                    return false;
-                }
-            });
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["createPopup"])(popupId, [txt, brEl, okBtn]);
-        }).catch(function(e) {
-            Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__["exceptionAlert"])(e);
-        })
-
-    }
-
-    //Gain int exp
-    _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].gainIntelligenceExp(5);
-}
-
-
-
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ 41)))
-
 /***/ }),
 /* 68 */
 /*!*************************!*\
@@ -63775,7 +63918,7 @@ module.exports = function crc32wrapper(input, crc) {
 "use strict";
 
 
-var external = __webpack_require__(/*! ./external */ 57);
+var external = __webpack_require__(/*! ./external */ 58);
 var DataWorker = __webpack_require__(/*! ./stream/DataWorker */ 92);
 var DataLengthProbe = __webpack_require__(/*! ./stream/DataLengthProbe */ 91);
 var Crc32Probe = __webpack_require__(/*! ./stream/Crc32Probe */ 90);
@@ -63910,7 +64053,7 @@ module.exports = function(it){
 
 /*<replacement>*/
 
-var processNextTick = __webpack_require__(/*! process-nextick-args */ 64).nextTick;
+var processNextTick = __webpack_require__(/*! process-nextick-args */ 65).nextTick;
 /*</replacement>*/
 
 module.exports = Writable;
@@ -63947,23 +64090,23 @@ var Duplex;
 Writable.WritableState = WritableState;
 
 /*<replacement>*/
-var util = __webpack_require__(/*! core-util-is */ 58);
+var util = __webpack_require__(/*! core-util-is */ 59);
 util.inherits = __webpack_require__(/*! inherits */ 55);
 /*</replacement>*/
 
 /*<replacement>*/
 var internalUtil = {
-  deprecate: __webpack_require__(/*! util-deprecate */ 158)
+  deprecate: __webpack_require__(/*! util-deprecate */ 159)
 };
 /*</replacement>*/
 
 /*<replacement>*/
-var Stream = __webpack_require__(/*! ./internal/streams/stream */ 103);
+var Stream = __webpack_require__(/*! ./internal/streams/stream */ 104);
 /*</replacement>*/
 
 /*<replacement>*/
 
-var Buffer = __webpack_require__(/*! safe-buffer */ 63).Buffer;
+var Buffer = __webpack_require__(/*! safe-buffer */ 64).Buffer;
 var OurUint8Array = global.Uint8Array || function () {};
 function _uint8ArrayToBuffer(chunk) {
   return Buffer.from(chunk);
@@ -63974,7 +64117,7 @@ function _isUint8Array(obj) {
 
 /*</replacement>*/
 
-var destroyImpl = __webpack_require__(/*! ./internal/streams/destroy */ 102);
+var destroyImpl = __webpack_require__(/*! ./internal/streams/destroy */ 103);
 
 util.inherits(Writable, Stream);
 
@@ -64558,7 +64701,7 @@ Writable.prototype._destroy = function (err, cb) {
   this.end();
   cb(err);
 };
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../process/browser.js */ 60), __webpack_require__(/*! ./../../timers-browserify/main.js */ 107).setImmediate, __webpack_require__(/*! ./../../webpack/buildin/global.js */ 48)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../process/browser.js */ 60), __webpack_require__(/*! ./../../timers-browserify/main.js */ 102).setImmediate, __webpack_require__(/*! ./../../webpack/buildin/global.js */ 49)))
 
 /***/ }),
 /* 75 */
@@ -64567,13 +64710,13 @@ Writable.prototype._destroy = function (err, cb) {
   \**********************************************************/
 /***/ (function(module, exports, __webpack_require__) {
 
-exports = module.exports = __webpack_require__(/*! ./lib/_stream_readable.js */ 104);
+exports = module.exports = __webpack_require__(/*! ./lib/_stream_readable.js */ 105);
 exports.Stream = exports;
 exports.Readable = exports;
 exports.Writable = __webpack_require__(/*! ./lib/_stream_writable.js */ 74);
 exports.Duplex = __webpack_require__(/*! ./lib/_stream_duplex.js */ 52);
 exports.Transform = __webpack_require__(/*! ./lib/_stream_transform.js */ 100);
-exports.PassThrough = __webpack_require__(/*! ./lib/_stream_passthrough.js */ 157);
+exports.PassThrough = __webpack_require__(/*! ./lib/_stream_passthrough.js */ 158);
 
 
 /***/ }),
@@ -64914,8 +65057,8 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Player.js */ 0);
 /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Server.js */ 10);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
-/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/IPAddress.js */ 15);
-/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 11);
+/* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16);
+/* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12);
 
 
 
@@ -65220,10 +65363,10 @@ module.exports = ArrayReader;
 
 
 var utils = __webpack_require__(/*! ../utils */ 31);
-var support = __webpack_require__(/*! ../support */ 47);
+var support = __webpack_require__(/*! ../support */ 50);
 var ArrayReader = __webpack_require__(/*! ./ArrayReader */ 81);
-var StringReader = __webpack_require__(/*! ./StringReader */ 118);
-var NodeBufferReader = __webpack_require__(/*! ./NodeBufferReader */ 117);
+var StringReader = __webpack_require__(/*! ./StringReader */ 119);
+var NodeBufferReader = __webpack_require__(/*! ./NodeBufferReader */ 118);
 var Uint8ArrayReader = __webpack_require__(/*! ./Uint8ArrayReader */ 79);
 
 /**
@@ -65411,7 +65554,7 @@ module.exports = ZStream;
 
 
 
-var utils = __webpack_require__(/*! ./common */ 46);
+var utils = __webpack_require__(/*! ./common */ 48);
 
 
 // Quick check if we can use fast array to bin string conversion
@@ -65745,7 +65888,7 @@ exports.STORE = {
         return new GenericWorker("STORE decompression");
     }
 };
-exports.DEFLATE = __webpack_require__(/*! ./flate */ 132);
+exports.DEFLATE = __webpack_require__(/*! ./flate */ 133);
 
 
 /***/ }),
@@ -65979,16 +66122,16 @@ exports.dosPermissions = null;
 /* WEBPACK VAR INJECTION */(function(Buffer) {
 
 var utils = __webpack_require__(/*! ../utils */ 31);
-var ConvertWorker = __webpack_require__(/*! ./ConvertWorker */ 136);
+var ConvertWorker = __webpack_require__(/*! ./ConvertWorker */ 137);
 var GenericWorker = __webpack_require__(/*! ./GenericWorker */ 37);
 var base64 = __webpack_require__(/*! ../base64 */ 99);
-var support = __webpack_require__(/*! ../support */ 47);
-var external = __webpack_require__(/*! ../external */ 57);
+var support = __webpack_require__(/*! ../support */ 50);
+var external = __webpack_require__(/*! ../external */ 58);
 
 var NodejsStreamOutputAdapter = null;
 if (support.nodestream) {
     try {
-        NodejsStreamOutputAdapter = __webpack_require__(/*! ../nodejs/NodejsStreamOutputAdapter */ 135);
+        NodejsStreamOutputAdapter = __webpack_require__(/*! ../nodejs/NodejsStreamOutputAdapter */ 136);
     } catch(e) {}
 }
 
@@ -66189,7 +66332,7 @@ StreamHelper.prototype = {
 
 module.exports = StreamHelper;
 
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../buffer/index.js */ 59).Buffer))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../buffer/index.js */ 61).Buffer))
 
 /***/ }),
 /* 95 */
@@ -66199,7 +66342,7 @@ module.exports = StreamHelper;
 /***/ (function(module, exports, __webpack_require__) {
 
 var isObject = __webpack_require__(/*! ./_is-object */ 73)
-  , document = __webpack_require__(/*! ./_global */ 61).document
+  , document = __webpack_require__(/*! ./_global */ 62).document
   // in old IE typeof document.createElement is 'object'
   , is = isObject(document) && isObject(document.createElement);
 module.exports = function(it){
@@ -66229,7 +66372,7 @@ module.exports = function(exec){
 /***/ (function(module, exports, __webpack_require__) {
 
 // optional / simple context binding
-var aFunction = __webpack_require__(/*! ./_a-function */ 149);
+var aFunction = __webpack_require__(/*! ./_a-function */ 150);
 module.exports = function(fn, that, length){
   aFunction(fn);
   if(that === undefined)return fn;
@@ -66269,7 +66412,7 @@ if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
 "use strict";
 
 var utils = __webpack_require__(/*! ./utils */ 31);
-var support = __webpack_require__(/*! ./support */ 47);
+var support = __webpack_require__(/*! ./support */ 50);
 // private property
 var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
 
@@ -66453,7 +66596,7 @@ module.exports = Transform;
 var Duplex = __webpack_require__(/*! ./_stream_duplex */ 52);
 
 /*<replacement>*/
-var util = __webpack_require__(/*! core-util-is */ 58);
+var util = __webpack_require__(/*! core-util-is */ 59);
 util.inherits = __webpack_require__(/*! inherits */ 55);
 /*</replacement>*/
 
@@ -66608,7 +66751,7 @@ function done(stream, er, data) {
 "use strict";
 
 
-var Buffer = __webpack_require__(/*! safe-buffer */ 63).Buffer;
+var Buffer = __webpack_require__(/*! safe-buffer */ 64).Buffer;
 
 var isEncoding = Buffer.isEncoding || function (encoding) {
   encoding = '' + encoding;
@@ -66881,6 +67024,76 @@ function simpleEnd(buf) {
 
 /***/ }),
 /* 102 */
+/*!************************************************!*\
+  !*** ./node_modules/timers-browserify/main.js ***!
+  \************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(global) {var apply = Function.prototype.apply;
+
+// DOM APIs, for completeness
+
+exports.setTimeout = function() {
+  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
+};
+exports.setInterval = function() {
+  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
+};
+exports.clearTimeout =
+exports.clearInterval = function(timeout) {
+  if (timeout) {
+    timeout.close();
+  }
+};
+
+function Timeout(id, clearFn) {
+  this._id = id;
+  this._clearFn = clearFn;
+}
+Timeout.prototype.unref = Timeout.prototype.ref = function() {};
+Timeout.prototype.close = function() {
+  this._clearFn.call(window, this._id);
+};
+
+// Does not start the time, just sets up the members needed.
+exports.enroll = function(item, msecs) {
+  clearTimeout(item._idleTimeoutId);
+  item._idleTimeout = msecs;
+};
+
+exports.unenroll = function(item) {
+  clearTimeout(item._idleTimeoutId);
+  item._idleTimeout = -1;
+};
+
+exports._unrefActive = exports.active = function(item) {
+  clearTimeout(item._idleTimeoutId);
+
+  var msecs = item._idleTimeout;
+  if (msecs >= 0) {
+    item._idleTimeoutId = setTimeout(function onTimeout() {
+      if (item._onTimeout)
+        item._onTimeout();
+    }, msecs);
+  }
+};
+
+// setimmediate attaches itself to the global object
+__webpack_require__(/*! setimmediate */ 160);
+// On some exotic environments, it's not clear which object `setimmeidate` was
+// able to install onto.  Search each possibility in the same order as the
+// `setimmediate` library.
+exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) ||
+                       (typeof global !== "undefined" && global.setImmediate) ||
+                       (this && this.setImmediate);
+exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) ||
+                         (typeof global !== "undefined" && global.clearImmediate) ||
+                         (this && this.clearImmediate);
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ 49)))
+
+/***/ }),
+/* 103 */
 /*!**********************************************************************!*\
   !*** ./node_modules/readable-stream/lib/internal/streams/destroy.js ***!
   \**********************************************************************/
@@ -66891,7 +67104,7 @@ function simpleEnd(buf) {
 
 /*<replacement>*/
 
-var processNextTick = __webpack_require__(/*! process-nextick-args */ 64).nextTick;
+var processNextTick = __webpack_require__(/*! process-nextick-args */ 65).nextTick;
 /*</replacement>*/
 
 // undocumented cb() API, needed for core, not for public API
@@ -66963,7 +67176,7 @@ module.exports = {
 };
 
 /***/ }),
-/* 103 */
+/* 104 */
 /*!*****************************************************************************!*\
   !*** ./node_modules/readable-stream/lib/internal/streams/stream-browser.js ***!
   \*****************************************************************************/
@@ -66973,7 +67186,7 @@ module.exports = __webpack_require__(/*! events */ 76).EventEmitter;
 
 
 /***/ }),
-/* 104 */
+/* 105 */
 /*!**************************************************************!*\
   !*** ./node_modules/readable-stream/lib/_stream_readable.js ***!
   \**************************************************************/
@@ -67005,13 +67218,13 @@ module.exports = __webpack_require__(/*! events */ 76).EventEmitter;
 
 /*<replacement>*/
 
-var processNextTick = __webpack_require__(/*! process-nextick-args */ 64).nextTick;
+var processNextTick = __webpack_require__(/*! process-nextick-args */ 65).nextTick;
 /*</replacement>*/
 
 module.exports = Readable;
 
 /*<replacement>*/
-var isArray = __webpack_require__(/*! isarray */ 106);
+var isArray = __webpack_require__(/*! isarray */ 107);
 /*</replacement>*/
 
 /*<replacement>*/
@@ -67029,12 +67242,12 @@ var EElistenerCount = function (emitter, type) {
 /*</replacement>*/
 
 /*<replacement>*/
-var Stream = __webpack_require__(/*! ./internal/streams/stream */ 103);
+var Stream = __webpack_require__(/*! ./internal/streams/stream */ 104);
 /*</replacement>*/
 
 /*<replacement>*/
 
-var Buffer = __webpack_require__(/*! safe-buffer */ 63).Buffer;
+var Buffer = __webpack_require__(/*! safe-buffer */ 64).Buffer;
 var OurUint8Array = global.Uint8Array || function () {};
 function _uint8ArrayToBuffer(chunk) {
   return Buffer.from(chunk);
@@ -67046,12 +67259,12 @@ function _isUint8Array(obj) {
 /*</replacement>*/
 
 /*<replacement>*/
-var util = __webpack_require__(/*! core-util-is */ 58);
+var util = __webpack_require__(/*! core-util-is */ 59);
 util.inherits = __webpack_require__(/*! inherits */ 55);
 /*</replacement>*/
 
 /*<replacement>*/
-var debugUtil = __webpack_require__(/*! util */ 161);
+var debugUtil = __webpack_require__(/*! util */ 163);
 var debug = void 0;
 if (debugUtil && debugUtil.debuglog) {
   debug = debugUtil.debuglog('stream');
@@ -67060,8 +67273,8 @@ if (debugUtil && debugUtil.debuglog) {
 }
 /*</replacement>*/
 
-var BufferList = __webpack_require__(/*! ./internal/streams/BufferList */ 160);
-var destroyImpl = __webpack_require__(/*! ./internal/streams/destroy */ 102);
+var BufferList = __webpack_require__(/*! ./internal/streams/BufferList */ 162);
+var destroyImpl = __webpack_require__(/*! ./internal/streams/destroy */ 103);
 var StringDecoder;
 
 util.inherits(Readable, Stream);
@@ -67995,10 +68208,10 @@ function indexOf(xs, x) {
   }
   return -1;
 }
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ 48), __webpack_require__(/*! ./../../process/browser.js */ 60)))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ 49), __webpack_require__(/*! ./../../process/browser.js */ 60)))
 
 /***/ }),
-/* 105 */
+/* 106 */
 /*!***********************************************************!*\
   !*** ./node_modules/jszip/lib/readable-stream-browser.js ***!
   \***********************************************************/
@@ -68012,11 +68225,11 @@ function indexOf(xs, x) {
  * reduce the final size of the bundle (only one stream implementation, not
  * two).
  */
-module.exports = __webpack_require__(/*! stream */ 162);
+module.exports = __webpack_require__(/*! stream */ 164);
 
 
 /***/ }),
-/* 106 */
+/* 107 */
 /*!***************************************!*\
   !*** ./node_modules/isarray/index.js ***!
   \***************************************/
@@ -68029,88 +68242,8 @@ module.exports = Array.isArray || function (arr) {
 };
 
 
-/***/ }),
-/* 107 */
-/*!************************************************!*\
-  !*** ./node_modules/timers-browserify/main.js ***!
-  \************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-/* WEBPACK VAR INJECTION */(function(global) {var apply = Function.prototype.apply;
-
-// DOM APIs, for completeness
-
-exports.setTimeout = function() {
-  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
-};
-exports.setInterval = function() {
-  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
-};
-exports.clearTimeout =
-exports.clearInterval = function(timeout) {
-  if (timeout) {
-    timeout.close();
-  }
-};
-
-function Timeout(id, clearFn) {
-  this._id = id;
-  this._clearFn = clearFn;
-}
-Timeout.prototype.unref = Timeout.prototype.ref = function() {};
-Timeout.prototype.close = function() {
-  this._clearFn.call(window, this._id);
-};
-
-// Does not start the time, just sets up the members needed.
-exports.enroll = function(item, msecs) {
-  clearTimeout(item._idleTimeoutId);
-  item._idleTimeout = msecs;
-};
-
-exports.unenroll = function(item) {
-  clearTimeout(item._idleTimeoutId);
-  item._idleTimeout = -1;
-};
-
-exports._unrefActive = exports.active = function(item) {
-  clearTimeout(item._idleTimeoutId);
-
-  var msecs = item._idleTimeout;
-  if (msecs >= 0) {
-    item._idleTimeoutId = setTimeout(function onTimeout() {
-      if (item._onTimeout)
-        item._onTimeout();
-    }, msecs);
-  }
-};
-
-// setimmediate attaches itself to the global object
-__webpack_require__(/*! setimmediate */ 166);
-// On some exotic environments, it's not clear which object `setimmeidate` was
-// able to install onto.  Search each possibility in the same order as the
-// `setimmediate` library.
-exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) ||
-                       (typeof global !== "undefined" && global.setImmediate) ||
-                       (this && this.setImmediate);
-exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) ||
-                         (typeof global !== "undefined" && global.clearImmediate) ||
-                         (this && this.clearImmediate);
-
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ 48)))
-
 /***/ }),
 /* 108 */
-/*!*************************************************!*\
-  !*** ./node_modules/brace/worker/javascript.js ***!
-  \*************************************************/
-/***/ (function(module, exports) {
-
-module.exports.id = 'ace/mode/javascript_worker';
-module.exports.src = "\"no use strict\";!function(window){function resolveModuleId(id,paths){for(var testPath=id,tail=\"\";testPath;){var alias=paths[testPath];if(\"string\"==typeof alias)return alias+tail;if(alias)return alias.location.replace(/\\/*$/,\"/\")+(tail||alias.main||alias.name);if(alias===!1)return\"\";var i=testPath.lastIndexOf(\"/\");if(-1===i)break;tail=testPath.substr(i)+tail,testPath=testPath.slice(0,i)}return id}if(!(void 0!==window.window&&window.document||window.acequire&&window.define)){window.console||(window.console=function(){var msgs=Array.prototype.slice.call(arguments,0);postMessage({type:\"log\",data:msgs})},window.console.error=window.console.warn=window.console.log=window.console.trace=window.console),window.window=window,window.ace=window,window.onerror=function(message,file,line,col,err){postMessage({type:\"error\",data:{message:message,data:err.data,file:file,line:line,col:col,stack:err.stack}})},window.normalizeModule=function(parentId,moduleName){if(-1!==moduleName.indexOf(\"!\")){var chunks=moduleName.split(\"!\");return window.normalizeModule(parentId,chunks[0])+\"!\"+window.normalizeModule(parentId,chunks[1])}if(\".\"==moduleName.charAt(0)){var base=parentId.split(\"/\").slice(0,-1).join(\"/\");for(moduleName=(base?base+\"/\":\"\")+moduleName;-1!==moduleName.indexOf(\".\")&&previous!=moduleName;){var previous=moduleName;moduleName=moduleName.replace(/^\\.\\//,\"\").replace(/\\/\\.\\//,\"/\").replace(/[^\\/]+\\/\\.\\.\\//,\"\")}}return moduleName},window.acequire=function acequire(parentId,id){if(id||(id=parentId,parentId=null),!id.charAt)throw Error(\"worker.js acequire() accepts only (parentId, id) as arguments\");id=window.normalizeModule(parentId,id);var module=window.acequire.modules[id];if(module)return module.initialized||(module.initialized=!0,module.exports=module.factory().exports),module.exports;if(!window.acequire.tlns)return console.log(\"unable to load \"+id);var path=resolveModuleId(id,window.acequire.tlns);return\".js\"!=path.slice(-3)&&(path+=\".js\"),window.acequire.id=id,window.acequire.modules[id]={},importScripts(path),window.acequire(parentId,id)},window.acequire.modules={},window.acequire.tlns={},window.define=function(id,deps,factory){if(2==arguments.length?(factory=deps,\"string\"!=typeof id&&(deps=id,id=window.acequire.id)):1==arguments.length&&(factory=id,deps=[],id=window.acequire.id),\"function\"!=typeof factory)return window.acequire.modules[id]={exports:factory,initialized:!0},void 0;deps.length||(deps=[\"require\",\"exports\",\"module\"]);var req=function(childId){return window.acequire(id,childId)};window.acequire.modules[id]={exports:{},factory:function(){var module=this,returnExports=factory.apply(this,deps.map(function(dep){switch(dep){case\"require\":return req;case\"exports\":return module.exports;case\"module\":return module;default:return req(dep)}}));return returnExports&&(module.exports=returnExports),module}}},window.define.amd={},acequire.tlns={},window.initBaseUrls=function(topLevelNamespaces){for(var i in topLevelNamespaces)acequire.tlns[i]=topLevelNamespaces[i]},window.initSender=function(){var EventEmitter=window.acequire(\"ace/lib/event_emitter\").EventEmitter,oop=window.acequire(\"ace/lib/oop\"),Sender=function(){};return function(){oop.implement(this,EventEmitter),this.callback=function(data,callbackId){postMessage({type:\"call\",id:callbackId,data:data})},this.emit=function(name,data){postMessage({type:\"event\",name:name,data:data})}}.call(Sender.prototype),new Sender};var main=window.main=null,sender=window.sender=null;window.onmessage=function(e){var msg=e.data;if(msg.event&&sender)sender._signal(msg.event,msg.data);else if(msg.command)if(main[msg.command])main[msg.command].apply(main,msg.args);else{if(!window[msg.command])throw Error(\"Unknown command:\"+msg.command);window[msg.command].apply(window,msg.args)}else if(msg.init){window.initBaseUrls(msg.tlns),acequire(\"ace/lib/es5-shim\"),sender=window.sender=window.initSender();var clazz=acequire(msg.module)[msg.classname];main=window.main=new clazz(sender)}}}}(this),ace.define(\"ace/lib/oop\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";exports.inherits=function(ctor,superCtor){ctor.super_=superCtor,ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:!1,writable:!0,configurable:!0}})},exports.mixin=function(obj,mixin){for(var key in mixin)obj[key]=mixin[key];return obj},exports.implement=function(proto,mixin){exports.mixin(proto,mixin)}}),ace.define(\"ace/range\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";var comparePoints=function(p1,p2){return p1.row-p2.row||p1.column-p2.column},Range=function(startRow,startColumn,endRow,endColumn){this.start={row:startRow,column:startColumn},this.end={row:endRow,column:endColumn}};(function(){this.isEqual=function(range){return this.start.row===range.start.row&&this.end.row===range.end.row&&this.start.column===range.start.column&&this.end.column===range.end.column},this.toString=function(){return\"Range: [\"+this.start.row+\"/\"+this.start.column+\"] -> [\"+this.end.row+\"/\"+this.end.column+\"]\"},this.contains=function(row,column){return 0==this.compare(row,column)},this.compareRange=function(range){var cmp,end=range.end,start=range.start;return cmp=this.compare(end.row,end.column),1==cmp?(cmp=this.compare(start.row,start.column),1==cmp?2:0==cmp?1:0):-1==cmp?-2:(cmp=this.compare(start.row,start.column),-1==cmp?-1:1==cmp?42:0)},this.comparePoint=function(p){return this.compare(p.row,p.column)},this.containsRange=function(range){return 0==this.comparePoint(range.start)&&0==this.comparePoint(range.end)},this.intersects=function(range){var cmp=this.compareRange(range);return-1==cmp||0==cmp||1==cmp},this.isEnd=function(row,column){return this.end.row==row&&this.end.column==column},this.isStart=function(row,column){return this.start.row==row&&this.start.column==column},this.setStart=function(row,column){\"object\"==typeof row?(this.start.column=row.column,this.start.row=row.row):(this.start.row=row,this.start.column=column)},this.setEnd=function(row,column){\"object\"==typeof row?(this.end.column=row.column,this.end.row=row.row):(this.end.row=row,this.end.column=column)},this.inside=function(row,column){return 0==this.compare(row,column)?this.isEnd(row,column)||this.isStart(row,column)?!1:!0:!1},this.insideStart=function(row,column){return 0==this.compare(row,column)?this.isEnd(row,column)?!1:!0:!1},this.insideEnd=function(row,column){return 0==this.compare(row,column)?this.isStart(row,column)?!1:!0:!1},this.compare=function(row,column){return this.isMultiLine()||row!==this.start.row?this.start.row>row?-1:row>this.end.row?1:this.start.row===row?column>=this.start.column?0:-1:this.end.row===row?this.end.column>=column?0:1:0:this.start.column>column?-1:column>this.end.column?1:0},this.compareStart=function(row,column){return this.start.row==row&&this.start.column==column?-1:this.compare(row,column)},this.compareEnd=function(row,column){return this.end.row==row&&this.end.column==column?1:this.compare(row,column)},this.compareInside=function(row,column){return this.end.row==row&&this.end.column==column?1:this.start.row==row&&this.start.column==column?-1:this.compare(row,column)},this.clipRows=function(firstRow,lastRow){if(this.end.row>lastRow)var end={row:lastRow+1,column:0};else if(firstRow>this.end.row)var end={row:firstRow,column:0};if(this.start.row>lastRow)var start={row:lastRow+1,column:0};else if(firstRow>this.start.row)var start={row:firstRow,column:0};return Range.fromPoints(start||this.start,end||this.end)},this.extend=function(row,column){var cmp=this.compare(row,column);if(0==cmp)return this;if(-1==cmp)var start={row:row,column:column};else var end={row:row,column:column};return Range.fromPoints(start||this.start,end||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return Range.fromPoints(this.start,this.end)},this.collapseRows=function(){return 0==this.end.column?new Range(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new Range(this.start.row,0,this.end.row,0)},this.toScreenRange=function(session){var screenPosStart=session.documentToScreenPosition(this.start),screenPosEnd=session.documentToScreenPosition(this.end);return new Range(screenPosStart.row,screenPosStart.column,screenPosEnd.row,screenPosEnd.column)},this.moveBy=function(row,column){this.start.row+=row,this.start.column+=column,this.end.row+=row,this.end.column+=column}}).call(Range.prototype),Range.fromPoints=function(start,end){return new Range(start.row,start.column,end.row,end.column)},Range.comparePoints=comparePoints,Range.comparePoints=function(p1,p2){return p1.row-p2.row||p1.column-p2.column},exports.Range=Range}),ace.define(\"ace/apply_delta\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";exports.applyDelta=function(docLines,delta){var row=delta.start.row,startColumn=delta.start.column,line=docLines[row]||\"\";switch(delta.action){case\"insert\":var lines=delta.lines;if(1===lines.length)docLines[row]=line.substring(0,startColumn)+delta.lines[0]+line.substring(startColumn);else{var args=[row,1].concat(delta.lines);docLines.splice.apply(docLines,args),docLines[row]=line.substring(0,startColumn)+docLines[row],docLines[row+delta.lines.length-1]+=line.substring(startColumn)}break;case\"remove\":var endColumn=delta.end.column,endRow=delta.end.row;row===endRow?docLines[row]=line.substring(0,startColumn)+line.substring(endColumn):docLines.splice(row,endRow-row+1,line.substring(0,startColumn)+docLines[endRow].substring(endColumn))}}}),ace.define(\"ace/lib/event_emitter\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";var EventEmitter={},stopPropagation=function(){this.propagationStopped=!0},preventDefault=function(){this.defaultPrevented=!0};EventEmitter._emit=EventEmitter._dispatchEvent=function(eventName,e){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var listeners=this._eventRegistry[eventName]||[],defaultHandler=this._defaultHandlers[eventName];if(listeners.length||defaultHandler){\"object\"==typeof e&&e||(e={}),e.type||(e.type=eventName),e.stopPropagation||(e.stopPropagation=stopPropagation),e.preventDefault||(e.preventDefault=preventDefault),listeners=listeners.slice();for(var i=0;listeners.length>i&&(listeners[i](e,this),!e.propagationStopped);i++);return defaultHandler&&!e.defaultPrevented?defaultHandler(e,this):void 0}},EventEmitter._signal=function(eventName,e){var listeners=(this._eventRegistry||{})[eventName];if(listeners){listeners=listeners.slice();for(var i=0;listeners.length>i;i++)listeners[i](e,this)}},EventEmitter.once=function(eventName,callback){var _self=this;callback&&this.addEventListener(eventName,function newCallback(){_self.removeEventListener(eventName,newCallback),callback.apply(null,arguments)})},EventEmitter.setDefaultHandler=function(eventName,callback){var handlers=this._defaultHandlers;if(handlers||(handlers=this._defaultHandlers={_disabled_:{}}),handlers[eventName]){var old=handlers[eventName],disabled=handlers._disabled_[eventName];disabled||(handlers._disabled_[eventName]=disabled=[]),disabled.push(old);var i=disabled.indexOf(callback);-1!=i&&disabled.splice(i,1)}handlers[eventName]=callback},EventEmitter.removeDefaultHandler=function(eventName,callback){var handlers=this._defaultHandlers;if(handlers){var disabled=handlers._disabled_[eventName];if(handlers[eventName]==callback)handlers[eventName],disabled&&this.setDefaultHandler(eventName,disabled.pop());else if(disabled){var i=disabled.indexOf(callback);-1!=i&&disabled.splice(i,1)}}},EventEmitter.on=EventEmitter.addEventListener=function(eventName,callback,capturing){this._eventRegistry=this._eventRegistry||{};var listeners=this._eventRegistry[eventName];return listeners||(listeners=this._eventRegistry[eventName]=[]),-1==listeners.indexOf(callback)&&listeners[capturing?\"unshift\":\"push\"](callback),callback},EventEmitter.off=EventEmitter.removeListener=EventEmitter.removeEventListener=function(eventName,callback){this._eventRegistry=this._eventRegistry||{};var listeners=this._eventRegistry[eventName];if(listeners){var index=listeners.indexOf(callback);-1!==index&&listeners.splice(index,1)}},EventEmitter.removeAllListeners=function(eventName){this._eventRegistry&&(this._eventRegistry[eventName]=[])},exports.EventEmitter=EventEmitter}),ace.define(\"ace/anchor\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(acequire,exports){\"use strict\";var oop=acequire(\"./lib/oop\"),EventEmitter=acequire(\"./lib/event_emitter\").EventEmitter,Anchor=exports.Anchor=function(doc,row,column){this.$onChange=this.onChange.bind(this),this.attach(doc),column===void 0?this.setPosition(row.row,row.column):this.setPosition(row,column)};(function(){function $pointsInOrder(point1,point2,equalPointsInOrder){var bColIsAfter=equalPointsInOrder?point1.column<=point2.column:point1.column<point2.column;return point1.row<point2.row||point1.row==point2.row&&bColIsAfter}function $getTransformedPoint(delta,point,moveIfEqual){var deltaIsInsert=\"insert\"==delta.action,deltaRowShift=(deltaIsInsert?1:-1)*(delta.end.row-delta.start.row),deltaColShift=(deltaIsInsert?1:-1)*(delta.end.column-delta.start.column),deltaStart=delta.start,deltaEnd=deltaIsInsert?deltaStart:delta.end;return $pointsInOrder(point,deltaStart,moveIfEqual)?{row:point.row,column:point.column}:$pointsInOrder(deltaEnd,point,!moveIfEqual)?{row:point.row+deltaRowShift,column:point.column+(point.row==deltaEnd.row?deltaColShift:0)}:{row:deltaStart.row,column:deltaStart.column}}oop.implement(this,EventEmitter),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(delta){if(!(delta.start.row==delta.end.row&&delta.start.row!=this.row||delta.start.row>this.row)){var point=$getTransformedPoint(delta,{row:this.row,column:this.column},this.$insertRight);this.setPosition(point.row,point.column,!0)}},this.setPosition=function(row,column,noClip){var pos;if(pos=noClip?{row:row,column:column}:this.$clipPositionToDocument(row,column),this.row!=pos.row||this.column!=pos.column){var old={row:this.row,column:this.column};this.row=pos.row,this.column=pos.column,this._signal(\"change\",{old:old,value:pos})}},this.detach=function(){this.document.removeEventListener(\"change\",this.$onChange)},this.attach=function(doc){this.document=doc||this.document,this.document.on(\"change\",this.$onChange)},this.$clipPositionToDocument=function(row,column){var pos={};return row>=this.document.getLength()?(pos.row=Math.max(0,this.document.getLength()-1),pos.column=this.document.getLine(pos.row).length):0>row?(pos.row=0,pos.column=0):(pos.row=row,pos.column=Math.min(this.document.getLine(pos.row).length,Math.max(0,column))),0>column&&(pos.column=0),pos}}).call(Anchor.prototype)}),ace.define(\"ace/document\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/apply_delta\",\"ace/lib/event_emitter\",\"ace/range\",\"ace/anchor\"],function(acequire,exports){\"use strict\";var oop=acequire(\"./lib/oop\"),applyDelta=acequire(\"./apply_delta\").applyDelta,EventEmitter=acequire(\"./lib/event_emitter\").EventEmitter,Range=acequire(\"./range\").Range,Anchor=acequire(\"./anchor\").Anchor,Document=function(textOrLines){this.$lines=[\"\"],0===textOrLines.length?this.$lines=[\"\"]:Array.isArray(textOrLines)?this.insertMergedLines({row:0,column:0},textOrLines):this.insert({row:0,column:0},textOrLines)};(function(){oop.implement(this,EventEmitter),this.setValue=function(text){var len=this.getLength()-1;this.remove(new Range(0,0,len,this.getLine(len).length)),this.insert({row:0,column:0},text)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(row,column){return new Anchor(this,row,column)},this.$split=0===\"aaa\".split(/a/).length?function(text){return text.replace(/\\r\\n|\\r/g,\"\\n\").split(\"\\n\")}:function(text){return text.split(/\\r\\n|\\r|\\n/)},this.$detectNewLine=function(text){var match=text.match(/^.*?(\\r\\n|\\r|\\n)/m);this.$autoNewLine=match?match[1]:\"\\n\",this._signal(\"changeNewLineMode\")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case\"windows\":return\"\\r\\n\";case\"unix\":return\"\\n\";default:return this.$autoNewLine||\"\\n\"}},this.$autoNewLine=\"\",this.$newLineMode=\"auto\",this.setNewLineMode=function(newLineMode){this.$newLineMode!==newLineMode&&(this.$newLineMode=newLineMode,this._signal(\"changeNewLineMode\"))},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(text){return\"\\r\\n\"==text||\"\\r\"==text||\"\\n\"==text},this.getLine=function(row){return this.$lines[row]||\"\"},this.getLines=function(firstRow,lastRow){return this.$lines.slice(firstRow,lastRow+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(range){return this.getLinesForRange(range).join(this.getNewLineCharacter())},this.getLinesForRange=function(range){var lines;if(range.start.row===range.end.row)lines=[this.getLine(range.start.row).substring(range.start.column,range.end.column)];else{lines=this.getLines(range.start.row,range.end.row),lines[0]=(lines[0]||\"\").substring(range.start.column);var l=lines.length-1;range.end.row-range.start.row==l&&(lines[l]=lines[l].substring(0,range.end.column))}return lines},this.insertLines=function(row,lines){return console.warn(\"Use of document.insertLines is deprecated. Use the insertFullLines method instead.\"),this.insertFullLines(row,lines)},this.removeLines=function(firstRow,lastRow){return console.warn(\"Use of document.removeLines is deprecated. Use the removeFullLines method instead.\"),this.removeFullLines(firstRow,lastRow)},this.insertNewLine=function(position){return console.warn(\"Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.\"),this.insertMergedLines(position,[\"\",\"\"])},this.insert=function(position,text){return 1>=this.getLength()&&this.$detectNewLine(text),this.insertMergedLines(position,this.$split(text))},this.insertInLine=function(position,text){var start=this.clippedPos(position.row,position.column),end=this.pos(position.row,position.column+text.length);return this.applyDelta({start:start,end:end,action:\"insert\",lines:[text]},!0),this.clonePos(end)},this.clippedPos=function(row,column){var length=this.getLength();void 0===row?row=length:0>row?row=0:row>=length&&(row=length-1,column=void 0);var line=this.getLine(row);return void 0==column&&(column=line.length),column=Math.min(Math.max(column,0),line.length),{row:row,column:column}},this.clonePos=function(pos){return{row:pos.row,column:pos.column}},this.pos=function(row,column){return{row:row,column:column}},this.$clipPosition=function(position){var length=this.getLength();return position.row>=length?(position.row=Math.max(0,length-1),position.column=this.getLine(length-1).length):(position.row=Math.max(0,position.row),position.column=Math.min(Math.max(position.column,0),this.getLine(position.row).length)),position},this.insertFullLines=function(row,lines){row=Math.min(Math.max(row,0),this.getLength());var column=0;this.getLength()>row?(lines=lines.concat([\"\"]),column=0):(lines=[\"\"].concat(lines),row--,column=this.$lines[row].length),this.insertMergedLines({row:row,column:column},lines)},this.insertMergedLines=function(position,lines){var start=this.clippedPos(position.row,position.column),end={row:start.row+lines.length-1,column:(1==lines.length?start.column:0)+lines[lines.length-1].length};return this.applyDelta({start:start,end:end,action:\"insert\",lines:lines}),this.clonePos(end)},this.remove=function(range){var start=this.clippedPos(range.start.row,range.start.column),end=this.clippedPos(range.end.row,range.end.column);return this.applyDelta({start:start,end:end,action:\"remove\",lines:this.getLinesForRange({start:start,end:end})}),this.clonePos(start)},this.removeInLine=function(row,startColumn,endColumn){var start=this.clippedPos(row,startColumn),end=this.clippedPos(row,endColumn);return this.applyDelta({start:start,end:end,action:\"remove\",lines:this.getLinesForRange({start:start,end:end})},!0),this.clonePos(start)},this.removeFullLines=function(firstRow,lastRow){firstRow=Math.min(Math.max(0,firstRow),this.getLength()-1),lastRow=Math.min(Math.max(0,lastRow),this.getLength()-1);var deleteFirstNewLine=lastRow==this.getLength()-1&&firstRow>0,deleteLastNewLine=this.getLength()-1>lastRow,startRow=deleteFirstNewLine?firstRow-1:firstRow,startCol=deleteFirstNewLine?this.getLine(startRow).length:0,endRow=deleteLastNewLine?lastRow+1:lastRow,endCol=deleteLastNewLine?0:this.getLine(endRow).length,range=new Range(startRow,startCol,endRow,endCol),deletedLines=this.$lines.slice(firstRow,lastRow+1);return this.applyDelta({start:range.start,end:range.end,action:\"remove\",lines:this.getLinesForRange(range)}),deletedLines},this.removeNewLine=function(row){this.getLength()-1>row&&row>=0&&this.applyDelta({start:this.pos(row,this.getLine(row).length),end:this.pos(row+1,0),action:\"remove\",lines:[\"\",\"\"]})},this.replace=function(range,text){if(range instanceof Range||(range=Range.fromPoints(range.start,range.end)),0===text.length&&range.isEmpty())return range.start;if(text==this.getTextRange(range))return range.end;this.remove(range);var end;return end=text?this.insert(range.start,text):range.start},this.applyDeltas=function(deltas){for(var i=0;deltas.length>i;i++)this.applyDelta(deltas[i])},this.revertDeltas=function(deltas){for(var i=deltas.length-1;i>=0;i--)this.revertDelta(deltas[i])},this.applyDelta=function(delta,doNotValidate){var isInsert=\"insert\"==delta.action;(isInsert?1>=delta.lines.length&&!delta.lines[0]:!Range.comparePoints(delta.start,delta.end))||(isInsert&&delta.lines.length>2e4&&this.$splitAndapplyLargeDelta(delta,2e4),applyDelta(this.$lines,delta,doNotValidate),this._signal(\"change\",delta))},this.$splitAndapplyLargeDelta=function(delta,MAX){for(var lines=delta.lines,l=lines.length,row=delta.start.row,column=delta.start.column,from=0,to=0;;){from=to,to+=MAX-1;var chunk=lines.slice(from,to);if(to>l){delta.lines=chunk,delta.start.row=row+from,delta.start.column=column;break}chunk.push(\"\"),this.applyDelta({start:this.pos(row+from,column),end:this.pos(row+to,column=0),action:delta.action,lines:chunk},!0)}},this.revertDelta=function(delta){this.applyDelta({start:this.clonePos(delta.start),end:this.clonePos(delta.end),action:\"insert\"==delta.action?\"remove\":\"insert\",lines:delta.lines.slice()})},this.indexToPosition=function(index,startRow){for(var lines=this.$lines||this.getAllLines(),newlineLength=this.getNewLineCharacter().length,i=startRow||0,l=lines.length;l>i;i++)if(index-=lines[i].length+newlineLength,0>index)return{row:i,column:index+lines[i].length+newlineLength};return{row:l-1,column:lines[l-1].length}},this.positionToIndex=function(pos,startRow){for(var lines=this.$lines||this.getAllLines(),newlineLength=this.getNewLineCharacter().length,index=0,row=Math.min(pos.row,lines.length),i=startRow||0;row>i;++i)index+=lines[i].length+newlineLength;return index+pos.column}}).call(Document.prototype),exports.Document=Document}),ace.define(\"ace/lib/lang\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";exports.last=function(a){return a[a.length-1]},exports.stringReverse=function(string){return string.split(\"\").reverse().join(\"\")},exports.stringRepeat=function(string,count){for(var result=\"\";count>0;)1&count&&(result+=string),(count>>=1)&&(string+=string);return result};var trimBeginRegexp=/^\\s\\s*/,trimEndRegexp=/\\s\\s*$/;exports.stringTrimLeft=function(string){return string.replace(trimBeginRegexp,\"\")},exports.stringTrimRight=function(string){return string.replace(trimEndRegexp,\"\")},exports.copyObject=function(obj){var copy={};for(var key in obj)copy[key]=obj[key];return copy},exports.copyArray=function(array){for(var copy=[],i=0,l=array.length;l>i;i++)copy[i]=array[i]&&\"object\"==typeof array[i]?this.copyObject(array[i]):array[i];return copy},exports.deepCopy=function deepCopy(obj){if(\"object\"!=typeof obj||!obj)return obj;var copy;if(Array.isArray(obj)){copy=[];for(var key=0;obj.length>key;key++)copy[key]=deepCopy(obj[key]);return copy}if(\"[object Object]\"!==Object.prototype.toString.call(obj))return obj;copy={};for(var key in obj)copy[key]=deepCopy(obj[key]);return copy},exports.arrayToMap=function(arr){for(var map={},i=0;arr.length>i;i++)map[arr[i]]=1;return map},exports.createMap=function(props){var map=Object.create(null);for(var i in props)map[i]=props[i];return map},exports.arrayRemove=function(array,value){for(var i=0;array.length>=i;i++)value===array[i]&&array.splice(i,1)},exports.escapeRegExp=function(str){return str.replace(/([.*+?^${}()|[\\]\\/\\\\])/g,\"\\\\$1\")},exports.escapeHTML=function(str){return str.replace(/&/g,\"&#38;\").replace(/\"/g,\"&#34;\").replace(/'/g,\"&#39;\").replace(/</g,\"&#60;\")},exports.getMatchOffsets=function(string,regExp){var matches=[];return string.replace(regExp,function(str){matches.push({offset:arguments[arguments.length-2],length:str.length})}),matches},exports.deferredCall=function(fcn){var timer=null,callback=function(){timer=null,fcn()},deferred=function(timeout){return deferred.cancel(),timer=setTimeout(callback,timeout||0),deferred};return deferred.schedule=deferred,deferred.call=function(){return this.cancel(),fcn(),deferred},deferred.cancel=function(){return clearTimeout(timer),timer=null,deferred},deferred.isPending=function(){return timer},deferred},exports.delayedCall=function(fcn,defaultTimeout){var timer=null,callback=function(){timer=null,fcn()},_self=function(timeout){null==timer&&(timer=setTimeout(callback,timeout||defaultTimeout))};return _self.delay=function(timeout){timer&&clearTimeout(timer),timer=setTimeout(callback,timeout||defaultTimeout)},_self.schedule=_self,_self.call=function(){this.cancel(),fcn()},_self.cancel=function(){timer&&clearTimeout(timer),timer=null},_self.isPending=function(){return timer},_self}}),ace.define(\"ace/worker/mirror\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/document\",\"ace/lib/lang\"],function(acequire,exports){\"use strict\";acequire(\"../range\").Range;var Document=acequire(\"../document\").Document,lang=acequire(\"../lib/lang\"),Mirror=exports.Mirror=function(sender){this.sender=sender;var doc=this.doc=new Document(\"\"),deferredUpdate=this.deferredUpdate=lang.delayedCall(this.onUpdate.bind(this)),_self=this;sender.on(\"change\",function(e){var data=e.data;if(data[0].start)doc.applyDeltas(data);else for(var i=0;data.length>i;i+=2){if(Array.isArray(data[i+1]))var d={action:\"insert\",start:data[i],lines:data[i+1]};else var d={action:\"remove\",start:data[i],end:data[i+1]};doc.applyDelta(d,!0)}return _self.$timeout?deferredUpdate.schedule(_self.$timeout):(_self.onUpdate(),void 0)})};(function(){this.$timeout=500,this.setTimeout=function(timeout){this.$timeout=timeout},this.setValue=function(value){this.doc.setValue(value),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(callbackId){this.sender.callback(this.doc.getValue(),callbackId)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(Mirror.prototype)}),ace.define(\"ace/mode/javascript/jshint\",[\"require\",\"exports\",\"module\"],function(acequire,exports,module){module.exports=function outer(modules,cache,entry){function newRequire(name,jumped){if(!cache[name]){if(!modules[name]){var currentRequire=\"function\"==typeof acequire&&acequire;if(!jumped&&currentRequire)return currentRequire(name,!0);if(previousRequire)return previousRequire(name,!0);var err=Error(\"Cannot find module '\"+name+\"'\");throw err.code=\"MODULE_NOT_FOUND\",err}var m=cache[name]={exports:{}};modules[name][0].call(m.exports,function(x){var id=modules[name][1][x];return newRequire(id?id:x)},m,m.exports,outer,modules,cache,entry)}return cache[name].exports}for(var previousRequire=\"function\"==typeof acequire&&acequire,i=0;entry.length>i;i++)newRequire(entry[i]);return newRequire(entry[0])}({\"/node_modules/browserify/node_modules/events/events.js\":[function(_dereq_,module){function EventEmitter(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function isFunction(arg){return\"function\"==typeof arg}function isNumber(arg){return\"number\"==typeof arg}function isObject(arg){return\"object\"==typeof arg&&null!==arg}function isUndefined(arg){return void 0===arg}module.exports=EventEmitter,EventEmitter.EventEmitter=EventEmitter,EventEmitter.prototype._events=void 0,EventEmitter.prototype._maxListeners=void 0,EventEmitter.defaultMaxListeners=10,EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||0>n||isNaN(n))throw TypeError(\"n must be a positive number\");return this._maxListeners=n,this},EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(this._events||(this._events={}),\"error\"===type&&(!this._events.error||isObject(this._events.error)&&!this._events.error.length)){if(er=arguments[1],er instanceof Error)throw er;throw TypeError('Uncaught, unspecified \"error\" event.')}if(handler=this._events[type],isUndefined(handler))return!1;if(isFunction(handler))switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:for(len=arguments.length,args=Array(len-1),i=1;len>i;i++)args[i-1]=arguments[i];handler.apply(this,args)}else if(isObject(handler)){for(len=arguments.length,args=Array(len-1),i=1;len>i;i++)args[i-1]=arguments[i];for(listeners=handler.slice(),len=listeners.length,i=0;len>i;i++)listeners[i].apply(this,args)}return!0},EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError(\"listener must be a function\");if(this._events||(this._events={}),this._events.newListener&&this.emit(\"newListener\",type,isFunction(listener.listener)?listener.listener:listener),this._events[type]?isObject(this._events[type])?this._events[type].push(listener):this._events[type]=[this._events[type],listener]:this._events[type]=listener,isObject(this._events[type])&&!this._events[type].warned){var m;m=isUndefined(this._maxListeners)?EventEmitter.defaultMaxListeners:this._maxListeners,m&&m>0&&this._events[type].length>m&&(this._events[type].warned=!0,console.error(\"(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.\",this._events[type].length),\"function\"==typeof console.trace&&console.trace())}return this},EventEmitter.prototype.on=EventEmitter.prototype.addListener,EventEmitter.prototype.once=function(type,listener){function g(){this.removeListener(type,g),fired||(fired=!0,listener.apply(this,arguments))}if(!isFunction(listener))throw TypeError(\"listener must be a function\");var fired=!1;return g.listener=listener,this.on(type,g),this},EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError(\"listener must be a function\");if(!this._events||!this._events[type])return this;if(list=this._events[type],length=list.length,position=-1,list===listener||isFunction(list.listener)&&list.listener===listener)delete this._events[type],this._events.removeListener&&this.emit(\"removeListener\",type,listener);else if(isObject(list)){for(i=length;i-->0;)if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}if(0>position)return this;1===list.length?(list.length=0,delete this._events[type]):list.splice(position,1),this._events.removeListener&&this.emit(\"removeListener\",type,listener)}return this},EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[type]&&delete this._events[type],this;if(0===arguments.length){for(key in this._events)\"removeListener\"!==key&&this.removeAllListeners(key);return this.removeAllListeners(\"removeListener\"),this._events={},this\n}if(listeners=this._events[type],isFunction(listeners))this.removeListener(type,listeners);else for(;listeners.length;)this.removeListener(type,listeners[listeners.length-1]);return delete this._events[type],this},EventEmitter.prototype.listeners=function(type){var ret;return ret=this._events&&this._events[type]?isFunction(this._events[type])?[this._events[type]]:this._events[type].slice():[]},EventEmitter.listenerCount=function(emitter,type){var ret;return ret=emitter._events&&emitter._events[type]?isFunction(emitter._events[type])?1:emitter._events[type].length:0}},{}],\"/node_modules/jshint/data/ascii-identifier-data.js\":[function(_dereq_,module){for(var identifierStartTable=[],i=0;128>i;i++)identifierStartTable[i]=36===i||i>=65&&90>=i||95===i||i>=97&&122>=i;for(var identifierPartTable=[],i=0;128>i;i++)identifierPartTable[i]=identifierStartTable[i]||i>=48&&57>=i;module.exports={asciiIdentifierStartTable:identifierStartTable,asciiIdentifierPartTable:identifierPartTable}},{}],\"/node_modules/jshint/lodash.js\":[function(_dereq_,module,exports){(function(global){(function(){function baseFindIndex(array,predicate,fromRight){for(var length=array.length,index=fromRight?length:-1;fromRight?index--:length>++index;)if(predicate(array[index],index,array))return index;return-1}function baseIndexOf(array,value,fromIndex){if(value!==value)return indexOfNaN(array,fromIndex);for(var index=fromIndex-1,length=array.length;length>++index;)if(array[index]===value)return index;return-1}function baseIsFunction(value){return\"function\"==typeof value||!1}function baseToString(value){return\"string\"==typeof value?value:null==value?\"\":value+\"\"}function indexOfNaN(array,fromIndex,fromRight){for(var length=array.length,index=fromIndex+(fromRight?0:-1);fromRight?index--:length>++index;){var other=array[index];if(other!==other)return index}return-1}function isObjectLike(value){return!!value&&\"object\"==typeof value}function lodash(){}function arrayCopy(source,array){var index=-1,length=source.length;for(array||(array=Array(length));length>++index;)array[index]=source[index];return array}function arrayEach(array,iteratee){for(var index=-1,length=array.length;length>++index&&iteratee(array[index],index,array)!==!1;);return array}function arrayFilter(array,predicate){for(var index=-1,length=array.length,resIndex=-1,result=[];length>++index;){var value=array[index];predicate(value,index,array)&&(result[++resIndex]=value)}return result}function arrayMap(array,iteratee){for(var index=-1,length=array.length,result=Array(length);length>++index;)result[index]=iteratee(array[index],index,array);return result}function arrayMax(array){for(var index=-1,length=array.length,result=NEGATIVE_INFINITY;length>++index;){var value=array[index];value>result&&(result=value)}return result}function arraySome(array,predicate){for(var index=-1,length=array.length;length>++index;)if(predicate(array[index],index,array))return!0;return!1}function assignWith(object,source,customizer){var props=keys(source);push.apply(props,getSymbols(source));for(var index=-1,length=props.length;length>++index;){var key=props[index],value=object[key],result=customizer(value,source[key],key,object,source);(result===result?result===value:value!==value)&&(value!==undefined||key in object)||(object[key]=result)}return object}function baseCopy(source,props,object){object||(object={});for(var index=-1,length=props.length;length>++index;){var key=props[index];object[key]=source[key]}return object}function baseCallback(func,thisArg,argCount){var type=typeof func;return\"function\"==type?thisArg===undefined?func:bindCallback(func,thisArg,argCount):null==func?identity:\"object\"==type?baseMatches(func):thisArg===undefined?property(func):baseMatchesProperty(func,thisArg)}function baseClone(value,isDeep,customizer,key,object,stackA,stackB){var result;if(customizer&&(result=object?customizer(value,key,object):customizer(value)),result!==undefined)return result;if(!isObject(value))return value;var isArr=isArray(value);if(isArr){if(result=initCloneArray(value),!isDeep)return arrayCopy(value,result)}else{var tag=objToString.call(value),isFunc=tag==funcTag;if(tag!=objectTag&&tag!=argsTag&&(!isFunc||object))return cloneableTags[tag]?initCloneByTag(value,tag,isDeep):object?value:{};if(result=initCloneObject(isFunc?{}:value),!isDeep)return baseAssign(result,value)}stackA||(stackA=[]),stackB||(stackB=[]);for(var length=stackA.length;length--;)if(stackA[length]==value)return stackB[length];return stackA.push(value),stackB.push(result),(isArr?arrayEach:baseForOwn)(value,function(subValue,key){result[key]=baseClone(subValue,isDeep,customizer,key,value,stackA,stackB)}),result}function baseFilter(collection,predicate){var result=[];return baseEach(collection,function(value,index,collection){predicate(value,index,collection)&&result.push(value)}),result}function baseForIn(object,iteratee){return baseFor(object,iteratee,keysIn)}function baseForOwn(object,iteratee){return baseFor(object,iteratee,keys)}function baseGet(object,path,pathKey){if(null!=object){pathKey!==undefined&&pathKey in toObject(object)&&(path=[pathKey]);for(var index=-1,length=path.length;null!=object&&length>++index;)var result=object=object[path[index]];return result}}function baseIsEqual(value,other,customizer,isLoose,stackA,stackB){if(value===other)return 0!==value||1/value==1/other;var valType=typeof value,othType=typeof other;return\"function\"!=valType&&\"object\"!=valType&&\"function\"!=othType&&\"object\"!=othType||null==value||null==other?value!==value&&other!==other:baseIsEqualDeep(value,other,baseIsEqual,customizer,isLoose,stackA,stackB)}function baseIsEqualDeep(object,other,equalFunc,customizer,isLoose,stackA,stackB){var objIsArr=isArray(object),othIsArr=isArray(other),objTag=arrayTag,othTag=arrayTag;objIsArr||(objTag=objToString.call(object),objTag==argsTag?objTag=objectTag:objTag!=objectTag&&(objIsArr=isTypedArray(object))),othIsArr||(othTag=objToString.call(other),othTag==argsTag?othTag=objectTag:othTag!=objectTag&&(othIsArr=isTypedArray(other)));var objIsObj=objTag==objectTag,othIsObj=othTag==objectTag,isSameTag=objTag==othTag;if(isSameTag&&!objIsArr&&!objIsObj)return equalByTag(object,other,objTag);if(!isLoose){var valWrapped=objIsObj&&hasOwnProperty.call(object,\"__wrapped__\"),othWrapped=othIsObj&&hasOwnProperty.call(other,\"__wrapped__\");if(valWrapped||othWrapped)return equalFunc(valWrapped?object.value():object,othWrapped?other.value():other,customizer,isLoose,stackA,stackB)}if(!isSameTag)return!1;stackA||(stackA=[]),stackB||(stackB=[]);for(var length=stackA.length;length--;)if(stackA[length]==object)return stackB[length]==other;stackA.push(object),stackB.push(other);var result=(objIsArr?equalArrays:equalObjects)(object,other,equalFunc,customizer,isLoose,stackA,stackB);return stackA.pop(),stackB.pop(),result}function baseIsMatch(object,props,values,strictCompareFlags,customizer){for(var index=-1,length=props.length,noCustomizer=!customizer;length>++index;)if(noCustomizer&&strictCompareFlags[index]?values[index]!==object[props[index]]:!(props[index]in object))return!1;for(index=-1;length>++index;){var key=props[index],objValue=object[key],srcValue=values[index];if(noCustomizer&&strictCompareFlags[index])var result=objValue!==undefined||key in object;else result=customizer?customizer(objValue,srcValue,key):undefined,result===undefined&&(result=baseIsEqual(srcValue,objValue,customizer,!0));if(!result)return!1}return!0}function baseMatches(source){var props=keys(source),length=props.length;if(!length)return constant(!0);if(1==length){var key=props[0],value=source[key];if(isStrictComparable(value))return function(object){return null==object?!1:object[key]===value&&(value!==undefined||key in toObject(object))}}for(var values=Array(length),strictCompareFlags=Array(length);length--;)value=source[props[length]],values[length]=value,strictCompareFlags[length]=isStrictComparable(value);return function(object){return null!=object&&baseIsMatch(toObject(object),props,values,strictCompareFlags)}}function baseMatchesProperty(path,value){var isArr=isArray(path),isCommon=isKey(path)&&isStrictComparable(value),pathKey=path+\"\";return path=toPath(path),function(object){if(null==object)return!1;var key=pathKey;if(object=toObject(object),!(!isArr&&isCommon||key in object)){if(object=1==path.length?object:baseGet(object,baseSlice(path,0,-1)),null==object)return!1;key=last(path),object=toObject(object)}return object[key]===value?value!==undefined||key in object:baseIsEqual(value,object[key],null,!0)}}function baseMerge(object,source,customizer,stackA,stackB){if(!isObject(object))return object;var isSrcArr=isLength(source.length)&&(isArray(source)||isTypedArray(source));if(!isSrcArr){var props=keys(source);push.apply(props,getSymbols(source))}return arrayEach(props||source,function(srcValue,key){if(props&&(key=srcValue,srcValue=source[key]),isObjectLike(srcValue))stackA||(stackA=[]),stackB||(stackB=[]),baseMergeDeep(object,source,key,baseMerge,customizer,stackA,stackB);else{var value=object[key],result=customizer?customizer(value,srcValue,key,object,source):undefined,isCommon=result===undefined;isCommon&&(result=srcValue),!isSrcArr&&result===undefined||!isCommon&&(result===result?result===value:value!==value)||(object[key]=result)}}),object}function baseMergeDeep(object,source,key,mergeFunc,customizer,stackA,stackB){for(var length=stackA.length,srcValue=source[key];length--;)if(stackA[length]==srcValue)return object[key]=stackB[length],undefined;var value=object[key],result=customizer?customizer(value,srcValue,key,object,source):undefined,isCommon=result===undefined;isCommon&&(result=srcValue,isLength(srcValue.length)&&(isArray(srcValue)||isTypedArray(srcValue))?result=isArray(value)?value:getLength(value)?arrayCopy(value):[]:isPlainObject(srcValue)||isArguments(srcValue)?result=isArguments(value)?toPlainObject(value):isPlainObject(value)?value:{}:isCommon=!1),stackA.push(srcValue),stackB.push(result),isCommon?object[key]=mergeFunc(result,srcValue,customizer,stackA,stackB):(result===result?result!==value:value===value)&&(object[key]=result)}function baseProperty(key){return function(object){return null==object?undefined:object[key]}}function basePropertyDeep(path){var pathKey=path+\"\";return path=toPath(path),function(object){return baseGet(object,path,pathKey)}}function baseSlice(array,start,end){var index=-1,length=array.length;start=null==start?0:+start||0,0>start&&(start=-start>length?0:length+start),end=end===undefined||end>length?length:+end||0,0>end&&(end+=length),length=start>end?0:end-start>>>0,start>>>=0;for(var result=Array(length);length>++index;)result[index]=array[index+start];return result}function baseSome(collection,predicate){var result;return baseEach(collection,function(value,index,collection){return result=predicate(value,index,collection),!result}),!!result}function baseValues(object,props){for(var index=-1,length=props.length,result=Array(length);length>++index;)result[index]=object[props[index]];return result}function binaryIndex(array,value,retHighest){var low=0,high=array?array.length:low;if(\"number\"==typeof value&&value===value&&HALF_MAX_ARRAY_LENGTH>=high){for(;high>low;){var mid=low+high>>>1,computed=array[mid];(retHighest?value>=computed:value>computed)?low=mid+1:high=mid}return high}return binaryIndexBy(array,value,identity,retHighest)}function binaryIndexBy(array,value,iteratee,retHighest){value=iteratee(value);for(var low=0,high=array?array.length:0,valIsNaN=value!==value,valIsUndef=value===undefined;high>low;){var mid=floor((low+high)/2),computed=iteratee(array[mid]),isReflexive=computed===computed;if(valIsNaN)var setLow=isReflexive||retHighest;else setLow=valIsUndef?isReflexive&&(retHighest||computed!==undefined):retHighest?value>=computed:value>computed;setLow?low=mid+1:high=mid}return nativeMin(high,MAX_ARRAY_INDEX)}function bindCallback(func,thisArg,argCount){if(\"function\"!=typeof func)return identity;if(thisArg===undefined)return func;switch(argCount){case 1:return function(value){return func.call(thisArg,value)};case 3:return function(value,index,collection){return func.call(thisArg,value,index,collection)};case 4:return function(accumulator,value,index,collection){return func.call(thisArg,accumulator,value,index,collection)};case 5:return function(value,other,key,object,source){return func.call(thisArg,value,other,key,object,source)}}return function(){return func.apply(thisArg,arguments)}}function bufferClone(buffer){return bufferSlice.call(buffer,0)}function createAssigner(assigner){return restParam(function(object,sources){var index=-1,length=null==object?0:sources.length,customizer=length>2&&sources[length-2],guard=length>2&&sources[2],thisArg=length>1&&sources[length-1];for(\"function\"==typeof customizer?(customizer=bindCallback(customizer,thisArg,5),length-=2):(customizer=\"function\"==typeof thisArg?thisArg:null,length-=customizer?1:0),guard&&isIterateeCall(sources[0],sources[1],guard)&&(customizer=3>length?null:customizer,length=1);length>++index;){var source=sources[index];source&&assigner(object,source,customizer)}return object})}function createBaseEach(eachFunc,fromRight){return function(collection,iteratee){var length=collection?getLength(collection):0;if(!isLength(length))return eachFunc(collection,iteratee);for(var index=fromRight?length:-1,iterable=toObject(collection);(fromRight?index--:length>++index)&&iteratee(iterable[index],index,iterable)!==!1;);return collection}}function createBaseFor(fromRight){return function(object,iteratee,keysFunc){for(var iterable=toObject(object),props=keysFunc(object),length=props.length,index=fromRight?length:-1;fromRight?index--:length>++index;){var key=props[index];if(iteratee(iterable[key],key,iterable)===!1)break}return object}}function createFindIndex(fromRight){return function(array,predicate,thisArg){return array&&array.length?(predicate=getCallback(predicate,thisArg,3),baseFindIndex(array,predicate,fromRight)):-1}}function createForEach(arrayFunc,eachFunc){return function(collection,iteratee,thisArg){return\"function\"==typeof iteratee&&thisArg===undefined&&isArray(collection)?arrayFunc(collection,iteratee):eachFunc(collection,bindCallback(iteratee,thisArg,3))}}function equalArrays(array,other,equalFunc,customizer,isLoose,stackA,stackB){var index=-1,arrLength=array.length,othLength=other.length,result=!0;if(arrLength!=othLength&&!(isLoose&&othLength>arrLength))return!1;for(;result&&arrLength>++index;){var arrValue=array[index],othValue=other[index];if(result=undefined,customizer&&(result=isLoose?customizer(othValue,arrValue,index):customizer(arrValue,othValue,index)),result===undefined)if(isLoose)for(var othIndex=othLength;othIndex--&&(othValue=other[othIndex],!(result=arrValue&&arrValue===othValue||equalFunc(arrValue,othValue,customizer,isLoose,stackA,stackB))););else result=arrValue&&arrValue===othValue||equalFunc(arrValue,othValue,customizer,isLoose,stackA,stackB)}return!!result}function equalByTag(object,other,tag){switch(tag){case boolTag:case dateTag:return+object==+other;case errorTag:return object.name==other.name&&object.message==other.message;case numberTag:return object!=+object?other!=+other:0==object?1/object==1/other:object==+other;case regexpTag:case stringTag:return object==other+\"\"}return!1}function equalObjects(object,other,equalFunc,customizer,isLoose,stackA,stackB){var objProps=keys(object),objLength=objProps.length,othProps=keys(other),othLength=othProps.length;if(objLength!=othLength&&!isLoose)return!1;for(var skipCtor=isLoose,index=-1;objLength>++index;){var key=objProps[index],result=isLoose?key in other:hasOwnProperty.call(other,key);if(result){var objValue=object[key],othValue=other[key];result=undefined,customizer&&(result=isLoose?customizer(othValue,objValue,key):customizer(objValue,othValue,key)),result===undefined&&(result=objValue&&objValue===othValue||equalFunc(objValue,othValue,customizer,isLoose,stackA,stackB))}if(!result)return!1;skipCtor||(skipCtor=\"constructor\"==key)}if(!skipCtor){var objCtor=object.constructor,othCtor=other.constructor;if(objCtor!=othCtor&&\"constructor\"in object&&\"constructor\"in other&&!(\"function\"==typeof objCtor&&objCtor instanceof objCtor&&\"function\"==typeof othCtor&&othCtor instanceof othCtor))return!1}return!0}function getCallback(func,thisArg,argCount){var result=lodash.callback||callback;return result=result===callback?baseCallback:result,argCount?result(func,thisArg,argCount):result}function getIndexOf(collection,target,fromIndex){var result=lodash.indexOf||indexOf;return result=result===indexOf?baseIndexOf:result,collection?result(collection,target,fromIndex):result}function initCloneArray(array){var length=array.length,result=new array.constructor(length);return length&&\"string\"==typeof array[0]&&hasOwnProperty.call(array,\"index\")&&(result.index=array.index,result.input=array.input),result}function initCloneObject(object){var Ctor=object.constructor;return\"function\"==typeof Ctor&&Ctor instanceof Ctor||(Ctor=Object),new Ctor}function initCloneByTag(object,tag,isDeep){var Ctor=object.constructor;switch(tag){case arrayBufferTag:return bufferClone(object);case boolTag:case dateTag:return new Ctor(+object);case float32Tag:case float64Tag:case int8Tag:case int16Tag:case int32Tag:case uint8Tag:case uint8ClampedTag:case uint16Tag:case uint32Tag:var buffer=object.buffer;return new Ctor(isDeep?bufferClone(buffer):buffer,object.byteOffset,object.length);case numberTag:case stringTag:return new Ctor(object);case regexpTag:var result=new Ctor(object.source,reFlags.exec(object));result.lastIndex=object.lastIndex}return result}function isIndex(value,length){return value=+value,length=null==length?MAX_SAFE_INTEGER:length,value>-1&&0==value%1&&length>value}function isIterateeCall(value,index,object){if(!isObject(object))return!1;var type=typeof index;if(\"number\"==type)var length=getLength(object),prereq=isLength(length)&&isIndex(index,length);else prereq=\"string\"==type&&index in object;if(prereq){var other=object[index];return value===value?value===other:other!==other}return!1}function isKey(value,object){var type=typeof value;if(\"string\"==type&&reIsPlainProp.test(value)||\"number\"==type)return!0;if(isArray(value))return!1;var result=!reIsDeepProp.test(value);return result||null!=object&&value in toObject(object)}function isLength(value){return\"number\"==typeof value&&value>-1&&0==value%1&&MAX_SAFE_INTEGER>=value}function isStrictComparable(value){return value===value&&(0===value?1/value>0:!isObject(value))}function shimIsPlainObject(value){var Ctor;if(lodash.support,!isObjectLike(value)||objToString.call(value)!=objectTag||!hasOwnProperty.call(value,\"constructor\")&&(Ctor=value.constructor,\"function\"==typeof Ctor&&!(Ctor instanceof Ctor)))return!1;var result;return baseForIn(value,function(subValue,key){result=key}),result===undefined||hasOwnProperty.call(value,result)}function shimKeys(object){for(var props=keysIn(object),propsLength=props.length,length=propsLength&&object.length,support=lodash.support,allowIndexes=length&&isLength(length)&&(isArray(object)||support.nonEnumArgs&&isArguments(object)),index=-1,result=[];propsLength>++index;){var key=props[index];(allowIndexes&&isIndex(key,length)||hasOwnProperty.call(object,key))&&result.push(key)}return result}function toObject(value){return isObject(value)?value:Object(value)}function toPath(value){if(isArray(value))return value;var result=[];return baseToString(value).replace(rePropName,function(match,number,quote,string){result.push(quote?string.replace(reEscapeChar,\"$1\"):number||match)}),result}function indexOf(array,value,fromIndex){var length=array?array.length:0;if(!length)return-1;if(\"number\"==typeof fromIndex)fromIndex=0>fromIndex?nativeMax(length+fromIndex,0):fromIndex;else if(fromIndex){var index=binaryIndex(array,value),other=array[index];return(value===value?value===other:other!==other)?index:-1}return baseIndexOf(array,value,fromIndex||0)}function last(array){var length=array?array.length:0;return length?array[length-1]:undefined}function slice(array,start,end){var length=array?array.length:0;return length?(end&&\"number\"!=typeof end&&isIterateeCall(array,start,end)&&(start=0,end=length),baseSlice(array,start,end)):[]}function unzip(array){for(var index=-1,length=(array&&array.length&&arrayMax(arrayMap(array,getLength)))>>>0,result=Array(length);length>++index;)result[index]=arrayMap(array,baseProperty(index));return result}function includes(collection,target,fromIndex,guard){var length=collection?getLength(collection):0;return isLength(length)||(collection=values(collection),length=collection.length),length?(fromIndex=\"number\"!=typeof fromIndex||guard&&isIterateeCall(target,fromIndex,guard)?0:0>fromIndex?nativeMax(length+fromIndex,0):fromIndex||0,\"string\"==typeof collection||!isArray(collection)&&isString(collection)?length>fromIndex&&collection.indexOf(target,fromIndex)>-1:getIndexOf(collection,target,fromIndex)>-1):!1}function reject(collection,predicate,thisArg){var func=isArray(collection)?arrayFilter:baseFilter;return predicate=getCallback(predicate,thisArg,3),func(collection,function(value,index,collection){return!predicate(value,index,collection)})}function some(collection,predicate,thisArg){var func=isArray(collection)?arraySome:baseSome;return thisArg&&isIterateeCall(collection,predicate,thisArg)&&(predicate=null),(\"function\"!=typeof predicate||thisArg!==undefined)&&(predicate=getCallback(predicate,thisArg,3)),func(collection,predicate)}function restParam(func,start){if(\"function\"!=typeof func)throw new TypeError(FUNC_ERROR_TEXT);return start=nativeMax(start===undefined?func.length-1:+start||0,0),function(){for(var args=arguments,index=-1,length=nativeMax(args.length-start,0),rest=Array(length);length>++index;)rest[index]=args[start+index];switch(start){case 0:return func.call(this,rest);case 1:return func.call(this,args[0],rest);case 2:return func.call(this,args[0],args[1],rest)}var otherArgs=Array(start+1);for(index=-1;start>++index;)otherArgs[index]=args[index];return otherArgs[start]=rest,func.apply(this,otherArgs)}}function clone(value,isDeep,customizer,thisArg){return isDeep&&\"boolean\"!=typeof isDeep&&isIterateeCall(value,isDeep,customizer)?isDeep=!1:\"function\"==typeof isDeep&&(thisArg=customizer,customizer=isDeep,isDeep=!1),customizer=\"function\"==typeof customizer&&bindCallback(customizer,thisArg,1),baseClone(value,isDeep,customizer)}function isArguments(value){var length=isObjectLike(value)?value.length:undefined;return isLength(length)&&objToString.call(value)==argsTag}function isEmpty(value){if(null==value)return!0;var length=getLength(value);return isLength(length)&&(isArray(value)||isString(value)||isArguments(value)||isObjectLike(value)&&isFunction(value.splice))?!length:!keys(value).length}function isObject(value){var type=typeof value;return\"function\"==type||!!value&&\"object\"==type}function isNative(value){return null==value?!1:objToString.call(value)==funcTag?reIsNative.test(fnToString.call(value)):isObjectLike(value)&&reIsHostCtor.test(value)}function isNumber(value){return\"number\"==typeof value||isObjectLike(value)&&objToString.call(value)==numberTag}function isString(value){return\"string\"==typeof value||isObjectLike(value)&&objToString.call(value)==stringTag}function isTypedArray(value){return isObjectLike(value)&&isLength(value.length)&&!!typedArrayTags[objToString.call(value)]}function toPlainObject(value){return baseCopy(value,keysIn(value))}function has(object,path){if(null==object)return!1;var result=hasOwnProperty.call(object,path);return result||isKey(path)||(path=toPath(path),object=1==path.length?object:baseGet(object,baseSlice(path,0,-1)),path=last(path),result=null!=object&&hasOwnProperty.call(object,path)),result}function keysIn(object){if(null==object)return[];isObject(object)||(object=Object(object));var length=object.length;length=length&&isLength(length)&&(isArray(object)||support.nonEnumArgs&&isArguments(object))&&length||0;for(var Ctor=object.constructor,index=-1,isProto=\"function\"==typeof Ctor&&Ctor.prototype===object,result=Array(length),skipIndexes=length>0;length>++index;)result[index]=index+\"\";for(var key in object)skipIndexes&&isIndex(key,length)||\"constructor\"==key&&(isProto||!hasOwnProperty.call(object,key))||result.push(key);return result}function values(object){return baseValues(object,keys(object))}function escapeRegExp(string){return string=baseToString(string),string&&reHasRegExpChars.test(string)?string.replace(reRegExpChars,\"\\\\$&\"):string}function callback(func,thisArg,guard){return guard&&isIterateeCall(func,thisArg,guard)&&(thisArg=null),baseCallback(func,thisArg)}function constant(value){return function(){return value}}function identity(value){return value}function property(path){return isKey(path)?baseProperty(path):basePropertyDeep(path)}var undefined,VERSION=\"3.7.0\",FUNC_ERROR_TEXT=\"Expected a function\",argsTag=\"[object Arguments]\",arrayTag=\"[object Array]\",boolTag=\"[object Boolean]\",dateTag=\"[object Date]\",errorTag=\"[object Error]\",funcTag=\"[object Function]\",mapTag=\"[object Map]\",numberTag=\"[object Number]\",objectTag=\"[object Object]\",regexpTag=\"[object RegExp]\",setTag=\"[object Set]\",stringTag=\"[object String]\",weakMapTag=\"[object WeakMap]\",arrayBufferTag=\"[object ArrayBuffer]\",float32Tag=\"[object Float32Array]\",float64Tag=\"[object Float64Array]\",int8Tag=\"[object Int8Array]\",int16Tag=\"[object Int16Array]\",int32Tag=\"[object Int32Array]\",uint8Tag=\"[object Uint8Array]\",uint8ClampedTag=\"[object Uint8ClampedArray]\",uint16Tag=\"[object Uint16Array]\",uint32Tag=\"[object Uint32Array]\",reIsDeepProp=/\\.|\\[(?:[^[\\]]+|([\"'])(?:(?!\\1)[^\\n\\\\]|\\\\.)*?)\\1\\]/,reIsPlainProp=/^\\w*$/,rePropName=/[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\n\\\\]|\\\\.)*?)\\2)\\]/g,reRegExpChars=/[.*+?^${}()|[\\]\\/\\\\]/g,reHasRegExpChars=RegExp(reRegExpChars.source),reEscapeChar=/\\\\(\\\\)?/g,reFlags=/\\w*$/,reIsHostCtor=/^\\[object .+?Constructor\\]$/,typedArrayTags={};typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=typedArrayTags[uint32Tag]=!0,typedArrayTags[argsTag]=typedArrayTags[arrayTag]=typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=typedArrayTags[dateTag]=typedArrayTags[errorTag]=typedArrayTags[funcTag]=typedArrayTags[mapTag]=typedArrayTags[numberTag]=typedArrayTags[objectTag]=typedArrayTags[regexpTag]=typedArrayTags[setTag]=typedArrayTags[stringTag]=typedArrayTags[weakMapTag]=!1;var cloneableTags={};cloneableTags[argsTag]=cloneableTags[arrayTag]=cloneableTags[arrayBufferTag]=cloneableTags[boolTag]=cloneableTags[dateTag]=cloneableTags[float32Tag]=cloneableTags[float64Tag]=cloneableTags[int8Tag]=cloneableTags[int16Tag]=cloneableTags[int32Tag]=cloneableTags[numberTag]=cloneableTags[objectTag]=cloneableTags[regexpTag]=cloneableTags[stringTag]=cloneableTags[uint8Tag]=cloneableTags[uint8ClampedTag]=cloneableTags[uint16Tag]=cloneableTags[uint32Tag]=!0,cloneableTags[errorTag]=cloneableTags[funcTag]=cloneableTags[mapTag]=cloneableTags[setTag]=cloneableTags[weakMapTag]=!1;var objectTypes={\"function\":!0,object:!0},freeExports=objectTypes[typeof exports]&&exports&&!exports.nodeType&&exports,freeModule=objectTypes[typeof module]&&module&&!module.nodeType&&module,freeGlobal=freeExports&&freeModule&&\"object\"==typeof global&&global&&global.Object&&global,freeSelf=objectTypes[typeof self]&&self&&self.Object&&self,freeWindow=objectTypes[typeof window]&&window&&window.Object&&window,moduleExports=freeModule&&freeModule.exports===freeExports&&freeExports,root=freeGlobal||freeWindow!==(this&&this.window)&&freeWindow||freeSelf||this,arrayProto=Array.prototype,objectProto=Object.prototype,fnToString=Function.prototype.toString,hasOwnProperty=objectProto.hasOwnProperty,objToString=objectProto.toString,reIsNative=RegExp(\"^\"+escapeRegExp(objToString).replace(/toString|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\"),ArrayBuffer=isNative(ArrayBuffer=root.ArrayBuffer)&&ArrayBuffer,bufferSlice=isNative(bufferSlice=ArrayBuffer&&new ArrayBuffer(0).slice)&&bufferSlice,floor=Math.floor,getOwnPropertySymbols=isNative(getOwnPropertySymbols=Object.getOwnPropertySymbols)&&getOwnPropertySymbols,getPrototypeOf=isNative(getPrototypeOf=Object.getPrototypeOf)&&getPrototypeOf,push=arrayProto.push,preventExtensions=isNative(Object.preventExtensions=Object.preventExtensions)&&preventExtensions,propertyIsEnumerable=objectProto.propertyIsEnumerable,Uint8Array=isNative(Uint8Array=root.Uint8Array)&&Uint8Array,Float64Array=function(){try{var func=isNative(func=root.Float64Array)&&func,result=new func(new ArrayBuffer(10),0,1)&&func}catch(e){}return result}(),nativeAssign=function(){var object={1:0},func=preventExtensions&&isNative(func=Object.assign)&&func;try{func(preventExtensions(object),\"xo\")}catch(e){}return!object[1]&&func}(),nativeIsArray=isNative(nativeIsArray=Array.isArray)&&nativeIsArray,nativeKeys=isNative(nativeKeys=Object.keys)&&nativeKeys,nativeMax=Math.max,nativeMin=Math.min,NEGATIVE_INFINITY=Number.NEGATIVE_INFINITY,MAX_ARRAY_LENGTH=Math.pow(2,32)-1,MAX_ARRAY_INDEX=MAX_ARRAY_LENGTH-1,HALF_MAX_ARRAY_LENGTH=MAX_ARRAY_LENGTH>>>1,FLOAT64_BYTES_PER_ELEMENT=Float64Array?Float64Array.BYTES_PER_ELEMENT:0,MAX_SAFE_INTEGER=Math.pow(2,53)-1,support=lodash.support={};(function(x){var Ctor=function(){this.x=x},props=[];Ctor.prototype={valueOf:x,y:x};for(var key in new Ctor)props.push(key);support.funcDecomp=/\\bthis\\b/.test(function(){return this}),support.funcNames=\"string\"==typeof Function.name;try{support.nonEnumArgs=!propertyIsEnumerable.call(arguments,1)}catch(e){support.nonEnumArgs=!0}})(1,0);var baseAssign=nativeAssign||function(object,source){return null==source?object:baseCopy(source,getSymbols(source),baseCopy(source,keys(source),object))},baseEach=createBaseEach(baseForOwn),baseFor=createBaseFor();bufferSlice||(bufferClone=ArrayBuffer&&Uint8Array?function(buffer){var byteLength=buffer.byteLength,floatLength=Float64Array?floor(byteLength/FLOAT64_BYTES_PER_ELEMENT):0,offset=floatLength*FLOAT64_BYTES_PER_ELEMENT,result=new ArrayBuffer(byteLength);if(floatLength){var view=new Float64Array(result,0,floatLength);view.set(new Float64Array(buffer,0,floatLength))}return byteLength!=offset&&(view=new Uint8Array(result,offset),view.set(new Uint8Array(buffer,offset))),result}:constant(null));var getLength=baseProperty(\"length\"),getSymbols=getOwnPropertySymbols?function(object){return getOwnPropertySymbols(toObject(object))}:constant([]),findLastIndex=createFindIndex(!0),zip=restParam(unzip),forEach=createForEach(arrayEach,baseEach),isArray=nativeIsArray||function(value){return isObjectLike(value)&&isLength(value.length)&&objToString.call(value)==arrayTag},isFunction=baseIsFunction(/x/)||Uint8Array&&!baseIsFunction(Uint8Array)?function(value){return objToString.call(value)==funcTag}:baseIsFunction,isPlainObject=getPrototypeOf?function(value){if(!value||objToString.call(value)!=objectTag)return!1;var valueOf=value.valueOf,objProto=isNative(valueOf)&&(objProto=getPrototypeOf(valueOf))&&getPrototypeOf(objProto);return objProto?value==objProto||getPrototypeOf(value)==objProto:shimIsPlainObject(value)}:shimIsPlainObject,assign=createAssigner(function(object,source,customizer){return customizer?assignWith(object,source,customizer):baseAssign(object,source)}),keys=nativeKeys?function(object){if(object)var Ctor=object.constructor,length=object.length;return\"function\"==typeof Ctor&&Ctor.prototype===object||\"function\"!=typeof object&&isLength(length)?shimKeys(object):isObject(object)?nativeKeys(object):[]}:shimKeys,merge=createAssigner(baseMerge);lodash.assign=assign,lodash.callback=callback,lodash.constant=constant,lodash.forEach=forEach,lodash.keys=keys,lodash.keysIn=keysIn,lodash.merge=merge,lodash.property=property,lodash.reject=reject,lodash.restParam=restParam,lodash.slice=slice,lodash.toPlainObject=toPlainObject,lodash.unzip=unzip,lodash.values=values,lodash.zip=zip,lodash.each=forEach,lodash.extend=assign,lodash.iteratee=callback,lodash.clone=clone,lodash.escapeRegExp=escapeRegExp,lodash.findLastIndex=findLastIndex,lodash.has=has,lodash.identity=identity,lodash.includes=includes,lodash.indexOf=indexOf,lodash.isArguments=isArguments,lodash.isArray=isArray,lodash.isEmpty=isEmpty,lodash.isFunction=isFunction,lodash.isNative=isNative,lodash.isNumber=isNumber,lodash.isObject=isObject,lodash.isPlainObject=isPlainObject,lodash.isString=isString,lodash.isTypedArray=isTypedArray,lodash.last=last,lodash.some=some,lodash.any=some,lodash.contains=includes,lodash.include=includes,lodash.VERSION=VERSION,freeExports&&freeModule?moduleExports?(freeModule.exports=lodash)._=lodash:freeExports._=lodash:root._=lodash\n}).call(this)}).call(this,\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{})},{}],\"/node_modules/jshint/src/jshint.js\":[function(_dereq_,module,exports){var _=_dereq_(\"../lodash\"),events=_dereq_(\"events\"),vars=_dereq_(\"./vars.js\"),messages=_dereq_(\"./messages.js\"),Lexer=_dereq_(\"./lex.js\").Lexer,reg=_dereq_(\"./reg.js\"),state=_dereq_(\"./state.js\").state,style=_dereq_(\"./style.js\"),options=_dereq_(\"./options.js\"),scopeManager=_dereq_(\"./scope-manager.js\"),JSHINT=function(){\"use strict\";function checkOption(name,t){return name=name.trim(),/^[+-]W\\d{3}$/g.test(name)?!0:-1!==options.validNames.indexOf(name)||\"jslint\"===t.type||_.has(options.removed,name)?!0:(error(\"E001\",t,name),!1)}function isString(obj){return\"[object String]\"===Object.prototype.toString.call(obj)}function isIdentifier(tkn,value){return tkn?tkn.identifier&&tkn.value===value?!0:!1:!1}function isReserved(token){if(!token.reserved)return!1;var meta=token.meta;if(meta&&meta.isFutureReservedWord&&state.inES5()){if(!meta.es5)return!1;if(meta.strictOnly&&!state.option.strict&&!state.isStrict())return!1;if(token.isProperty)return!1}return!0}function supplant(str,data){return str.replace(/\\{([^{}]*)\\}/g,function(a,b){var r=data[b];return\"string\"==typeof r||\"number\"==typeof r?r:a})}function combine(dest,src){Object.keys(src).forEach(function(name){_.has(JSHINT.blacklist,name)||(dest[name]=src[name])})}function processenforceall(){if(state.option.enforceall){for(var enforceopt in options.bool.enforcing)void 0!==state.option[enforceopt]||options.noenforceall[enforceopt]||(state.option[enforceopt]=!0);for(var relaxopt in options.bool.relaxing)void 0===state.option[relaxopt]&&(state.option[relaxopt]=!1)}}function assume(){processenforceall(),state.option.esversion||state.option.moz||(state.option.esversion=state.option.es3?3:state.option.esnext?6:5),state.inES5()&&combine(predefined,vars.ecmaIdentifiers[5]),state.inES6()&&combine(predefined,vars.ecmaIdentifiers[6]),state.option.module&&(state.option.strict===!0&&(state.option.strict=\"global\"),state.inES6()||warning(\"W134\",state.tokens.next,\"module\",6)),state.option.couch&&combine(predefined,vars.couch),state.option.qunit&&combine(predefined,vars.qunit),state.option.rhino&&combine(predefined,vars.rhino),state.option.shelljs&&(combine(predefined,vars.shelljs),combine(predefined,vars.node)),state.option.typed&&combine(predefined,vars.typed),state.option.phantom&&(combine(predefined,vars.phantom),state.option.strict===!0&&(state.option.strict=\"global\")),state.option.prototypejs&&combine(predefined,vars.prototypejs),state.option.node&&(combine(predefined,vars.node),combine(predefined,vars.typed),state.option.strict===!0&&(state.option.strict=\"global\")),state.option.devel&&combine(predefined,vars.devel),state.option.dojo&&combine(predefined,vars.dojo),state.option.browser&&(combine(predefined,vars.browser),combine(predefined,vars.typed)),state.option.browserify&&(combine(predefined,vars.browser),combine(predefined,vars.typed),combine(predefined,vars.browserify),state.option.strict===!0&&(state.option.strict=\"global\")),state.option.nonstandard&&combine(predefined,vars.nonstandard),state.option.jasmine&&combine(predefined,vars.jasmine),state.option.jquery&&combine(predefined,vars.jquery),state.option.mootools&&combine(predefined,vars.mootools),state.option.worker&&combine(predefined,vars.worker),state.option.wsh&&combine(predefined,vars.wsh),state.option.globalstrict&&state.option.strict!==!1&&(state.option.strict=\"global\"),state.option.yui&&combine(predefined,vars.yui),state.option.mocha&&combine(predefined,vars.mocha)}function quit(code,line,chr){var percentage=Math.floor(100*(line/state.lines.length)),message=messages.errors[code].desc;throw{name:\"JSHintError\",line:line,character:chr,message:message+\" (\"+percentage+\"% scanned).\",raw:message,code:code}}function removeIgnoredMessages(){var ignored=state.ignoredLines;_.isEmpty(ignored)||(JSHINT.errors=_.reject(JSHINT.errors,function(err){return ignored[err.line]}))}function warning(code,t,a,b,c,d){var ch,l,w,msg;if(/^W\\d{3}$/.test(code)){if(state.ignored[code])return;msg=messages.warnings[code]}else/E\\d{3}/.test(code)?msg=messages.errors[code]:/I\\d{3}/.test(code)&&(msg=messages.info[code]);return t=t||state.tokens.next||{},\"(end)\"===t.id&&(t=state.tokens.curr),l=t.line||0,ch=t.from||0,w={id:\"(error)\",raw:msg.desc,code:msg.code,evidence:state.lines[l-1]||\"\",line:l,character:ch,scope:JSHINT.scope,a:a,b:b,c:c,d:d},w.reason=supplant(msg.desc,w),JSHINT.errors.push(w),removeIgnoredMessages(),JSHINT.errors.length>=state.option.maxerr&&quit(\"E043\",l,ch),w}function warningAt(m,l,ch,a,b,c,d){return warning(m,{line:l,from:ch},a,b,c,d)}function error(m,t,a,b,c,d){warning(m,t,a,b,c,d)}function errorAt(m,l,ch,a,b,c,d){return error(m,{line:l,from:ch},a,b,c,d)}function addInternalSrc(elem,src){var i;return i={id:\"(internal)\",elem:elem,value:src},JSHINT.internals.push(i),i}function doOption(){var nt=state.tokens.next,body=nt.body.match(/(-\\s+)?[^\\s,:]+(?:\\s*:\\s*(-\\s+)?[^\\s,]+)?/g)||[],predef={};if(\"globals\"===nt.type){body.forEach(function(g,idx){g=g.split(\":\");var key=(g[0]||\"\").trim(),val=(g[1]||\"\").trim();if(\"-\"===key||!key.length){if(idx>0&&idx===body.length-1)return;return error(\"E002\",nt),void 0}\"-\"===key.charAt(0)?(key=key.slice(1),val=!1,JSHINT.blacklist[key]=key,delete predefined[key]):predef[key]=\"true\"===val}),combine(predefined,predef);for(var key in predef)_.has(predef,key)&&(declared[key]=nt)}\"exported\"===nt.type&&body.forEach(function(e,idx){if(!e.length){if(idx>0&&idx===body.length-1)return;return error(\"E002\",nt),void 0}state.funct[\"(scope)\"].addExported(e)}),\"members\"===nt.type&&(membersOnly=membersOnly||{},body.forEach(function(m){var ch1=m.charAt(0),ch2=m.charAt(m.length-1);ch1!==ch2||'\"'!==ch1&&\"'\"!==ch1||(m=m.substr(1,m.length-2).replace('\\\\\"','\"')),membersOnly[m]=!1}));var numvals=[\"maxstatements\",\"maxparams\",\"maxdepth\",\"maxcomplexity\",\"maxerr\",\"maxlen\",\"indent\"];(\"jshint\"===nt.type||\"jslint\"===nt.type)&&(body.forEach(function(g){g=g.split(\":\");var key=(g[0]||\"\").trim(),val=(g[1]||\"\").trim();if(checkOption(key,nt))if(numvals.indexOf(key)>=0)if(\"false\"!==val){if(val=+val,\"number\"!=typeof val||!isFinite(val)||0>=val||Math.floor(val)!==val)return error(\"E032\",nt,g[1].trim()),void 0;state.option[key]=val}else state.option[key]=\"indent\"===key?4:!1;else{if(\"validthis\"===key)return state.funct[\"(global)\"]?void error(\"E009\"):\"true\"!==val&&\"false\"!==val?void error(\"E002\",nt):(state.option.validthis=\"true\"===val,void 0);if(\"quotmark\"!==key)if(\"shadow\"!==key)if(\"unused\"!==key)if(\"latedef\"!==key)if(\"ignore\"!==key)if(\"strict\"!==key){\"module\"===key&&(hasParsedCode(state.funct)||error(\"E055\",state.tokens.next,\"module\"));var esversions={es3:3,es5:5,esnext:6};if(!_.has(esversions,key)){if(\"esversion\"===key){switch(val){case\"5\":state.inES5(!0)&&warning(\"I003\");case\"3\":case\"6\":state.option.moz=!1,state.option.esversion=+val;break;case\"2015\":state.option.moz=!1,state.option.esversion=6;break;default:error(\"E002\",nt)}return hasParsedCode(state.funct)||error(\"E055\",state.tokens.next,\"esversion\"),void 0}var match=/^([+-])(W\\d{3})$/g.exec(key);if(match)return state.ignored[match[2]]=\"-\"===match[1],void 0;var tn;return\"true\"===val||\"false\"===val?(\"jslint\"===nt.type?(tn=options.renamed[key]||key,state.option[tn]=\"true\"===val,void 0!==options.inverted[tn]&&(state.option[tn]=!state.option[tn])):state.option[key]=\"true\"===val,\"newcap\"===key&&(state.option[\"(explicitNewcap)\"]=!0),void 0):(error(\"E002\",nt),void 0)}switch(val){case\"true\":state.option.moz=!1,state.option.esversion=esversions[key];break;case\"false\":state.option.moz||(state.option.esversion=5);break;default:error(\"E002\",nt)}}else switch(val){case\"true\":state.option.strict=!0;break;case\"false\":state.option.strict=!1;break;case\"func\":case\"global\":case\"implied\":state.option.strict=val;break;default:error(\"E002\",nt)}else switch(val){case\"line\":state.ignoredLines[nt.line]=!0,removeIgnoredMessages();break;default:error(\"E002\",nt)}else switch(val){case\"true\":state.option.latedef=!0;break;case\"false\":state.option.latedef=!1;break;case\"nofunc\":state.option.latedef=\"nofunc\";break;default:error(\"E002\",nt)}else switch(val){case\"true\":state.option.unused=!0;break;case\"false\":state.option.unused=!1;break;case\"vars\":case\"strict\":state.option.unused=val;break;default:error(\"E002\",nt)}else switch(val){case\"true\":state.option.shadow=!0;break;case\"outer\":state.option.shadow=\"outer\";break;case\"false\":case\"inner\":state.option.shadow=\"inner\";break;default:error(\"E002\",nt)}else switch(val){case\"true\":case\"false\":state.option.quotmark=\"true\"===val;break;case\"double\":case\"single\":state.option.quotmark=val;break;default:error(\"E002\",nt)}}}),assume())}function peek(p){var t,i=p||0,j=lookahead.length;if(j>i)return lookahead[i];for(;i>=j;)t=lookahead[j],t||(t=lookahead[j]=lex.token()),j+=1;return t||\"(end)\"!==state.tokens.next.id?t:state.tokens.next}function peekIgnoreEOL(){var t,i=0;do t=peek(i++);while(\"(endline)\"===t.id);return t}function advance(id,t){switch(state.tokens.curr.id){case\"(number)\":\".\"===state.tokens.next.id&&warning(\"W005\",state.tokens.curr);break;case\"-\":(\"-\"===state.tokens.next.id||\"--\"===state.tokens.next.id)&&warning(\"W006\");break;case\"+\":(\"+\"===state.tokens.next.id||\"++\"===state.tokens.next.id)&&warning(\"W007\")}for(id&&state.tokens.next.id!==id&&(t?\"(end)\"===state.tokens.next.id?error(\"E019\",t,t.id):error(\"E020\",state.tokens.next,id,t.id,t.line,state.tokens.next.value):(\"(identifier)\"!==state.tokens.next.type||state.tokens.next.value!==id)&&warning(\"W116\",state.tokens.next,id,state.tokens.next.value)),state.tokens.prev=state.tokens.curr,state.tokens.curr=state.tokens.next;;){if(state.tokens.next=lookahead.shift()||lex.token(),state.tokens.next||quit(\"E041\",state.tokens.curr.line),\"(end)\"===state.tokens.next.id||\"(error)\"===state.tokens.next.id)return;if(state.tokens.next.check&&state.tokens.next.check(),state.tokens.next.isSpecial)\"falls through\"===state.tokens.next.type?state.tokens.curr.caseFallsThrough=!0:doOption();else if(\"(endline)\"!==state.tokens.next.id)break}}function isInfix(token){return token.infix||!token.identifier&&!token.template&&!!token.led}function isEndOfExpr(){var curr=state.tokens.curr,next=state.tokens.next;return\";\"===next.id||\"}\"===next.id||\":\"===next.id?!0:isInfix(next)===isInfix(curr)||\"yield\"===curr.id&&state.inMoz()?curr.line!==startLine(next):!1}function isBeginOfExpr(prev){return!prev.left&&\"unary\"!==prev.arity}function expression(rbp,initial){var left,isArray=!1,isObject=!1,isLetExpr=!1;state.nameStack.push(),initial||\"let\"!==state.tokens.next.value||\"(\"!==peek(0).value||(state.inMoz()||warning(\"W118\",state.tokens.next,\"let expressions\"),isLetExpr=!0,state.funct[\"(scope)\"].stack(),advance(\"let\"),advance(\"(\"),state.tokens.prev.fud(),advance(\")\")),\"(end)\"===state.tokens.next.id&&error(\"E006\",state.tokens.curr);var isDangerous=state.option.asi&&state.tokens.prev.line!==startLine(state.tokens.curr)&&_.contains([\"]\",\")\"],state.tokens.prev.id)&&_.contains([\"[\",\"(\"],state.tokens.curr.id);if(isDangerous&&warning(\"W014\",state.tokens.curr,state.tokens.curr.id),advance(),initial&&(state.funct[\"(verb)\"]=state.tokens.curr.value,state.tokens.curr.beginsStmt=!0),initial===!0&&state.tokens.curr.fud)left=state.tokens.curr.fud();else for(state.tokens.curr.nud?left=state.tokens.curr.nud():error(\"E030\",state.tokens.curr,state.tokens.curr.id);(state.tokens.next.lbp>rbp||\"(template)\"===state.tokens.next.type)&&!isEndOfExpr();)isArray=\"Array\"===state.tokens.curr.value,isObject=\"Object\"===state.tokens.curr.value,left&&(left.value||left.first&&left.first.value)&&(\"new\"!==left.value||left.first&&left.first.value&&\".\"===left.first.value)&&(isArray=!1,left.value!==state.tokens.curr.value&&(isObject=!1)),advance(),isArray&&\"(\"===state.tokens.curr.id&&\")\"===state.tokens.next.id&&warning(\"W009\",state.tokens.curr),isObject&&\"(\"===state.tokens.curr.id&&\")\"===state.tokens.next.id&&warning(\"W010\",state.tokens.curr),left&&state.tokens.curr.led?left=state.tokens.curr.led(left):error(\"E033\",state.tokens.curr,state.tokens.curr.id);return isLetExpr&&state.funct[\"(scope)\"].unstack(),state.nameStack.pop(),left}function startLine(token){return token.startLine||token.line}function nobreaknonadjacent(left,right){left=left||state.tokens.curr,right=right||state.tokens.next,state.option.laxbreak||left.line===startLine(right)||warning(\"W014\",right,right.value)}function nolinebreak(t){t=t||state.tokens.curr,t.line!==startLine(state.tokens.next)&&warning(\"E022\",t,t.value)}function nobreakcomma(left,right){left.line!==startLine(right)&&(state.option.laxcomma||(comma.first&&(warning(\"I001\"),comma.first=!1),warning(\"W014\",left,right.value)))}function comma(opts){if(opts=opts||{},opts.peek?nobreakcomma(state.tokens.prev,state.tokens.curr):(nobreakcomma(state.tokens.curr,state.tokens.next),advance(\",\")),state.tokens.next.identifier&&(!opts.property||!state.inES5()))switch(state.tokens.next.value){case\"break\":case\"case\":case\"catch\":case\"continue\":case\"default\":case\"do\":case\"else\":case\"finally\":case\"for\":case\"if\":case\"in\":case\"instanceof\":case\"return\":case\"switch\":case\"throw\":case\"try\":case\"var\":case\"let\":case\"while\":case\"with\":return error(\"E024\",state.tokens.next,state.tokens.next.value),!1}if(\"(punctuator)\"===state.tokens.next.type)switch(state.tokens.next.value){case\"}\":case\"]\":case\",\":if(opts.allowTrailing)return!0;case\")\":return error(\"E024\",state.tokens.next,state.tokens.next.value),!1}return!0}function symbol(s,p){var x=state.syntax[s];return x&&\"object\"==typeof x||(state.syntax[s]=x={id:s,lbp:p,value:s}),x}function delim(s){var x=symbol(s,0);return x.delim=!0,x}function stmt(s,f){var x=delim(s);return x.identifier=x.reserved=!0,x.fud=f,x}function blockstmt(s,f){var x=stmt(s,f);return x.block=!0,x}function reserveName(x){var c=x.id.charAt(0);return(c>=\"a\"&&\"z\">=c||c>=\"A\"&&\"Z\">=c)&&(x.identifier=x.reserved=!0),x}function prefix(s,f){var x=symbol(s,150);return reserveName(x),x.nud=\"function\"==typeof f?f:function(){return this.arity=\"unary\",this.right=expression(150),(\"++\"===this.id||\"--\"===this.id)&&(state.option.plusplus?warning(\"W016\",this,this.id):!this.right||this.right.identifier&&!isReserved(this.right)||\".\"===this.right.id||\"[\"===this.right.id||warning(\"W017\",this),this.right&&this.right.isMetaProperty?error(\"E031\",this):this.right&&this.right.identifier&&state.funct[\"(scope)\"].block.modify(this.right.value,this)),this},x}function type(s,f){var x=delim(s);return x.type=s,x.nud=f,x}function reserve(name,func){var x=type(name,func);return x.identifier=!0,x.reserved=!0,x}function FutureReservedWord(name,meta){var x=type(name,meta&&meta.nud||function(){return this});return meta=meta||{},meta.isFutureReservedWord=!0,x.value=name,x.identifier=!0,x.reserved=!0,x.meta=meta,x}function reservevar(s,v){return reserve(s,function(){return\"function\"==typeof v&&v(this),this})}function infix(s,f,p,w){var x=symbol(s,p);return reserveName(x),x.infix=!0,x.led=function(left){return w||nobreaknonadjacent(state.tokens.prev,state.tokens.curr),\"in\"!==s&&\"instanceof\"!==s||\"!\"!==left.id||warning(\"W018\",left,\"!\"),\"function\"==typeof f?f(left,this):(this.left=left,this.right=expression(p),this)},x}function application(s){var x=symbol(s,42);return x.led=function(left){return nobreaknonadjacent(state.tokens.prev,state.tokens.curr),this.left=left,this.right=doFunction({type:\"arrow\",loneArg:left}),this},x}function relation(s,f){var x=symbol(s,100);return x.led=function(left){nobreaknonadjacent(state.tokens.prev,state.tokens.curr),this.left=left;var right=this.right=expression(100);return isIdentifier(left,\"NaN\")||isIdentifier(right,\"NaN\")?warning(\"W019\",this):f&&f.apply(this,[left,right]),left&&right||quit(\"E041\",state.tokens.curr.line),\"!\"===left.id&&warning(\"W018\",left,\"!\"),\"!\"===right.id&&warning(\"W018\",right,\"!\"),this},x}function isPoorRelation(node){return node&&(\"(number)\"===node.type&&0===+node.value||\"(string)\"===node.type&&\"\"===node.value||\"null\"===node.type&&!state.option.eqnull||\"true\"===node.type||\"false\"===node.type||\"undefined\"===node.type)}function isTypoTypeof(left,right,state){var values;return state.option.notypeof?!1:left&&right?(values=state.inES6()?typeofValues.es6:typeofValues.es3,\"(identifier)\"===right.type&&\"typeof\"===right.value&&\"(string)\"===left.type?!_.contains(values,left.value):!1):!1}function isGlobalEval(left,state){var isGlobal=!1;return\"this\"===left.type&&null===state.funct[\"(context)\"]?isGlobal=!0:\"(identifier)\"===left.type&&(state.option.node&&\"global\"===left.value?isGlobal=!0:!state.option.browser||\"window\"!==left.value&&\"document\"!==left.value||(isGlobal=!0)),isGlobal}function findNativePrototype(left){function walkPrototype(obj){return\"object\"==typeof obj?\"prototype\"===obj.right?obj:walkPrototype(obj.left):void 0}function walkNative(obj){for(;!obj.identifier&&\"object\"==typeof obj.left;)obj=obj.left;return obj.identifier&&natives.indexOf(obj.value)>=0?obj.value:void 0}var natives=[\"Array\",\"ArrayBuffer\",\"Boolean\",\"Collator\",\"DataView\",\"Date\",\"DateTimeFormat\",\"Error\",\"EvalError\",\"Float32Array\",\"Float64Array\",\"Function\",\"Infinity\",\"Intl\",\"Int16Array\",\"Int32Array\",\"Int8Array\",\"Iterator\",\"Number\",\"NumberFormat\",\"Object\",\"RangeError\",\"ReferenceError\",\"RegExp\",\"StopIteration\",\"String\",\"SyntaxError\",\"TypeError\",\"Uint16Array\",\"Uint32Array\",\"Uint8Array\",\"Uint8ClampedArray\",\"URIError\"],prototype=walkPrototype(left);return prototype?walkNative(prototype):void 0}function checkLeftSideAssign(left,assignToken,options){var allowDestructuring=options&&options.allowDestructuring;if(assignToken=assignToken||left,state.option.freeze){var nativeObject=findNativePrototype(left);nativeObject&&warning(\"W121\",left,nativeObject)}return left.identifier&&!left.isMetaProperty&&state.funct[\"(scope)\"].block.reassign(left.value,left),\".\"===left.id?((!left.left||\"arguments\"===left.left.value&&!state.isStrict())&&warning(\"E031\",assignToken),state.nameStack.set(state.tokens.prev),!0):\"{\"===left.id||\"[\"===left.id?(allowDestructuring&&state.tokens.curr.left.destructAssign?state.tokens.curr.left.destructAssign.forEach(function(t){t.id&&state.funct[\"(scope)\"].block.modify(t.id,t.token)}):\"{\"!==left.id&&left.left?\"arguments\"!==left.left.value||state.isStrict()||warning(\"E031\",assignToken):warning(\"E031\",assignToken),\"[\"===left.id&&state.nameStack.set(left.right),!0):left.isMetaProperty?(error(\"E031\",assignToken),!0):left.identifier&&!isReserved(left)?(\"exception\"===state.funct[\"(scope)\"].labeltype(left.value)&&warning(\"W022\",left),state.nameStack.set(left),!0):(left===state.syntax[\"function\"]&&warning(\"W023\",state.tokens.curr),!1)}function assignop(s,f,p){var x=infix(s,\"function\"==typeof f?f:function(left,that){return that.left=left,left&&checkLeftSideAssign(left,that,{allowDestructuring:!0})?(that.right=expression(10),that):(error(\"E031\",that),void 0)},p);return x.exps=!0,x.assign=!0,x}function bitwise(s,f,p){var x=symbol(s,p);return reserveName(x),x.led=\"function\"==typeof f?f:function(left){return state.option.bitwise&&warning(\"W016\",this,this.id),this.left=left,this.right=expression(p),this},x}function bitwiseassignop(s){return assignop(s,function(left,that){return state.option.bitwise&&warning(\"W016\",that,that.id),left&&checkLeftSideAssign(left,that)?(that.right=expression(10),that):(error(\"E031\",that),void 0)},20)}function suffix(s){var x=symbol(s,150);return x.led=function(left){return state.option.plusplus?warning(\"W016\",this,this.id):left.identifier&&!isReserved(left)||\".\"===left.id||\"[\"===left.id||warning(\"W017\",this),left.isMetaProperty?error(\"E031\",this):left&&left.identifier&&state.funct[\"(scope)\"].block.modify(left.value,left),this.left=left,this},x}function optionalidentifier(fnparam,prop,preserve){if(state.tokens.next.identifier){preserve||advance();var curr=state.tokens.curr,val=state.tokens.curr.value;return isReserved(curr)?prop&&state.inES5()?val:fnparam&&\"undefined\"===val?val:(warning(\"W024\",state.tokens.curr,state.tokens.curr.id),val):val}}function identifier(fnparam,prop){var i=optionalidentifier(fnparam,prop,!1);if(i)return i;if(\"...\"===state.tokens.next.value){if(state.inES6(!0)||warning(\"W119\",state.tokens.next,\"spread/rest operator\",\"6\"),advance(),checkPunctuator(state.tokens.next,\"...\"))for(warning(\"E024\",state.tokens.next,\"...\");checkPunctuator(state.tokens.next,\"...\");)advance();return state.tokens.next.identifier?identifier(fnparam,prop):(warning(\"E024\",state.tokens.curr,\"...\"),void 0)}error(\"E030\",state.tokens.next,state.tokens.next.value),\";\"!==state.tokens.next.id&&advance()}function reachable(controlToken){var t,i=0;if(\";\"===state.tokens.next.id&&!controlToken.inBracelessBlock)for(;;){do t=peek(i),i+=1;while(\"(end)\"!==t.id&&\"(comment)\"===t.id);if(t.reach)return;if(\"(endline)\"!==t.id){if(\"function\"===t.id){state.option.latedef===!0&&warning(\"W026\",t);break}warning(\"W027\",t,t.value,controlToken.value);break}}}function parseFinalSemicolon(){if(\";\"!==state.tokens.next.id){if(state.tokens.next.isUnclosed)return advance();var sameLine=startLine(state.tokens.next)===state.tokens.curr.line&&\"(end)\"!==state.tokens.next.id,blockEnd=checkPunctuator(state.tokens.next,\"}\");sameLine&&!blockEnd?errorAt(\"E058\",state.tokens.curr.line,state.tokens.curr.character):state.option.asi||(blockEnd&&!state.option.lastsemic||!sameLine)&&warningAt(\"W033\",state.tokens.curr.line,state.tokens.curr.character)}else advance(\";\")}function statement(){var r,i=indent,t=state.tokens.next,hasOwnScope=!1;if(\";\"===t.id)return advance(\";\"),void 0;var res=isReserved(t);if(res&&t.meta&&t.meta.isFutureReservedWord&&\":\"===peek().id&&(warning(\"W024\",t,t.id),res=!1),t.identifier&&!res&&\":\"===peek().id&&(advance(),advance(\":\"),hasOwnScope=!0,state.funct[\"(scope)\"].stack(),state.funct[\"(scope)\"].block.addBreakLabel(t.value,{token:state.tokens.curr}),state.tokens.next.labelled||\"{\"===state.tokens.next.value||warning(\"W028\",state.tokens.next,t.value,state.tokens.next.value),state.tokens.next.label=t.value,t=state.tokens.next),\"{\"===t.id){var iscase=\"case\"===state.funct[\"(verb)\"]&&\":\"===state.tokens.curr.value;return block(!0,!0,!1,!1,iscase),void 0}return r=expression(0,!0),!r||r.identifier&&\"function\"===r.value||\"(punctuator)\"===r.type&&r.left&&r.left.identifier&&\"function\"===r.left.value||state.isStrict()||\"global\"!==state.option.strict||warning(\"E007\"),t.block||(state.option.expr||r&&r.exps?state.option.nonew&&r&&r.left&&\"(\"===r.id&&\"new\"===r.left.id&&warning(\"W031\",t):warning(\"W030\",state.tokens.curr),parseFinalSemicolon()),indent=i,hasOwnScope&&state.funct[\"(scope)\"].unstack(),r}function statements(){for(var p,a=[];!state.tokens.next.reach&&\"(end)\"!==state.tokens.next.id;)\";\"===state.tokens.next.id?(p=peek(),(!p||\"(\"!==p.id&&\"[\"!==p.id)&&warning(\"W032\"),advance(\";\")):a.push(statement());return a}function directives(){for(var i,p,pn;\"(string)\"===state.tokens.next.id;){if(p=peek(0),\"(endline)\"===p.id){i=1;do pn=peek(i++);while(\"(endline)\"===pn.id);if(\";\"===pn.id)p=pn;else{if(\"[\"===pn.value||\".\"===pn.value)break;state.option.asi&&\"(\"!==pn.value||warning(\"W033\",state.tokens.next)}}else{if(\".\"===p.id||\"[\"===p.id)break;\";\"!==p.id&&warning(\"W033\",p)}advance();var directive=state.tokens.curr.value;(state.directive[directive]||\"use strict\"===directive&&\"implied\"===state.option.strict)&&warning(\"W034\",state.tokens.curr,directive),state.directive[directive]=!0,\";\"===p.id&&advance(\";\")}state.isStrict()&&(state.option[\"(explicitNewcap)\"]||(state.option.newcap=!0),state.option.undef=!0)}function block(ordinary,stmt,isfunc,isfatarrow,iscase){var a,m,t,line,d,b=inblock,old_indent=indent;inblock=ordinary,t=state.tokens.next;var metrics=state.funct[\"(metrics)\"];if(metrics.nestedBlockDepth+=1,metrics.verifyMaxNestedBlockDepthPerFunction(),\"{\"===state.tokens.next.id){if(advance(\"{\"),state.funct[\"(scope)\"].stack(),line=state.tokens.curr.line,\"}\"!==state.tokens.next.id){for(indent+=state.option.indent;!ordinary&&state.tokens.next.from>indent;)indent+=state.option.indent;if(isfunc){m={};for(d in state.directive)_.has(state.directive,d)&&(m[d]=state.directive[d]);directives(),state.option.strict&&state.funct[\"(context)\"][\"(global)\"]&&(m[\"use strict\"]||state.isStrict()||warning(\"E007\"))}a=statements(),metrics.statementCount+=a.length,indent-=state.option.indent}advance(\"}\",t),isfunc&&(state.funct[\"(scope)\"].validateParams(),m&&(state.directive=m)),state.funct[\"(scope)\"].unstack(),indent=old_indent}else if(ordinary)state.funct[\"(noblockscopedvar)\"]=\"for\"!==state.tokens.next.id,state.funct[\"(scope)\"].stack(),(!stmt||state.option.curly)&&warning(\"W116\",state.tokens.next,\"{\",state.tokens.next.value),state.tokens.next.inBracelessBlock=!0,indent+=state.option.indent,a=[statement()],indent-=state.option.indent,state.funct[\"(scope)\"].unstack(),delete state.funct[\"(noblockscopedvar)\"];else if(isfunc){if(state.funct[\"(scope)\"].stack(),m={},!stmt||isfatarrow||state.inMoz()||error(\"W118\",state.tokens.curr,\"function closure expressions\"),!stmt)for(d in state.directive)_.has(state.directive,d)&&(m[d]=state.directive[d]);expression(10),state.option.strict&&state.funct[\"(context)\"][\"(global)\"]&&(m[\"use strict\"]||state.isStrict()||warning(\"E007\")),state.funct[\"(scope)\"].unstack()}else error(\"E021\",state.tokens.next,\"{\",state.tokens.next.value);switch(state.funct[\"(verb)\"]){case\"break\":case\"continue\":case\"return\":case\"throw\":if(iscase)break;default:state.funct[\"(verb)\"]=null}return inblock=b,!ordinary||!state.option.noempty||a&&0!==a.length||warning(\"W035\",state.tokens.prev),metrics.nestedBlockDepth-=1,a}function countMember(m){membersOnly&&\"boolean\"!=typeof membersOnly[m]&&warning(\"W036\",state.tokens.curr,m),\"number\"==typeof member[m]?member[m]+=1:member[m]=1}function comprehensiveArrayExpression(){var res={};res.exps=!0,state.funct[\"(comparray)\"].stack();var reversed=!1;return\"for\"!==state.tokens.next.value&&(reversed=!0,state.inMoz()||warning(\"W116\",state.tokens.next,\"for\",state.tokens.next.value),state.funct[\"(comparray)\"].setState(\"use\"),res.right=expression(10)),advance(\"for\"),\"each\"===state.tokens.next.value&&(advance(\"each\"),state.inMoz()||warning(\"W118\",state.tokens.curr,\"for each\")),advance(\"(\"),state.funct[\"(comparray)\"].setState(\"define\"),res.left=expression(130),_.contains([\"in\",\"of\"],state.tokens.next.value)?advance():error(\"E045\",state.tokens.curr),state.funct[\"(comparray)\"].setState(\"generate\"),expression(10),advance(\")\"),\"if\"===state.tokens.next.value&&(advance(\"if\"),advance(\"(\"),state.funct[\"(comparray)\"].setState(\"filter\"),res.filter=expression(10),advance(\")\")),reversed||(state.funct[\"(comparray)\"].setState(\"use\"),res.right=expression(10)),advance(\"]\"),state.funct[\"(comparray)\"].unstack(),res}function isMethod(){return state.funct[\"(statement)\"]&&\"class\"===state.funct[\"(statement)\"].type||state.funct[\"(context)\"]&&\"class\"===state.funct[\"(context)\"][\"(verb)\"]}function isPropertyName(token){return token.identifier||\"(string)\"===token.id||\"(number)\"===token.id}function propertyName(preserveOrToken){var id,preserve=!0;return\"object\"==typeof preserveOrToken?id=preserveOrToken:(preserve=preserveOrToken,id=optionalidentifier(!1,!0,preserve)),id?\"object\"==typeof id&&(\"(string)\"===id.id||\"(identifier)\"===id.id?id=id.value:\"(number)\"===id.id&&(id=\"\"+id.value)):\"(string)\"===state.tokens.next.id?(id=state.tokens.next.value,preserve||advance()):\"(number)\"===state.tokens.next.id&&(id=\"\"+state.tokens.next.value,preserve||advance()),\"hasOwnProperty\"===id&&warning(\"W001\"),id}function functionparams(options){function addParam(addParamArgs){state.funct[\"(scope)\"].addParam.apply(state.funct[\"(scope)\"],addParamArgs)}var next,ident,t,paramsIds=[],tokens=[],pastDefault=!1,pastRest=!1,arity=0,loneArg=options&&options.loneArg;if(loneArg&&loneArg.identifier===!0)return state.funct[\"(scope)\"].addParam(loneArg.value,loneArg),{arity:1,params:[loneArg.value]};if(next=state.tokens.next,options&&options.parsedOpening||advance(\"(\"),\")\"===state.tokens.next.id)return advance(\")\"),void 0;for(;;){arity++;var currentParams=[];if(_.contains([\"{\",\"[\"],state.tokens.next.id)){tokens=destructuringPattern();for(t in tokens)t=tokens[t],t.id&&(paramsIds.push(t.id),currentParams.push([t.id,t.token]))}else if(checkPunctuator(state.tokens.next,\"...\")&&(pastRest=!0),ident=identifier(!0))paramsIds.push(ident),currentParams.push([ident,state.tokens.curr]);else for(;!checkPunctuators(state.tokens.next,[\",\",\")\"]);)advance();if(pastDefault&&\"=\"!==state.tokens.next.id&&error(\"W138\",state.tokens.current),\"=\"===state.tokens.next.id&&(state.inES6()||warning(\"W119\",state.tokens.next,\"default parameters\",\"6\"),advance(\"=\"),pastDefault=!0,expression(10)),currentParams.forEach(addParam),\",\"!==state.tokens.next.id)return advance(\")\",next),{arity:arity,params:paramsIds};pastRest&&warning(\"W131\",state.tokens.next),comma()}}function functor(name,token,overwrites){var funct={\"(name)\":name,\"(breakage)\":0,\"(loopage)\":0,\"(tokens)\":{},\"(properties)\":{},\"(catch)\":!1,\"(global)\":!1,\"(line)\":null,\"(character)\":null,\"(metrics)\":null,\"(statement)\":null,\"(context)\":null,\"(scope)\":null,\"(comparray)\":null,\"(generator)\":null,\"(arrow)\":null,\"(params)\":null};return token&&_.extend(funct,{\"(line)\":token.line,\"(character)\":token.character,\"(metrics)\":createMetrics(token)}),_.extend(funct,overwrites),funct[\"(context)\"]&&(funct[\"(scope)\"]=funct[\"(context)\"][\"(scope)\"],funct[\"(comparray)\"]=funct[\"(context)\"][\"(comparray)\"]),funct}function isFunctor(token){return\"(scope)\"in token}function hasParsedCode(funct){return funct[\"(global)\"]&&!funct[\"(verb)\"]}function doTemplateLiteral(left){function end(){if(state.tokens.curr.template&&state.tokens.curr.tail&&state.tokens.curr.context===ctx)return!0;var complete=state.tokens.next.template&&state.tokens.next.tail&&state.tokens.next.context===ctx;return complete&&advance(),complete||state.tokens.next.isUnclosed}var ctx=this.context,noSubst=this.noSubst,depth=this.depth;if(!noSubst)for(;!end();)!state.tokens.next.template||state.tokens.next.depth>depth?expression(0):advance();return{id:\"(template)\",type:\"(template)\",tag:left}}function doFunction(options){var f,token,name,statement,classExprBinding,isGenerator,isArrow,ignoreLoopFunc,oldOption=state.option,oldIgnored=state.ignored;options&&(name=options.name,statement=options.statement,classExprBinding=options.classExprBinding,isGenerator=\"generator\"===options.type,isArrow=\"arrow\"===options.type,ignoreLoopFunc=options.ignoreLoopFunc),state.option=Object.create(state.option),state.ignored=Object.create(state.ignored),state.funct=functor(name||state.nameStack.infer(),state.tokens.next,{\"(statement)\":statement,\"(context)\":state.funct,\"(arrow)\":isArrow,\"(generator)\":isGenerator}),f=state.funct,token=state.tokens.curr,token.funct=state.funct,functions.push(state.funct),state.funct[\"(scope)\"].stack(\"functionouter\");var internallyAccessibleName=name||classExprBinding;internallyAccessibleName&&state.funct[\"(scope)\"].block.add(internallyAccessibleName,classExprBinding?\"class\":\"function\",state.tokens.curr,!1),state.funct[\"(scope)\"].stack(\"functionparams\");var paramsInfo=functionparams(options);return paramsInfo?(state.funct[\"(params)\"]=paramsInfo.params,state.funct[\"(metrics)\"].arity=paramsInfo.arity,state.funct[\"(metrics)\"].verifyMaxParametersPerFunction()):state.funct[\"(metrics)\"].arity=0,isArrow&&(state.inES6(!0)||warning(\"W119\",state.tokens.curr,\"arrow function syntax (=>)\",\"6\"),options.loneArg||advance(\"=>\")),block(!1,!0,!0,isArrow),!state.option.noyield&&isGenerator&&\"yielded\"!==state.funct[\"(generator)\"]&&warning(\"W124\",state.tokens.curr),state.funct[\"(metrics)\"].verifyMaxStatementsPerFunction(),state.funct[\"(metrics)\"].verifyMaxComplexityPerFunction(),state.funct[\"(unusedOption)\"]=state.option.unused,state.option=oldOption,state.ignored=oldIgnored,state.funct[\"(last)\"]=state.tokens.curr.line,state.funct[\"(lastcharacter)\"]=state.tokens.curr.character,state.funct[\"(scope)\"].unstack(),state.funct[\"(scope)\"].unstack(),state.funct=state.funct[\"(context)\"],ignoreLoopFunc||state.option.loopfunc||!state.funct[\"(loopage)\"]||f[\"(isCapturing)\"]&&warning(\"W083\",token),f}function createMetrics(functionStartToken){return{statementCount:0,nestedBlockDepth:-1,ComplexityCount:1,arity:0,verifyMaxStatementsPerFunction:function(){state.option.maxstatements&&this.statementCount>state.option.maxstatements&&warning(\"W071\",functionStartToken,this.statementCount)\n},verifyMaxParametersPerFunction:function(){_.isNumber(state.option.maxparams)&&this.arity>state.option.maxparams&&warning(\"W072\",functionStartToken,this.arity)},verifyMaxNestedBlockDepthPerFunction:function(){state.option.maxdepth&&this.nestedBlockDepth>0&&this.nestedBlockDepth===state.option.maxdepth+1&&warning(\"W073\",null,this.nestedBlockDepth)},verifyMaxComplexityPerFunction:function(){var max=state.option.maxcomplexity,cc=this.ComplexityCount;max&&cc>max&&warning(\"W074\",functionStartToken,cc)}}}function increaseComplexityCount(){state.funct[\"(metrics)\"].ComplexityCount+=1}function checkCondAssignment(expr){var id,paren;switch(expr&&(id=expr.id,paren=expr.paren,\",\"===id&&(expr=expr.exprs[expr.exprs.length-1])&&(id=expr.id,paren=paren||expr.paren)),id){case\"=\":case\"+=\":case\"-=\":case\"*=\":case\"%=\":case\"&=\":case\"|=\":case\"^=\":case\"/=\":paren||state.option.boss||warning(\"W084\")}}function checkProperties(props){if(state.inES5())for(var name in props)props[name]&&props[name].setterToken&&!props[name].getterToken&&warning(\"W078\",props[name].setterToken)}function metaProperty(name,c){if(checkPunctuator(state.tokens.next,\".\")){var left=state.tokens.curr.id;advance(\".\");var id=identifier();return state.tokens.curr.isMetaProperty=!0,name!==id?error(\"E057\",state.tokens.prev,left,id):c(),state.tokens.curr}}function destructuringPattern(options){var isAssignment=options&&options.assignment;return state.inES6()||warning(\"W104\",state.tokens.curr,isAssignment?\"destructuring assignment\":\"destructuring binding\",\"6\"),destructuringPatternRecursive(options)}function destructuringPatternRecursive(options){var ids,identifiers=[],openingParsed=options&&options.openingParsed,isAssignment=options&&options.assignment,recursiveOptions=isAssignment?{assignment:isAssignment}:null,firstToken=openingParsed?state.tokens.curr:state.tokens.next,nextInnerDE=function(){var ident;if(checkPunctuators(state.tokens.next,[\"[\",\"{\"])){ids=destructuringPatternRecursive(recursiveOptions);for(var id in ids)id=ids[id],identifiers.push({id:id.id,token:id.token})}else if(checkPunctuator(state.tokens.next,\",\"))identifiers.push({id:null,token:state.tokens.curr});else{if(!checkPunctuator(state.tokens.next,\"(\")){var is_rest=checkPunctuator(state.tokens.next,\"...\");if(isAssignment){var identifierToken=is_rest?peek(0):state.tokens.next;identifierToken.identifier||warning(\"E030\",identifierToken,identifierToken.value);var assignTarget=expression(155);assignTarget&&(checkLeftSideAssign(assignTarget),assignTarget.identifier&&(ident=assignTarget.value))}else ident=identifier();return ident&&identifiers.push({id:ident,token:state.tokens.curr}),is_rest}advance(\"(\"),nextInnerDE(),advance(\")\")}return!1},assignmentProperty=function(){var id;checkPunctuator(state.tokens.next,\"[\")?(advance(\"[\"),expression(10),advance(\"]\"),advance(\":\"),nextInnerDE()):\"(string)\"===state.tokens.next.id||\"(number)\"===state.tokens.next.id?(advance(),advance(\":\"),nextInnerDE()):(id=identifier(),checkPunctuator(state.tokens.next,\":\")?(advance(\":\"),nextInnerDE()):id&&(isAssignment&&checkLeftSideAssign(state.tokens.curr),identifiers.push({id:id,token:state.tokens.curr})))};if(checkPunctuator(firstToken,\"[\")){openingParsed||advance(\"[\"),checkPunctuator(state.tokens.next,\"]\")&&warning(\"W137\",state.tokens.curr);for(var element_after_rest=!1;!checkPunctuator(state.tokens.next,\"]\");)nextInnerDE()&&!element_after_rest&&checkPunctuator(state.tokens.next,\",\")&&(warning(\"W130\",state.tokens.next),element_after_rest=!0),checkPunctuator(state.tokens.next,\"=\")&&(checkPunctuator(state.tokens.prev,\"...\")?advance(\"]\"):advance(\"=\"),\"undefined\"===state.tokens.next.id&&warning(\"W080\",state.tokens.prev,state.tokens.prev.value),expression(10)),checkPunctuator(state.tokens.next,\"]\")||advance(\",\");advance(\"]\")}else if(checkPunctuator(firstToken,\"{\")){for(openingParsed||advance(\"{\"),checkPunctuator(state.tokens.next,\"}\")&&warning(\"W137\",state.tokens.curr);!checkPunctuator(state.tokens.next,\"}\")&&(assignmentProperty(),checkPunctuator(state.tokens.next,\"=\")&&(advance(\"=\"),\"undefined\"===state.tokens.next.id&&warning(\"W080\",state.tokens.prev,state.tokens.prev.value),expression(10)),checkPunctuator(state.tokens.next,\"}\")||(advance(\",\"),!checkPunctuator(state.tokens.next,\"}\"))););advance(\"}\")}return identifiers}function destructuringPatternMatch(tokens,value){var first=value.first;first&&_.zip(tokens,Array.isArray(first)?first:[first]).forEach(function(val){var token=val[0],value=val[1];token&&value?token.first=value:token&&token.first&&!value&&warning(\"W080\",token.first,token.first.value)})}function blockVariableStatement(type,statement,context){var tokens,lone,value,letblock,prefix=context&&context.prefix,inexport=context&&context.inexport,isLet=\"let\"===type,isConst=\"const\"===type;for(state.inES6()||warning(\"W104\",state.tokens.curr,type,\"6\"),isLet&&\"(\"===state.tokens.next.value?(state.inMoz()||warning(\"W118\",state.tokens.next,\"let block\"),advance(\"(\"),state.funct[\"(scope)\"].stack(),letblock=!0):state.funct[\"(noblockscopedvar)\"]&&error(\"E048\",state.tokens.curr,isConst?\"Const\":\"Let\"),statement.first=[];;){var names=[];_.contains([\"{\",\"[\"],state.tokens.next.value)?(tokens=destructuringPattern(),lone=!1):(tokens=[{id:identifier(),token:state.tokens.curr}],lone=!0),!prefix&&isConst&&\"=\"!==state.tokens.next.id&&warning(\"E012\",state.tokens.curr,state.tokens.curr.value);for(var t in tokens)tokens.hasOwnProperty(t)&&(t=tokens[t],state.funct[\"(scope)\"].block.isGlobal()&&predefined[t.id]===!1&&warning(\"W079\",t.token,t.id),t.id&&!state.funct[\"(noblockscopedvar)\"]&&(state.funct[\"(scope)\"].addlabel(t.id,{type:type,token:t.token}),names.push(t.token),lone&&inexport&&state.funct[\"(scope)\"].setExported(t.token.value,t.token)));if(\"=\"===state.tokens.next.id&&(advance(\"=\"),prefix||\"undefined\"!==state.tokens.next.id||warning(\"W080\",state.tokens.prev,state.tokens.prev.value),!prefix&&\"=\"===peek(0).id&&state.tokens.next.identifier&&warning(\"W120\",state.tokens.next,state.tokens.next.value),value=expression(prefix?120:10),lone?tokens[0].first=value:destructuringPatternMatch(names,value)),statement.first=statement.first.concat(names),\",\"!==state.tokens.next.id)break;comma()}return letblock&&(advance(\")\"),block(!0,!0),statement.block=!0,state.funct[\"(scope)\"].unstack()),statement}function classdef(isStatement){return state.inES6()||warning(\"W104\",state.tokens.curr,\"class\",\"6\"),isStatement?(this.name=identifier(),state.funct[\"(scope)\"].addlabel(this.name,{type:\"class\",token:state.tokens.curr})):state.tokens.next.identifier&&\"extends\"!==state.tokens.next.value?(this.name=identifier(),this.namedExpr=!0):this.name=state.nameStack.infer(),classtail(this),this}function classtail(c){var wasInClassBody=state.inClassBody;\"extends\"===state.tokens.next.value&&(advance(\"extends\"),c.heritage=expression(10)),state.inClassBody=!0,advance(\"{\"),c.body=classbody(c),advance(\"}\"),state.inClassBody=wasInClassBody}function classbody(c){for(var name,isStatic,isGenerator,getset,computed,props=Object.create(null),staticProps=Object.create(null),i=0;\"}\"!==state.tokens.next.id;++i)if(name=state.tokens.next,isStatic=!1,isGenerator=!1,getset=null,\";\"!==name.id){if(\"*\"===name.id&&(isGenerator=!0,advance(\"*\"),name=state.tokens.next),\"[\"===name.id)name=computedPropertyName(),computed=!0;else{if(!isPropertyName(name)){warning(\"W052\",state.tokens.next,state.tokens.next.value||state.tokens.next.type),advance();continue}advance(),computed=!1,name.identifier&&\"static\"===name.value&&(checkPunctuator(state.tokens.next,\"*\")&&(isGenerator=!0,advance(\"*\")),(isPropertyName(state.tokens.next)||\"[\"===state.tokens.next.id)&&(computed=\"[\"===state.tokens.next.id,isStatic=!0,name=state.tokens.next,\"[\"===state.tokens.next.id?name=computedPropertyName():advance())),!name.identifier||\"get\"!==name.value&&\"set\"!==name.value||(isPropertyName(state.tokens.next)||\"[\"===state.tokens.next.id)&&(computed=\"[\"===state.tokens.next.id,getset=name,name=state.tokens.next,\"[\"===state.tokens.next.id?name=computedPropertyName():advance())}if(!checkPunctuator(state.tokens.next,\"(\")){for(error(\"E054\",state.tokens.next,state.tokens.next.value);\"}\"!==state.tokens.next.id&&!checkPunctuator(state.tokens.next,\"(\");)advance();\"(\"!==state.tokens.next.value&&doFunction({statement:c})}if(computed||(getset?saveAccessor(getset.value,isStatic?staticProps:props,name.value,name,!0,isStatic):(\"constructor\"===name.value?state.nameStack.set(c):state.nameStack.set(name),saveProperty(isStatic?staticProps:props,name.value,name,!0,isStatic))),getset&&\"constructor\"===name.value){var propDesc=\"get\"===getset.value?\"class getter method\":\"class setter method\";error(\"E049\",name,propDesc,\"constructor\")}else\"prototype\"===name.value&&error(\"E049\",name,\"class method\",\"prototype\");propertyName(name),doFunction({statement:c,type:isGenerator?\"generator\":null,classExprBinding:c.namedExpr?c.name:null})}else warning(\"W032\"),advance(\";\");checkProperties(props)}function saveProperty(props,name,tkn,isClass,isStatic){var msg=[\"key\",\"class method\",\"static class method\"];msg=msg[(isClass||!1)+(isStatic||!1)],tkn.identifier&&(name=tkn.value),props[name]&&\"__proto__\"!==name?warning(\"W075\",state.tokens.next,msg,name):props[name]=Object.create(null),props[name].basic=!0,props[name].basictkn=tkn}function saveAccessor(accessorType,props,name,tkn,isClass,isStatic){var flagName=\"get\"===accessorType?\"getterToken\":\"setterToken\",msg=\"\";isClass?(isStatic&&(msg+=\"static \"),msg+=accessorType+\"ter method\"):msg=\"key\",state.tokens.curr.accessorType=accessorType,state.nameStack.set(tkn),props[name]?(props[name].basic||props[name][flagName])&&\"__proto__\"!==name&&warning(\"W075\",state.tokens.next,msg,name):props[name]=Object.create(null),props[name][flagName]=tkn}function computedPropertyName(){advance(\"[\"),state.inES6()||warning(\"W119\",state.tokens.curr,\"computed property names\",\"6\");var value=expression(10);return advance(\"]\"),value}function checkPunctuators(token,values){return\"(punctuator)\"===token.type?_.contains(values,token.value):!1}function checkPunctuator(token,value){return\"(punctuator)\"===token.type&&token.value===value}function destructuringAssignOrJsonValue(){var block=lookupBlockType();block.notJson?(!state.inES6()&&block.isDestAssign&&warning(\"W104\",state.tokens.curr,\"destructuring assignment\",\"6\"),statements()):(state.option.laxbreak=!0,state.jsonMode=!0,jsonValue())}function jsonValue(){function jsonObject(){var o={},t=state.tokens.next;if(advance(\"{\"),\"}\"!==state.tokens.next.id)for(;;){if(\"(end)\"===state.tokens.next.id)error(\"E026\",state.tokens.next,t.line);else{if(\"}\"===state.tokens.next.id){warning(\"W094\",state.tokens.curr);break}\",\"===state.tokens.next.id?error(\"E028\",state.tokens.next):\"(string)\"!==state.tokens.next.id&&warning(\"W095\",state.tokens.next,state.tokens.next.value)}if(o[state.tokens.next.value]===!0?warning(\"W075\",state.tokens.next,\"key\",state.tokens.next.value):\"__proto__\"===state.tokens.next.value&&!state.option.proto||\"__iterator__\"===state.tokens.next.value&&!state.option.iterator?warning(\"W096\",state.tokens.next,state.tokens.next.value):o[state.tokens.next.value]=!0,advance(),advance(\":\"),jsonValue(),\",\"!==state.tokens.next.id)break;advance(\",\")}advance(\"}\")}function jsonArray(){var t=state.tokens.next;if(advance(\"[\"),\"]\"!==state.tokens.next.id)for(;;){if(\"(end)\"===state.tokens.next.id)error(\"E027\",state.tokens.next,t.line);else{if(\"]\"===state.tokens.next.id){warning(\"W094\",state.tokens.curr);break}\",\"===state.tokens.next.id&&error(\"E028\",state.tokens.next)}if(jsonValue(),\",\"!==state.tokens.next.id)break;advance(\",\")}advance(\"]\")}switch(state.tokens.next.id){case\"{\":jsonObject();break;case\"[\":jsonArray();break;case\"true\":case\"false\":case\"null\":case\"(number)\":case\"(string)\":advance();break;case\"-\":advance(\"-\"),advance(\"(number)\");break;default:error(\"E003\",state.tokens.next)}}var api,declared,functions,inblock,indent,lookahead,lex,member,membersOnly,predefined,stack,urls,bang={\"<\":!0,\"<=\":!0,\"==\":!0,\"===\":!0,\"!==\":!0,\"!=\":!0,\">\":!0,\">=\":!0,\"+\":!0,\"-\":!0,\"*\":!0,\"/\":!0,\"%\":!0},functionicity=[\"closure\",\"exception\",\"global\",\"label\",\"outer\",\"unused\",\"var\"],extraModules=[],emitter=new events.EventEmitter,typeofValues={};typeofValues.legacy=[\"xml\",\"unknown\"],typeofValues.es3=[\"undefined\",\"boolean\",\"number\",\"string\",\"function\",\"object\"],typeofValues.es3=typeofValues.es3.concat(typeofValues.legacy),typeofValues.es6=typeofValues.es3.concat(\"symbol\"),type(\"(number)\",function(){return this}),type(\"(string)\",function(){return this}),state.syntax[\"(identifier)\"]={type:\"(identifier)\",lbp:0,identifier:!0,nud:function(){var v=this.value;return\"=>\"===state.tokens.next.id?this:(state.funct[\"(comparray)\"].check(v)||state.funct[\"(scope)\"].block.use(v,state.tokens.curr),this)},led:function(){error(\"E033\",state.tokens.next,state.tokens.next.value)}};var baseTemplateSyntax={lbp:0,identifier:!1,template:!0};state.syntax[\"(template)\"]=_.extend({type:\"(template)\",nud:doTemplateLiteral,led:doTemplateLiteral,noSubst:!1},baseTemplateSyntax),state.syntax[\"(template middle)\"]=_.extend({type:\"(template middle)\",middle:!0,noSubst:!1},baseTemplateSyntax),state.syntax[\"(template tail)\"]=_.extend({type:\"(template tail)\",tail:!0,noSubst:!1},baseTemplateSyntax),state.syntax[\"(no subst template)\"]=_.extend({type:\"(template)\",nud:doTemplateLiteral,led:doTemplateLiteral,noSubst:!0,tail:!0},baseTemplateSyntax),type(\"(regexp)\",function(){return this}),delim(\"(endline)\"),delim(\"(begin)\"),delim(\"(end)\").reach=!0,delim(\"(error)\").reach=!0,delim(\"}\").reach=!0,delim(\")\"),delim(\"]\"),delim('\"').reach=!0,delim(\"'\").reach=!0,delim(\";\"),delim(\":\").reach=!0,delim(\"#\"),reserve(\"else\"),reserve(\"case\").reach=!0,reserve(\"catch\"),reserve(\"default\").reach=!0,reserve(\"finally\"),reservevar(\"arguments\",function(x){state.isStrict()&&state.funct[\"(global)\"]&&warning(\"E008\",x)}),reservevar(\"eval\"),reservevar(\"false\"),reservevar(\"Infinity\"),reservevar(\"null\"),reservevar(\"this\",function(x){state.isStrict()&&!isMethod()&&!state.option.validthis&&(state.funct[\"(statement)\"]&&state.funct[\"(name)\"].charAt(0)>\"Z\"||state.funct[\"(global)\"])&&warning(\"W040\",x)}),reservevar(\"true\"),reservevar(\"undefined\"),assignop(\"=\",\"assign\",20),assignop(\"+=\",\"assignadd\",20),assignop(\"-=\",\"assignsub\",20),assignop(\"*=\",\"assignmult\",20),assignop(\"/=\",\"assigndiv\",20).nud=function(){error(\"E014\")},assignop(\"%=\",\"assignmod\",20),bitwiseassignop(\"&=\"),bitwiseassignop(\"|=\"),bitwiseassignop(\"^=\"),bitwiseassignop(\"<<=\"),bitwiseassignop(\">>=\"),bitwiseassignop(\">>>=\"),infix(\",\",function(left,that){var expr;if(that.exprs=[left],state.option.nocomma&&warning(\"W127\"),!comma({peek:!0}))return that;for(;;){if(!(expr=expression(10)))break;if(that.exprs.push(expr),\",\"!==state.tokens.next.value||!comma())break}return that},10,!0),infix(\"?\",function(left,that){return increaseComplexityCount(),that.left=left,that.right=expression(10),advance(\":\"),that[\"else\"]=expression(10),that},30);var orPrecendence=40;infix(\"||\",function(left,that){return increaseComplexityCount(),that.left=left,that.right=expression(orPrecendence),that},orPrecendence),infix(\"&&\",\"and\",50),bitwise(\"|\",\"bitor\",70),bitwise(\"^\",\"bitxor\",80),bitwise(\"&\",\"bitand\",90),relation(\"==\",function(left,right){var eqnull=state.option.eqnull&&(\"null\"===(left&&left.value)||\"null\"===(right&&right.value));switch(!0){case!eqnull&&state.option.eqeqeq:this.from=this.character,warning(\"W116\",this,\"===\",\"==\");break;case isPoorRelation(left):warning(\"W041\",this,\"===\",left.value);break;case isPoorRelation(right):warning(\"W041\",this,\"===\",right.value);break;case isTypoTypeof(right,left,state):warning(\"W122\",this,right.value);break;case isTypoTypeof(left,right,state):warning(\"W122\",this,left.value)}return this}),relation(\"===\",function(left,right){return isTypoTypeof(right,left,state)?warning(\"W122\",this,right.value):isTypoTypeof(left,right,state)&&warning(\"W122\",this,left.value),this}),relation(\"!=\",function(left,right){var eqnull=state.option.eqnull&&(\"null\"===(left&&left.value)||\"null\"===(right&&right.value));return!eqnull&&state.option.eqeqeq?(this.from=this.character,warning(\"W116\",this,\"!==\",\"!=\")):isPoorRelation(left)?warning(\"W041\",this,\"!==\",left.value):isPoorRelation(right)?warning(\"W041\",this,\"!==\",right.value):isTypoTypeof(right,left,state)?warning(\"W122\",this,right.value):isTypoTypeof(left,right,state)&&warning(\"W122\",this,left.value),this}),relation(\"!==\",function(left,right){return isTypoTypeof(right,left,state)?warning(\"W122\",this,right.value):isTypoTypeof(left,right,state)&&warning(\"W122\",this,left.value),this}),relation(\"<\"),relation(\">\"),relation(\"<=\"),relation(\">=\"),bitwise(\"<<\",\"shiftleft\",120),bitwise(\">>\",\"shiftright\",120),bitwise(\">>>\",\"shiftrightunsigned\",120),infix(\"in\",\"in\",120),infix(\"instanceof\",\"instanceof\",120),infix(\"+\",function(left,that){var right;return that.left=left,that.right=right=expression(130),left&&right&&\"(string)\"===left.id&&\"(string)\"===right.id?(left.value+=right.value,left.character=right.character,!state.option.scripturl&&reg.javascriptURL.test(left.value)&&warning(\"W050\",left),left):that},130),prefix(\"+\",\"num\"),prefix(\"+++\",function(){return warning(\"W007\"),this.arity=\"unary\",this.right=expression(150),this}),infix(\"+++\",function(left){return warning(\"W007\"),this.left=left,this.right=expression(130),this},130),infix(\"-\",\"sub\",130),prefix(\"-\",\"neg\"),prefix(\"---\",function(){return warning(\"W006\"),this.arity=\"unary\",this.right=expression(150),this}),infix(\"---\",function(left){return warning(\"W006\"),this.left=left,this.right=expression(130),this},130),infix(\"*\",\"mult\",140),infix(\"/\",\"div\",140),infix(\"%\",\"mod\",140),suffix(\"++\"),prefix(\"++\",\"preinc\"),state.syntax[\"++\"].exps=!0,suffix(\"--\"),prefix(\"--\",\"predec\"),state.syntax[\"--\"].exps=!0,prefix(\"delete\",function(){var p=expression(10);return p?(\".\"!==p.id&&\"[\"!==p.id&&warning(\"W051\"),this.first=p,p.identifier&&!state.isStrict()&&(p.forgiveUndef=!0),this):this}).exps=!0,prefix(\"~\",function(){return state.option.bitwise&&warning(\"W016\",this,\"~\"),this.arity=\"unary\",this.right=expression(150),this}),prefix(\"...\",function(){return state.inES6(!0)||warning(\"W119\",this,\"spread/rest operator\",\"6\"),state.tokens.next.identifier||\"(string)\"===state.tokens.next.type||checkPunctuators(state.tokens.next,[\"[\",\"(\"])||error(\"E030\",state.tokens.next,state.tokens.next.value),expression(150),this}),prefix(\"!\",function(){return this.arity=\"unary\",this.right=expression(150),this.right||quit(\"E041\",this.line||0),bang[this.right.id]===!0&&warning(\"W018\",this,\"!\"),this}),prefix(\"typeof\",function(){var p=expression(150);return this.first=this.right=p,p||quit(\"E041\",this.line||0,this.character||0),p.identifier&&(p.forgiveUndef=!0),this}),prefix(\"new\",function(){var mp=metaProperty(\"target\",function(){state.inES6(!0)||warning(\"W119\",state.tokens.prev,\"new.target\",\"6\");for(var inFunction,c=state.funct;c&&(inFunction=!c[\"(global)\"],c[\"(arrow)\"]);)c=c[\"(context)\"];inFunction||warning(\"W136\",state.tokens.prev,\"new.target\")});if(mp)return mp;var i,c=expression(155);if(c&&\"function\"!==c.id)if(c.identifier)switch(c[\"new\"]=!0,c.value){case\"Number\":case\"String\":case\"Boolean\":case\"Math\":case\"JSON\":warning(\"W053\",state.tokens.prev,c.value);break;case\"Symbol\":state.inES6()&&warning(\"W053\",state.tokens.prev,c.value);break;case\"Function\":state.option.evil||warning(\"W054\");break;case\"Date\":case\"RegExp\":case\"this\":break;default:\"function\"!==c.id&&(i=c.value.substr(0,1),state.option.newcap&&(\"A\">i||i>\"Z\")&&!state.funct[\"(scope)\"].isPredefined(c.value)&&warning(\"W055\",state.tokens.curr))}else\".\"!==c.id&&\"[\"!==c.id&&\"(\"!==c.id&&warning(\"W056\",state.tokens.curr);else state.option.supernew||warning(\"W057\",this);return\"(\"===state.tokens.next.id||state.option.supernew||warning(\"W058\",state.tokens.curr,state.tokens.curr.value),this.first=this.right=c,this}),state.syntax[\"new\"].exps=!0,prefix(\"void\").exps=!0,infix(\".\",function(left,that){var m=identifier(!1,!0);return\"string\"==typeof m&&countMember(m),that.left=left,that.right=m,m&&\"hasOwnProperty\"===m&&\"=\"===state.tokens.next.value&&warning(\"W001\"),!left||\"arguments\"!==left.value||\"callee\"!==m&&\"caller\"!==m?state.option.evil||!left||\"document\"!==left.value||\"write\"!==m&&\"writeln\"!==m||warning(\"W060\",left):state.option.noarg?warning(\"W059\",left,m):state.isStrict()&&error(\"E008\"),state.option.evil||\"eval\"!==m&&\"execScript\"!==m||isGlobalEval(left,state)&&warning(\"W061\"),that},160,!0),infix(\"(\",function(left,that){state.option.immed&&left&&!left.immed&&\"function\"===left.id&&warning(\"W062\");var n=0,p=[];if(left&&\"(identifier)\"===left.type&&left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)&&-1===\"Array Number String Boolean Date Object Error Symbol\".indexOf(left.value)&&(\"Math\"===left.value?warning(\"W063\",left):state.option.newcap&&warning(\"W064\",left)),\")\"!==state.tokens.next.id)for(;p[p.length]=expression(10),n+=1,\",\"===state.tokens.next.id;)comma();return advance(\")\"),\"object\"==typeof left&&(state.inES5()||\"parseInt\"!==left.value||1!==n||warning(\"W065\",state.tokens.curr),state.option.evil||(\"eval\"===left.value||\"Function\"===left.value||\"execScript\"===left.value?(warning(\"W061\",left),p[0]&&\"(string)\"===[0].id&&addInternalSrc(left,p[0].value)):!p[0]||\"(string)\"!==p[0].id||\"setTimeout\"!==left.value&&\"setInterval\"!==left.value?!p[0]||\"(string)\"!==p[0].id||\".\"!==left.value||\"window\"!==left.left.value||\"setTimeout\"!==left.right&&\"setInterval\"!==left.right||(warning(\"W066\",left),addInternalSrc(left,p[0].value)):(warning(\"W066\",left),addInternalSrc(left,p[0].value))),left.identifier||\".\"===left.id||\"[\"===left.id||\"=>\"===left.id||\"(\"===left.id||\"&&\"===left.id||\"||\"===left.id||\"?\"===left.id||state.inES6()&&left[\"(name)\"]||warning(\"W067\",that)),that.left=left,that},155,!0).exps=!0,prefix(\"(\",function(){var pn1,ret,triggerFnExpr,first,last,pn=state.tokens.next,i=-1,parens=1,opening=state.tokens.curr,preceeding=state.tokens.prev,isNecessary=!state.option.singleGroups;do\"(\"===pn.value?parens+=1:\")\"===pn.value&&(parens-=1),i+=1,pn1=pn,pn=peek(i);while((0!==parens||\")\"!==pn1.value)&&\";\"!==pn.value&&\"(end)\"!==pn.type);if(\"function\"===state.tokens.next.id&&(triggerFnExpr=state.tokens.next.immed=!0),\"=>\"===pn.value)return doFunction({type:\"arrow\",parsedOpening:!0});var exprs=[];if(\")\"!==state.tokens.next.id)for(;exprs.push(expression(10)),\",\"===state.tokens.next.id;)state.option.nocomma&&warning(\"W127\"),comma();return advance(\")\",this),state.option.immed&&exprs[0]&&\"function\"===exprs[0].id&&\"(\"!==state.tokens.next.id&&\".\"!==state.tokens.next.id&&\"[\"!==state.tokens.next.id&&warning(\"W068\",this),exprs.length?(exprs.length>1?(ret=Object.create(state.syntax[\",\"]),ret.exprs=exprs,first=exprs[0],last=exprs[exprs.length-1],isNecessary||(isNecessary=preceeding.assign||preceeding.delim)):(ret=first=last=exprs[0],isNecessary||(isNecessary=opening.beginsStmt&&(\"{\"===ret.id||triggerFnExpr||isFunctor(ret))||triggerFnExpr&&(!isEndOfExpr()||\"}\"!==state.tokens.prev.id)||isFunctor(ret)&&!isEndOfExpr()||\"{\"===ret.id&&\"=>\"===preceeding.id||\"(number)\"===ret.type&&checkPunctuator(pn,\".\")&&/^\\d+$/.test(ret.value))),ret&&(!isNecessary&&(first.left||first.right||ret.exprs)&&(isNecessary=!isBeginOfExpr(preceeding)&&first.lbp<=preceeding.lbp||!isEndOfExpr()&&last.lbp<state.tokens.next.lbp),isNecessary||warning(\"W126\",opening),ret.paren=!0),ret):void 0}),application(\"=>\"),infix(\"[\",function(left,that){var s,e=expression(10);return e&&\"(string)\"===e.type&&(state.option.evil||\"eval\"!==e.value&&\"execScript\"!==e.value||isGlobalEval(left,state)&&warning(\"W061\"),countMember(e.value),!state.option.sub&&reg.identifier.test(e.value)&&(s=state.syntax[e.value],s&&isReserved(s)||warning(\"W069\",state.tokens.prev,e.value))),advance(\"]\",that),e&&\"hasOwnProperty\"===e.value&&\"=\"===state.tokens.next.value&&warning(\"W001\"),that.left=left,that.right=e,that},160,!0),prefix(\"[\",function(){var blocktype=lookupBlockType();if(blocktype.isCompArray)return state.option.esnext||state.inMoz()||warning(\"W118\",state.tokens.curr,\"array comprehension\"),comprehensiveArrayExpression();if(blocktype.isDestAssign)return this.destructAssign=destructuringPattern({openingParsed:!0,assignment:!0}),this;var b=state.tokens.curr.line!==startLine(state.tokens.next);for(this.first=[],b&&(indent+=state.option.indent,state.tokens.next.from===indent+state.option.indent&&(indent+=state.option.indent));\"(end)\"!==state.tokens.next.id;){for(;\",\"===state.tokens.next.id;){if(!state.option.elision){if(state.inES5()){warning(\"W128\");do advance(\",\");while(\",\"===state.tokens.next.id);continue}warning(\"W070\")}advance(\",\")}if(\"]\"===state.tokens.next.id)break;if(this.first.push(expression(10)),\",\"!==state.tokens.next.id)break;if(comma({allowTrailing:!0}),\"]\"===state.tokens.next.id&&!state.inES5()){warning(\"W070\",state.tokens.curr);break}}return b&&(indent-=state.option.indent),advance(\"]\",this),this}),function(x){x.nud=function(){var b,f,i,p,t,nextVal,isGeneratorMethod=!1,props=Object.create(null);b=state.tokens.curr.line!==startLine(state.tokens.next),b&&(indent+=state.option.indent,state.tokens.next.from===indent+state.option.indent&&(indent+=state.option.indent));var blocktype=lookupBlockType();if(blocktype.isDestAssign)return this.destructAssign=destructuringPattern({openingParsed:!0,assignment:!0}),this;for(;\"}\"!==state.tokens.next.id;){if(nextVal=state.tokens.next.value,!state.tokens.next.identifier||\",\"!==peekIgnoreEOL().id&&\"}\"!==peekIgnoreEOL().id)if(\":\"===peek().id||\"get\"!==nextVal&&\"set\"!==nextVal){if(\"*\"===state.tokens.next.value&&\"(punctuator)\"===state.tokens.next.type?(state.inES6()||warning(\"W104\",state.tokens.next,\"generator functions\",\"6\"),advance(\"*\"),isGeneratorMethod=!0):isGeneratorMethod=!1,\"[\"===state.tokens.next.id)i=computedPropertyName(),state.nameStack.set(i);else if(state.nameStack.set(state.tokens.next),i=propertyName(),saveProperty(props,i,state.tokens.next),\"string\"!=typeof i)break;\"(\"===state.tokens.next.value?(state.inES6()||warning(\"W104\",state.tokens.curr,\"concise methods\",\"6\"),doFunction({type:isGeneratorMethod?\"generator\":null})):(advance(\":\"),expression(10))}else advance(nextVal),state.inES5()||error(\"E034\"),i=propertyName(),i||state.inES6()||error(\"E035\"),i&&saveAccessor(nextVal,props,i,state.tokens.curr),t=state.tokens.next,f=doFunction(),p=f[\"(params)\"],\"get\"===nextVal&&i&&p?warning(\"W076\",t,p[0],i):\"set\"!==nextVal||!i||p&&1===p.length||warning(\"W077\",t,i);else state.inES6()||warning(\"W104\",state.tokens.next,\"object short notation\",\"6\"),i=propertyName(!0),saveProperty(props,i,state.tokens.next),expression(10);if(countMember(i),\",\"!==state.tokens.next.id)break;comma({allowTrailing:!0,property:!0}),\",\"===state.tokens.next.id?warning(\"W070\",state.tokens.curr):\"}\"!==state.tokens.next.id||state.inES5()||warning(\"W070\",state.tokens.curr)}return b&&(indent-=state.option.indent),advance(\"}\",this),checkProperties(props),this},x.fud=function(){error(\"E036\",state.tokens.curr)}}(delim(\"{\"));var conststatement=stmt(\"const\",function(context){return blockVariableStatement(\"const\",this,context)});conststatement.exps=!0;var letstatement=stmt(\"let\",function(context){return blockVariableStatement(\"let\",this,context)});letstatement.exps=!0;var varstatement=stmt(\"var\",function(context){var tokens,lone,value,prefix=context&&context.prefix,inexport=context&&context.inexport,implied=context&&context.implied,report=!(context&&context.ignore);for(this.first=[];;){var names=[];_.contains([\"{\",\"[\"],state.tokens.next.value)?(tokens=destructuringPattern(),lone=!1):(tokens=[{id:identifier(),token:state.tokens.curr}],lone=!0),prefix&&implied||!report||!state.option.varstmt||warning(\"W132\",this),this.first=this.first.concat(names);for(var t in tokens)tokens.hasOwnProperty(t)&&(t=tokens[t],!implied&&state.funct[\"(global)\"]&&(predefined[t.id]===!1?warning(\"W079\",t.token,t.id):state.option.futurehostile===!1&&(!state.inES5()&&vars.ecmaIdentifiers[5][t.id]===!1||!state.inES6()&&vars.ecmaIdentifiers[6][t.id]===!1)&&warning(\"W129\",t.token,t.id)),t.id&&(\"for\"===implied?(state.funct[\"(scope)\"].has(t.id)||report&&warning(\"W088\",t.token,t.id),state.funct[\"(scope)\"].block.use(t.id,t.token)):(state.funct[\"(scope)\"].addlabel(t.id,{type:\"var\",token:t.token}),lone&&inexport&&state.funct[\"(scope)\"].setExported(t.id,t.token)),names.push(t.token)));if(\"=\"===state.tokens.next.id&&(state.nameStack.set(state.tokens.curr),advance(\"=\"),prefix||!report||state.funct[\"(loopage)\"]||\"undefined\"!==state.tokens.next.id||warning(\"W080\",state.tokens.prev,state.tokens.prev.value),\"=\"===peek(0).id&&state.tokens.next.identifier&&(!prefix&&report&&!state.funct[\"(params)\"]||-1===state.funct[\"(params)\"].indexOf(state.tokens.next.value))&&warning(\"W120\",state.tokens.next,state.tokens.next.value),value=expression(prefix?120:10),lone?tokens[0].first=value:destructuringPatternMatch(names,value)),\",\"!==state.tokens.next.id)break;comma()}return this});varstatement.exps=!0,blockstmt(\"class\",function(){return classdef.call(this,!0)}),blockstmt(\"function\",function(context){var inexport=context&&context.inexport,generator=!1;\"*\"===state.tokens.next.value&&(advance(\"*\"),state.inES6({strict:!0})?generator=!0:warning(\"W119\",state.tokens.curr,\"function*\",\"6\")),inblock&&warning(\"W082\",state.tokens.curr);var i=optionalidentifier();return state.funct[\"(scope)\"].addlabel(i,{type:\"function\",token:state.tokens.curr}),void 0===i?warning(\"W025\"):inexport&&state.funct[\"(scope)\"].setExported(i,state.tokens.prev),doFunction({name:i,statement:this,type:generator?\"generator\":null,ignoreLoopFunc:inblock}),\"(\"===state.tokens.next.id&&state.tokens.next.line===state.tokens.curr.line&&error(\"E039\"),this}),prefix(\"function\",function(){var generator=!1;\"*\"===state.tokens.next.value&&(state.inES6()||warning(\"W119\",state.tokens.curr,\"function*\",\"6\"),advance(\"*\"),generator=!0);var i=optionalidentifier();return doFunction({name:i,type:generator?\"generator\":null}),this}),blockstmt(\"if\",function(){var t=state.tokens.next;increaseComplexityCount(),state.condition=!0,advance(\"(\");var expr=expression(0);checkCondAssignment(expr);var forinifcheck=null;state.option.forin&&state.forinifcheckneeded&&(state.forinifcheckneeded=!1,forinifcheck=state.forinifchecks[state.forinifchecks.length-1],forinifcheck.type=\"(punctuator)\"===expr.type&&\"!\"===expr.value?\"(negative)\":\"(positive)\"),advance(\")\",t),state.condition=!1;var s=block(!0,!0);return forinifcheck&&\"(negative)\"===forinifcheck.type&&s&&s[0]&&\"(identifier)\"===s[0].type&&\"continue\"===s[0].value&&(forinifcheck.type=\"(negative-with-continue)\"),\"else\"===state.tokens.next.id&&(advance(\"else\"),\"if\"===state.tokens.next.id||\"switch\"===state.tokens.next.id?statement():block(!0,!0)),this}),blockstmt(\"try\",function(){function doCatch(){if(advance(\"catch\"),advance(\"(\"),state.funct[\"(scope)\"].stack(\"catchparams\"),checkPunctuators(state.tokens.next,[\"[\",\"{\"])){var tokens=destructuringPattern();_.each(tokens,function(token){token.id&&state.funct[\"(scope)\"].addParam(token.id,token,\"exception\")})}else\"(identifier)\"!==state.tokens.next.type?warning(\"E030\",state.tokens.next,state.tokens.next.value):state.funct[\"(scope)\"].addParam(identifier(),state.tokens.curr,\"exception\");\"if\"===state.tokens.next.value&&(state.inMoz()||warning(\"W118\",state.tokens.curr,\"catch filter\"),advance(\"if\"),expression(0)),advance(\")\"),block(!1),state.funct[\"(scope)\"].unstack()}var b;for(block(!0);\"catch\"===state.tokens.next.id;)increaseComplexityCount(),b&&!state.inMoz()&&warning(\"W118\",state.tokens.next,\"multiple catch blocks\"),doCatch(),b=!0;return\"finally\"===state.tokens.next.id?(advance(\"finally\"),block(!0),void 0):(b||error(\"E021\",state.tokens.next,\"catch\",state.tokens.next.value),this)}),blockstmt(\"while\",function(){var t=state.tokens.next;return state.funct[\"(breakage)\"]+=1,state.funct[\"(loopage)\"]+=1,increaseComplexityCount(),advance(\"(\"),checkCondAssignment(expression(0)),advance(\")\",t),block(!0,!0),state.funct[\"(breakage)\"]-=1,state.funct[\"(loopage)\"]-=1,this}).labelled=!0,blockstmt(\"with\",function(){var t=state.tokens.next;return state.isStrict()?error(\"E010\",state.tokens.curr):state.option.withstmt||warning(\"W085\",state.tokens.curr),advance(\"(\"),expression(0),advance(\")\",t),block(!0,!0),this}),blockstmt(\"switch\",function(){var t=state.tokens.next,g=!1,noindent=!1;\nfor(state.funct[\"(breakage)\"]+=1,advance(\"(\"),checkCondAssignment(expression(0)),advance(\")\",t),t=state.tokens.next,advance(\"{\"),state.tokens.next.from===indent&&(noindent=!0),noindent||(indent+=state.option.indent),this.cases=[];;)switch(state.tokens.next.id){case\"case\":switch(state.funct[\"(verb)\"]){case\"yield\":case\"break\":case\"case\":case\"continue\":case\"return\":case\"switch\":case\"throw\":break;default:state.tokens.curr.caseFallsThrough||warning(\"W086\",state.tokens.curr,\"case\")}advance(\"case\"),this.cases.push(expression(0)),increaseComplexityCount(),g=!0,advance(\":\"),state.funct[\"(verb)\"]=\"case\";break;case\"default\":switch(state.funct[\"(verb)\"]){case\"yield\":case\"break\":case\"continue\":case\"return\":case\"throw\":break;default:this.cases.length&&(state.tokens.curr.caseFallsThrough||warning(\"W086\",state.tokens.curr,\"default\"))}advance(\"default\"),g=!0,advance(\":\");break;case\"}\":return noindent||(indent-=state.option.indent),advance(\"}\",t),state.funct[\"(breakage)\"]-=1,state.funct[\"(verb)\"]=void 0,void 0;case\"(end)\":return error(\"E023\",state.tokens.next,\"}\"),void 0;default:if(indent+=state.option.indent,g)switch(state.tokens.curr.id){case\",\":return error(\"E040\"),void 0;case\":\":g=!1,statements();break;default:return error(\"E025\",state.tokens.curr),void 0}else{if(\":\"!==state.tokens.curr.id)return error(\"E021\",state.tokens.next,\"case\",state.tokens.next.value),void 0;advance(\":\"),error(\"E024\",state.tokens.curr,\":\"),statements()}indent-=state.option.indent}return this}).labelled=!0,stmt(\"debugger\",function(){return state.option.debug||warning(\"W087\",this),this}).exps=!0,function(){var x=stmt(\"do\",function(){state.funct[\"(breakage)\"]+=1,state.funct[\"(loopage)\"]+=1,increaseComplexityCount(),this.first=block(!0,!0),advance(\"while\");var t=state.tokens.next;return advance(\"(\"),checkCondAssignment(expression(0)),advance(\")\",t),state.funct[\"(breakage)\"]-=1,state.funct[\"(loopage)\"]-=1,this});x.labelled=!0,x.exps=!0}(),blockstmt(\"for\",function(){var s,t=state.tokens.next,letscope=!1,foreachtok=null;\"each\"===t.value&&(foreachtok=t,advance(\"each\"),state.inMoz()||warning(\"W118\",state.tokens.curr,\"for each\")),increaseComplexityCount(),advance(\"(\");var nextop,comma,initializer,i=0,inof=[\"in\",\"of\"],level=0;checkPunctuators(state.tokens.next,[\"{\",\"[\"])&&++level;do{if(nextop=peek(i),++i,checkPunctuators(nextop,[\"{\",\"[\"])?++level:checkPunctuators(nextop,[\"}\",\"]\"])&&--level,0>level)break;0===level&&(!comma&&checkPunctuator(nextop,\",\")?comma=nextop:!initializer&&checkPunctuator(nextop,\"=\")&&(initializer=nextop))}while(level>0||!_.contains(inof,nextop.value)&&\";\"!==nextop.value&&\"(end)\"!==nextop.type);if(_.contains(inof,nextop.value)){state.inES6()||\"of\"!==nextop.value||warning(\"W104\",nextop,\"for of\",\"6\");var ok=!(initializer||comma);if(initializer&&error(\"W133\",comma,nextop.value,\"initializer is forbidden\"),comma&&error(\"W133\",comma,nextop.value,\"more than one ForBinding\"),\"var\"===state.tokens.next.id?(advance(\"var\"),state.tokens.curr.fud({prefix:!0})):\"let\"===state.tokens.next.id||\"const\"===state.tokens.next.id?(advance(state.tokens.next.id),letscope=!0,state.funct[\"(scope)\"].stack(),state.tokens.curr.fud({prefix:!0})):Object.create(varstatement).fud({prefix:!0,implied:\"for\",ignore:!ok}),advance(nextop.value),expression(20),advance(\")\",t),\"in\"===nextop.value&&state.option.forin&&(state.forinifcheckneeded=!0,void 0===state.forinifchecks&&(state.forinifchecks=[]),state.forinifchecks.push({type:\"(none)\"})),state.funct[\"(breakage)\"]+=1,state.funct[\"(loopage)\"]+=1,s=block(!0,!0),\"in\"===nextop.value&&state.option.forin){if(state.forinifchecks&&state.forinifchecks.length>0){var check=state.forinifchecks.pop();(s&&s.length>0&&(\"object\"!=typeof s[0]||\"if\"!==s[0].value)||\"(positive)\"===check.type&&s.length>1||\"(negative)\"===check.type)&&warning(\"W089\",this)}state.forinifcheckneeded=!1}state.funct[\"(breakage)\"]-=1,state.funct[\"(loopage)\"]-=1}else{if(foreachtok&&error(\"E045\",foreachtok),\";\"!==state.tokens.next.id)if(\"var\"===state.tokens.next.id)advance(\"var\"),state.tokens.curr.fud();else if(\"let\"===state.tokens.next.id)advance(\"let\"),letscope=!0,state.funct[\"(scope)\"].stack(),state.tokens.curr.fud();else for(;expression(0,\"for\"),\",\"===state.tokens.next.id;)comma();if(nolinebreak(state.tokens.curr),advance(\";\"),state.funct[\"(loopage)\"]+=1,\";\"!==state.tokens.next.id&&checkCondAssignment(expression(0)),nolinebreak(state.tokens.curr),advance(\";\"),\";\"===state.tokens.next.id&&error(\"E021\",state.tokens.next,\")\",\";\"),\")\"!==state.tokens.next.id)for(;expression(0,\"for\"),\",\"===state.tokens.next.id;)comma();advance(\")\",t),state.funct[\"(breakage)\"]+=1,block(!0,!0),state.funct[\"(breakage)\"]-=1,state.funct[\"(loopage)\"]-=1}return letscope&&state.funct[\"(scope)\"].unstack(),this}).labelled=!0,stmt(\"break\",function(){var v=state.tokens.next.value;return state.option.asi||nolinebreak(this),\";\"===state.tokens.next.id||state.tokens.next.reach||state.tokens.curr.line!==startLine(state.tokens.next)?0===state.funct[\"(breakage)\"]&&warning(\"W052\",state.tokens.next,this.value):(state.funct[\"(scope)\"].funct.hasBreakLabel(v)||warning(\"W090\",state.tokens.next,v),this.first=state.tokens.next,advance()),reachable(this),this}).exps=!0,stmt(\"continue\",function(){var v=state.tokens.next.value;return 0===state.funct[\"(breakage)\"]&&warning(\"W052\",state.tokens.next,this.value),state.funct[\"(loopage)\"]||warning(\"W052\",state.tokens.next,this.value),state.option.asi||nolinebreak(this),\";\"===state.tokens.next.id||state.tokens.next.reach||state.tokens.curr.line===startLine(state.tokens.next)&&(state.funct[\"(scope)\"].funct.hasBreakLabel(v)||warning(\"W090\",state.tokens.next,v),this.first=state.tokens.next,advance()),reachable(this),this}).exps=!0,stmt(\"return\",function(){return this.line===startLine(state.tokens.next)?\";\"===state.tokens.next.id||state.tokens.next.reach||(this.first=expression(0),!this.first||\"(punctuator)\"!==this.first.type||\"=\"!==this.first.value||this.first.paren||state.option.boss||warningAt(\"W093\",this.first.line,this.first.character)):\"(punctuator)\"===state.tokens.next.type&&[\"[\",\"{\",\"+\",\"-\"].indexOf(state.tokens.next.value)>-1&&nolinebreak(this),reachable(this),this}).exps=!0,function(x){x.exps=!0,x.lbp=25}(prefix(\"yield\",function(){var prev=state.tokens.prev;state.inES6(!0)&&!state.funct[\"(generator)\"]?\"(catch)\"===state.funct[\"(name)\"]&&state.funct[\"(context)\"][\"(generator)\"]||error(\"E046\",state.tokens.curr,\"yield\"):state.inES6()||warning(\"W104\",state.tokens.curr,\"yield\",\"6\"),state.funct[\"(generator)\"]=\"yielded\";var delegatingYield=!1;return\"*\"===state.tokens.next.value&&(delegatingYield=!0,advance(\"*\")),this.line!==startLine(state.tokens.next)&&state.inMoz()?state.option.asi||nolinebreak(this):((delegatingYield||\";\"!==state.tokens.next.id&&!state.option.asi&&!state.tokens.next.reach&&state.tokens.next.nud)&&(nobreaknonadjacent(state.tokens.curr,state.tokens.next),this.first=expression(10),\"(punctuator)\"!==this.first.type||\"=\"!==this.first.value||this.first.paren||state.option.boss||warningAt(\"W093\",this.first.line,this.first.character)),state.inMoz()&&\")\"!==state.tokens.next.id&&(prev.lbp>30||!prev.assign&&!isEndOfExpr()||\"yield\"===prev.id)&&error(\"E050\",this)),this})),stmt(\"throw\",function(){return nolinebreak(this),this.first=expression(20),reachable(this),this}).exps=!0,stmt(\"import\",function(){if(state.inES6()||warning(\"W119\",state.tokens.curr,\"import\",\"6\"),\"(string)\"===state.tokens.next.type)return advance(\"(string)\"),this;if(state.tokens.next.identifier){if(this.name=identifier(),state.funct[\"(scope)\"].addlabel(this.name,{type:\"const\",token:state.tokens.curr}),\",\"!==state.tokens.next.value)return advance(\"from\"),advance(\"(string)\"),this;advance(\",\")}if(\"*\"===state.tokens.next.id)advance(\"*\"),advance(\"as\"),state.tokens.next.identifier&&(this.name=identifier(),state.funct[\"(scope)\"].addlabel(this.name,{type:\"const\",token:state.tokens.curr}));else for(advance(\"{\");;){if(\"}\"===state.tokens.next.value){advance(\"}\");break}var importName;if(\"default\"===state.tokens.next.type?(importName=\"default\",advance(\"default\")):importName=identifier(),\"as\"===state.tokens.next.value&&(advance(\"as\"),importName=identifier()),state.funct[\"(scope)\"].addlabel(importName,{type:\"const\",token:state.tokens.curr}),\",\"!==state.tokens.next.value){if(\"}\"===state.tokens.next.value){advance(\"}\");break}error(\"E024\",state.tokens.next,state.tokens.next.value);break}advance(\",\")}return advance(\"from\"),advance(\"(string)\"),this}).exps=!0,stmt(\"export\",function(){var token,identifier,ok=!0;if(state.inES6()||(warning(\"W119\",state.tokens.curr,\"export\",\"6\"),ok=!1),state.funct[\"(scope)\"].block.isGlobal()||(error(\"E053\",state.tokens.curr),ok=!1),\"*\"===state.tokens.next.value)return advance(\"*\"),advance(\"from\"),advance(\"(string)\"),this;if(\"default\"===state.tokens.next.type){state.nameStack.set(state.tokens.next),advance(\"default\");var exportType=state.tokens.next.id;return(\"function\"===exportType||\"class\"===exportType)&&(this.block=!0),token=peek(),expression(10),identifier=token.value,this.block&&(state.funct[\"(scope)\"].addlabel(identifier,{type:exportType,token:token}),state.funct[\"(scope)\"].setExported(identifier,token)),this}if(\"{\"===state.tokens.next.value){advance(\"{\");for(var exportedTokens=[];;){if(state.tokens.next.identifier||error(\"E030\",state.tokens.next,state.tokens.next.value),advance(),exportedTokens.push(state.tokens.curr),\"as\"===state.tokens.next.value&&(advance(\"as\"),state.tokens.next.identifier||error(\"E030\",state.tokens.next,state.tokens.next.value),advance()),\",\"!==state.tokens.next.value){if(\"}\"===state.tokens.next.value){advance(\"}\");break}error(\"E024\",state.tokens.next,state.tokens.next.value);break}advance(\",\")}return\"from\"===state.tokens.next.value?(advance(\"from\"),advance(\"(string)\")):ok&&exportedTokens.forEach(function(token){state.funct[\"(scope)\"].setExported(token.value,token)}),this}if(\"var\"===state.tokens.next.id)advance(\"var\"),state.tokens.curr.fud({inexport:!0});else if(\"let\"===state.tokens.next.id)advance(\"let\"),state.tokens.curr.fud({inexport:!0});else if(\"const\"===state.tokens.next.id)advance(\"const\"),state.tokens.curr.fud({inexport:!0});else if(\"function\"===state.tokens.next.id)this.block=!0,advance(\"function\"),state.syntax[\"function\"].fud({inexport:!0});else if(\"class\"===state.tokens.next.id){this.block=!0,advance(\"class\");var classNameToken=state.tokens.next;state.syntax[\"class\"].fud(),state.funct[\"(scope)\"].setExported(classNameToken.value,classNameToken)}else error(\"E024\",state.tokens.next,state.tokens.next.value);return this}).exps=!0,FutureReservedWord(\"abstract\"),FutureReservedWord(\"boolean\"),FutureReservedWord(\"byte\"),FutureReservedWord(\"char\"),FutureReservedWord(\"class\",{es5:!0,nud:classdef}),FutureReservedWord(\"double\"),FutureReservedWord(\"enum\",{es5:!0}),FutureReservedWord(\"export\",{es5:!0}),FutureReservedWord(\"extends\",{es5:!0}),FutureReservedWord(\"final\"),FutureReservedWord(\"float\"),FutureReservedWord(\"goto\"),FutureReservedWord(\"implements\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"import\",{es5:!0}),FutureReservedWord(\"int\"),FutureReservedWord(\"interface\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"long\"),FutureReservedWord(\"native\"),FutureReservedWord(\"package\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"private\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"protected\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"public\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"short\"),FutureReservedWord(\"static\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"super\",{es5:!0}),FutureReservedWord(\"synchronized\"),FutureReservedWord(\"transient\"),FutureReservedWord(\"volatile\");var lookupBlockType=function(){var pn,pn1,prev,i=-1,bracketStack=0,ret={};checkPunctuators(state.tokens.curr,[\"[\",\"{\"])&&(bracketStack+=1);do{if(prev=-1===i?state.tokens.curr:pn,pn=-1===i?state.tokens.next:peek(i),pn1=peek(i+1),i+=1,checkPunctuators(pn,[\"[\",\"{\"])?bracketStack+=1:checkPunctuators(pn,[\"]\",\"}\"])&&(bracketStack-=1),1===bracketStack&&pn.identifier&&\"for\"===pn.value&&!checkPunctuator(prev,\".\")){ret.isCompArray=!0,ret.notJson=!0;break}if(0===bracketStack&&checkPunctuators(pn,[\"}\",\"]\"])){if(\"=\"===pn1.value){ret.isDestAssign=!0,ret.notJson=!0;break}if(\".\"===pn1.value){ret.notJson=!0;break}}checkPunctuator(pn,\";\")&&(ret.isBlock=!0,ret.notJson=!0)}while(bracketStack>0&&\"(end)\"!==pn.id);return ret},arrayComprehension=function(){function declare(v){var l=_current.variables.filter(function(elt){return elt.value===v?(elt.undef=!1,v):void 0}).length;return 0!==l}function use(v){var l=_current.variables.filter(function(elt){return elt.value!==v||elt.undef?void 0:(elt.unused===!0&&(elt.unused=!1),v)}).length;return 0===l}var _current,CompArray=function(){this.mode=\"use\",this.variables=[]},_carrays=[];return{stack:function(){_current=new CompArray,_carrays.push(_current)},unstack:function(){_current.variables.filter(function(v){v.unused&&warning(\"W098\",v.token,v.raw_text||v.value),v.undef&&state.funct[\"(scope)\"].block.use(v.value,v.token)}),_carrays.splice(-1,1),_current=_carrays[_carrays.length-1]},setState:function(s){_.contains([\"use\",\"define\",\"generate\",\"filter\"],s)&&(_current.mode=s)},check:function(v){return _current?_current&&\"use\"===_current.mode?(use(v)&&_current.variables.push({funct:state.funct,token:state.tokens.curr,value:v,undef:!0,unused:!1}),!0):_current&&\"define\"===_current.mode?(declare(v)||_current.variables.push({funct:state.funct,token:state.tokens.curr,value:v,undef:!1,unused:!0}),!0):_current&&\"generate\"===_current.mode?(state.funct[\"(scope)\"].block.use(v,state.tokens.curr),!0):_current&&\"filter\"===_current.mode?(use(v)&&state.funct[\"(scope)\"].block.use(v,state.tokens.curr),!0):!1:void 0}}},escapeRegex=function(str){return str.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g,\"\\\\$&\")},itself=function(s,o,g){function each(obj,cb){obj&&(Array.isArray(obj)||\"object\"!=typeof obj||(obj=Object.keys(obj)),obj.forEach(cb))}var i,k,x,reIgnoreStr,reIgnore,optionKeys,newOptionObj={},newIgnoredObj={};o=_.clone(o),state.reset(),o&&o.scope?JSHINT.scope=o.scope:(JSHINT.errors=[],JSHINT.undefs=[],JSHINT.internals=[],JSHINT.blacklist={},JSHINT.scope=\"(main)\"),predefined=Object.create(null),combine(predefined,vars.ecmaIdentifiers[3]),combine(predefined,vars.reservedVars),combine(predefined,g||{}),declared=Object.create(null);var exported=Object.create(null);if(o)for(each(o.predef||null,function(item){var slice,prop;\"-\"===item[0]?(slice=item.slice(1),JSHINT.blacklist[slice]=slice,delete predefined[slice]):(prop=Object.getOwnPropertyDescriptor(o.predef,item),predefined[item]=prop?prop.value:!1)}),each(o.exported||null,function(item){exported[item]=!0}),delete o.predef,delete o.exported,optionKeys=Object.keys(o),x=0;optionKeys.length>x;x++)if(/^-W\\d{3}$/g.test(optionKeys[x]))newIgnoredObj[optionKeys[x].slice(1)]=!0;else{var optionKey=optionKeys[x];newOptionObj[optionKey]=o[optionKey],(\"esversion\"===optionKey&&5===o[optionKey]||\"es5\"===optionKey&&o[optionKey])&&warning(\"I003\"),\"newcap\"===optionKeys[x]&&o[optionKey]===!1&&(newOptionObj[\"(explicitNewcap)\"]=!0)}state.option=newOptionObj,state.ignored=newIgnoredObj,state.option.indent=state.option.indent||4,state.option.maxerr=state.option.maxerr||50,indent=1;var scopeManagerInst=scopeManager(state,predefined,exported,declared);if(scopeManagerInst.on(\"warning\",function(ev){warning.apply(null,[ev.code,ev.token].concat(ev.data))}),scopeManagerInst.on(\"error\",function(ev){error.apply(null,[ev.code,ev.token].concat(ev.data))}),state.funct=functor(\"(global)\",null,{\"(global)\":!0,\"(scope)\":scopeManagerInst,\"(comparray)\":arrayComprehension(),\"(metrics)\":createMetrics(state.tokens.next)}),functions=[state.funct],urls=[],stack=null,member={},membersOnly=null,inblock=!1,lookahead=[],!isString(s)&&!Array.isArray(s))return errorAt(\"E004\",0),!1;api={get isJSON(){return state.jsonMode},getOption:function(name){return state.option[name]||null},getCache:function(name){return state.cache[name]},setCache:function(name,value){state.cache[name]=value},warn:function(code,data){warningAt.apply(null,[code,data.line,data.char].concat(data.data))},on:function(names,listener){names.split(\" \").forEach(function(name){emitter.on(name,listener)}.bind(this))}},emitter.removeAllListeners(),(extraModules||[]).forEach(function(func){func(api)}),state.tokens.prev=state.tokens.curr=state.tokens.next=state.syntax[\"(begin)\"],o&&o.ignoreDelimiters&&(Array.isArray(o.ignoreDelimiters)||(o.ignoreDelimiters=[o.ignoreDelimiters]),o.ignoreDelimiters.forEach(function(delimiterPair){delimiterPair.start&&delimiterPair.end&&(reIgnoreStr=escapeRegex(delimiterPair.start)+\"[\\\\s\\\\S]*?\"+escapeRegex(delimiterPair.end),reIgnore=RegExp(reIgnoreStr,\"ig\"),s=s.replace(reIgnore,function(match){return match.replace(/./g,\" \")}))})),lex=new Lexer(s),lex.on(\"warning\",function(ev){warningAt.apply(null,[ev.code,ev.line,ev.character].concat(ev.data))}),lex.on(\"error\",function(ev){errorAt.apply(null,[ev.code,ev.line,ev.character].concat(ev.data))}),lex.on(\"fatal\",function(ev){quit(\"E041\",ev.line,ev.from)}),lex.on(\"Identifier\",function(ev){emitter.emit(\"Identifier\",ev)}),lex.on(\"String\",function(ev){emitter.emit(\"String\",ev)}),lex.on(\"Number\",function(ev){emitter.emit(\"Number\",ev)}),lex.start();for(var name in o)_.has(o,name)&&checkOption(name,state.tokens.curr);assume(),combine(predefined,g||{}),comma.first=!0;try{switch(advance(),state.tokens.next.id){case\"{\":case\"[\":destructuringAssignOrJsonValue();break;default:directives(),state.directive[\"use strict\"]&&\"global\"!==state.option.strict&&warning(\"W097\",state.tokens.prev),statements()}\"(end)\"!==state.tokens.next.id&&quit(\"E041\",state.tokens.curr.line),state.funct[\"(scope)\"].unstack()}catch(err){if(!err||\"JSHintError\"!==err.name)throw err;var nt=state.tokens.next||{};JSHINT.errors.push({scope:\"(main)\",raw:err.raw,code:err.code,reason:err.message,line:err.line||nt.line,character:err.character||nt.from},null)}if(\"(main)\"===JSHINT.scope)for(o=o||{},i=0;JSHINT.internals.length>i;i+=1)k=JSHINT.internals[i],o.scope=k.elem,itself(k.value,o,g);return 0===JSHINT.errors.length};return itself.addModule=function(func){extraModules.push(func)},itself.addModule(style.register),itself.data=function(){var fu,f,i,j,n,globals,data={functions:[],options:state.option};itself.errors.length&&(data.errors=itself.errors),state.jsonMode&&(data.json=!0);var impliedGlobals=state.funct[\"(scope)\"].getImpliedGlobals();for(impliedGlobals.length>0&&(data.implieds=impliedGlobals),urls.length>0&&(data.urls=urls),globals=state.funct[\"(scope)\"].getUsedOrDefinedGlobals(),globals.length>0&&(data.globals=globals),i=1;functions.length>i;i+=1){for(f=functions[i],fu={},j=0;functionicity.length>j;j+=1)fu[functionicity[j]]=[];for(j=0;functionicity.length>j;j+=1)0===fu[functionicity[j]].length&&delete fu[functionicity[j]];fu.name=f[\"(name)\"],fu.param=f[\"(params)\"],fu.line=f[\"(line)\"],fu.character=f[\"(character)\"],fu.last=f[\"(last)\"],fu.lastcharacter=f[\"(lastcharacter)\"],fu.metrics={complexity:f[\"(metrics)\"].ComplexityCount,parameters:f[\"(metrics)\"].arity,statements:f[\"(metrics)\"].statementCount},data.functions.push(fu)}var unuseds=state.funct[\"(scope)\"].getUnuseds();unuseds.length>0&&(data.unused=unuseds);for(n in member)if(\"number\"==typeof member[n]){data.member=member;break}return data},itself.jshint=itself,itself}();\"object\"==typeof exports&&exports&&(exports.JSHINT=JSHINT)},{\"../lodash\":\"/node_modules/jshint/lodash.js\",\"./lex.js\":\"/node_modules/jshint/src/lex.js\",\"./messages.js\":\"/node_modules/jshint/src/messages.js\",\"./options.js\":\"/node_modules/jshint/src/options.js\",\"./reg.js\":\"/node_modules/jshint/src/reg.js\",\"./scope-manager.js\":\"/node_modules/jshint/src/scope-manager.js\",\"./state.js\":\"/node_modules/jshint/src/state.js\",\"./style.js\":\"/node_modules/jshint/src/style.js\",\"./vars.js\":\"/node_modules/jshint/src/vars.js\",events:\"/node_modules/browserify/node_modules/events/events.js\"}],\"/node_modules/jshint/src/lex.js\":[function(_dereq_,module,exports){\"use strict\";function asyncTrigger(){var _checks=[];return{push:function(fn){_checks.push(fn)},check:function(){for(var check=0;_checks.length>check;++check)_checks[check]();_checks.splice(0,_checks.length)}}}function Lexer(source){var lines=source;\"string\"==typeof lines&&(lines=lines.replace(/\\r\\n/g,\"\\n\").replace(/\\r/g,\"\\n\").split(\"\\n\")),lines[0]&&\"#!\"===lines[0].substr(0,2)&&(-1!==lines[0].indexOf(\"node\")&&(state.option.node=!0),lines[0]=\"\"),this.emitter=new events.EventEmitter,this.source=source,this.setLines(lines),this.prereg=!0,this.line=0,this.char=1,this.from=1,this.input=\"\",this.inComment=!1,this.context=[],this.templateStarts=[];for(var i=0;state.option.indent>i;i+=1)state.tab+=\" \";this.ignoreLinterErrors=!1}var _=_dereq_(\"../lodash\"),events=_dereq_(\"events\"),reg=_dereq_(\"./reg.js\"),state=_dereq_(\"./state.js\").state,unicodeData=_dereq_(\"../data/ascii-identifier-data.js\"),asciiIdentifierStartTable=unicodeData.asciiIdentifierStartTable,asciiIdentifierPartTable=unicodeData.asciiIdentifierPartTable,Token={Identifier:1,Punctuator:2,NumericLiteral:3,StringLiteral:4,Comment:5,Keyword:6,NullLiteral:7,BooleanLiteral:8,RegExp:9,TemplateHead:10,TemplateMiddle:11,TemplateTail:12,NoSubstTemplate:13},Context={Block:1,Template:2};Lexer.prototype={_lines:[],inContext:function(ctxType){return this.context.length>0&&this.context[this.context.length-1].type===ctxType},pushContext:function(ctxType){this.context.push({type:ctxType})},popContext:function(){return this.context.pop()},isContext:function(context){return this.context.length>0&&this.context[this.context.length-1]===context},currentContext:function(){return this.context.length>0&&this.context[this.context.length-1]},getLines:function(){return this._lines=state.lines,this._lines},setLines:function(val){this._lines=val,state.lines=this._lines},peek:function(i){return this.input.charAt(i||0)},skip:function(i){i=i||1,this.char+=i,this.input=this.input.slice(i)},on:function(names,listener){names.split(\" \").forEach(function(name){this.emitter.on(name,listener)}.bind(this))},trigger:function(){this.emitter.emit.apply(this.emitter,Array.prototype.slice.call(arguments))},triggerAsync:function(type,args,checks,fn){checks.push(function(){fn()&&this.trigger(type,args)}.bind(this))},scanPunctuator:function(){var ch2,ch3,ch4,ch1=this.peek();switch(ch1){case\".\":if(/^[0-9]$/.test(this.peek(1)))return null;if(\".\"===this.peek(1)&&\".\"===this.peek(2))return{type:Token.Punctuator,value:\"...\"};case\"(\":case\")\":case\";\":case\",\":case\"[\":case\"]\":case\":\":case\"~\":case\"?\":return{type:Token.Punctuator,value:ch1};case\"{\":return this.pushContext(Context.Block),{type:Token.Punctuator,value:ch1};case\"}\":return this.inContext(Context.Block)&&this.popContext(),{type:Token.Punctuator,value:ch1};case\"#\":return{type:Token.Punctuator,value:ch1};case\"\":return null}return ch2=this.peek(1),ch3=this.peek(2),ch4=this.peek(3),\">\"===ch1&&\">\"===ch2&&\">\"===ch3&&\"=\"===ch4?{type:Token.Punctuator,value:\">>>=\"}:\"=\"===ch1&&\"=\"===ch2&&\"=\"===ch3?{type:Token.Punctuator,value:\"===\"}:\"!\"===ch1&&\"=\"===ch2&&\"=\"===ch3?{type:Token.Punctuator,value:\"!==\"}:\">\"===ch1&&\">\"===ch2&&\">\"===ch3?{type:Token.Punctuator,value:\">>>\"}:\"<\"===ch1&&\"<\"===ch2&&\"=\"===ch3?{type:Token.Punctuator,value:\"<<=\"}:\">\"===ch1&&\">\"===ch2&&\"=\"===ch3?{type:Token.Punctuator,value:\">>=\"}:\"=\"===ch1&&\">\"===ch2?{type:Token.Punctuator,value:ch1+ch2}:ch1===ch2&&\"+-<>&|\".indexOf(ch1)>=0?{type:Token.Punctuator,value:ch1+ch2}:\"<>=!+-*%&|^\".indexOf(ch1)>=0?\"=\"===ch2?{type:Token.Punctuator,value:ch1+ch2}:{type:Token.Punctuator,value:ch1}:\"/\"===ch1?\"=\"===ch2?{type:Token.Punctuator,value:\"/=\"}:{type:Token.Punctuator,value:\"/\"}:null},scanComments:function(){function commentToken(label,body,opt){var special=[\"jshint\",\"jslint\",\"members\",\"member\",\"globals\",\"global\",\"exported\"],isSpecial=!1,value=label+body,commentType=\"plain\";return opt=opt||{},opt.isMultiline&&(value+=\"*/\"),body=body.replace(/\\n/g,\" \"),\"/*\"===label&&reg.fallsThrough.test(body)&&(isSpecial=!0,commentType=\"falls through\"),special.forEach(function(str){if(!isSpecial&&(\"//\"!==label||\"jshint\"===str)&&(\" \"===body.charAt(str.length)&&body.substr(0,str.length)===str&&(isSpecial=!0,label+=str,body=body.substr(str.length)),isSpecial||\" \"!==body.charAt(0)||\" \"!==body.charAt(str.length+1)||body.substr(1,str.length)!==str||(isSpecial=!0,label=label+\" \"+str,body=body.substr(str.length+1)),isSpecial))switch(str){case\"member\":commentType=\"members\";break;case\"global\":commentType=\"globals\";break;default:var options=body.split(\":\").map(function(v){return v.replace(/^\\s+/,\"\").replace(/\\s+$/,\"\")});if(2===options.length)switch(options[0]){case\"ignore\":switch(options[1]){case\"start\":self.ignoringLinterErrors=!0,isSpecial=!1;break;case\"end\":self.ignoringLinterErrors=!1,isSpecial=!1}}commentType=str}}),{type:Token.Comment,commentType:commentType,value:value,body:body,isSpecial:isSpecial,isMultiline:opt.isMultiline||!1,isMalformed:opt.isMalformed||!1}}var ch1=this.peek(),ch2=this.peek(1),rest=this.input.substr(2),startLine=this.line,startChar=this.char,self=this;if(\"*\"===ch1&&\"/\"===ch2)return this.trigger(\"error\",{code:\"E018\",line:startLine,character:startChar}),this.skip(2),null;if(\"/\"!==ch1||\"*\"!==ch2&&\"/\"!==ch2)return null;if(\"/\"===ch2)return this.skip(this.input.length),commentToken(\"//\",rest);var body=\"\";if(\"*\"===ch2){for(this.inComment=!0,this.skip(2);\"*\"!==this.peek()||\"/\"!==this.peek(1);)if(\"\"===this.peek()){if(body+=\"\\n\",!this.nextLine())return this.trigger(\"error\",{code:\"E017\",line:startLine,character:startChar}),this.inComment=!1,commentToken(\"/*\",body,{isMultiline:!0,isMalformed:!0})}else body+=this.peek(),this.skip();return this.skip(2),this.inComment=!1,commentToken(\"/*\",body,{isMultiline:!0})}},scanKeyword:function(){var result=/^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input),keywords=[\"if\",\"in\",\"do\",\"var\",\"for\",\"new\",\"try\",\"let\",\"this\",\"else\",\"case\",\"void\",\"with\",\"enum\",\"while\",\"break\",\"catch\",\"throw\",\"const\",\"yield\",\"class\",\"super\",\"return\",\"typeof\",\"delete\",\"switch\",\"export\",\"import\",\"default\",\"finally\",\"extends\",\"function\",\"continue\",\"debugger\",\"instanceof\"];return result&&keywords.indexOf(result[0])>=0?{type:Token.Keyword,value:result[0]}:null},scanIdentifier:function(){function isNonAsciiIdentifierStart(code){return code>256}function isNonAsciiIdentifierPart(code){return code>256}function isHexDigit(str){return/^[0-9a-fA-F]$/.test(str)}function removeEscapeSequences(id){return id.replace(/\\\\u([0-9a-fA-F]{4})/g,function(m0,codepoint){return String.fromCharCode(parseInt(codepoint,16))})}var type,char,id=\"\",index=0,readUnicodeEscapeSequence=function(){if(index+=1,\"u\"!==this.peek(index))return null;var code,ch1=this.peek(index+1),ch2=this.peek(index+2),ch3=this.peek(index+3),ch4=this.peek(index+4);return isHexDigit(ch1)&&isHexDigit(ch2)&&isHexDigit(ch3)&&isHexDigit(ch4)?(code=parseInt(ch1+ch2+ch3+ch4,16),asciiIdentifierPartTable[code]||isNonAsciiIdentifierPart(code)?(index+=5,\"\\\\u\"+ch1+ch2+ch3+ch4):null):null}.bind(this),getIdentifierStart=function(){var chr=this.peek(index),code=chr.charCodeAt(0);return 92===code?readUnicodeEscapeSequence():128>code?asciiIdentifierStartTable[code]?(index+=1,chr):null:isNonAsciiIdentifierStart(code)?(index+=1,chr):null}.bind(this),getIdentifierPart=function(){var chr=this.peek(index),code=chr.charCodeAt(0);return 92===code?readUnicodeEscapeSequence():128>code?asciiIdentifierPartTable[code]?(index+=1,chr):null:isNonAsciiIdentifierPart(code)?(index+=1,chr):null}.bind(this);if(char=getIdentifierStart(),null===char)return null;for(id=char;char=getIdentifierPart(),null!==char;)id+=char;switch(id){case\"true\":case\"false\":type=Token.BooleanLiteral;break;case\"null\":type=Token.NullLiteral;break;default:type=Token.Identifier}return{type:type,value:removeEscapeSequences(id),text:id,tokenLength:id.length}},scanNumericLiteral:function(){function isDecimalDigit(str){return/^[0-9]$/.test(str)}function isOctalDigit(str){return/^[0-7]$/.test(str)}function isBinaryDigit(str){return/^[01]$/.test(str)}function isHexDigit(str){return/^[0-9a-fA-F]$/.test(str)}function isIdentifierStart(ch){return\"$\"===ch||\"_\"===ch||\"\\\\\"===ch||ch>=\"a\"&&\"z\">=ch||ch>=\"A\"&&\"Z\">=ch}var bad,index=0,value=\"\",length=this.input.length,char=this.peek(index),isAllowedDigit=isDecimalDigit,base=10,isLegacy=!1;if(\".\"!==char&&!isDecimalDigit(char))return null;if(\".\"!==char){for(value=this.peek(index),index+=1,char=this.peek(index),\"0\"===value&&((\"x\"===char||\"X\"===char)&&(isAllowedDigit=isHexDigit,base=16,index+=1,value+=char),(\"o\"===char||\"O\"===char)&&(isAllowedDigit=isOctalDigit,base=8,state.inES6(!0)||this.trigger(\"warning\",{code:\"W119\",line:this.line,character:this.char,data:[\"Octal integer literal\",\"6\"]}),index+=1,value+=char),(\"b\"===char||\"B\"===char)&&(isAllowedDigit=isBinaryDigit,base=2,state.inES6(!0)||this.trigger(\"warning\",{code:\"W119\",line:this.line,character:this.char,data:[\"Binary integer literal\",\"6\"]}),index+=1,value+=char),isOctalDigit(char)&&(isAllowedDigit=isOctalDigit,base=8,isLegacy=!0,bad=!1,index+=1,value+=char),!isOctalDigit(char)&&isDecimalDigit(char)&&(index+=1,value+=char));length>index;){if(char=this.peek(index),isLegacy&&isDecimalDigit(char))bad=!0;else if(!isAllowedDigit(char))break;value+=char,index+=1}if(isAllowedDigit!==isDecimalDigit)return!isLegacy&&2>=value.length?{type:Token.NumericLiteral,value:value,isMalformed:!0}:length>index&&(char=this.peek(index),isIdentifierStart(char))?null:{type:Token.NumericLiteral,value:value,base:base,isLegacy:isLegacy,isMalformed:!1}}if(\".\"===char)for(value+=char,index+=1;length>index&&(char=this.peek(index),isDecimalDigit(char));)value+=char,index+=1;if(\"e\"===char||\"E\"===char){if(value+=char,index+=1,char=this.peek(index),(\"+\"===char||\"-\"===char)&&(value+=this.peek(index),index+=1),char=this.peek(index),!isDecimalDigit(char))return null;for(value+=char,index+=1;length>index&&(char=this.peek(index),isDecimalDigit(char));)value+=char,index+=1}return length>index&&(char=this.peek(index),isIdentifierStart(char))?null:{type:Token.NumericLiteral,value:value,base:base,isMalformed:!isFinite(value)}},scanEscapeSequence:function(checks){var allowNewLine=!1,jump=1;this.skip();var char=this.peek();switch(char){case\"'\":this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\'\"]},checks,function(){return state.jsonMode});break;case\"b\":char=\"\\\\b\";break;case\"f\":char=\"\\\\f\";break;case\"n\":char=\"\\\\n\";break;case\"r\":char=\"\\\\r\";break;case\"t\":char=\"\\\\t\";break;case\"0\":char=\"\\\\0\";var n=parseInt(this.peek(1),10);this.triggerAsync(\"warning\",{code:\"W115\",line:this.line,character:this.char},checks,function(){return n>=0&&7>=n&&state.isStrict()});break;case\"u\":var hexCode=this.input.substr(1,4),code=parseInt(hexCode,16);isNaN(code)&&this.trigger(\"warning\",{code:\"W052\",line:this.line,character:this.char,data:[\"u\"+hexCode]}),char=String.fromCharCode(code),jump=5;break;case\"v\":this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\v\"]},checks,function(){return state.jsonMode}),char=\"\u000b\";break;case\"x\":var x=parseInt(this.input.substr(1,2),16);this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\x-\"]},checks,function(){return state.jsonMode}),char=String.fromCharCode(x),jump=3;break;case\"\\\\\":char=\"\\\\\\\\\";break;case'\"':char='\\\\\"';break;case\"/\":break;case\"\":allowNewLine=!0,char=\"\"}return{\"char\":char,jump:jump,allowNewLine:allowNewLine}},scanTemplateLiteral:function(checks){var tokenType,ch,value=\"\",startLine=this.line,startChar=this.char,depth=this.templateStarts.length;if(!state.inES6(!0))return null;if(\"`\"===this.peek())tokenType=Token.TemplateHead,this.templateStarts.push({line:this.line,\"char\":this.char}),depth=this.templateStarts.length,this.skip(1),this.pushContext(Context.Template);else{if(!this.inContext(Context.Template)||\"}\"!==this.peek())return null;tokenType=Token.TemplateMiddle}for(;\"`\"!==this.peek();){for(;\"\"===(ch=this.peek());)if(value+=\"\\n\",!this.nextLine()){var startPos=this.templateStarts.pop();return this.trigger(\"error\",{code:\"E052\",line:startPos.line,character:startPos.char}),{type:tokenType,value:value,startLine:startLine,startChar:startChar,isUnclosed:!0,depth:depth,context:this.popContext()}}if(\"$\"===ch&&\"{\"===this.peek(1))return value+=\"${\",this.skip(2),{type:tokenType,value:value,startLine:startLine,startChar:startChar,isUnclosed:!1,depth:depth,context:this.currentContext()};\nif(\"\\\\\"===ch){var escape=this.scanEscapeSequence(checks);value+=escape.char,this.skip(escape.jump)}else\"`\"!==ch&&(value+=ch,this.skip(1))}return tokenType=tokenType===Token.TemplateHead?Token.NoSubstTemplate:Token.TemplateTail,this.skip(1),this.templateStarts.pop(),{type:tokenType,value:value,startLine:startLine,startChar:startChar,isUnclosed:!1,depth:depth,context:this.popContext()}},scanStringLiteral:function(checks){var quote=this.peek();if('\"'!==quote&&\"'\"!==quote)return null;this.triggerAsync(\"warning\",{code:\"W108\",line:this.line,character:this.char},checks,function(){return state.jsonMode&&'\"'!==quote});var value=\"\",startLine=this.line,startChar=this.char,allowNewLine=!1;for(this.skip();this.peek()!==quote;)if(\"\"===this.peek()){if(allowNewLine?(allowNewLine=!1,this.triggerAsync(\"warning\",{code:\"W043\",line:this.line,character:this.char},checks,function(){return!state.option.multistr}),this.triggerAsync(\"warning\",{code:\"W042\",line:this.line,character:this.char},checks,function(){return state.jsonMode&&state.option.multistr})):this.trigger(\"warning\",{code:\"W112\",line:this.line,character:this.char}),!this.nextLine())return this.trigger(\"error\",{code:\"E029\",line:startLine,character:startChar}),{type:Token.StringLiteral,value:value,startLine:startLine,startChar:startChar,isUnclosed:!0,quote:quote}}else{allowNewLine=!1;var char=this.peek(),jump=1;if(\" \">char&&this.trigger(\"warning\",{code:\"W113\",line:this.line,character:this.char,data:[\"<non-printable>\"]}),\"\\\\\"===char){var parsed=this.scanEscapeSequence(checks);char=parsed.char,jump=parsed.jump,allowNewLine=parsed.allowNewLine}value+=char,this.skip(jump)}return this.skip(),{type:Token.StringLiteral,value:value,startLine:startLine,startChar:startChar,isUnclosed:!1,quote:quote}},scanRegExp:function(){var terminated,index=0,length=this.input.length,char=this.peek(),value=char,body=\"\",flags=[],malformed=!1,isCharSet=!1,scanUnexpectedChars=function(){\" \">char&&(malformed=!0,this.trigger(\"warning\",{code:\"W048\",line:this.line,character:this.char})),\"<\"===char&&(malformed=!0,this.trigger(\"warning\",{code:\"W049\",line:this.line,character:this.char,data:[char]}))}.bind(this);if(!this.prereg||\"/\"!==char)return null;for(index+=1,terminated=!1;length>index;)if(char=this.peek(index),value+=char,body+=char,isCharSet)\"]\"===char&&(\"\\\\\"!==this.peek(index-1)||\"\\\\\"===this.peek(index-2))&&(isCharSet=!1),\"\\\\\"===char&&(index+=1,char=this.peek(index),body+=char,value+=char,scanUnexpectedChars()),index+=1;else{if(\"\\\\\"===char){if(index+=1,char=this.peek(index),body+=char,value+=char,scanUnexpectedChars(),\"/\"===char){index+=1;continue}if(\"[\"===char){index+=1;continue}}if(\"[\"!==char){if(\"/\"===char){body=body.substr(0,body.length-1),terminated=!0,index+=1;break}index+=1}else isCharSet=!0,index+=1}if(!terminated)return this.trigger(\"error\",{code:\"E015\",line:this.line,character:this.from}),void this.trigger(\"fatal\",{line:this.line,from:this.from});for(;length>index&&(char=this.peek(index),/[gim]/.test(char));)flags.push(char),value+=char,index+=1;try{RegExp(body,flags.join(\"\"))}catch(err){malformed=!0,this.trigger(\"error\",{code:\"E016\",line:this.line,character:this.char,data:[err.message]})}return{type:Token.RegExp,value:value,flags:flags,isMalformed:malformed}},scanNonBreakingSpaces:function(){return state.option.nonbsp?this.input.search(/(\\u00A0)/):-1},scanUnsafeChars:function(){return this.input.search(reg.unsafeChars)},next:function(checks){this.from=this.char;var start;if(/\\s/.test(this.peek()))for(start=this.char;/\\s/.test(this.peek());)this.from+=1,this.skip();var match=this.scanComments()||this.scanStringLiteral(checks)||this.scanTemplateLiteral(checks);return match?match:(match=this.scanRegExp()||this.scanPunctuator()||this.scanKeyword()||this.scanIdentifier()||this.scanNumericLiteral(),match?(this.skip(match.tokenLength||match.value.length),match):null)},nextLine:function(){var char;if(this.line>=this.getLines().length)return!1;this.input=this.getLines()[this.line],this.line+=1,this.char=1,this.from=1;var inputTrimmed=this.input.trim(),startsWith=function(){return _.some(arguments,function(prefix){return 0===inputTrimmed.indexOf(prefix)})},endsWith=function(){return _.some(arguments,function(suffix){return-1!==inputTrimmed.indexOf(suffix,inputTrimmed.length-suffix.length)})};if(this.ignoringLinterErrors===!0&&(startsWith(\"/*\",\"//\")||this.inComment&&endsWith(\"*/\")||(this.input=\"\")),char=this.scanNonBreakingSpaces(),char>=0&&this.trigger(\"warning\",{code:\"W125\",line:this.line,character:char+1}),this.input=this.input.replace(/\\t/g,state.tab),char=this.scanUnsafeChars(),char>=0&&this.trigger(\"warning\",{code:\"W100\",line:this.line,character:char}),!this.ignoringLinterErrors&&state.option.maxlen&&state.option.maxlen<this.input.length){var inComment=this.inComment||startsWith.call(inputTrimmed,\"//\")||startsWith.call(inputTrimmed,\"/*\"),shouldTriggerError=!inComment||!reg.maxlenException.test(inputTrimmed);shouldTriggerError&&this.trigger(\"warning\",{code:\"W101\",line:this.line,character:this.input.length})}return!0},start:function(){this.nextLine()},token:function(){function isReserved(token,isProperty){if(!token.reserved)return!1;var meta=token.meta;if(meta&&meta.isFutureReservedWord&&state.inES5()){if(!meta.es5)return!1;if(meta.strictOnly&&!state.option.strict&&!state.isStrict())return!1;if(isProperty)return!1}return!0}for(var token,checks=asyncTrigger(),create=function(type,value,isProperty,token){var obj;if(\"(endline)\"!==type&&\"(end)\"!==type&&(this.prereg=!1),\"(punctuator)\"===type){switch(value){case\".\":case\")\":case\"~\":case\"#\":case\"]\":case\"++\":case\"--\":this.prereg=!1;break;default:this.prereg=!0}obj=Object.create(state.syntax[value]||state.syntax[\"(error)\"])}return\"(identifier)\"===type&&((\"return\"===value||\"case\"===value||\"typeof\"===value)&&(this.prereg=!0),_.has(state.syntax,value)&&(obj=Object.create(state.syntax[value]||state.syntax[\"(error)\"]),isReserved(obj,isProperty&&\"(identifier)\"===type)||(obj=null))),obj||(obj=Object.create(state.syntax[type])),obj.identifier=\"(identifier)\"===type,obj.type=obj.type||type,obj.value=value,obj.line=this.line,obj.character=this.char,obj.from=this.from,obj.identifier&&token&&(obj.raw_text=token.text||token.value),token&&token.startLine&&token.startLine!==this.line&&(obj.startLine=token.startLine),token&&token.context&&(obj.context=token.context),token&&token.depth&&(obj.depth=token.depth),token&&token.isUnclosed&&(obj.isUnclosed=token.isUnclosed),isProperty&&obj.identifier&&(obj.isProperty=isProperty),obj.check=checks.check,obj}.bind(this);;){if(!this.input.length)return this.nextLine()?create(\"(endline)\",\"\"):this.exhausted?null:(this.exhausted=!0,create(\"(end)\",\"\"));if(token=this.next(checks))switch(token.type){case Token.StringLiteral:return this.triggerAsync(\"String\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value,quote:token.quote},checks,function(){return!0}),create(\"(string)\",token.value,null,token);case Token.TemplateHead:return this.trigger(\"TemplateHead\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value}),create(\"(template)\",token.value,null,token);case Token.TemplateMiddle:return this.trigger(\"TemplateMiddle\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value}),create(\"(template middle)\",token.value,null,token);case Token.TemplateTail:return this.trigger(\"TemplateTail\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value}),create(\"(template tail)\",token.value,null,token);case Token.NoSubstTemplate:return this.trigger(\"NoSubstTemplate\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value}),create(\"(no subst template)\",token.value,null,token);case Token.Identifier:this.triggerAsync(\"Identifier\",{line:this.line,\"char\":this.char,from:this.form,name:token.value,raw_name:token.text,isProperty:\".\"===state.tokens.curr.id},checks,function(){return!0});case Token.Keyword:case Token.NullLiteral:case Token.BooleanLiteral:return create(\"(identifier)\",token.value,\".\"===state.tokens.curr.id,token);case Token.NumericLiteral:return token.isMalformed&&this.trigger(\"warning\",{code:\"W045\",line:this.line,character:this.char,data:[token.value]}),this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"0x-\"]},checks,function(){return 16===token.base&&state.jsonMode}),this.triggerAsync(\"warning\",{code:\"W115\",line:this.line,character:this.char},checks,function(){return state.isStrict()&&8===token.base&&token.isLegacy}),this.trigger(\"Number\",{line:this.line,\"char\":this.char,from:this.from,value:token.value,base:token.base,isMalformed:token.malformed}),create(\"(number)\",token.value);case Token.RegExp:return create(\"(regexp)\",token.value);case Token.Comment:if(state.tokens.curr.comment=!0,token.isSpecial)return{id:\"(comment)\",value:token.value,body:token.body,type:token.commentType,isSpecial:token.isSpecial,line:this.line,character:this.char,from:this.from};break;case\"\":break;default:return create(\"(punctuator)\",token.value)}else this.input.length&&(this.trigger(\"error\",{code:\"E024\",line:this.line,character:this.char,data:[this.peek()]}),this.input=\"\")}}},exports.Lexer=Lexer,exports.Context=Context},{\"../data/ascii-identifier-data.js\":\"/node_modules/jshint/data/ascii-identifier-data.js\",\"../lodash\":\"/node_modules/jshint/lodash.js\",\"./reg.js\":\"/node_modules/jshint/src/reg.js\",\"./state.js\":\"/node_modules/jshint/src/state.js\",events:\"/node_modules/browserify/node_modules/events/events.js\"}],\"/node_modules/jshint/src/messages.js\":[function(_dereq_,module,exports){\"use strict\";var _=_dereq_(\"../lodash\"),errors={E001:\"Bad option: '{a}'.\",E002:\"Bad option value.\",E003:\"Expected a JSON value.\",E004:\"Input is neither a string nor an array of strings.\",E005:\"Input is empty.\",E006:\"Unexpected early end of program.\",E007:'Missing \"use strict\" statement.',E008:\"Strict violation.\",E009:\"Option 'validthis' can't be used in a global scope.\",E010:\"'with' is not allowed in strict mode.\",E011:\"'{a}' has already been declared.\",E012:\"const '{a}' is initialized to 'undefined'.\",E013:\"Attempting to override '{a}' which is a constant.\",E014:\"A regular expression literal can be confused with '/='.\",E015:\"Unclosed regular expression.\",E016:\"Invalid regular expression.\",E017:\"Unclosed comment.\",E018:\"Unbegun comment.\",E019:\"Unmatched '{a}'.\",E020:\"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.\",E021:\"Expected '{a}' and instead saw '{b}'.\",E022:\"Line breaking error '{a}'.\",E023:\"Missing '{a}'.\",E024:\"Unexpected '{a}'.\",E025:\"Missing ':' on a case clause.\",E026:\"Missing '}' to match '{' from line {a}.\",E027:\"Missing ']' to match '[' from line {a}.\",E028:\"Illegal comma.\",E029:\"Unclosed string.\",E030:\"Expected an identifier and instead saw '{a}'.\",E031:\"Bad assignment.\",E032:\"Expected a small integer or 'false' and instead saw '{a}'.\",E033:\"Expected an operator and instead saw '{a}'.\",E034:\"get/set are ES5 features.\",E035:\"Missing property name.\",E036:\"Expected to see a statement and instead saw a block.\",E037:null,E038:null,E039:\"Function declarations are not invocable. Wrap the whole function invocation in parens.\",E040:\"Each value should have its own case label.\",E041:\"Unrecoverable syntax error.\",E042:\"Stopping.\",E043:\"Too many errors.\",E044:null,E045:\"Invalid for each loop.\",E046:\"A yield statement shall be within a generator function (with syntax: `function*`)\",E047:null,E048:\"{a} declaration not directly within block.\",E049:\"A {a} cannot be named '{b}'.\",E050:\"Mozilla acequires the yield expression to be parenthesized here.\",E051:null,E052:\"Unclosed template literal.\",E053:\"Export declaration must be in global scope.\",E054:\"Class properties must be methods. Expected '(' but instead saw '{a}'.\",E055:\"The '{a}' option cannot be set after any executable code.\",E056:\"'{a}' was used before it was declared, which is illegal for '{b}' variables.\",E057:\"Invalid meta property: '{a}.{b}'.\",E058:\"Missing semicolon.\"},warnings={W001:\"'hasOwnProperty' is a really bad name.\",W002:\"Value of '{a}' may be overwritten in IE 8 and earlier.\",W003:\"'{a}' was used before it was defined.\",W004:\"'{a}' is already defined.\",W005:\"A dot following a number can be confused with a decimal point.\",W006:\"Confusing minuses.\",W007:\"Confusing plusses.\",W008:\"A leading decimal point can be confused with a dot: '{a}'.\",W009:\"The array literal notation [] is preferable.\",W010:\"The object literal notation {} is preferable.\",W011:null,W012:null,W013:null,W014:\"Bad line breaking before '{a}'.\",W015:null,W016:\"Unexpected use of '{a}'.\",W017:\"Bad operand.\",W018:\"Confusing use of '{a}'.\",W019:\"Use the isNaN function to compare with NaN.\",W020:\"Read only.\",W021:\"Reassignment of '{a}', which is is a {b}. Use 'var' or 'let' to declare bindings that may change.\",W022:\"Do not assign to the exception parameter.\",W023:\"Expected an identifier in an assignment and instead saw a function invocation.\",W024:\"Expected an identifier and instead saw '{a}' (a reserved word).\",W025:\"Missing name in function declaration.\",W026:\"Inner functions should be listed at the top of the outer function.\",W027:\"Unreachable '{a}' after '{b}'.\",W028:\"Label '{a}' on {b} statement.\",W030:\"Expected an assignment or function call and instead saw an expression.\",W031:\"Do not use 'new' for side effects.\",W032:\"Unnecessary semicolon.\",W033:\"Missing semicolon.\",W034:'Unnecessary directive \"{a}\".',W035:\"Empty block.\",W036:\"Unexpected /*member '{a}'.\",W037:\"'{a}' is a statement label.\",W038:\"'{a}' used out of scope.\",W039:\"'{a}' is not allowed.\",W040:\"Possible strict violation.\",W041:\"Use '{a}' to compare with '{b}'.\",W042:\"Avoid EOL escaping.\",W043:\"Bad escaping of EOL. Use option multistr if needed.\",W044:\"Bad or unnecessary escaping.\",W045:\"Bad number '{a}'.\",W046:\"Don't use extra leading zeros '{a}'.\",W047:\"A trailing decimal point can be confused with a dot: '{a}'.\",W048:\"Unexpected control character in regular expression.\",W049:\"Unexpected escaped character '{a}' in regular expression.\",W050:\"JavaScript URL.\",W051:\"Variables should not be deleted.\",W052:\"Unexpected '{a}'.\",W053:\"Do not use {a} as a constructor.\",W054:\"The Function constructor is a form of eval.\",W055:\"A constructor name should start with an uppercase letter.\",W056:\"Bad constructor.\",W057:\"Weird construction. Is 'new' necessary?\",W058:\"Missing '()' invoking a constructor.\",W059:\"Avoid arguments.{a}.\",W060:\"document.write can be a form of eval.\",W061:\"eval can be harmful.\",W062:\"Wrap an immediate function invocation in parens to assist the reader in understanding that the expression is the result of a function, and not the function itself.\",W063:\"Math is not a function.\",W064:\"Missing 'new' prefix when invoking a constructor.\",W065:\"Missing radix parameter.\",W066:\"Implied eval. Consider passing a function instead of a string.\",W067:\"Bad invocation.\",W068:\"Wrapping non-IIFE function literals in parens is unnecessary.\",W069:\"['{a}'] is better written in dot notation.\",W070:\"Extra comma. (it breaks older versions of IE)\",W071:\"This function has too many statements. ({a})\",W072:\"This function has too many parameters. ({a})\",W073:\"Blocks are nested too deeply. ({a})\",W074:\"This function's cyclomatic complexity is too high. ({a})\",W075:\"Duplicate {a} '{b}'.\",W076:\"Unexpected parameter '{a}' in get {b} function.\",W077:\"Expected a single parameter in set {a} function.\",W078:\"Setter is defined without getter.\",W079:\"Redefinition of '{a}'.\",W080:\"It's not necessary to initialize '{a}' to 'undefined'.\",W081:null,W082:\"Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.\",W083:\"Don't make functions within a loop.\",W084:\"Assignment in conditional expression\",W085:\"Don't use 'with'.\",W086:\"Expected a 'break' statement before '{a}'.\",W087:\"Forgotten 'debugger' statement?\",W088:\"Creating global 'for' variable. Should be 'for (var {a} ...'.\",W089:\"The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.\",W090:\"'{a}' is not a statement label.\",W091:null,W093:\"Did you mean to return a conditional instead of an assignment?\",W094:\"Unexpected comma.\",W095:\"Expected a string and instead saw {a}.\",W096:\"The '{a}' key may produce unexpected results.\",W097:'Use the function form of \"use strict\".',W098:\"'{a}' is defined but never used.\",W099:null,W100:\"This character may get silently deleted by one or more browsers.\",W101:\"Line is too long.\",W102:null,W103:\"The '{a}' property is deprecated.\",W104:\"'{a}' is available in ES{b} (use 'esversion: {b}') or Mozilla JS extensions (use moz).\",W105:\"Unexpected {a} in '{b}'.\",W106:\"Identifier '{a}' is not in camel case.\",W107:\"Script URL.\",W108:\"Strings must use doublequote.\",W109:\"Strings must use singlequote.\",W110:\"Mixed double and single quotes.\",W112:\"Unclosed string.\",W113:\"Control character in string: {a}.\",W114:\"Avoid {a}.\",W115:\"Octal literals are not allowed in strict mode.\",W116:\"Expected '{a}' and instead saw '{b}'.\",W117:\"'{a}' is not defined.\",W118:\"'{a}' is only available in Mozilla JavaScript extensions (use moz option).\",W119:\"'{a}' is only available in ES{b} (use 'esversion: {b}').\",W120:\"You might be leaking a variable ({a}) here.\",W121:\"Extending prototype of native object: '{a}'.\",W122:\"Invalid typeof value '{a}'\",W123:\"'{a}' is already defined in outer scope.\",W124:\"A generator function shall contain a yield statement.\",W125:\"This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp\",W126:\"Unnecessary grouping operator.\",W127:\"Unexpected use of a comma operator.\",W128:\"Empty array elements acequire elision=true.\",W129:\"'{a}' is defined in a future version of JavaScript. Use a different variable name to avoid migration issues.\",W130:\"Invalid element after rest element.\",W131:\"Invalid parameter after rest parameter.\",W132:\"`var` declarations are forbidden. Use `let` or `const` instead.\",W133:\"Invalid for-{a} loop left-hand-side: {b}.\",W134:\"The '{a}' option is only available when linting ECMAScript {b} code.\",W135:\"{a} may not be supported by non-browser environments.\",W136:\"'{a}' must be in function scope.\",W137:\"Empty destructuring.\",W138:\"Regular parameters should not come after default parameters.\"},info={I001:\"Comma warnings can be turned off with 'laxcomma'.\",I002:null,I003:\"ES5 option is now set per default\"};exports.errors={},exports.warnings={},exports.info={},_.each(errors,function(desc,code){exports.errors[code]={code:code,desc:desc}}),_.each(warnings,function(desc,code){exports.warnings[code]={code:code,desc:desc}}),_.each(info,function(desc,code){exports.info[code]={code:code,desc:desc}})},{\"../lodash\":\"/node_modules/jshint/lodash.js\"}],\"/node_modules/jshint/src/name-stack.js\":[function(_dereq_,module){\"use strict\";function NameStack(){this._stack=[]}Object.defineProperty(NameStack.prototype,\"length\",{get:function(){return this._stack.length}}),NameStack.prototype.push=function(){this._stack.push(null)},NameStack.prototype.pop=function(){this._stack.pop()},NameStack.prototype.set=function(token){this._stack[this.length-1]=token},NameStack.prototype.infer=function(){var type,nameToken=this._stack[this.length-1],prefix=\"\";return nameToken&&\"class\"!==nameToken.type||(nameToken=this._stack[this.length-2]),nameToken?(type=nameToken.type,\"(string)\"!==type&&\"(number)\"!==type&&\"(identifier)\"!==type&&\"default\"!==type?\"(expression)\":(nameToken.accessorType&&(prefix=nameToken.accessorType+\" \"),prefix+nameToken.value)):\"(empty)\"},module.exports=NameStack},{}],\"/node_modules/jshint/src/options.js\":[function(_dereq_,module,exports){\"use strict\";exports.bool={enforcing:{bitwise:!0,freeze:!0,camelcase:!0,curly:!0,eqeqeq:!0,futurehostile:!0,notypeof:!0,es3:!0,es5:!0,forin:!0,funcscope:!0,immed:!0,iterator:!0,newcap:!0,noarg:!0,nocomma:!0,noempty:!0,nonbsp:!0,nonew:!0,undef:!0,singleGroups:!1,varstmt:!1,enforceall:!1},relaxing:{asi:!0,multistr:!0,debug:!0,boss:!0,evil:!0,globalstrict:!0,plusplus:!0,proto:!0,scripturl:!0,sub:!0,supernew:!0,laxbreak:!0,laxcomma:!0,validthis:!0,withstmt:!0,moz:!0,noyield:!0,eqnull:!0,lastsemic:!0,loopfunc:!0,expr:!0,esnext:!0,elision:!0},environments:{mootools:!0,couch:!0,jasmine:!0,jquery:!0,node:!0,qunit:!0,rhino:!0,shelljs:!0,prototypejs:!0,yui:!0,mocha:!0,module:!0,wsh:!0,worker:!0,nonstandard:!0,browser:!0,browserify:!0,devel:!0,dojo:!0,typed:!0,phantom:!0},obsolete:{onecase:!0,regexp:!0,regexdash:!0}},exports.val={maxlen:!1,indent:!1,maxerr:!1,predef:!1,globals:!1,quotmark:!1,scope:!1,maxstatements:!1,maxdepth:!1,maxparams:!1,maxcomplexity:!1,shadow:!1,strict:!0,unused:!0,latedef:!1,ignore:!1,ignoreDelimiters:!1,esversion:5},exports.inverted={bitwise:!0,forin:!0,newcap:!0,plusplus:!0,regexp:!0,undef:!0,eqeqeq:!0,strict:!0},exports.validNames=Object.keys(exports.val).concat(Object.keys(exports.bool.relaxing)).concat(Object.keys(exports.bool.enforcing)).concat(Object.keys(exports.bool.obsolete)).concat(Object.keys(exports.bool.environments)),exports.renamed={eqeq:\"eqeqeq\",windows:\"wsh\",sloppy:\"strict\"},exports.removed={nomen:!0,onevar:!0,passfail:!0,white:!0,gcl:!0,smarttabs:!0,trailing:!0},exports.noenforceall={varstmt:!0,strict:!0}},{}],\"/node_modules/jshint/src/reg.js\":[function(_dereq_,module,exports){\"use strict\";exports.unsafeString=/@cc|<\\/?|script|\\]\\s*\\]|<\\s*!|&lt/i,exports.unsafeChars=/[\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,exports.needEsc=/[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,exports.needEscGlobal=/[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,exports.starSlash=/\\*\\//,exports.identifier=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,exports.javascriptURL=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\\s*:/i,exports.fallsThrough=/^\\s*falls?\\sthrough\\s*$/,exports.maxlenException=/^(?:(?:\\/\\/|\\/\\*|\\*) ?)?[^ ]+$/},{}],\"/node_modules/jshint/src/scope-manager.js\":[function(_dereq_,module){\"use strict\";var _=_dereq_(\"../lodash\"),events=_dereq_(\"events\"),marker={},scopeManager=function(state,predefined,exported,declared){function _newScope(type){_current={\"(labels)\":Object.create(null),\"(usages)\":Object.create(null),\"(breakLabels)\":Object.create(null),\"(parent)\":_current,\"(type)\":type,\"(params)\":\"functionparams\"===type||\"catchparams\"===type?[]:null},_scopeStack.push(_current)}function warning(code,token){emitter.emit(\"warning\",{code:code,token:token,data:_.slice(arguments,2)})}function error(code,token){emitter.emit(\"warning\",{code:code,token:token,data:_.slice(arguments,2)})}function _setupUsages(labelName){_current[\"(usages)\"][labelName]||(_current[\"(usages)\"][labelName]={\"(modified)\":[],\"(reassigned)\":[],\"(tokens)\":[]})}function _checkForUnused(){if(\"functionparams\"===_current[\"(type)\"])return _checkParams(),void 0;var curentLabels=_current[\"(labels)\"];for(var labelName in curentLabels)curentLabels[labelName]&&\"exception\"!==curentLabels[labelName][\"(type)\"]&&curentLabels[labelName][\"(unused)\"]&&_warnUnused(labelName,curentLabels[labelName][\"(token)\"],\"var\")}function _checkParams(){var params=_current[\"(params)\"];if(params)for(var unused_opt,param=params.pop();param;){var label=_current[\"(labels)\"][param];if(unused_opt=_getUnusedOption(state.funct[\"(unusedOption)\"]),\"undefined\"===param)return;if(label[\"(unused)\"])_warnUnused(param,label[\"(token)\"],\"param\",state.funct[\"(unusedOption)\"]);else if(\"last-param\"===unused_opt)return;param=params.pop()}}function _getLabel(labelName){for(var i=_scopeStack.length-1;i>=0;--i){var scopeLabels=_scopeStack[i][\"(labels)\"];if(scopeLabels[labelName])return scopeLabels}}function usedSoFarInCurrentFunction(labelName){for(var i=_scopeStack.length-1;i>=0;i--){var current=_scopeStack[i];if(current[\"(usages)\"][labelName])return current[\"(usages)\"][labelName];if(current===_currentFunctBody)break}return!1}function _checkOuterShadow(labelName,token){if(\"outer\"===state.option.shadow)for(var isGlobal=\"global\"===_currentFunctBody[\"(type)\"],isNewFunction=\"functionparams\"===_current[\"(type)\"],outsideCurrentFunction=!isGlobal,i=0;_scopeStack.length>i;i++){var stackItem=_scopeStack[i];isNewFunction||_scopeStack[i+1]!==_currentFunctBody||(outsideCurrentFunction=!1),outsideCurrentFunction&&stackItem[\"(labels)\"][labelName]&&warning(\"W123\",token,labelName),stackItem[\"(breakLabels)\"][labelName]&&warning(\"W123\",token,labelName)}}function _latedefWarning(type,labelName,token){state.option.latedef&&(state.option.latedef===!0&&\"function\"===type||\"function\"!==type)&&warning(\"W003\",token,labelName)}var _current,_scopeStack=[];_newScope(\"global\"),_current[\"(predefined)\"]=predefined;var _currentFunctBody=_current,usedPredefinedAndGlobals=Object.create(null),impliedGlobals=Object.create(null),unuseds=[],emitter=new events.EventEmitter,_getUnusedOption=function(unused_opt){return void 0===unused_opt&&(unused_opt=state.option.unused),unused_opt===!0&&(unused_opt=\"last-param\"),unused_opt},_warnUnused=function(name,tkn,type,unused_opt){var line=tkn.line,chr=tkn.from,raw_name=tkn.raw_text||name;unused_opt=_getUnusedOption(unused_opt);var warnable_types={vars:[\"var\"],\"last-param\":[\"var\",\"param\"],strict:[\"var\",\"param\",\"last-param\"]};unused_opt&&warnable_types[unused_opt]&&-1!==warnable_types[unused_opt].indexOf(type)&&warning(\"W098\",{line:line,from:chr},raw_name),(unused_opt||\"var\"===type)&&unuseds.push({name:name,line:line,character:chr})},scopeManagerInst={on:function(names,listener){names.split(\" \").forEach(function(name){emitter.on(name,listener)})},isPredefined:function(labelName){return!this.has(labelName)&&_.has(_scopeStack[0][\"(predefined)\"],labelName)},stack:function(type){var previousScope=_current;_newScope(type),type||\"functionparams\"!==previousScope[\"(type)\"]||(_current[\"(isFuncBody)\"]=!0,_current[\"(context)\"]=_currentFunctBody,_currentFunctBody=_current)},unstack:function(){var i,j,subScope=_scopeStack.length>1?_scopeStack[_scopeStack.length-2]:null,isUnstackingFunctionBody=_current===_currentFunctBody,isUnstackingFunctionParams=\"functionparams\"===_current[\"(type)\"],isUnstackingFunctionOuter=\"functionouter\"===_current[\"(type)\"],currentUsages=_current[\"(usages)\"],currentLabels=_current[\"(labels)\"],usedLabelNameList=Object.keys(currentUsages);for(currentUsages.__proto__&&-1===usedLabelNameList.indexOf(\"__proto__\")&&usedLabelNameList.push(\"__proto__\"),i=0;usedLabelNameList.length>i;i++){var usedLabelName=usedLabelNameList[i],usage=currentUsages[usedLabelName],usedLabel=currentLabels[usedLabelName];if(usedLabel){var usedLabelType=usedLabel[\"(type)\"];if(usedLabel[\"(useOutsideOfScope)\"]&&!state.option.funcscope){var usedTokens=usage[\"(tokens)\"];if(usedTokens)for(j=0;usedTokens.length>j;j++)usedLabel[\"(function)\"]===usedTokens[j][\"(function)\"]&&error(\"W038\",usedTokens[j],usedLabelName)}if(_current[\"(labels)\"][usedLabelName][\"(unused)\"]=!1,\"const\"===usedLabelType&&usage[\"(modified)\"])for(j=0;usage[\"(modified)\"].length>j;j++)error(\"E013\",usage[\"(modified)\"][j],usedLabelName);if((\"function\"===usedLabelType||\"class\"===usedLabelType)&&usage[\"(reassigned)\"])for(j=0;usage[\"(reassigned)\"].length>j;j++)error(\"W021\",usage[\"(reassigned)\"][j],usedLabelName,usedLabelType)}else if(isUnstackingFunctionOuter&&(state.funct[\"(isCapturing)\"]=!0),subScope)if(subScope[\"(usages)\"][usedLabelName]){var subScopeUsage=subScope[\"(usages)\"][usedLabelName];subScopeUsage[\"(modified)\"]=subScopeUsage[\"(modified)\"].concat(usage[\"(modified)\"]),subScopeUsage[\"(tokens)\"]=subScopeUsage[\"(tokens)\"].concat(usage[\"(tokens)\"]),subScopeUsage[\"(reassigned)\"]=subScopeUsage[\"(reassigned)\"].concat(usage[\"(reassigned)\"]),subScopeUsage[\"(onlyUsedSubFunction)\"]=!1}else subScope[\"(usages)\"][usedLabelName]=usage,isUnstackingFunctionBody&&(subScope[\"(usages)\"][usedLabelName][\"(onlyUsedSubFunction)\"]=!0);else if(\"boolean\"==typeof _current[\"(predefined)\"][usedLabelName]){if(delete declared[usedLabelName],usedPredefinedAndGlobals[usedLabelName]=marker,_current[\"(predefined)\"][usedLabelName]===!1&&usage[\"(reassigned)\"])for(j=0;usage[\"(reassigned)\"].length>j;j++)warning(\"W020\",usage[\"(reassigned)\"][j])}else if(usage[\"(tokens)\"])for(j=0;usage[\"(tokens)\"].length>j;j++){var undefinedToken=usage[\"(tokens)\"][j];undefinedToken.forgiveUndef||(state.option.undef&&!undefinedToken.ignoreUndef&&warning(\"W117\",undefinedToken,usedLabelName),impliedGlobals[usedLabelName]?impliedGlobals[usedLabelName].line.push(undefinedToken.line):impliedGlobals[usedLabelName]={name:usedLabelName,line:[undefinedToken.line]})}}if(subScope||Object.keys(declared).forEach(function(labelNotUsed){_warnUnused(labelNotUsed,declared[labelNotUsed],\"var\")}),subScope&&!isUnstackingFunctionBody&&!isUnstackingFunctionParams&&!isUnstackingFunctionOuter){var labelNames=Object.keys(currentLabels);for(i=0;labelNames.length>i;i++){var defLabelName=labelNames[i];currentLabels[defLabelName][\"(blockscoped)\"]||\"exception\"===currentLabels[defLabelName][\"(type)\"]||this.funct.has(defLabelName,{excludeCurrent:!0})||(subScope[\"(labels)\"][defLabelName]=currentLabels[defLabelName],\"global\"!==_currentFunctBody[\"(type)\"]&&(subScope[\"(labels)\"][defLabelName][\"(useOutsideOfScope)\"]=!0),delete currentLabels[defLabelName])}}_checkForUnused(),_scopeStack.pop(),isUnstackingFunctionBody&&(_currentFunctBody=_scopeStack[_.findLastIndex(_scopeStack,function(scope){return scope[\"(isFuncBody)\"]||\"global\"===scope[\"(type)\"]})]),_current=subScope},addParam:function(labelName,token,type){if(type=type||\"param\",\"exception\"===type){var previouslyDefinedLabelType=this.funct.labeltype(labelName);previouslyDefinedLabelType&&\"exception\"!==previouslyDefinedLabelType&&(state.option.node||warning(\"W002\",state.tokens.next,labelName))}if(_.has(_current[\"(labels)\"],labelName)?_current[\"(labels)\"][labelName].duplicated=!0:(_checkOuterShadow(labelName,token,type),_current[\"(labels)\"][labelName]={\"(type)\":type,\"(token)\":token,\"(unused)\":!0},_current[\"(params)\"].push(labelName)),_.has(_current[\"(usages)\"],labelName)){var usage=_current[\"(usages)\"][labelName];usage[\"(onlyUsedSubFunction)\"]?_latedefWarning(type,labelName,token):warning(\"E056\",token,labelName,type)}},validateParams:function(){if(\"global\"!==_currentFunctBody[\"(type)\"]){var isStrict=state.isStrict(),currentFunctParamScope=_currentFunctBody[\"(parent)\"];currentFunctParamScope[\"(params)\"]&&currentFunctParamScope[\"(params)\"].forEach(function(labelName){var label=currentFunctParamScope[\"(labels)\"][labelName];label&&label.duplicated&&(isStrict?warning(\"E011\",label[\"(token)\"],labelName):state.option.shadow!==!0&&warning(\"W004\",label[\"(token)\"],labelName))})}},getUsedOrDefinedGlobals:function(){var list=Object.keys(usedPredefinedAndGlobals);return usedPredefinedAndGlobals.__proto__===marker&&-1===list.indexOf(\"__proto__\")&&list.push(\"__proto__\"),list},getImpliedGlobals:function(){var values=_.values(impliedGlobals),hasProto=!1;return impliedGlobals.__proto__&&(hasProto=values.some(function(value){return\"__proto__\"===value.name}),hasProto||values.push(impliedGlobals.__proto__)),values},getUnuseds:function(){return unuseds},has:function(labelName){return Boolean(_getLabel(labelName))},labeltype:function(labelName){var scopeLabels=_getLabel(labelName);return scopeLabels?scopeLabels[labelName][\"(type)\"]:null},addExported:function(labelName){var globalLabels=_scopeStack[0][\"(labels)\"];if(_.has(declared,labelName))delete declared[labelName];else if(_.has(globalLabels,labelName))globalLabels[labelName][\"(unused)\"]=!1;else{for(var i=1;_scopeStack.length>i;i++){var scope=_scopeStack[i];if(scope[\"(type)\"])break;if(_.has(scope[\"(labels)\"],labelName)&&!scope[\"(labels)\"][labelName][\"(blockscoped)\"])return scope[\"(labels)\"][labelName][\"(unused)\"]=!1,void 0}exported[labelName]=!0}},setExported:function(labelName,token){this.block.use(labelName,token)\n},addlabel:function(labelName,opts){var type=opts.type,token=opts.token,isblockscoped=\"let\"===type||\"const\"===type||\"class\"===type,isexported=\"global\"===(isblockscoped?_current:_currentFunctBody)[\"(type)\"]&&_.has(exported,labelName);if(_checkOuterShadow(labelName,token,type),isblockscoped){var declaredInCurrentScope=_current[\"(labels)\"][labelName];if(declaredInCurrentScope||_current!==_currentFunctBody||\"global\"===_current[\"(type)\"]||(declaredInCurrentScope=!!_currentFunctBody[\"(parent)\"][\"(labels)\"][labelName]),!declaredInCurrentScope&&_current[\"(usages)\"][labelName]){var usage=_current[\"(usages)\"][labelName];usage[\"(onlyUsedSubFunction)\"]?_latedefWarning(type,labelName,token):warning(\"E056\",token,labelName,type)}declaredInCurrentScope?warning(\"E011\",token,labelName):\"outer\"===state.option.shadow&&scopeManagerInst.funct.has(labelName)&&warning(\"W004\",token,labelName),scopeManagerInst.block.add(labelName,type,token,!isexported)}else{var declaredInCurrentFunctionScope=scopeManagerInst.funct.has(labelName);!declaredInCurrentFunctionScope&&usedSoFarInCurrentFunction(labelName)&&_latedefWarning(type,labelName,token),scopeManagerInst.funct.has(labelName,{onlyBlockscoped:!0})?warning(\"E011\",token,labelName):state.option.shadow!==!0&&declaredInCurrentFunctionScope&&\"__proto__\"!==labelName&&\"global\"!==_currentFunctBody[\"(type)\"]&&warning(\"W004\",token,labelName),scopeManagerInst.funct.add(labelName,type,token,!isexported),\"global\"===_currentFunctBody[\"(type)\"]&&(usedPredefinedAndGlobals[labelName]=marker)}},funct:{labeltype:function(labelName,options){for(var onlyBlockscoped=options&&options.onlyBlockscoped,excludeParams=options&&options.excludeParams,currentScopeIndex=_scopeStack.length-(options&&options.excludeCurrent?2:1),i=currentScopeIndex;i>=0;i--){var current=_scopeStack[i];if(current[\"(labels)\"][labelName]&&(!onlyBlockscoped||current[\"(labels)\"][labelName][\"(blockscoped)\"]))return current[\"(labels)\"][labelName][\"(type)\"];var scopeCheck=excludeParams?_scopeStack[i-1]:current;if(scopeCheck&&\"functionparams\"===scopeCheck[\"(type)\"])return null}return null},hasBreakLabel:function(labelName){for(var i=_scopeStack.length-1;i>=0;i--){var current=_scopeStack[i];if(current[\"(breakLabels)\"][labelName])return!0;if(\"functionparams\"===current[\"(type)\"])return!1}return!1},has:function(labelName,options){return Boolean(this.labeltype(labelName,options))},add:function(labelName,type,tok,unused){_current[\"(labels)\"][labelName]={\"(type)\":type,\"(token)\":tok,\"(blockscoped)\":!1,\"(function)\":_currentFunctBody,\"(unused)\":unused}}},block:{isGlobal:function(){return\"global\"===_current[\"(type)\"]},use:function(labelName,token){var paramScope=_currentFunctBody[\"(parent)\"];paramScope&&paramScope[\"(labels)\"][labelName]&&\"param\"===paramScope[\"(labels)\"][labelName][\"(type)\"]&&(scopeManagerInst.funct.has(labelName,{excludeParams:!0,onlyBlockscoped:!0})||(paramScope[\"(labels)\"][labelName][\"(unused)\"]=!1)),token&&(state.ignored.W117||state.option.undef===!1)&&(token.ignoreUndef=!0),_setupUsages(labelName),token&&(token[\"(function)\"]=_currentFunctBody,_current[\"(usages)\"][labelName][\"(tokens)\"].push(token))},reassign:function(labelName,token){this.modify(labelName,token),_current[\"(usages)\"][labelName][\"(reassigned)\"].push(token)},modify:function(labelName,token){_setupUsages(labelName),_current[\"(usages)\"][labelName][\"(modified)\"].push(token)},add:function(labelName,type,tok,unused){_current[\"(labels)\"][labelName]={\"(type)\":type,\"(token)\":tok,\"(blockscoped)\":!0,\"(unused)\":unused}},addBreakLabel:function(labelName,opts){var token=opts.token;scopeManagerInst.funct.hasBreakLabel(labelName)?warning(\"E011\",token,labelName):\"outer\"===state.option.shadow&&(scopeManagerInst.funct.has(labelName)?warning(\"W004\",token,labelName):_checkOuterShadow(labelName,token)),_current[\"(breakLabels)\"][labelName]=token}}};return scopeManagerInst};module.exports=scopeManager},{\"../lodash\":\"/node_modules/jshint/lodash.js\",events:\"/node_modules/browserify/node_modules/events/events.js\"}],\"/node_modules/jshint/src/state.js\":[function(_dereq_,module,exports){\"use strict\";var NameStack=_dereq_(\"./name-stack.js\"),state={syntax:{},isStrict:function(){return this.directive[\"use strict\"]||this.inClassBody||this.option.module||\"implied\"===this.option.strict},inMoz:function(){return this.option.moz},inES6:function(){return this.option.moz||this.option.esversion>=6},inES5:function(strict){return strict?!(this.option.esversion&&5!==this.option.esversion||this.option.moz):!this.option.esversion||this.option.esversion>=5||this.option.moz},reset:function(){this.tokens={prev:null,next:null,curr:null},this.option={},this.funct=null,this.ignored={},this.directive={},this.jsonMode=!1,this.jsonWarnings=[],this.lines=[],this.tab=\"\",this.cache={},this.ignoredLines={},this.forinifcheckneeded=!1,this.nameStack=new NameStack,this.inClassBody=!1}};exports.state=state},{\"./name-stack.js\":\"/node_modules/jshint/src/name-stack.js\"}],\"/node_modules/jshint/src/style.js\":[function(_dereq_,module,exports){\"use strict\";exports.register=function(linter){linter.on(\"Identifier\",function(data){linter.getOption(\"proto\")||\"__proto__\"===data.name&&linter.warn(\"W103\",{line:data.line,\"char\":data.char,data:[data.name,\"6\"]})}),linter.on(\"Identifier\",function(data){linter.getOption(\"iterator\")||\"__iterator__\"===data.name&&linter.warn(\"W103\",{line:data.line,\"char\":data.char,data:[data.name]})}),linter.on(\"Identifier\",function(data){linter.getOption(\"camelcase\")&&data.name.replace(/^_+|_+$/g,\"\").indexOf(\"_\")>-1&&!data.name.match(/^[A-Z0-9_]*$/)&&linter.warn(\"W106\",{line:data.line,\"char\":data.from,data:[data.name]})}),linter.on(\"String\",function(data){var code,quotmark=linter.getOption(\"quotmark\");quotmark&&(\"single\"===quotmark&&\"'\"!==data.quote&&(code=\"W109\"),\"double\"===quotmark&&'\"'!==data.quote&&(code=\"W108\"),quotmark===!0&&(linter.getCache(\"quotmark\")||linter.setCache(\"quotmark\",data.quote),linter.getCache(\"quotmark\")!==data.quote&&(code=\"W110\")),code&&linter.warn(code,{line:data.line,\"char\":data.char}))}),linter.on(\"Number\",function(data){\".\"===data.value.charAt(0)&&linter.warn(\"W008\",{line:data.line,\"char\":data.char,data:[data.value]}),\".\"===data.value.substr(data.value.length-1)&&linter.warn(\"W047\",{line:data.line,\"char\":data.char,data:[data.value]}),/^00+/.test(data.value)&&linter.warn(\"W046\",{line:data.line,\"char\":data.char,data:[data.value]})}),linter.on(\"String\",function(data){var re=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\\s*:/i;linter.getOption(\"scripturl\")||re.test(data.value)&&linter.warn(\"W107\",{line:data.line,\"char\":data.char})})}},{}],\"/node_modules/jshint/src/vars.js\":[function(_dereq_,module,exports){\"use strict\";exports.reservedVars={arguments:!1,NaN:!1},exports.ecmaIdentifiers={3:{Array:!1,Boolean:!1,Date:!1,decodeURI:!1,decodeURIComponent:!1,encodeURI:!1,encodeURIComponent:!1,Error:!1,eval:!1,EvalError:!1,Function:!1,hasOwnProperty:!1,isFinite:!1,isNaN:!1,Math:!1,Number:!1,Object:!1,parseInt:!1,parseFloat:!1,RangeError:!1,ReferenceError:!1,RegExp:!1,String:!1,SyntaxError:!1,TypeError:!1,URIError:!1},5:{JSON:!1},6:{Map:!1,Promise:!1,Proxy:!1,Reflect:!1,Set:!1,Symbol:!1,WeakMap:!1,WeakSet:!1}},exports.browser={Audio:!1,Blob:!1,addEventListener:!1,applicationCache:!1,atob:!1,blur:!1,btoa:!1,cancelAnimationFrame:!1,CanvasGradient:!1,CanvasPattern:!1,CanvasRenderingContext2D:!1,CSS:!1,clearInterval:!1,clearTimeout:!1,close:!1,closed:!1,Comment:!1,CustomEvent:!1,DOMParser:!1,defaultStatus:!1,Document:!1,document:!1,DocumentFragment:!1,Element:!1,ElementTimeControl:!1,Event:!1,event:!1,fetch:!1,FileReader:!1,FormData:!1,focus:!1,frames:!1,getComputedStyle:!1,HTMLElement:!1,HTMLAnchorElement:!1,HTMLBaseElement:!1,HTMLBlockquoteElement:!1,HTMLBodyElement:!1,HTMLBRElement:!1,HTMLButtonElement:!1,HTMLCanvasElement:!1,HTMLCollection:!1,HTMLDirectoryElement:!1,HTMLDivElement:!1,HTMLDListElement:!1,HTMLFieldSetElement:!1,HTMLFontElement:!1,HTMLFormElement:!1,HTMLFrameElement:!1,HTMLFrameSetElement:!1,HTMLHeadElement:!1,HTMLHeadingElement:!1,HTMLHRElement:!1,HTMLHtmlElement:!1,HTMLIFrameElement:!1,HTMLImageElement:!1,HTMLInputElement:!1,HTMLIsIndexElement:!1,HTMLLabelElement:!1,HTMLLayerElement:!1,HTMLLegendElement:!1,HTMLLIElement:!1,HTMLLinkElement:!1,HTMLMapElement:!1,HTMLMenuElement:!1,HTMLMetaElement:!1,HTMLModElement:!1,HTMLObjectElement:!1,HTMLOListElement:!1,HTMLOptGroupElement:!1,HTMLOptionElement:!1,HTMLParagraphElement:!1,HTMLParamElement:!1,HTMLPreElement:!1,HTMLQuoteElement:!1,HTMLScriptElement:!1,HTMLSelectElement:!1,HTMLStyleElement:!1,HTMLTableCaptionElement:!1,HTMLTableCellElement:!1,HTMLTableColElement:!1,HTMLTableElement:!1,HTMLTableRowElement:!1,HTMLTableSectionElement:!1,HTMLTemplateElement:!1,HTMLTextAreaElement:!1,HTMLTitleElement:!1,HTMLUListElement:!1,HTMLVideoElement:!1,history:!1,Image:!1,Intl:!1,length:!1,localStorage:!1,location:!1,matchMedia:!1,MessageChannel:!1,MessageEvent:!1,MessagePort:!1,MouseEvent:!1,moveBy:!1,moveTo:!1,MutationObserver:!1,name:!1,Node:!1,NodeFilter:!1,NodeList:!1,Notification:!1,navigator:!1,onbeforeunload:!0,onblur:!0,onerror:!0,onfocus:!0,onload:!0,onresize:!0,onunload:!0,open:!1,openDatabase:!1,opener:!1,Option:!1,parent:!1,performance:!1,print:!1,Range:!1,requestAnimationFrame:!1,removeEventListener:!1,resizeBy:!1,resizeTo:!1,screen:!1,scroll:!1,scrollBy:!1,scrollTo:!1,sessionStorage:!1,setInterval:!1,setTimeout:!1,SharedWorker:!1,status:!1,SVGAElement:!1,SVGAltGlyphDefElement:!1,SVGAltGlyphElement:!1,SVGAltGlyphItemElement:!1,SVGAngle:!1,SVGAnimateColorElement:!1,SVGAnimateElement:!1,SVGAnimateMotionElement:!1,SVGAnimateTransformElement:!1,SVGAnimatedAngle:!1,SVGAnimatedBoolean:!1,SVGAnimatedEnumeration:!1,SVGAnimatedInteger:!1,SVGAnimatedLength:!1,SVGAnimatedLengthList:!1,SVGAnimatedNumber:!1,SVGAnimatedNumberList:!1,SVGAnimatedPathData:!1,SVGAnimatedPoints:!1,SVGAnimatedPreserveAspectRatio:!1,SVGAnimatedRect:!1,SVGAnimatedString:!1,SVGAnimatedTransformList:!1,SVGAnimationElement:!1,SVGCSSRule:!1,SVGCircleElement:!1,SVGClipPathElement:!1,SVGColor:!1,SVGColorProfileElement:!1,SVGColorProfileRule:!1,SVGComponentTransferFunctionElement:!1,SVGCursorElement:!1,SVGDefsElement:!1,SVGDescElement:!1,SVGDocument:!1,SVGElement:!1,SVGElementInstance:!1,SVGElementInstanceList:!1,SVGEllipseElement:!1,SVGExternalResourcesRequired:!1,SVGFEBlendElement:!1,SVGFEColorMatrixElement:!1,SVGFEComponentTransferElement:!1,SVGFECompositeElement:!1,SVGFEConvolveMatrixElement:!1,SVGFEDiffuseLightingElement:!1,SVGFEDisplacementMapElement:!1,SVGFEDistantLightElement:!1,SVGFEFloodElement:!1,SVGFEFuncAElement:!1,SVGFEFuncBElement:!1,SVGFEFuncGElement:!1,SVGFEFuncRElement:!1,SVGFEGaussianBlurElement:!1,SVGFEImageElement:!1,SVGFEMergeElement:!1,SVGFEMergeNodeElement:!1,SVGFEMorphologyElement:!1,SVGFEOffsetElement:!1,SVGFEPointLightElement:!1,SVGFESpecularLightingElement:!1,SVGFESpotLightElement:!1,SVGFETileElement:!1,SVGFETurbulenceElement:!1,SVGFilterElement:!1,SVGFilterPrimitiveStandardAttributes:!1,SVGFitToViewBox:!1,SVGFontElement:!1,SVGFontFaceElement:!1,SVGFontFaceFormatElement:!1,SVGFontFaceNameElement:!1,SVGFontFaceSrcElement:!1,SVGFontFaceUriElement:!1,SVGForeignObjectElement:!1,SVGGElement:!1,SVGGlyphElement:!1,SVGGlyphRefElement:!1,SVGGradientElement:!1,SVGHKernElement:!1,SVGICCColor:!1,SVGImageElement:!1,SVGLangSpace:!1,SVGLength:!1,SVGLengthList:!1,SVGLineElement:!1,SVGLinearGradientElement:!1,SVGLocatable:!1,SVGMPathElement:!1,SVGMarkerElement:!1,SVGMaskElement:!1,SVGMatrix:!1,SVGMetadataElement:!1,SVGMissingGlyphElement:!1,SVGNumber:!1,SVGNumberList:!1,SVGPaint:!1,SVGPathElement:!1,SVGPathSeg:!1,SVGPathSegArcAbs:!1,SVGPathSegArcRel:!1,SVGPathSegClosePath:!1,SVGPathSegCurvetoCubicAbs:!1,SVGPathSegCurvetoCubicRel:!1,SVGPathSegCurvetoCubicSmoothAbs:!1,SVGPathSegCurvetoCubicSmoothRel:!1,SVGPathSegCurvetoQuadraticAbs:!1,SVGPathSegCurvetoQuadraticRel:!1,SVGPathSegCurvetoQuadraticSmoothAbs:!1,SVGPathSegCurvetoQuadraticSmoothRel:!1,SVGPathSegLinetoAbs:!1,SVGPathSegLinetoHorizontalAbs:!1,SVGPathSegLinetoHorizontalRel:!1,SVGPathSegLinetoRel:!1,SVGPathSegLinetoVerticalAbs:!1,SVGPathSegLinetoVerticalRel:!1,SVGPathSegList:!1,SVGPathSegMovetoAbs:!1,SVGPathSegMovetoRel:!1,SVGPatternElement:!1,SVGPoint:!1,SVGPointList:!1,SVGPolygonElement:!1,SVGPolylineElement:!1,SVGPreserveAspectRatio:!1,SVGRadialGradientElement:!1,SVGRect:!1,SVGRectElement:!1,SVGRenderingIntent:!1,SVGSVGElement:!1,SVGScriptElement:!1,SVGSetElement:!1,SVGStopElement:!1,SVGStringList:!1,SVGStylable:!1,SVGStyleElement:!1,SVGSwitchElement:!1,SVGSymbolElement:!1,SVGTRefElement:!1,SVGTSpanElement:!1,SVGTests:!1,SVGTextContentElement:!1,SVGTextElement:!1,SVGTextPathElement:!1,SVGTextPositioningElement:!1,SVGTitleElement:!1,SVGTransform:!1,SVGTransformList:!1,SVGTransformable:!1,SVGURIReference:!1,SVGUnitTypes:!1,SVGUseElement:!1,SVGVKernElement:!1,SVGViewElement:!1,SVGViewSpec:!1,SVGZoomAndPan:!1,Text:!1,TextDecoder:!1,TextEncoder:!1,TimeEvent:!1,top:!1,URL:!1,WebGLActiveInfo:!1,WebGLBuffer:!1,WebGLContextEvent:!1,WebGLFramebuffer:!1,WebGLProgram:!1,WebGLRenderbuffer:!1,WebGLRenderingContext:!1,WebGLShader:!1,WebGLShaderPrecisionFormat:!1,WebGLTexture:!1,WebGLUniformLocation:!1,WebSocket:!1,window:!1,Window:!1,Worker:!1,XDomainRequest:!1,XMLHttpRequest:!1,XMLSerializer:!1,XPathEvaluator:!1,XPathException:!1,XPathExpression:!1,XPathNamespace:!1,XPathNSResolver:!1,XPathResult:!1},exports.devel={alert:!1,confirm:!1,console:!1,Debug:!1,opera:!1,prompt:!1},exports.worker={importScripts:!0,postMessage:!0,self:!0,FileReaderSync:!0},exports.nonstandard={escape:!1,unescape:!1},exports.couch={require:!1,respond:!1,getRow:!1,emit:!1,send:!1,start:!1,sum:!1,log:!1,exports:!1,module:!1,provides:!1},exports.node={__filename:!1,__dirname:!1,GLOBAL:!1,global:!1,module:!1,acequire:!1,Buffer:!0,console:!0,exports:!0,process:!0,setTimeout:!0,clearTimeout:!0,setInterval:!0,clearInterval:!0,setImmediate:!0,clearImmediate:!0},exports.browserify={__filename:!1,__dirname:!1,global:!1,module:!1,acequire:!1,Buffer:!0,exports:!0,process:!0},exports.phantom={phantom:!0,acequire:!0,WebPage:!0,console:!0,exports:!0},exports.qunit={asyncTest:!1,deepEqual:!1,equal:!1,expect:!1,module:!1,notDeepEqual:!1,notEqual:!1,notPropEqual:!1,notStrictEqual:!1,ok:!1,propEqual:!1,QUnit:!1,raises:!1,start:!1,stop:!1,strictEqual:!1,test:!1,\"throws\":!1},exports.rhino={defineClass:!1,deserialize:!1,gc:!1,help:!1,importClass:!1,importPackage:!1,java:!1,load:!1,loadClass:!1,Packages:!1,print:!1,quit:!1,readFile:!1,readUrl:!1,runCommand:!1,seal:!1,serialize:!1,spawn:!1,sync:!1,toint32:!1,version:!1},exports.shelljs={target:!1,echo:!1,exit:!1,cd:!1,pwd:!1,ls:!1,find:!1,cp:!1,rm:!1,mv:!1,mkdir:!1,test:!1,cat:!1,sed:!1,grep:!1,which:!1,dirs:!1,pushd:!1,popd:!1,env:!1,exec:!1,chmod:!1,config:!1,error:!1,tempdir:!1},exports.typed={ArrayBuffer:!1,ArrayBufferView:!1,DataView:!1,Float32Array:!1,Float64Array:!1,Int16Array:!1,Int32Array:!1,Int8Array:!1,Uint16Array:!1,Uint32Array:!1,Uint8Array:!1,Uint8ClampedArray:!1},exports.wsh={ActiveXObject:!0,Enumerator:!0,GetObject:!0,ScriptEngine:!0,ScriptEngineBuildVersion:!0,ScriptEngineMajorVersion:!0,ScriptEngineMinorVersion:!0,VBArray:!0,WSH:!0,WScript:!0,XDomainRequest:!0},exports.dojo={dojo:!1,dijit:!1,dojox:!1,define:!1,require:!1},exports.jquery={$:!1,jQuery:!1},exports.mootools={$:!1,$$:!1,Asset:!1,Browser:!1,Chain:!1,Class:!1,Color:!1,Cookie:!1,Core:!1,Document:!1,DomReady:!1,DOMEvent:!1,DOMReady:!1,Drag:!1,Element:!1,Elements:!1,Event:!1,Events:!1,Fx:!1,Group:!1,Hash:!1,HtmlTable:!1,IFrame:!1,IframeShim:!1,InputValidator:!1,instanceOf:!1,Keyboard:!1,Locale:!1,Mask:!1,MooTools:!1,Native:!1,Options:!1,OverText:!1,Request:!1,Scroller:!1,Slick:!1,Slider:!1,Sortables:!1,Spinner:!1,Swiff:!1,Tips:!1,Type:!1,typeOf:!1,URI:!1,Window:!1},exports.prototypejs={$:!1,$$:!1,$A:!1,$F:!1,$H:!1,$R:!1,$break:!1,$continue:!1,$w:!1,Abstract:!1,Ajax:!1,Class:!1,Enumerable:!1,Element:!1,Event:!1,Field:!1,Form:!1,Hash:!1,Insertion:!1,ObjectRange:!1,PeriodicalExecuter:!1,Position:!1,Prototype:!1,Selector:!1,Template:!1,Toggle:!1,Try:!1,Autocompleter:!1,Builder:!1,Control:!1,Draggable:!1,Draggables:!1,Droppables:!1,Effect:!1,Sortable:!1,SortableObserver:!1,Sound:!1,Scriptaculous:!1},exports.yui={YUI:!1,Y:!1,YUI_config:!1},exports.mocha={mocha:!1,describe:!1,xdescribe:!1,it:!1,xit:!1,context:!1,xcontext:!1,before:!1,after:!1,beforeEach:!1,afterEach:!1,suite:!1,test:!1,setup:!1,teardown:!1,suiteSetup:!1,suiteTeardown:!1},exports.jasmine={jasmine:!1,describe:!1,xdescribe:!1,it:!1,xit:!1,beforeEach:!1,afterEach:!1,setFixtures:!1,loadFixtures:!1,spyOn:!1,expect:!1,runs:!1,waitsFor:!1,waits:!1,beforeAll:!1,afterAll:!1,fail:!1,fdescribe:!1,fit:!1,pending:!1}},{}]},{},[\"/node_modules/jshint/src/jshint.js\"])}),ace.define(\"ace/mode/javascript_worker\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/worker/mirror\",\"ace/mode/javascript/jshint\"],function(acequire,exports,module){\"use strict\";function startRegex(arr){return RegExp(\"^(\"+arr.join(\"|\")+\")\")}var oop=acequire(\"../lib/oop\"),Mirror=acequire(\"../worker/mirror\").Mirror,lint=acequire(\"./javascript/jshint\").JSHINT,disabledWarningsRe=startRegex([\"Bad for in variable '(.+)'.\",'Missing \"use strict\"']),errorsRe=startRegex([\"Unexpected\",\"Expected \",\"Confusing (plus|minus)\",\"\\\\{a\\\\} unterminated regular expression\",\"Unclosed \",\"Unmatched \",\"Unbegun comment\",\"Bad invocation\",\"Missing space after\",\"Missing operator at\"]),infoRe=startRegex([\"Expected an assignment\",\"Bad escapement of EOL\",\"Unexpected comma\",\"Unexpected space\",\"Missing radix parameter.\",\"A leading decimal point can\",\"\\\\['{a}'\\\\] is better written in dot notation.\",\"'{a}' used out of scope\"]),JavaScriptWorker=exports.JavaScriptWorker=function(sender){Mirror.call(this,sender),this.setTimeout(500),this.setOptions()};oop.inherits(JavaScriptWorker,Mirror),function(){this.setOptions=function(options){this.options=options||{esnext:!0,moz:!0,devel:!0,browser:!0,node:!0,laxcomma:!0,laxbreak:!0,lastsemic:!0,onevar:!1,passfail:!1,maxerr:100,expr:!0,multistr:!0,globalstrict:!0},this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.changeOptions=function(newOptions){oop.mixin(this.options,newOptions),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.isValidJS=function(str){try{eval(\"throw 0;\"+str)}catch(e){if(0===e)return!0}return!1},this.onUpdate=function(){var value=this.doc.getValue();if(value=value.replace(/^#!.*\\n/,\"\\n\"),!value)return this.sender.emit(\"annotate\",[]);var errors=[],maxErrorLevel=this.isValidJS(value)?\"warning\":\"error\";lint(value,this.options,this.options.globals);for(var results=lint.errors,errorAdded=!1,i=0;results.length>i;i++){var error=results[i];if(error){var raw=error.raw,type=\"warning\";if(\"Missing semicolon.\"==raw){var str=error.evidence.substr(error.character);str=str.charAt(str.search(/\\S/)),\"error\"==maxErrorLevel&&str&&/[\\w\\d{(['\"]/.test(str)?(error.reason='Missing \";\" before statement',type=\"error\"):type=\"info\"}else{if(disabledWarningsRe.test(raw))continue;infoRe.test(raw)?type=\"info\":errorsRe.test(raw)?(errorAdded=!0,type=maxErrorLevel):\"'{a}' is not defined.\"==raw?type=\"warning\":\"'{a}' is defined but never used.\"==raw&&(type=\"info\")}errors.push({row:error.line-1,column:error.character-1,text:error.reason,type:type,raw:raw})}}this.sender.emit(\"annotate\",errors)}}.call(JavaScriptWorker.prototype)}),ace.define(\"ace/lib/es5-shim\",[\"require\",\"exports\",\"module\"],function(){function Empty(){}function doesDefinePropertyWork(object){try{return Object.defineProperty(object,\"sentinel\",{}),\"sentinel\"in object}catch(exception){}}function toInteger(n){return n=+n,n!==n?n=0:0!==n&&n!==1/0&&n!==-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n))),n}Function.prototype.bind||(Function.prototype.bind=function(that){var target=this;if(\"function\"!=typeof target)throw new TypeError(\"Function.prototype.bind called on incompatible \"+target);var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var result=target.apply(this,args.concat(slice.call(arguments)));return Object(result)===result?result:this}return target.apply(that,args.concat(slice.call(arguments)))};return target.prototype&&(Empty.prototype=target.prototype,bound.prototype=new Empty,Empty.prototype=null),bound});var defineGetter,defineSetter,lookupGetter,lookupSetter,supportsAccessors,call=Function.prototype.call,prototypeOfArray=Array.prototype,prototypeOfObject=Object.prototype,slice=prototypeOfArray.slice,_toString=call.bind(prototypeOfObject.toString),owns=call.bind(prototypeOfObject.hasOwnProperty);if((supportsAccessors=owns(prototypeOfObject,\"__defineGetter__\"))&&(defineGetter=call.bind(prototypeOfObject.__defineGetter__),defineSetter=call.bind(prototypeOfObject.__defineSetter__),lookupGetter=call.bind(prototypeOfObject.__lookupGetter__),lookupSetter=call.bind(prototypeOfObject.__lookupSetter__)),2!=[1,2].splice(0).length)if(function(){function makeArray(l){var a=Array(l+2);return a[0]=a[1]=0,a}var lengthBefore,array=[];return array.splice.apply(array,makeArray(20)),array.splice.apply(array,makeArray(26)),lengthBefore=array.length,array.splice(5,0,\"XXX\"),lengthBefore+1==array.length,lengthBefore+1==array.length?!0:void 0}()){var array_splice=Array.prototype.splice;Array.prototype.splice=function(start,deleteCount){return arguments.length?array_splice.apply(this,[void 0===start?0:start,void 0===deleteCount?this.length-start:deleteCount].concat(slice.call(arguments,2))):[]}}else Array.prototype.splice=function(pos,removeCount){var length=this.length;pos>0?pos>length&&(pos=length):void 0==pos?pos=0:0>pos&&(pos=Math.max(length+pos,0)),length>pos+removeCount||(removeCount=length-pos);var removed=this.slice(pos,pos+removeCount),insert=slice.call(arguments,2),add=insert.length;if(pos===length)add&&this.push.apply(this,insert);else{var remove=Math.min(removeCount,length-pos),tailOldPos=pos+remove,tailNewPos=tailOldPos+add-remove,tailCount=length-tailOldPos,lengthAfterRemove=length-remove;if(tailOldPos>tailNewPos)for(var i=0;tailCount>i;++i)this[tailNewPos+i]=this[tailOldPos+i];else if(tailNewPos>tailOldPos)for(i=tailCount;i--;)this[tailNewPos+i]=this[tailOldPos+i];if(add&&pos===lengthAfterRemove)this.length=lengthAfterRemove,this.push.apply(this,insert);else for(this.length=lengthAfterRemove+add,i=0;add>i;++i)this[pos+i]=insert[i]}return removed};Array.isArray||(Array.isArray=function(obj){return\"[object Array]\"==_toString(obj)});var boxedString=Object(\"a\"),splitString=\"a\"!=boxedString[0]||!(0 in boxedString);if(Array.prototype.forEach||(Array.prototype.forEach=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,thisp=arguments[1],i=-1,length=self.length>>>0;if(\"[object Function]\"!=_toString(fun))throw new TypeError;for(;length>++i;)i in self&&fun.call(thisp,self[i],i,object)}),Array.prototype.map||(Array.prototype.map=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0,result=Array(length),thisp=arguments[1];if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");for(var i=0;length>i;i++)i in self&&(result[i]=fun.call(thisp,self[i],i,object));return result}),Array.prototype.filter||(Array.prototype.filter=function(fun){var value,object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0,result=[],thisp=arguments[1];if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");for(var i=0;length>i;i++)i in self&&(value=self[i],fun.call(thisp,value,i,object)&&result.push(value));return result}),Array.prototype.every||(Array.prototype.every=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0,thisp=arguments[1];if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");for(var i=0;length>i;i++)if(i in self&&!fun.call(thisp,self[i],i,object))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0,thisp=arguments[1];if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");for(var i=0;length>i;i++)if(i in self&&fun.call(thisp,self[i],i,object))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0;if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");if(!length&&1==arguments.length)throw new TypeError(\"reduce of empty array with no initial value\");var result,i=0;if(arguments.length>=2)result=arguments[1];else for(;;){if(i in self){result=self[i++];break}if(++i>=length)throw new TypeError(\"reduce of empty array with no initial value\")}for(;length>i;i++)i in self&&(result=fun.call(void 0,result,self[i],i,object));return result}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0;if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");if(!length&&1==arguments.length)throw new TypeError(\"reduceRight of empty array with no initial value\");var result,i=length-1;if(arguments.length>=2)result=arguments[1];else for(;;){if(i in self){result=self[i--];break}if(0>--i)throw new TypeError(\"reduceRight of empty array with no initial value\")}do i in this&&(result=fun.call(void 0,result,self[i],i,object));while(i--);return result}),Array.prototype.indexOf&&-1==[0,1].indexOf(1,2)||(Array.prototype.indexOf=function(sought){var self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):toObject(this),length=self.length>>>0;if(!length)return-1;var i=0;for(arguments.length>1&&(i=toInteger(arguments[1])),i=i>=0?i:Math.max(0,length+i);length>i;i++)if(i in self&&self[i]===sought)return i;return-1}),Array.prototype.lastIndexOf&&-1==[0,1].lastIndexOf(0,-3)||(Array.prototype.lastIndexOf=function(sought){var self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):toObject(this),length=self.length>>>0;if(!length)return-1;var i=length-1;for(arguments.length>1&&(i=Math.min(i,toInteger(arguments[1]))),i=i>=0?i:length-Math.abs(i);i>=0;i--)if(i in self&&sought===self[i])return i;return-1}),Object.getPrototypeOf||(Object.getPrototypeOf=function(object){return object.__proto__||(object.constructor?object.constructor.prototype:prototypeOfObject)}),!Object.getOwnPropertyDescriptor){var ERR_NON_OBJECT=\"Object.getOwnPropertyDescriptor called on a non-object: \";Object.getOwnPropertyDescriptor=function(object,property){if(\"object\"!=typeof object&&\"function\"!=typeof object||null===object)throw new TypeError(ERR_NON_OBJECT+object);if(owns(object,property)){var descriptor,getter,setter;if(descriptor={enumerable:!0,configurable:!0},supportsAccessors){var prototype=object.__proto__;object.__proto__=prototypeOfObject;var getter=lookupGetter(object,property),setter=lookupSetter(object,property);if(object.__proto__=prototype,getter||setter)return getter&&(descriptor.get=getter),setter&&(descriptor.set=setter),descriptor}return descriptor.value=object[property],descriptor}}}if(Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(object){return Object.keys(object)}),!Object.create){var createEmpty;createEmpty=null===Object.prototype.__proto__?function(){return{__proto__:null}}:function(){var empty={};for(var i in empty)empty[i]=null;return empty.constructor=empty.hasOwnProperty=empty.propertyIsEnumerable=empty.isPrototypeOf=empty.toLocaleString=empty.toString=empty.valueOf=empty.__proto__=null,empty},Object.create=function(prototype,properties){var object;if(null===prototype)object=createEmpty();else{if(\"object\"!=typeof prototype)throw new TypeError(\"typeof prototype[\"+typeof prototype+\"] != 'object'\");var Type=function(){};Type.prototype=prototype,object=new Type,object.__proto__=prototype}return void 0!==properties&&Object.defineProperties(object,properties),object}}if(Object.defineProperty){var definePropertyWorksOnObject=doesDefinePropertyWork({}),definePropertyWorksOnDom=\"undefined\"==typeof document||doesDefinePropertyWork(document.createElement(\"div\"));if(!definePropertyWorksOnObject||!definePropertyWorksOnDom)var definePropertyFallback=Object.defineProperty}if(!Object.defineProperty||definePropertyFallback){var ERR_NON_OBJECT_DESCRIPTOR=\"Property description must be an object: \",ERR_NON_OBJECT_TARGET=\"Object.defineProperty called on non-object: \",ERR_ACCESSORS_NOT_SUPPORTED=\"getters & setters can not be defined on this javascript engine\";Object.defineProperty=function(object,property,descriptor){if(\"object\"!=typeof object&&\"function\"!=typeof object||null===object)throw new TypeError(ERR_NON_OBJECT_TARGET+object);if(\"object\"!=typeof descriptor&&\"function\"!=typeof descriptor||null===descriptor)throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR+descriptor);if(definePropertyFallback)try{return definePropertyFallback.call(Object,object,property,descriptor)}catch(exception){}if(owns(descriptor,\"value\"))if(supportsAccessors&&(lookupGetter(object,property)||lookupSetter(object,property))){var prototype=object.__proto__;object.__proto__=prototypeOfObject,delete object[property],object[property]=descriptor.value,object.__proto__=prototype}else object[property]=descriptor.value;else{if(!supportsAccessors)throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);owns(descriptor,\"get\")&&defineGetter(object,property,descriptor.get),owns(descriptor,\"set\")&&defineSetter(object,property,descriptor.set)}return object}}Object.defineProperties||(Object.defineProperties=function(object,properties){for(var property in properties)owns(properties,property)&&Object.defineProperty(object,property,properties[property]);return object}),Object.seal||(Object.seal=function(object){return object}),Object.freeze||(Object.freeze=function(object){return object});try{Object.freeze(function(){})}catch(exception){Object.freeze=function(freezeObject){return function(object){return\"function\"==typeof object?object:freezeObject(object)}}(Object.freeze)}if(Object.preventExtensions||(Object.preventExtensions=function(object){return object}),Object.isSealed||(Object.isSealed=function(){return!1}),Object.isFrozen||(Object.isFrozen=function(){return!1}),Object.isExtensible||(Object.isExtensible=function(object){if(Object(object)===object)throw new TypeError;for(var name=\"\";owns(object,name);)name+=\"?\";object[name]=!0;var returnValue=owns(object,name);return delete object[name],returnValue}),!Object.keys){var hasDontEnumBug=!0,dontEnums=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"],dontEnumsLength=dontEnums.length;for(var key in{toString:null})hasDontEnumBug=!1;Object.keys=function(object){if(\"object\"!=typeof object&&\"function\"!=typeof object||null===object)throw new TypeError(\"Object.keys called on a non-object\");var keys=[];for(var name in object)owns(object,name)&&keys.push(name);if(hasDontEnumBug)for(var i=0,ii=dontEnumsLength;ii>i;i++){var dontEnum=dontEnums[i];owns(object,dontEnum)&&keys.push(dontEnum)}return keys}}Date.now||(Date.now=function(){return(new Date).getTime()});var ws=\"\t\\n\u000b\\f\\r   ᠎              \\u2028\\u2029\";if(!String.prototype.trim||ws.trim()){ws=\"[\"+ws+\"]\";var trimBeginRegexp=RegExp(\"^\"+ws+ws+\"*\"),trimEndRegexp=RegExp(ws+ws+\"*$\");String.prototype.trim=function(){return(this+\"\").replace(trimBeginRegexp,\"\").replace(trimEndRegexp,\"\")}}var toObject=function(o){if(null==o)throw new TypeError(\"can't convert \"+o+\" to object\");return Object(o)}});";
-
-/***/ }),
-/* 109 */
 /*!************************************************!*\
   !*** ./node_modules/sprintf-js/src/sprintf.js ***!
   \************************************************/
@@ -68337,268 +68470,97 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/* global window, exports, define */
 }()
 
 
+/***/ }),
+/* 109 */
+/*!*************************************************!*\
+  !*** ./node_modules/brace/worker/javascript.js ***!
+  \*************************************************/
+/***/ (function(module, exports) {
+
+module.exports.id = 'ace/mode/javascript_worker';
+module.exports.src = "\"no use strict\";!function(window){function resolveModuleId(id,paths){for(var testPath=id,tail=\"\";testPath;){var alias=paths[testPath];if(\"string\"==typeof alias)return alias+tail;if(alias)return alias.location.replace(/\\/*$/,\"/\")+(tail||alias.main||alias.name);if(alias===!1)return\"\";var i=testPath.lastIndexOf(\"/\");if(-1===i)break;tail=testPath.substr(i)+tail,testPath=testPath.slice(0,i)}return id}if(!(void 0!==window.window&&window.document||window.acequire&&window.define)){window.console||(window.console=function(){var msgs=Array.prototype.slice.call(arguments,0);postMessage({type:\"log\",data:msgs})},window.console.error=window.console.warn=window.console.log=window.console.trace=window.console),window.window=window,window.ace=window,window.onerror=function(message,file,line,col,err){postMessage({type:\"error\",data:{message:message,data:err.data,file:file,line:line,col:col,stack:err.stack}})},window.normalizeModule=function(parentId,moduleName){if(-1!==moduleName.indexOf(\"!\")){var chunks=moduleName.split(\"!\");return window.normalizeModule(parentId,chunks[0])+\"!\"+window.normalizeModule(parentId,chunks[1])}if(\".\"==moduleName.charAt(0)){var base=parentId.split(\"/\").slice(0,-1).join(\"/\");for(moduleName=(base?base+\"/\":\"\")+moduleName;-1!==moduleName.indexOf(\".\")&&previous!=moduleName;){var previous=moduleName;moduleName=moduleName.replace(/^\\.\\//,\"\").replace(/\\/\\.\\//,\"/\").replace(/[^\\/]+\\/\\.\\.\\//,\"\")}}return moduleName},window.acequire=function acequire(parentId,id){if(id||(id=parentId,parentId=null),!id.charAt)throw Error(\"worker.js acequire() accepts only (parentId, id) as arguments\");id=window.normalizeModule(parentId,id);var module=window.acequire.modules[id];if(module)return module.initialized||(module.initialized=!0,module.exports=module.factory().exports),module.exports;if(!window.acequire.tlns)return console.log(\"unable to load \"+id);var path=resolveModuleId(id,window.acequire.tlns);return\".js\"!=path.slice(-3)&&(path+=\".js\"),window.acequire.id=id,window.acequire.modules[id]={},importScripts(path),window.acequire(parentId,id)},window.acequire.modules={},window.acequire.tlns={},window.define=function(id,deps,factory){if(2==arguments.length?(factory=deps,\"string\"!=typeof id&&(deps=id,id=window.acequire.id)):1==arguments.length&&(factory=id,deps=[],id=window.acequire.id),\"function\"!=typeof factory)return window.acequire.modules[id]={exports:factory,initialized:!0},void 0;deps.length||(deps=[\"require\",\"exports\",\"module\"]);var req=function(childId){return window.acequire(id,childId)};window.acequire.modules[id]={exports:{},factory:function(){var module=this,returnExports=factory.apply(this,deps.map(function(dep){switch(dep){case\"require\":return req;case\"exports\":return module.exports;case\"module\":return module;default:return req(dep)}}));return returnExports&&(module.exports=returnExports),module}}},window.define.amd={},acequire.tlns={},window.initBaseUrls=function(topLevelNamespaces){for(var i in topLevelNamespaces)acequire.tlns[i]=topLevelNamespaces[i]},window.initSender=function(){var EventEmitter=window.acequire(\"ace/lib/event_emitter\").EventEmitter,oop=window.acequire(\"ace/lib/oop\"),Sender=function(){};return function(){oop.implement(this,EventEmitter),this.callback=function(data,callbackId){postMessage({type:\"call\",id:callbackId,data:data})},this.emit=function(name,data){postMessage({type:\"event\",name:name,data:data})}}.call(Sender.prototype),new Sender};var main=window.main=null,sender=window.sender=null;window.onmessage=function(e){var msg=e.data;if(msg.event&&sender)sender._signal(msg.event,msg.data);else if(msg.command)if(main[msg.command])main[msg.command].apply(main,msg.args);else{if(!window[msg.command])throw Error(\"Unknown command:\"+msg.command);window[msg.command].apply(window,msg.args)}else if(msg.init){window.initBaseUrls(msg.tlns),acequire(\"ace/lib/es5-shim\"),sender=window.sender=window.initSender();var clazz=acequire(msg.module)[msg.classname];main=window.main=new clazz(sender)}}}}(this),ace.define(\"ace/lib/oop\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";exports.inherits=function(ctor,superCtor){ctor.super_=superCtor,ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:!1,writable:!0,configurable:!0}})},exports.mixin=function(obj,mixin){for(var key in mixin)obj[key]=mixin[key];return obj},exports.implement=function(proto,mixin){exports.mixin(proto,mixin)}}),ace.define(\"ace/range\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";var comparePoints=function(p1,p2){return p1.row-p2.row||p1.column-p2.column},Range=function(startRow,startColumn,endRow,endColumn){this.start={row:startRow,column:startColumn},this.end={row:endRow,column:endColumn}};(function(){this.isEqual=function(range){return this.start.row===range.start.row&&this.end.row===range.end.row&&this.start.column===range.start.column&&this.end.column===range.end.column},this.toString=function(){return\"Range: [\"+this.start.row+\"/\"+this.start.column+\"] -> [\"+this.end.row+\"/\"+this.end.column+\"]\"},this.contains=function(row,column){return 0==this.compare(row,column)},this.compareRange=function(range){var cmp,end=range.end,start=range.start;return cmp=this.compare(end.row,end.column),1==cmp?(cmp=this.compare(start.row,start.column),1==cmp?2:0==cmp?1:0):-1==cmp?-2:(cmp=this.compare(start.row,start.column),-1==cmp?-1:1==cmp?42:0)},this.comparePoint=function(p){return this.compare(p.row,p.column)},this.containsRange=function(range){return 0==this.comparePoint(range.start)&&0==this.comparePoint(range.end)},this.intersects=function(range){var cmp=this.compareRange(range);return-1==cmp||0==cmp||1==cmp},this.isEnd=function(row,column){return this.end.row==row&&this.end.column==column},this.isStart=function(row,column){return this.start.row==row&&this.start.column==column},this.setStart=function(row,column){\"object\"==typeof row?(this.start.column=row.column,this.start.row=row.row):(this.start.row=row,this.start.column=column)},this.setEnd=function(row,column){\"object\"==typeof row?(this.end.column=row.column,this.end.row=row.row):(this.end.row=row,this.end.column=column)},this.inside=function(row,column){return 0==this.compare(row,column)?this.isEnd(row,column)||this.isStart(row,column)?!1:!0:!1},this.insideStart=function(row,column){return 0==this.compare(row,column)?this.isEnd(row,column)?!1:!0:!1},this.insideEnd=function(row,column){return 0==this.compare(row,column)?this.isStart(row,column)?!1:!0:!1},this.compare=function(row,column){return this.isMultiLine()||row!==this.start.row?this.start.row>row?-1:row>this.end.row?1:this.start.row===row?column>=this.start.column?0:-1:this.end.row===row?this.end.column>=column?0:1:0:this.start.column>column?-1:column>this.end.column?1:0},this.compareStart=function(row,column){return this.start.row==row&&this.start.column==column?-1:this.compare(row,column)},this.compareEnd=function(row,column){return this.end.row==row&&this.end.column==column?1:this.compare(row,column)},this.compareInside=function(row,column){return this.end.row==row&&this.end.column==column?1:this.start.row==row&&this.start.column==column?-1:this.compare(row,column)},this.clipRows=function(firstRow,lastRow){if(this.end.row>lastRow)var end={row:lastRow+1,column:0};else if(firstRow>this.end.row)var end={row:firstRow,column:0};if(this.start.row>lastRow)var start={row:lastRow+1,column:0};else if(firstRow>this.start.row)var start={row:firstRow,column:0};return Range.fromPoints(start||this.start,end||this.end)},this.extend=function(row,column){var cmp=this.compare(row,column);if(0==cmp)return this;if(-1==cmp)var start={row:row,column:column};else var end={row:row,column:column};return Range.fromPoints(start||this.start,end||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return Range.fromPoints(this.start,this.end)},this.collapseRows=function(){return 0==this.end.column?new Range(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new Range(this.start.row,0,this.end.row,0)},this.toScreenRange=function(session){var screenPosStart=session.documentToScreenPosition(this.start),screenPosEnd=session.documentToScreenPosition(this.end);return new Range(screenPosStart.row,screenPosStart.column,screenPosEnd.row,screenPosEnd.column)},this.moveBy=function(row,column){this.start.row+=row,this.start.column+=column,this.end.row+=row,this.end.column+=column}}).call(Range.prototype),Range.fromPoints=function(start,end){return new Range(start.row,start.column,end.row,end.column)},Range.comparePoints=comparePoints,Range.comparePoints=function(p1,p2){return p1.row-p2.row||p1.column-p2.column},exports.Range=Range}),ace.define(\"ace/apply_delta\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";exports.applyDelta=function(docLines,delta){var row=delta.start.row,startColumn=delta.start.column,line=docLines[row]||\"\";switch(delta.action){case\"insert\":var lines=delta.lines;if(1===lines.length)docLines[row]=line.substring(0,startColumn)+delta.lines[0]+line.substring(startColumn);else{var args=[row,1].concat(delta.lines);docLines.splice.apply(docLines,args),docLines[row]=line.substring(0,startColumn)+docLines[row],docLines[row+delta.lines.length-1]+=line.substring(startColumn)}break;case\"remove\":var endColumn=delta.end.column,endRow=delta.end.row;row===endRow?docLines[row]=line.substring(0,startColumn)+line.substring(endColumn):docLines.splice(row,endRow-row+1,line.substring(0,startColumn)+docLines[endRow].substring(endColumn))}}}),ace.define(\"ace/lib/event_emitter\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";var EventEmitter={},stopPropagation=function(){this.propagationStopped=!0},preventDefault=function(){this.defaultPrevented=!0};EventEmitter._emit=EventEmitter._dispatchEvent=function(eventName,e){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var listeners=this._eventRegistry[eventName]||[],defaultHandler=this._defaultHandlers[eventName];if(listeners.length||defaultHandler){\"object\"==typeof e&&e||(e={}),e.type||(e.type=eventName),e.stopPropagation||(e.stopPropagation=stopPropagation),e.preventDefault||(e.preventDefault=preventDefault),listeners=listeners.slice();for(var i=0;listeners.length>i&&(listeners[i](e,this),!e.propagationStopped);i++);return defaultHandler&&!e.defaultPrevented?defaultHandler(e,this):void 0}},EventEmitter._signal=function(eventName,e){var listeners=(this._eventRegistry||{})[eventName];if(listeners){listeners=listeners.slice();for(var i=0;listeners.length>i;i++)listeners[i](e,this)}},EventEmitter.once=function(eventName,callback){var _self=this;callback&&this.addEventListener(eventName,function newCallback(){_self.removeEventListener(eventName,newCallback),callback.apply(null,arguments)})},EventEmitter.setDefaultHandler=function(eventName,callback){var handlers=this._defaultHandlers;if(handlers||(handlers=this._defaultHandlers={_disabled_:{}}),handlers[eventName]){var old=handlers[eventName],disabled=handlers._disabled_[eventName];disabled||(handlers._disabled_[eventName]=disabled=[]),disabled.push(old);var i=disabled.indexOf(callback);-1!=i&&disabled.splice(i,1)}handlers[eventName]=callback},EventEmitter.removeDefaultHandler=function(eventName,callback){var handlers=this._defaultHandlers;if(handlers){var disabled=handlers._disabled_[eventName];if(handlers[eventName]==callback)handlers[eventName],disabled&&this.setDefaultHandler(eventName,disabled.pop());else if(disabled){var i=disabled.indexOf(callback);-1!=i&&disabled.splice(i,1)}}},EventEmitter.on=EventEmitter.addEventListener=function(eventName,callback,capturing){this._eventRegistry=this._eventRegistry||{};var listeners=this._eventRegistry[eventName];return listeners||(listeners=this._eventRegistry[eventName]=[]),-1==listeners.indexOf(callback)&&listeners[capturing?\"unshift\":\"push\"](callback),callback},EventEmitter.off=EventEmitter.removeListener=EventEmitter.removeEventListener=function(eventName,callback){this._eventRegistry=this._eventRegistry||{};var listeners=this._eventRegistry[eventName];if(listeners){var index=listeners.indexOf(callback);-1!==index&&listeners.splice(index,1)}},EventEmitter.removeAllListeners=function(eventName){this._eventRegistry&&(this._eventRegistry[eventName]=[])},exports.EventEmitter=EventEmitter}),ace.define(\"ace/anchor\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(acequire,exports){\"use strict\";var oop=acequire(\"./lib/oop\"),EventEmitter=acequire(\"./lib/event_emitter\").EventEmitter,Anchor=exports.Anchor=function(doc,row,column){this.$onChange=this.onChange.bind(this),this.attach(doc),column===void 0?this.setPosition(row.row,row.column):this.setPosition(row,column)};(function(){function $pointsInOrder(point1,point2,equalPointsInOrder){var bColIsAfter=equalPointsInOrder?point1.column<=point2.column:point1.column<point2.column;return point1.row<point2.row||point1.row==point2.row&&bColIsAfter}function $getTransformedPoint(delta,point,moveIfEqual){var deltaIsInsert=\"insert\"==delta.action,deltaRowShift=(deltaIsInsert?1:-1)*(delta.end.row-delta.start.row),deltaColShift=(deltaIsInsert?1:-1)*(delta.end.column-delta.start.column),deltaStart=delta.start,deltaEnd=deltaIsInsert?deltaStart:delta.end;return $pointsInOrder(point,deltaStart,moveIfEqual)?{row:point.row,column:point.column}:$pointsInOrder(deltaEnd,point,!moveIfEqual)?{row:point.row+deltaRowShift,column:point.column+(point.row==deltaEnd.row?deltaColShift:0)}:{row:deltaStart.row,column:deltaStart.column}}oop.implement(this,EventEmitter),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(delta){if(!(delta.start.row==delta.end.row&&delta.start.row!=this.row||delta.start.row>this.row)){var point=$getTransformedPoint(delta,{row:this.row,column:this.column},this.$insertRight);this.setPosition(point.row,point.column,!0)}},this.setPosition=function(row,column,noClip){var pos;if(pos=noClip?{row:row,column:column}:this.$clipPositionToDocument(row,column),this.row!=pos.row||this.column!=pos.column){var old={row:this.row,column:this.column};this.row=pos.row,this.column=pos.column,this._signal(\"change\",{old:old,value:pos})}},this.detach=function(){this.document.removeEventListener(\"change\",this.$onChange)},this.attach=function(doc){this.document=doc||this.document,this.document.on(\"change\",this.$onChange)},this.$clipPositionToDocument=function(row,column){var pos={};return row>=this.document.getLength()?(pos.row=Math.max(0,this.document.getLength()-1),pos.column=this.document.getLine(pos.row).length):0>row?(pos.row=0,pos.column=0):(pos.row=row,pos.column=Math.min(this.document.getLine(pos.row).length,Math.max(0,column))),0>column&&(pos.column=0),pos}}).call(Anchor.prototype)}),ace.define(\"ace/document\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/apply_delta\",\"ace/lib/event_emitter\",\"ace/range\",\"ace/anchor\"],function(acequire,exports){\"use strict\";var oop=acequire(\"./lib/oop\"),applyDelta=acequire(\"./apply_delta\").applyDelta,EventEmitter=acequire(\"./lib/event_emitter\").EventEmitter,Range=acequire(\"./range\").Range,Anchor=acequire(\"./anchor\").Anchor,Document=function(textOrLines){this.$lines=[\"\"],0===textOrLines.length?this.$lines=[\"\"]:Array.isArray(textOrLines)?this.insertMergedLines({row:0,column:0},textOrLines):this.insert({row:0,column:0},textOrLines)};(function(){oop.implement(this,EventEmitter),this.setValue=function(text){var len=this.getLength()-1;this.remove(new Range(0,0,len,this.getLine(len).length)),this.insert({row:0,column:0},text)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(row,column){return new Anchor(this,row,column)},this.$split=0===\"aaa\".split(/a/).length?function(text){return text.replace(/\\r\\n|\\r/g,\"\\n\").split(\"\\n\")}:function(text){return text.split(/\\r\\n|\\r|\\n/)},this.$detectNewLine=function(text){var match=text.match(/^.*?(\\r\\n|\\r|\\n)/m);this.$autoNewLine=match?match[1]:\"\\n\",this._signal(\"changeNewLineMode\")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case\"windows\":return\"\\r\\n\";case\"unix\":return\"\\n\";default:return this.$autoNewLine||\"\\n\"}},this.$autoNewLine=\"\",this.$newLineMode=\"auto\",this.setNewLineMode=function(newLineMode){this.$newLineMode!==newLineMode&&(this.$newLineMode=newLineMode,this._signal(\"changeNewLineMode\"))},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(text){return\"\\r\\n\"==text||\"\\r\"==text||\"\\n\"==text},this.getLine=function(row){return this.$lines[row]||\"\"},this.getLines=function(firstRow,lastRow){return this.$lines.slice(firstRow,lastRow+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(range){return this.getLinesForRange(range).join(this.getNewLineCharacter())},this.getLinesForRange=function(range){var lines;if(range.start.row===range.end.row)lines=[this.getLine(range.start.row).substring(range.start.column,range.end.column)];else{lines=this.getLines(range.start.row,range.end.row),lines[0]=(lines[0]||\"\").substring(range.start.column);var l=lines.length-1;range.end.row-range.start.row==l&&(lines[l]=lines[l].substring(0,range.end.column))}return lines},this.insertLines=function(row,lines){return console.warn(\"Use of document.insertLines is deprecated. Use the insertFullLines method instead.\"),this.insertFullLines(row,lines)},this.removeLines=function(firstRow,lastRow){return console.warn(\"Use of document.removeLines is deprecated. Use the removeFullLines method instead.\"),this.removeFullLines(firstRow,lastRow)},this.insertNewLine=function(position){return console.warn(\"Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.\"),this.insertMergedLines(position,[\"\",\"\"])},this.insert=function(position,text){return 1>=this.getLength()&&this.$detectNewLine(text),this.insertMergedLines(position,this.$split(text))},this.insertInLine=function(position,text){var start=this.clippedPos(position.row,position.column),end=this.pos(position.row,position.column+text.length);return this.applyDelta({start:start,end:end,action:\"insert\",lines:[text]},!0),this.clonePos(end)},this.clippedPos=function(row,column){var length=this.getLength();void 0===row?row=length:0>row?row=0:row>=length&&(row=length-1,column=void 0);var line=this.getLine(row);return void 0==column&&(column=line.length),column=Math.min(Math.max(column,0),line.length),{row:row,column:column}},this.clonePos=function(pos){return{row:pos.row,column:pos.column}},this.pos=function(row,column){return{row:row,column:column}},this.$clipPosition=function(position){var length=this.getLength();return position.row>=length?(position.row=Math.max(0,length-1),position.column=this.getLine(length-1).length):(position.row=Math.max(0,position.row),position.column=Math.min(Math.max(position.column,0),this.getLine(position.row).length)),position},this.insertFullLines=function(row,lines){row=Math.min(Math.max(row,0),this.getLength());var column=0;this.getLength()>row?(lines=lines.concat([\"\"]),column=0):(lines=[\"\"].concat(lines),row--,column=this.$lines[row].length),this.insertMergedLines({row:row,column:column},lines)},this.insertMergedLines=function(position,lines){var start=this.clippedPos(position.row,position.column),end={row:start.row+lines.length-1,column:(1==lines.length?start.column:0)+lines[lines.length-1].length};return this.applyDelta({start:start,end:end,action:\"insert\",lines:lines}),this.clonePos(end)},this.remove=function(range){var start=this.clippedPos(range.start.row,range.start.column),end=this.clippedPos(range.end.row,range.end.column);return this.applyDelta({start:start,end:end,action:\"remove\",lines:this.getLinesForRange({start:start,end:end})}),this.clonePos(start)},this.removeInLine=function(row,startColumn,endColumn){var start=this.clippedPos(row,startColumn),end=this.clippedPos(row,endColumn);return this.applyDelta({start:start,end:end,action:\"remove\",lines:this.getLinesForRange({start:start,end:end})},!0),this.clonePos(start)},this.removeFullLines=function(firstRow,lastRow){firstRow=Math.min(Math.max(0,firstRow),this.getLength()-1),lastRow=Math.min(Math.max(0,lastRow),this.getLength()-1);var deleteFirstNewLine=lastRow==this.getLength()-1&&firstRow>0,deleteLastNewLine=this.getLength()-1>lastRow,startRow=deleteFirstNewLine?firstRow-1:firstRow,startCol=deleteFirstNewLine?this.getLine(startRow).length:0,endRow=deleteLastNewLine?lastRow+1:lastRow,endCol=deleteLastNewLine?0:this.getLine(endRow).length,range=new Range(startRow,startCol,endRow,endCol),deletedLines=this.$lines.slice(firstRow,lastRow+1);return this.applyDelta({start:range.start,end:range.end,action:\"remove\",lines:this.getLinesForRange(range)}),deletedLines},this.removeNewLine=function(row){this.getLength()-1>row&&row>=0&&this.applyDelta({start:this.pos(row,this.getLine(row).length),end:this.pos(row+1,0),action:\"remove\",lines:[\"\",\"\"]})},this.replace=function(range,text){if(range instanceof Range||(range=Range.fromPoints(range.start,range.end)),0===text.length&&range.isEmpty())return range.start;if(text==this.getTextRange(range))return range.end;this.remove(range);var end;return end=text?this.insert(range.start,text):range.start},this.applyDeltas=function(deltas){for(var i=0;deltas.length>i;i++)this.applyDelta(deltas[i])},this.revertDeltas=function(deltas){for(var i=deltas.length-1;i>=0;i--)this.revertDelta(deltas[i])},this.applyDelta=function(delta,doNotValidate){var isInsert=\"insert\"==delta.action;(isInsert?1>=delta.lines.length&&!delta.lines[0]:!Range.comparePoints(delta.start,delta.end))||(isInsert&&delta.lines.length>2e4&&this.$splitAndapplyLargeDelta(delta,2e4),applyDelta(this.$lines,delta,doNotValidate),this._signal(\"change\",delta))},this.$splitAndapplyLargeDelta=function(delta,MAX){for(var lines=delta.lines,l=lines.length,row=delta.start.row,column=delta.start.column,from=0,to=0;;){from=to,to+=MAX-1;var chunk=lines.slice(from,to);if(to>l){delta.lines=chunk,delta.start.row=row+from,delta.start.column=column;break}chunk.push(\"\"),this.applyDelta({start:this.pos(row+from,column),end:this.pos(row+to,column=0),action:delta.action,lines:chunk},!0)}},this.revertDelta=function(delta){this.applyDelta({start:this.clonePos(delta.start),end:this.clonePos(delta.end),action:\"insert\"==delta.action?\"remove\":\"insert\",lines:delta.lines.slice()})},this.indexToPosition=function(index,startRow){for(var lines=this.$lines||this.getAllLines(),newlineLength=this.getNewLineCharacter().length,i=startRow||0,l=lines.length;l>i;i++)if(index-=lines[i].length+newlineLength,0>index)return{row:i,column:index+lines[i].length+newlineLength};return{row:l-1,column:lines[l-1].length}},this.positionToIndex=function(pos,startRow){for(var lines=this.$lines||this.getAllLines(),newlineLength=this.getNewLineCharacter().length,index=0,row=Math.min(pos.row,lines.length),i=startRow||0;row>i;++i)index+=lines[i].length+newlineLength;return index+pos.column}}).call(Document.prototype),exports.Document=Document}),ace.define(\"ace/lib/lang\",[\"require\",\"exports\",\"module\"],function(acequire,exports){\"use strict\";exports.last=function(a){return a[a.length-1]},exports.stringReverse=function(string){return string.split(\"\").reverse().join(\"\")},exports.stringRepeat=function(string,count){for(var result=\"\";count>0;)1&count&&(result+=string),(count>>=1)&&(string+=string);return result};var trimBeginRegexp=/^\\s\\s*/,trimEndRegexp=/\\s\\s*$/;exports.stringTrimLeft=function(string){return string.replace(trimBeginRegexp,\"\")},exports.stringTrimRight=function(string){return string.replace(trimEndRegexp,\"\")},exports.copyObject=function(obj){var copy={};for(var key in obj)copy[key]=obj[key];return copy},exports.copyArray=function(array){for(var copy=[],i=0,l=array.length;l>i;i++)copy[i]=array[i]&&\"object\"==typeof array[i]?this.copyObject(array[i]):array[i];return copy},exports.deepCopy=function deepCopy(obj){if(\"object\"!=typeof obj||!obj)return obj;var copy;if(Array.isArray(obj)){copy=[];for(var key=0;obj.length>key;key++)copy[key]=deepCopy(obj[key]);return copy}if(\"[object Object]\"!==Object.prototype.toString.call(obj))return obj;copy={};for(var key in obj)copy[key]=deepCopy(obj[key]);return copy},exports.arrayToMap=function(arr){for(var map={},i=0;arr.length>i;i++)map[arr[i]]=1;return map},exports.createMap=function(props){var map=Object.create(null);for(var i in props)map[i]=props[i];return map},exports.arrayRemove=function(array,value){for(var i=0;array.length>=i;i++)value===array[i]&&array.splice(i,1)},exports.escapeRegExp=function(str){return str.replace(/([.*+?^${}()|[\\]\\/\\\\])/g,\"\\\\$1\")},exports.escapeHTML=function(str){return str.replace(/&/g,\"&#38;\").replace(/\"/g,\"&#34;\").replace(/'/g,\"&#39;\").replace(/</g,\"&#60;\")},exports.getMatchOffsets=function(string,regExp){var matches=[];return string.replace(regExp,function(str){matches.push({offset:arguments[arguments.length-2],length:str.length})}),matches},exports.deferredCall=function(fcn){var timer=null,callback=function(){timer=null,fcn()},deferred=function(timeout){return deferred.cancel(),timer=setTimeout(callback,timeout||0),deferred};return deferred.schedule=deferred,deferred.call=function(){return this.cancel(),fcn(),deferred},deferred.cancel=function(){return clearTimeout(timer),timer=null,deferred},deferred.isPending=function(){return timer},deferred},exports.delayedCall=function(fcn,defaultTimeout){var timer=null,callback=function(){timer=null,fcn()},_self=function(timeout){null==timer&&(timer=setTimeout(callback,timeout||defaultTimeout))};return _self.delay=function(timeout){timer&&clearTimeout(timer),timer=setTimeout(callback,timeout||defaultTimeout)},_self.schedule=_self,_self.call=function(){this.cancel(),fcn()},_self.cancel=function(){timer&&clearTimeout(timer),timer=null},_self.isPending=function(){return timer},_self}}),ace.define(\"ace/worker/mirror\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/document\",\"ace/lib/lang\"],function(acequire,exports){\"use strict\";acequire(\"../range\").Range;var Document=acequire(\"../document\").Document,lang=acequire(\"../lib/lang\"),Mirror=exports.Mirror=function(sender){this.sender=sender;var doc=this.doc=new Document(\"\"),deferredUpdate=this.deferredUpdate=lang.delayedCall(this.onUpdate.bind(this)),_self=this;sender.on(\"change\",function(e){var data=e.data;if(data[0].start)doc.applyDeltas(data);else for(var i=0;data.length>i;i+=2){if(Array.isArray(data[i+1]))var d={action:\"insert\",start:data[i],lines:data[i+1]};else var d={action:\"remove\",start:data[i],end:data[i+1]};doc.applyDelta(d,!0)}return _self.$timeout?deferredUpdate.schedule(_self.$timeout):(_self.onUpdate(),void 0)})};(function(){this.$timeout=500,this.setTimeout=function(timeout){this.$timeout=timeout},this.setValue=function(value){this.doc.setValue(value),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(callbackId){this.sender.callback(this.doc.getValue(),callbackId)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(Mirror.prototype)}),ace.define(\"ace/mode/javascript/jshint\",[\"require\",\"exports\",\"module\"],function(acequire,exports,module){module.exports=function outer(modules,cache,entry){function newRequire(name,jumped){if(!cache[name]){if(!modules[name]){var currentRequire=\"function\"==typeof acequire&&acequire;if(!jumped&&currentRequire)return currentRequire(name,!0);if(previousRequire)return previousRequire(name,!0);var err=Error(\"Cannot find module '\"+name+\"'\");throw err.code=\"MODULE_NOT_FOUND\",err}var m=cache[name]={exports:{}};modules[name][0].call(m.exports,function(x){var id=modules[name][1][x];return newRequire(id?id:x)},m,m.exports,outer,modules,cache,entry)}return cache[name].exports}for(var previousRequire=\"function\"==typeof acequire&&acequire,i=0;entry.length>i;i++)newRequire(entry[i]);return newRequire(entry[0])}({\"/node_modules/browserify/node_modules/events/events.js\":[function(_dereq_,module){function EventEmitter(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function isFunction(arg){return\"function\"==typeof arg}function isNumber(arg){return\"number\"==typeof arg}function isObject(arg){return\"object\"==typeof arg&&null!==arg}function isUndefined(arg){return void 0===arg}module.exports=EventEmitter,EventEmitter.EventEmitter=EventEmitter,EventEmitter.prototype._events=void 0,EventEmitter.prototype._maxListeners=void 0,EventEmitter.defaultMaxListeners=10,EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||0>n||isNaN(n))throw TypeError(\"n must be a positive number\");return this._maxListeners=n,this},EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(this._events||(this._events={}),\"error\"===type&&(!this._events.error||isObject(this._events.error)&&!this._events.error.length)){if(er=arguments[1],er instanceof Error)throw er;throw TypeError('Uncaught, unspecified \"error\" event.')}if(handler=this._events[type],isUndefined(handler))return!1;if(isFunction(handler))switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:for(len=arguments.length,args=Array(len-1),i=1;len>i;i++)args[i-1]=arguments[i];handler.apply(this,args)}else if(isObject(handler)){for(len=arguments.length,args=Array(len-1),i=1;len>i;i++)args[i-1]=arguments[i];for(listeners=handler.slice(),len=listeners.length,i=0;len>i;i++)listeners[i].apply(this,args)}return!0},EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError(\"listener must be a function\");if(this._events||(this._events={}),this._events.newListener&&this.emit(\"newListener\",type,isFunction(listener.listener)?listener.listener:listener),this._events[type]?isObject(this._events[type])?this._events[type].push(listener):this._events[type]=[this._events[type],listener]:this._events[type]=listener,isObject(this._events[type])&&!this._events[type].warned){var m;m=isUndefined(this._maxListeners)?EventEmitter.defaultMaxListeners:this._maxListeners,m&&m>0&&this._events[type].length>m&&(this._events[type].warned=!0,console.error(\"(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.\",this._events[type].length),\"function\"==typeof console.trace&&console.trace())}return this},EventEmitter.prototype.on=EventEmitter.prototype.addListener,EventEmitter.prototype.once=function(type,listener){function g(){this.removeListener(type,g),fired||(fired=!0,listener.apply(this,arguments))}if(!isFunction(listener))throw TypeError(\"listener must be a function\");var fired=!1;return g.listener=listener,this.on(type,g),this},EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError(\"listener must be a function\");if(!this._events||!this._events[type])return this;if(list=this._events[type],length=list.length,position=-1,list===listener||isFunction(list.listener)&&list.listener===listener)delete this._events[type],this._events.removeListener&&this.emit(\"removeListener\",type,listener);else if(isObject(list)){for(i=length;i-->0;)if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}if(0>position)return this;1===list.length?(list.length=0,delete this._events[type]):list.splice(position,1),this._events.removeListener&&this.emit(\"removeListener\",type,listener)}return this},EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[type]&&delete this._events[type],this;if(0===arguments.length){for(key in this._events)\"removeListener\"!==key&&this.removeAllListeners(key);return this.removeAllListeners(\"removeListener\"),this._events={},this\n}if(listeners=this._events[type],isFunction(listeners))this.removeListener(type,listeners);else for(;listeners.length;)this.removeListener(type,listeners[listeners.length-1]);return delete this._events[type],this},EventEmitter.prototype.listeners=function(type){var ret;return ret=this._events&&this._events[type]?isFunction(this._events[type])?[this._events[type]]:this._events[type].slice():[]},EventEmitter.listenerCount=function(emitter,type){var ret;return ret=emitter._events&&emitter._events[type]?isFunction(emitter._events[type])?1:emitter._events[type].length:0}},{}],\"/node_modules/jshint/data/ascii-identifier-data.js\":[function(_dereq_,module){for(var identifierStartTable=[],i=0;128>i;i++)identifierStartTable[i]=36===i||i>=65&&90>=i||95===i||i>=97&&122>=i;for(var identifierPartTable=[],i=0;128>i;i++)identifierPartTable[i]=identifierStartTable[i]||i>=48&&57>=i;module.exports={asciiIdentifierStartTable:identifierStartTable,asciiIdentifierPartTable:identifierPartTable}},{}],\"/node_modules/jshint/lodash.js\":[function(_dereq_,module,exports){(function(global){(function(){function baseFindIndex(array,predicate,fromRight){for(var length=array.length,index=fromRight?length:-1;fromRight?index--:length>++index;)if(predicate(array[index],index,array))return index;return-1}function baseIndexOf(array,value,fromIndex){if(value!==value)return indexOfNaN(array,fromIndex);for(var index=fromIndex-1,length=array.length;length>++index;)if(array[index]===value)return index;return-1}function baseIsFunction(value){return\"function\"==typeof value||!1}function baseToString(value){return\"string\"==typeof value?value:null==value?\"\":value+\"\"}function indexOfNaN(array,fromIndex,fromRight){for(var length=array.length,index=fromIndex+(fromRight?0:-1);fromRight?index--:length>++index;){var other=array[index];if(other!==other)return index}return-1}function isObjectLike(value){return!!value&&\"object\"==typeof value}function lodash(){}function arrayCopy(source,array){var index=-1,length=source.length;for(array||(array=Array(length));length>++index;)array[index]=source[index];return array}function arrayEach(array,iteratee){for(var index=-1,length=array.length;length>++index&&iteratee(array[index],index,array)!==!1;);return array}function arrayFilter(array,predicate){for(var index=-1,length=array.length,resIndex=-1,result=[];length>++index;){var value=array[index];predicate(value,index,array)&&(result[++resIndex]=value)}return result}function arrayMap(array,iteratee){for(var index=-1,length=array.length,result=Array(length);length>++index;)result[index]=iteratee(array[index],index,array);return result}function arrayMax(array){for(var index=-1,length=array.length,result=NEGATIVE_INFINITY;length>++index;){var value=array[index];value>result&&(result=value)}return result}function arraySome(array,predicate){for(var index=-1,length=array.length;length>++index;)if(predicate(array[index],index,array))return!0;return!1}function assignWith(object,source,customizer){var props=keys(source);push.apply(props,getSymbols(source));for(var index=-1,length=props.length;length>++index;){var key=props[index],value=object[key],result=customizer(value,source[key],key,object,source);(result===result?result===value:value!==value)&&(value!==undefined||key in object)||(object[key]=result)}return object}function baseCopy(source,props,object){object||(object={});for(var index=-1,length=props.length;length>++index;){var key=props[index];object[key]=source[key]}return object}function baseCallback(func,thisArg,argCount){var type=typeof func;return\"function\"==type?thisArg===undefined?func:bindCallback(func,thisArg,argCount):null==func?identity:\"object\"==type?baseMatches(func):thisArg===undefined?property(func):baseMatchesProperty(func,thisArg)}function baseClone(value,isDeep,customizer,key,object,stackA,stackB){var result;if(customizer&&(result=object?customizer(value,key,object):customizer(value)),result!==undefined)return result;if(!isObject(value))return value;var isArr=isArray(value);if(isArr){if(result=initCloneArray(value),!isDeep)return arrayCopy(value,result)}else{var tag=objToString.call(value),isFunc=tag==funcTag;if(tag!=objectTag&&tag!=argsTag&&(!isFunc||object))return cloneableTags[tag]?initCloneByTag(value,tag,isDeep):object?value:{};if(result=initCloneObject(isFunc?{}:value),!isDeep)return baseAssign(result,value)}stackA||(stackA=[]),stackB||(stackB=[]);for(var length=stackA.length;length--;)if(stackA[length]==value)return stackB[length];return stackA.push(value),stackB.push(result),(isArr?arrayEach:baseForOwn)(value,function(subValue,key){result[key]=baseClone(subValue,isDeep,customizer,key,value,stackA,stackB)}),result}function baseFilter(collection,predicate){var result=[];return baseEach(collection,function(value,index,collection){predicate(value,index,collection)&&result.push(value)}),result}function baseForIn(object,iteratee){return baseFor(object,iteratee,keysIn)}function baseForOwn(object,iteratee){return baseFor(object,iteratee,keys)}function baseGet(object,path,pathKey){if(null!=object){pathKey!==undefined&&pathKey in toObject(object)&&(path=[pathKey]);for(var index=-1,length=path.length;null!=object&&length>++index;)var result=object=object[path[index]];return result}}function baseIsEqual(value,other,customizer,isLoose,stackA,stackB){if(value===other)return 0!==value||1/value==1/other;var valType=typeof value,othType=typeof other;return\"function\"!=valType&&\"object\"!=valType&&\"function\"!=othType&&\"object\"!=othType||null==value||null==other?value!==value&&other!==other:baseIsEqualDeep(value,other,baseIsEqual,customizer,isLoose,stackA,stackB)}function baseIsEqualDeep(object,other,equalFunc,customizer,isLoose,stackA,stackB){var objIsArr=isArray(object),othIsArr=isArray(other),objTag=arrayTag,othTag=arrayTag;objIsArr||(objTag=objToString.call(object),objTag==argsTag?objTag=objectTag:objTag!=objectTag&&(objIsArr=isTypedArray(object))),othIsArr||(othTag=objToString.call(other),othTag==argsTag?othTag=objectTag:othTag!=objectTag&&(othIsArr=isTypedArray(other)));var objIsObj=objTag==objectTag,othIsObj=othTag==objectTag,isSameTag=objTag==othTag;if(isSameTag&&!objIsArr&&!objIsObj)return equalByTag(object,other,objTag);if(!isLoose){var valWrapped=objIsObj&&hasOwnProperty.call(object,\"__wrapped__\"),othWrapped=othIsObj&&hasOwnProperty.call(other,\"__wrapped__\");if(valWrapped||othWrapped)return equalFunc(valWrapped?object.value():object,othWrapped?other.value():other,customizer,isLoose,stackA,stackB)}if(!isSameTag)return!1;stackA||(stackA=[]),stackB||(stackB=[]);for(var length=stackA.length;length--;)if(stackA[length]==object)return stackB[length]==other;stackA.push(object),stackB.push(other);var result=(objIsArr?equalArrays:equalObjects)(object,other,equalFunc,customizer,isLoose,stackA,stackB);return stackA.pop(),stackB.pop(),result}function baseIsMatch(object,props,values,strictCompareFlags,customizer){for(var index=-1,length=props.length,noCustomizer=!customizer;length>++index;)if(noCustomizer&&strictCompareFlags[index]?values[index]!==object[props[index]]:!(props[index]in object))return!1;for(index=-1;length>++index;){var key=props[index],objValue=object[key],srcValue=values[index];if(noCustomizer&&strictCompareFlags[index])var result=objValue!==undefined||key in object;else result=customizer?customizer(objValue,srcValue,key):undefined,result===undefined&&(result=baseIsEqual(srcValue,objValue,customizer,!0));if(!result)return!1}return!0}function baseMatches(source){var props=keys(source),length=props.length;if(!length)return constant(!0);if(1==length){var key=props[0],value=source[key];if(isStrictComparable(value))return function(object){return null==object?!1:object[key]===value&&(value!==undefined||key in toObject(object))}}for(var values=Array(length),strictCompareFlags=Array(length);length--;)value=source[props[length]],values[length]=value,strictCompareFlags[length]=isStrictComparable(value);return function(object){return null!=object&&baseIsMatch(toObject(object),props,values,strictCompareFlags)}}function baseMatchesProperty(path,value){var isArr=isArray(path),isCommon=isKey(path)&&isStrictComparable(value),pathKey=path+\"\";return path=toPath(path),function(object){if(null==object)return!1;var key=pathKey;if(object=toObject(object),!(!isArr&&isCommon||key in object)){if(object=1==path.length?object:baseGet(object,baseSlice(path,0,-1)),null==object)return!1;key=last(path),object=toObject(object)}return object[key]===value?value!==undefined||key in object:baseIsEqual(value,object[key],null,!0)}}function baseMerge(object,source,customizer,stackA,stackB){if(!isObject(object))return object;var isSrcArr=isLength(source.length)&&(isArray(source)||isTypedArray(source));if(!isSrcArr){var props=keys(source);push.apply(props,getSymbols(source))}return arrayEach(props||source,function(srcValue,key){if(props&&(key=srcValue,srcValue=source[key]),isObjectLike(srcValue))stackA||(stackA=[]),stackB||(stackB=[]),baseMergeDeep(object,source,key,baseMerge,customizer,stackA,stackB);else{var value=object[key],result=customizer?customizer(value,srcValue,key,object,source):undefined,isCommon=result===undefined;isCommon&&(result=srcValue),!isSrcArr&&result===undefined||!isCommon&&(result===result?result===value:value!==value)||(object[key]=result)}}),object}function baseMergeDeep(object,source,key,mergeFunc,customizer,stackA,stackB){for(var length=stackA.length,srcValue=source[key];length--;)if(stackA[length]==srcValue)return object[key]=stackB[length],undefined;var value=object[key],result=customizer?customizer(value,srcValue,key,object,source):undefined,isCommon=result===undefined;isCommon&&(result=srcValue,isLength(srcValue.length)&&(isArray(srcValue)||isTypedArray(srcValue))?result=isArray(value)?value:getLength(value)?arrayCopy(value):[]:isPlainObject(srcValue)||isArguments(srcValue)?result=isArguments(value)?toPlainObject(value):isPlainObject(value)?value:{}:isCommon=!1),stackA.push(srcValue),stackB.push(result),isCommon?object[key]=mergeFunc(result,srcValue,customizer,stackA,stackB):(result===result?result!==value:value===value)&&(object[key]=result)}function baseProperty(key){return function(object){return null==object?undefined:object[key]}}function basePropertyDeep(path){var pathKey=path+\"\";return path=toPath(path),function(object){return baseGet(object,path,pathKey)}}function baseSlice(array,start,end){var index=-1,length=array.length;start=null==start?0:+start||0,0>start&&(start=-start>length?0:length+start),end=end===undefined||end>length?length:+end||0,0>end&&(end+=length),length=start>end?0:end-start>>>0,start>>>=0;for(var result=Array(length);length>++index;)result[index]=array[index+start];return result}function baseSome(collection,predicate){var result;return baseEach(collection,function(value,index,collection){return result=predicate(value,index,collection),!result}),!!result}function baseValues(object,props){for(var index=-1,length=props.length,result=Array(length);length>++index;)result[index]=object[props[index]];return result}function binaryIndex(array,value,retHighest){var low=0,high=array?array.length:low;if(\"number\"==typeof value&&value===value&&HALF_MAX_ARRAY_LENGTH>=high){for(;high>low;){var mid=low+high>>>1,computed=array[mid];(retHighest?value>=computed:value>computed)?low=mid+1:high=mid}return high}return binaryIndexBy(array,value,identity,retHighest)}function binaryIndexBy(array,value,iteratee,retHighest){value=iteratee(value);for(var low=0,high=array?array.length:0,valIsNaN=value!==value,valIsUndef=value===undefined;high>low;){var mid=floor((low+high)/2),computed=iteratee(array[mid]),isReflexive=computed===computed;if(valIsNaN)var setLow=isReflexive||retHighest;else setLow=valIsUndef?isReflexive&&(retHighest||computed!==undefined):retHighest?value>=computed:value>computed;setLow?low=mid+1:high=mid}return nativeMin(high,MAX_ARRAY_INDEX)}function bindCallback(func,thisArg,argCount){if(\"function\"!=typeof func)return identity;if(thisArg===undefined)return func;switch(argCount){case 1:return function(value){return func.call(thisArg,value)};case 3:return function(value,index,collection){return func.call(thisArg,value,index,collection)};case 4:return function(accumulator,value,index,collection){return func.call(thisArg,accumulator,value,index,collection)};case 5:return function(value,other,key,object,source){return func.call(thisArg,value,other,key,object,source)}}return function(){return func.apply(thisArg,arguments)}}function bufferClone(buffer){return bufferSlice.call(buffer,0)}function createAssigner(assigner){return restParam(function(object,sources){var index=-1,length=null==object?0:sources.length,customizer=length>2&&sources[length-2],guard=length>2&&sources[2],thisArg=length>1&&sources[length-1];for(\"function\"==typeof customizer?(customizer=bindCallback(customizer,thisArg,5),length-=2):(customizer=\"function\"==typeof thisArg?thisArg:null,length-=customizer?1:0),guard&&isIterateeCall(sources[0],sources[1],guard)&&(customizer=3>length?null:customizer,length=1);length>++index;){var source=sources[index];source&&assigner(object,source,customizer)}return object})}function createBaseEach(eachFunc,fromRight){return function(collection,iteratee){var length=collection?getLength(collection):0;if(!isLength(length))return eachFunc(collection,iteratee);for(var index=fromRight?length:-1,iterable=toObject(collection);(fromRight?index--:length>++index)&&iteratee(iterable[index],index,iterable)!==!1;);return collection}}function createBaseFor(fromRight){return function(object,iteratee,keysFunc){for(var iterable=toObject(object),props=keysFunc(object),length=props.length,index=fromRight?length:-1;fromRight?index--:length>++index;){var key=props[index];if(iteratee(iterable[key],key,iterable)===!1)break}return object}}function createFindIndex(fromRight){return function(array,predicate,thisArg){return array&&array.length?(predicate=getCallback(predicate,thisArg,3),baseFindIndex(array,predicate,fromRight)):-1}}function createForEach(arrayFunc,eachFunc){return function(collection,iteratee,thisArg){return\"function\"==typeof iteratee&&thisArg===undefined&&isArray(collection)?arrayFunc(collection,iteratee):eachFunc(collection,bindCallback(iteratee,thisArg,3))}}function equalArrays(array,other,equalFunc,customizer,isLoose,stackA,stackB){var index=-1,arrLength=array.length,othLength=other.length,result=!0;if(arrLength!=othLength&&!(isLoose&&othLength>arrLength))return!1;for(;result&&arrLength>++index;){var arrValue=array[index],othValue=other[index];if(result=undefined,customizer&&(result=isLoose?customizer(othValue,arrValue,index):customizer(arrValue,othValue,index)),result===undefined)if(isLoose)for(var othIndex=othLength;othIndex--&&(othValue=other[othIndex],!(result=arrValue&&arrValue===othValue||equalFunc(arrValue,othValue,customizer,isLoose,stackA,stackB))););else result=arrValue&&arrValue===othValue||equalFunc(arrValue,othValue,customizer,isLoose,stackA,stackB)}return!!result}function equalByTag(object,other,tag){switch(tag){case boolTag:case dateTag:return+object==+other;case errorTag:return object.name==other.name&&object.message==other.message;case numberTag:return object!=+object?other!=+other:0==object?1/object==1/other:object==+other;case regexpTag:case stringTag:return object==other+\"\"}return!1}function equalObjects(object,other,equalFunc,customizer,isLoose,stackA,stackB){var objProps=keys(object),objLength=objProps.length,othProps=keys(other),othLength=othProps.length;if(objLength!=othLength&&!isLoose)return!1;for(var skipCtor=isLoose,index=-1;objLength>++index;){var key=objProps[index],result=isLoose?key in other:hasOwnProperty.call(other,key);if(result){var objValue=object[key],othValue=other[key];result=undefined,customizer&&(result=isLoose?customizer(othValue,objValue,key):customizer(objValue,othValue,key)),result===undefined&&(result=objValue&&objValue===othValue||equalFunc(objValue,othValue,customizer,isLoose,stackA,stackB))}if(!result)return!1;skipCtor||(skipCtor=\"constructor\"==key)}if(!skipCtor){var objCtor=object.constructor,othCtor=other.constructor;if(objCtor!=othCtor&&\"constructor\"in object&&\"constructor\"in other&&!(\"function\"==typeof objCtor&&objCtor instanceof objCtor&&\"function\"==typeof othCtor&&othCtor instanceof othCtor))return!1}return!0}function getCallback(func,thisArg,argCount){var result=lodash.callback||callback;return result=result===callback?baseCallback:result,argCount?result(func,thisArg,argCount):result}function getIndexOf(collection,target,fromIndex){var result=lodash.indexOf||indexOf;return result=result===indexOf?baseIndexOf:result,collection?result(collection,target,fromIndex):result}function initCloneArray(array){var length=array.length,result=new array.constructor(length);return length&&\"string\"==typeof array[0]&&hasOwnProperty.call(array,\"index\")&&(result.index=array.index,result.input=array.input),result}function initCloneObject(object){var Ctor=object.constructor;return\"function\"==typeof Ctor&&Ctor instanceof Ctor||(Ctor=Object),new Ctor}function initCloneByTag(object,tag,isDeep){var Ctor=object.constructor;switch(tag){case arrayBufferTag:return bufferClone(object);case boolTag:case dateTag:return new Ctor(+object);case float32Tag:case float64Tag:case int8Tag:case int16Tag:case int32Tag:case uint8Tag:case uint8ClampedTag:case uint16Tag:case uint32Tag:var buffer=object.buffer;return new Ctor(isDeep?bufferClone(buffer):buffer,object.byteOffset,object.length);case numberTag:case stringTag:return new Ctor(object);case regexpTag:var result=new Ctor(object.source,reFlags.exec(object));result.lastIndex=object.lastIndex}return result}function isIndex(value,length){return value=+value,length=null==length?MAX_SAFE_INTEGER:length,value>-1&&0==value%1&&length>value}function isIterateeCall(value,index,object){if(!isObject(object))return!1;var type=typeof index;if(\"number\"==type)var length=getLength(object),prereq=isLength(length)&&isIndex(index,length);else prereq=\"string\"==type&&index in object;if(prereq){var other=object[index];return value===value?value===other:other!==other}return!1}function isKey(value,object){var type=typeof value;if(\"string\"==type&&reIsPlainProp.test(value)||\"number\"==type)return!0;if(isArray(value))return!1;var result=!reIsDeepProp.test(value);return result||null!=object&&value in toObject(object)}function isLength(value){return\"number\"==typeof value&&value>-1&&0==value%1&&MAX_SAFE_INTEGER>=value}function isStrictComparable(value){return value===value&&(0===value?1/value>0:!isObject(value))}function shimIsPlainObject(value){var Ctor;if(lodash.support,!isObjectLike(value)||objToString.call(value)!=objectTag||!hasOwnProperty.call(value,\"constructor\")&&(Ctor=value.constructor,\"function\"==typeof Ctor&&!(Ctor instanceof Ctor)))return!1;var result;return baseForIn(value,function(subValue,key){result=key}),result===undefined||hasOwnProperty.call(value,result)}function shimKeys(object){for(var props=keysIn(object),propsLength=props.length,length=propsLength&&object.length,support=lodash.support,allowIndexes=length&&isLength(length)&&(isArray(object)||support.nonEnumArgs&&isArguments(object)),index=-1,result=[];propsLength>++index;){var key=props[index];(allowIndexes&&isIndex(key,length)||hasOwnProperty.call(object,key))&&result.push(key)}return result}function toObject(value){return isObject(value)?value:Object(value)}function toPath(value){if(isArray(value))return value;var result=[];return baseToString(value).replace(rePropName,function(match,number,quote,string){result.push(quote?string.replace(reEscapeChar,\"$1\"):number||match)}),result}function indexOf(array,value,fromIndex){var length=array?array.length:0;if(!length)return-1;if(\"number\"==typeof fromIndex)fromIndex=0>fromIndex?nativeMax(length+fromIndex,0):fromIndex;else if(fromIndex){var index=binaryIndex(array,value),other=array[index];return(value===value?value===other:other!==other)?index:-1}return baseIndexOf(array,value,fromIndex||0)}function last(array){var length=array?array.length:0;return length?array[length-1]:undefined}function slice(array,start,end){var length=array?array.length:0;return length?(end&&\"number\"!=typeof end&&isIterateeCall(array,start,end)&&(start=0,end=length),baseSlice(array,start,end)):[]}function unzip(array){for(var index=-1,length=(array&&array.length&&arrayMax(arrayMap(array,getLength)))>>>0,result=Array(length);length>++index;)result[index]=arrayMap(array,baseProperty(index));return result}function includes(collection,target,fromIndex,guard){var length=collection?getLength(collection):0;return isLength(length)||(collection=values(collection),length=collection.length),length?(fromIndex=\"number\"!=typeof fromIndex||guard&&isIterateeCall(target,fromIndex,guard)?0:0>fromIndex?nativeMax(length+fromIndex,0):fromIndex||0,\"string\"==typeof collection||!isArray(collection)&&isString(collection)?length>fromIndex&&collection.indexOf(target,fromIndex)>-1:getIndexOf(collection,target,fromIndex)>-1):!1}function reject(collection,predicate,thisArg){var func=isArray(collection)?arrayFilter:baseFilter;return predicate=getCallback(predicate,thisArg,3),func(collection,function(value,index,collection){return!predicate(value,index,collection)})}function some(collection,predicate,thisArg){var func=isArray(collection)?arraySome:baseSome;return thisArg&&isIterateeCall(collection,predicate,thisArg)&&(predicate=null),(\"function\"!=typeof predicate||thisArg!==undefined)&&(predicate=getCallback(predicate,thisArg,3)),func(collection,predicate)}function restParam(func,start){if(\"function\"!=typeof func)throw new TypeError(FUNC_ERROR_TEXT);return start=nativeMax(start===undefined?func.length-1:+start||0,0),function(){for(var args=arguments,index=-1,length=nativeMax(args.length-start,0),rest=Array(length);length>++index;)rest[index]=args[start+index];switch(start){case 0:return func.call(this,rest);case 1:return func.call(this,args[0],rest);case 2:return func.call(this,args[0],args[1],rest)}var otherArgs=Array(start+1);for(index=-1;start>++index;)otherArgs[index]=args[index];return otherArgs[start]=rest,func.apply(this,otherArgs)}}function clone(value,isDeep,customizer,thisArg){return isDeep&&\"boolean\"!=typeof isDeep&&isIterateeCall(value,isDeep,customizer)?isDeep=!1:\"function\"==typeof isDeep&&(thisArg=customizer,customizer=isDeep,isDeep=!1),customizer=\"function\"==typeof customizer&&bindCallback(customizer,thisArg,1),baseClone(value,isDeep,customizer)}function isArguments(value){var length=isObjectLike(value)?value.length:undefined;return isLength(length)&&objToString.call(value)==argsTag}function isEmpty(value){if(null==value)return!0;var length=getLength(value);return isLength(length)&&(isArray(value)||isString(value)||isArguments(value)||isObjectLike(value)&&isFunction(value.splice))?!length:!keys(value).length}function isObject(value){var type=typeof value;return\"function\"==type||!!value&&\"object\"==type}function isNative(value){return null==value?!1:objToString.call(value)==funcTag?reIsNative.test(fnToString.call(value)):isObjectLike(value)&&reIsHostCtor.test(value)}function isNumber(value){return\"number\"==typeof value||isObjectLike(value)&&objToString.call(value)==numberTag}function isString(value){return\"string\"==typeof value||isObjectLike(value)&&objToString.call(value)==stringTag}function isTypedArray(value){return isObjectLike(value)&&isLength(value.length)&&!!typedArrayTags[objToString.call(value)]}function toPlainObject(value){return baseCopy(value,keysIn(value))}function has(object,path){if(null==object)return!1;var result=hasOwnProperty.call(object,path);return result||isKey(path)||(path=toPath(path),object=1==path.length?object:baseGet(object,baseSlice(path,0,-1)),path=last(path),result=null!=object&&hasOwnProperty.call(object,path)),result}function keysIn(object){if(null==object)return[];isObject(object)||(object=Object(object));var length=object.length;length=length&&isLength(length)&&(isArray(object)||support.nonEnumArgs&&isArguments(object))&&length||0;for(var Ctor=object.constructor,index=-1,isProto=\"function\"==typeof Ctor&&Ctor.prototype===object,result=Array(length),skipIndexes=length>0;length>++index;)result[index]=index+\"\";for(var key in object)skipIndexes&&isIndex(key,length)||\"constructor\"==key&&(isProto||!hasOwnProperty.call(object,key))||result.push(key);return result}function values(object){return baseValues(object,keys(object))}function escapeRegExp(string){return string=baseToString(string),string&&reHasRegExpChars.test(string)?string.replace(reRegExpChars,\"\\\\$&\"):string}function callback(func,thisArg,guard){return guard&&isIterateeCall(func,thisArg,guard)&&(thisArg=null),baseCallback(func,thisArg)}function constant(value){return function(){return value}}function identity(value){return value}function property(path){return isKey(path)?baseProperty(path):basePropertyDeep(path)}var undefined,VERSION=\"3.7.0\",FUNC_ERROR_TEXT=\"Expected a function\",argsTag=\"[object Arguments]\",arrayTag=\"[object Array]\",boolTag=\"[object Boolean]\",dateTag=\"[object Date]\",errorTag=\"[object Error]\",funcTag=\"[object Function]\",mapTag=\"[object Map]\",numberTag=\"[object Number]\",objectTag=\"[object Object]\",regexpTag=\"[object RegExp]\",setTag=\"[object Set]\",stringTag=\"[object String]\",weakMapTag=\"[object WeakMap]\",arrayBufferTag=\"[object ArrayBuffer]\",float32Tag=\"[object Float32Array]\",float64Tag=\"[object Float64Array]\",int8Tag=\"[object Int8Array]\",int16Tag=\"[object Int16Array]\",int32Tag=\"[object Int32Array]\",uint8Tag=\"[object Uint8Array]\",uint8ClampedTag=\"[object Uint8ClampedArray]\",uint16Tag=\"[object Uint16Array]\",uint32Tag=\"[object Uint32Array]\",reIsDeepProp=/\\.|\\[(?:[^[\\]]+|([\"'])(?:(?!\\1)[^\\n\\\\]|\\\\.)*?)\\1\\]/,reIsPlainProp=/^\\w*$/,rePropName=/[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\n\\\\]|\\\\.)*?)\\2)\\]/g,reRegExpChars=/[.*+?^${}()|[\\]\\/\\\\]/g,reHasRegExpChars=RegExp(reRegExpChars.source),reEscapeChar=/\\\\(\\\\)?/g,reFlags=/\\w*$/,reIsHostCtor=/^\\[object .+?Constructor\\]$/,typedArrayTags={};typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=typedArrayTags[uint32Tag]=!0,typedArrayTags[argsTag]=typedArrayTags[arrayTag]=typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=typedArrayTags[dateTag]=typedArrayTags[errorTag]=typedArrayTags[funcTag]=typedArrayTags[mapTag]=typedArrayTags[numberTag]=typedArrayTags[objectTag]=typedArrayTags[regexpTag]=typedArrayTags[setTag]=typedArrayTags[stringTag]=typedArrayTags[weakMapTag]=!1;var cloneableTags={};cloneableTags[argsTag]=cloneableTags[arrayTag]=cloneableTags[arrayBufferTag]=cloneableTags[boolTag]=cloneableTags[dateTag]=cloneableTags[float32Tag]=cloneableTags[float64Tag]=cloneableTags[int8Tag]=cloneableTags[int16Tag]=cloneableTags[int32Tag]=cloneableTags[numberTag]=cloneableTags[objectTag]=cloneableTags[regexpTag]=cloneableTags[stringTag]=cloneableTags[uint8Tag]=cloneableTags[uint8ClampedTag]=cloneableTags[uint16Tag]=cloneableTags[uint32Tag]=!0,cloneableTags[errorTag]=cloneableTags[funcTag]=cloneableTags[mapTag]=cloneableTags[setTag]=cloneableTags[weakMapTag]=!1;var objectTypes={\"function\":!0,object:!0},freeExports=objectTypes[typeof exports]&&exports&&!exports.nodeType&&exports,freeModule=objectTypes[typeof module]&&module&&!module.nodeType&&module,freeGlobal=freeExports&&freeModule&&\"object\"==typeof global&&global&&global.Object&&global,freeSelf=objectTypes[typeof self]&&self&&self.Object&&self,freeWindow=objectTypes[typeof window]&&window&&window.Object&&window,moduleExports=freeModule&&freeModule.exports===freeExports&&freeExports,root=freeGlobal||freeWindow!==(this&&this.window)&&freeWindow||freeSelf||this,arrayProto=Array.prototype,objectProto=Object.prototype,fnToString=Function.prototype.toString,hasOwnProperty=objectProto.hasOwnProperty,objToString=objectProto.toString,reIsNative=RegExp(\"^\"+escapeRegExp(objToString).replace(/toString|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\"),ArrayBuffer=isNative(ArrayBuffer=root.ArrayBuffer)&&ArrayBuffer,bufferSlice=isNative(bufferSlice=ArrayBuffer&&new ArrayBuffer(0).slice)&&bufferSlice,floor=Math.floor,getOwnPropertySymbols=isNative(getOwnPropertySymbols=Object.getOwnPropertySymbols)&&getOwnPropertySymbols,getPrototypeOf=isNative(getPrototypeOf=Object.getPrototypeOf)&&getPrototypeOf,push=arrayProto.push,preventExtensions=isNative(Object.preventExtensions=Object.preventExtensions)&&preventExtensions,propertyIsEnumerable=objectProto.propertyIsEnumerable,Uint8Array=isNative(Uint8Array=root.Uint8Array)&&Uint8Array,Float64Array=function(){try{var func=isNative(func=root.Float64Array)&&func,result=new func(new ArrayBuffer(10),0,1)&&func}catch(e){}return result}(),nativeAssign=function(){var object={1:0},func=preventExtensions&&isNative(func=Object.assign)&&func;try{func(preventExtensions(object),\"xo\")}catch(e){}return!object[1]&&func}(),nativeIsArray=isNative(nativeIsArray=Array.isArray)&&nativeIsArray,nativeKeys=isNative(nativeKeys=Object.keys)&&nativeKeys,nativeMax=Math.max,nativeMin=Math.min,NEGATIVE_INFINITY=Number.NEGATIVE_INFINITY,MAX_ARRAY_LENGTH=Math.pow(2,32)-1,MAX_ARRAY_INDEX=MAX_ARRAY_LENGTH-1,HALF_MAX_ARRAY_LENGTH=MAX_ARRAY_LENGTH>>>1,FLOAT64_BYTES_PER_ELEMENT=Float64Array?Float64Array.BYTES_PER_ELEMENT:0,MAX_SAFE_INTEGER=Math.pow(2,53)-1,support=lodash.support={};(function(x){var Ctor=function(){this.x=x},props=[];Ctor.prototype={valueOf:x,y:x};for(var key in new Ctor)props.push(key);support.funcDecomp=/\\bthis\\b/.test(function(){return this}),support.funcNames=\"string\"==typeof Function.name;try{support.nonEnumArgs=!propertyIsEnumerable.call(arguments,1)}catch(e){support.nonEnumArgs=!0}})(1,0);var baseAssign=nativeAssign||function(object,source){return null==source?object:baseCopy(source,getSymbols(source),baseCopy(source,keys(source),object))},baseEach=createBaseEach(baseForOwn),baseFor=createBaseFor();bufferSlice||(bufferClone=ArrayBuffer&&Uint8Array?function(buffer){var byteLength=buffer.byteLength,floatLength=Float64Array?floor(byteLength/FLOAT64_BYTES_PER_ELEMENT):0,offset=floatLength*FLOAT64_BYTES_PER_ELEMENT,result=new ArrayBuffer(byteLength);if(floatLength){var view=new Float64Array(result,0,floatLength);view.set(new Float64Array(buffer,0,floatLength))}return byteLength!=offset&&(view=new Uint8Array(result,offset),view.set(new Uint8Array(buffer,offset))),result}:constant(null));var getLength=baseProperty(\"length\"),getSymbols=getOwnPropertySymbols?function(object){return getOwnPropertySymbols(toObject(object))}:constant([]),findLastIndex=createFindIndex(!0),zip=restParam(unzip),forEach=createForEach(arrayEach,baseEach),isArray=nativeIsArray||function(value){return isObjectLike(value)&&isLength(value.length)&&objToString.call(value)==arrayTag},isFunction=baseIsFunction(/x/)||Uint8Array&&!baseIsFunction(Uint8Array)?function(value){return objToString.call(value)==funcTag}:baseIsFunction,isPlainObject=getPrototypeOf?function(value){if(!value||objToString.call(value)!=objectTag)return!1;var valueOf=value.valueOf,objProto=isNative(valueOf)&&(objProto=getPrototypeOf(valueOf))&&getPrototypeOf(objProto);return objProto?value==objProto||getPrototypeOf(value)==objProto:shimIsPlainObject(value)}:shimIsPlainObject,assign=createAssigner(function(object,source,customizer){return customizer?assignWith(object,source,customizer):baseAssign(object,source)}),keys=nativeKeys?function(object){if(object)var Ctor=object.constructor,length=object.length;return\"function\"==typeof Ctor&&Ctor.prototype===object||\"function\"!=typeof object&&isLength(length)?shimKeys(object):isObject(object)?nativeKeys(object):[]}:shimKeys,merge=createAssigner(baseMerge);lodash.assign=assign,lodash.callback=callback,lodash.constant=constant,lodash.forEach=forEach,lodash.keys=keys,lodash.keysIn=keysIn,lodash.merge=merge,lodash.property=property,lodash.reject=reject,lodash.restParam=restParam,lodash.slice=slice,lodash.toPlainObject=toPlainObject,lodash.unzip=unzip,lodash.values=values,lodash.zip=zip,lodash.each=forEach,lodash.extend=assign,lodash.iteratee=callback,lodash.clone=clone,lodash.escapeRegExp=escapeRegExp,lodash.findLastIndex=findLastIndex,lodash.has=has,lodash.identity=identity,lodash.includes=includes,lodash.indexOf=indexOf,lodash.isArguments=isArguments,lodash.isArray=isArray,lodash.isEmpty=isEmpty,lodash.isFunction=isFunction,lodash.isNative=isNative,lodash.isNumber=isNumber,lodash.isObject=isObject,lodash.isPlainObject=isPlainObject,lodash.isString=isString,lodash.isTypedArray=isTypedArray,lodash.last=last,lodash.some=some,lodash.any=some,lodash.contains=includes,lodash.include=includes,lodash.VERSION=VERSION,freeExports&&freeModule?moduleExports?(freeModule.exports=lodash)._=lodash:freeExports._=lodash:root._=lodash\n}).call(this)}).call(this,\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{})},{}],\"/node_modules/jshint/src/jshint.js\":[function(_dereq_,module,exports){var _=_dereq_(\"../lodash\"),events=_dereq_(\"events\"),vars=_dereq_(\"./vars.js\"),messages=_dereq_(\"./messages.js\"),Lexer=_dereq_(\"./lex.js\").Lexer,reg=_dereq_(\"./reg.js\"),state=_dereq_(\"./state.js\").state,style=_dereq_(\"./style.js\"),options=_dereq_(\"./options.js\"),scopeManager=_dereq_(\"./scope-manager.js\"),JSHINT=function(){\"use strict\";function checkOption(name,t){return name=name.trim(),/^[+-]W\\d{3}$/g.test(name)?!0:-1!==options.validNames.indexOf(name)||\"jslint\"===t.type||_.has(options.removed,name)?!0:(error(\"E001\",t,name),!1)}function isString(obj){return\"[object String]\"===Object.prototype.toString.call(obj)}function isIdentifier(tkn,value){return tkn?tkn.identifier&&tkn.value===value?!0:!1:!1}function isReserved(token){if(!token.reserved)return!1;var meta=token.meta;if(meta&&meta.isFutureReservedWord&&state.inES5()){if(!meta.es5)return!1;if(meta.strictOnly&&!state.option.strict&&!state.isStrict())return!1;if(token.isProperty)return!1}return!0}function supplant(str,data){return str.replace(/\\{([^{}]*)\\}/g,function(a,b){var r=data[b];return\"string\"==typeof r||\"number\"==typeof r?r:a})}function combine(dest,src){Object.keys(src).forEach(function(name){_.has(JSHINT.blacklist,name)||(dest[name]=src[name])})}function processenforceall(){if(state.option.enforceall){for(var enforceopt in options.bool.enforcing)void 0!==state.option[enforceopt]||options.noenforceall[enforceopt]||(state.option[enforceopt]=!0);for(var relaxopt in options.bool.relaxing)void 0===state.option[relaxopt]&&(state.option[relaxopt]=!1)}}function assume(){processenforceall(),state.option.esversion||state.option.moz||(state.option.esversion=state.option.es3?3:state.option.esnext?6:5),state.inES5()&&combine(predefined,vars.ecmaIdentifiers[5]),state.inES6()&&combine(predefined,vars.ecmaIdentifiers[6]),state.option.module&&(state.option.strict===!0&&(state.option.strict=\"global\"),state.inES6()||warning(\"W134\",state.tokens.next,\"module\",6)),state.option.couch&&combine(predefined,vars.couch),state.option.qunit&&combine(predefined,vars.qunit),state.option.rhino&&combine(predefined,vars.rhino),state.option.shelljs&&(combine(predefined,vars.shelljs),combine(predefined,vars.node)),state.option.typed&&combine(predefined,vars.typed),state.option.phantom&&(combine(predefined,vars.phantom),state.option.strict===!0&&(state.option.strict=\"global\")),state.option.prototypejs&&combine(predefined,vars.prototypejs),state.option.node&&(combine(predefined,vars.node),combine(predefined,vars.typed),state.option.strict===!0&&(state.option.strict=\"global\")),state.option.devel&&combine(predefined,vars.devel),state.option.dojo&&combine(predefined,vars.dojo),state.option.browser&&(combine(predefined,vars.browser),combine(predefined,vars.typed)),state.option.browserify&&(combine(predefined,vars.browser),combine(predefined,vars.typed),combine(predefined,vars.browserify),state.option.strict===!0&&(state.option.strict=\"global\")),state.option.nonstandard&&combine(predefined,vars.nonstandard),state.option.jasmine&&combine(predefined,vars.jasmine),state.option.jquery&&combine(predefined,vars.jquery),state.option.mootools&&combine(predefined,vars.mootools),state.option.worker&&combine(predefined,vars.worker),state.option.wsh&&combine(predefined,vars.wsh),state.option.globalstrict&&state.option.strict!==!1&&(state.option.strict=\"global\"),state.option.yui&&combine(predefined,vars.yui),state.option.mocha&&combine(predefined,vars.mocha)}function quit(code,line,chr){var percentage=Math.floor(100*(line/state.lines.length)),message=messages.errors[code].desc;throw{name:\"JSHintError\",line:line,character:chr,message:message+\" (\"+percentage+\"% scanned).\",raw:message,code:code}}function removeIgnoredMessages(){var ignored=state.ignoredLines;_.isEmpty(ignored)||(JSHINT.errors=_.reject(JSHINT.errors,function(err){return ignored[err.line]}))}function warning(code,t,a,b,c,d){var ch,l,w,msg;if(/^W\\d{3}$/.test(code)){if(state.ignored[code])return;msg=messages.warnings[code]}else/E\\d{3}/.test(code)?msg=messages.errors[code]:/I\\d{3}/.test(code)&&(msg=messages.info[code]);return t=t||state.tokens.next||{},\"(end)\"===t.id&&(t=state.tokens.curr),l=t.line||0,ch=t.from||0,w={id:\"(error)\",raw:msg.desc,code:msg.code,evidence:state.lines[l-1]||\"\",line:l,character:ch,scope:JSHINT.scope,a:a,b:b,c:c,d:d},w.reason=supplant(msg.desc,w),JSHINT.errors.push(w),removeIgnoredMessages(),JSHINT.errors.length>=state.option.maxerr&&quit(\"E043\",l,ch),w}function warningAt(m,l,ch,a,b,c,d){return warning(m,{line:l,from:ch},a,b,c,d)}function error(m,t,a,b,c,d){warning(m,t,a,b,c,d)}function errorAt(m,l,ch,a,b,c,d){return error(m,{line:l,from:ch},a,b,c,d)}function addInternalSrc(elem,src){var i;return i={id:\"(internal)\",elem:elem,value:src},JSHINT.internals.push(i),i}function doOption(){var nt=state.tokens.next,body=nt.body.match(/(-\\s+)?[^\\s,:]+(?:\\s*:\\s*(-\\s+)?[^\\s,]+)?/g)||[],predef={};if(\"globals\"===nt.type){body.forEach(function(g,idx){g=g.split(\":\");var key=(g[0]||\"\").trim(),val=(g[1]||\"\").trim();if(\"-\"===key||!key.length){if(idx>0&&idx===body.length-1)return;return error(\"E002\",nt),void 0}\"-\"===key.charAt(0)?(key=key.slice(1),val=!1,JSHINT.blacklist[key]=key,delete predefined[key]):predef[key]=\"true\"===val}),combine(predefined,predef);for(var key in predef)_.has(predef,key)&&(declared[key]=nt)}\"exported\"===nt.type&&body.forEach(function(e,idx){if(!e.length){if(idx>0&&idx===body.length-1)return;return error(\"E002\",nt),void 0}state.funct[\"(scope)\"].addExported(e)}),\"members\"===nt.type&&(membersOnly=membersOnly||{},body.forEach(function(m){var ch1=m.charAt(0),ch2=m.charAt(m.length-1);ch1!==ch2||'\"'!==ch1&&\"'\"!==ch1||(m=m.substr(1,m.length-2).replace('\\\\\"','\"')),membersOnly[m]=!1}));var numvals=[\"maxstatements\",\"maxparams\",\"maxdepth\",\"maxcomplexity\",\"maxerr\",\"maxlen\",\"indent\"];(\"jshint\"===nt.type||\"jslint\"===nt.type)&&(body.forEach(function(g){g=g.split(\":\");var key=(g[0]||\"\").trim(),val=(g[1]||\"\").trim();if(checkOption(key,nt))if(numvals.indexOf(key)>=0)if(\"false\"!==val){if(val=+val,\"number\"!=typeof val||!isFinite(val)||0>=val||Math.floor(val)!==val)return error(\"E032\",nt,g[1].trim()),void 0;state.option[key]=val}else state.option[key]=\"indent\"===key?4:!1;else{if(\"validthis\"===key)return state.funct[\"(global)\"]?void error(\"E009\"):\"true\"!==val&&\"false\"!==val?void error(\"E002\",nt):(state.option.validthis=\"true\"===val,void 0);if(\"quotmark\"!==key)if(\"shadow\"!==key)if(\"unused\"!==key)if(\"latedef\"!==key)if(\"ignore\"!==key)if(\"strict\"!==key){\"module\"===key&&(hasParsedCode(state.funct)||error(\"E055\",state.tokens.next,\"module\"));var esversions={es3:3,es5:5,esnext:6};if(!_.has(esversions,key)){if(\"esversion\"===key){switch(val){case\"5\":state.inES5(!0)&&warning(\"I003\");case\"3\":case\"6\":state.option.moz=!1,state.option.esversion=+val;break;case\"2015\":state.option.moz=!1,state.option.esversion=6;break;default:error(\"E002\",nt)}return hasParsedCode(state.funct)||error(\"E055\",state.tokens.next,\"esversion\"),void 0}var match=/^([+-])(W\\d{3})$/g.exec(key);if(match)return state.ignored[match[2]]=\"-\"===match[1],void 0;var tn;return\"true\"===val||\"false\"===val?(\"jslint\"===nt.type?(tn=options.renamed[key]||key,state.option[tn]=\"true\"===val,void 0!==options.inverted[tn]&&(state.option[tn]=!state.option[tn])):state.option[key]=\"true\"===val,\"newcap\"===key&&(state.option[\"(explicitNewcap)\"]=!0),void 0):(error(\"E002\",nt),void 0)}switch(val){case\"true\":state.option.moz=!1,state.option.esversion=esversions[key];break;case\"false\":state.option.moz||(state.option.esversion=5);break;default:error(\"E002\",nt)}}else switch(val){case\"true\":state.option.strict=!0;break;case\"false\":state.option.strict=!1;break;case\"func\":case\"global\":case\"implied\":state.option.strict=val;break;default:error(\"E002\",nt)}else switch(val){case\"line\":state.ignoredLines[nt.line]=!0,removeIgnoredMessages();break;default:error(\"E002\",nt)}else switch(val){case\"true\":state.option.latedef=!0;break;case\"false\":state.option.latedef=!1;break;case\"nofunc\":state.option.latedef=\"nofunc\";break;default:error(\"E002\",nt)}else switch(val){case\"true\":state.option.unused=!0;break;case\"false\":state.option.unused=!1;break;case\"vars\":case\"strict\":state.option.unused=val;break;default:error(\"E002\",nt)}else switch(val){case\"true\":state.option.shadow=!0;break;case\"outer\":state.option.shadow=\"outer\";break;case\"false\":case\"inner\":state.option.shadow=\"inner\";break;default:error(\"E002\",nt)}else switch(val){case\"true\":case\"false\":state.option.quotmark=\"true\"===val;break;case\"double\":case\"single\":state.option.quotmark=val;break;default:error(\"E002\",nt)}}}),assume())}function peek(p){var t,i=p||0,j=lookahead.length;if(j>i)return lookahead[i];for(;i>=j;)t=lookahead[j],t||(t=lookahead[j]=lex.token()),j+=1;return t||\"(end)\"!==state.tokens.next.id?t:state.tokens.next}function peekIgnoreEOL(){var t,i=0;do t=peek(i++);while(\"(endline)\"===t.id);return t}function advance(id,t){switch(state.tokens.curr.id){case\"(number)\":\".\"===state.tokens.next.id&&warning(\"W005\",state.tokens.curr);break;case\"-\":(\"-\"===state.tokens.next.id||\"--\"===state.tokens.next.id)&&warning(\"W006\");break;case\"+\":(\"+\"===state.tokens.next.id||\"++\"===state.tokens.next.id)&&warning(\"W007\")}for(id&&state.tokens.next.id!==id&&(t?\"(end)\"===state.tokens.next.id?error(\"E019\",t,t.id):error(\"E020\",state.tokens.next,id,t.id,t.line,state.tokens.next.value):(\"(identifier)\"!==state.tokens.next.type||state.tokens.next.value!==id)&&warning(\"W116\",state.tokens.next,id,state.tokens.next.value)),state.tokens.prev=state.tokens.curr,state.tokens.curr=state.tokens.next;;){if(state.tokens.next=lookahead.shift()||lex.token(),state.tokens.next||quit(\"E041\",state.tokens.curr.line),\"(end)\"===state.tokens.next.id||\"(error)\"===state.tokens.next.id)return;if(state.tokens.next.check&&state.tokens.next.check(),state.tokens.next.isSpecial)\"falls through\"===state.tokens.next.type?state.tokens.curr.caseFallsThrough=!0:doOption();else if(\"(endline)\"!==state.tokens.next.id)break}}function isInfix(token){return token.infix||!token.identifier&&!token.template&&!!token.led}function isEndOfExpr(){var curr=state.tokens.curr,next=state.tokens.next;return\";\"===next.id||\"}\"===next.id||\":\"===next.id?!0:isInfix(next)===isInfix(curr)||\"yield\"===curr.id&&state.inMoz()?curr.line!==startLine(next):!1}function isBeginOfExpr(prev){return!prev.left&&\"unary\"!==prev.arity}function expression(rbp,initial){var left,isArray=!1,isObject=!1,isLetExpr=!1;state.nameStack.push(),initial||\"let\"!==state.tokens.next.value||\"(\"!==peek(0).value||(state.inMoz()||warning(\"W118\",state.tokens.next,\"let expressions\"),isLetExpr=!0,state.funct[\"(scope)\"].stack(),advance(\"let\"),advance(\"(\"),state.tokens.prev.fud(),advance(\")\")),\"(end)\"===state.tokens.next.id&&error(\"E006\",state.tokens.curr);var isDangerous=state.option.asi&&state.tokens.prev.line!==startLine(state.tokens.curr)&&_.contains([\"]\",\")\"],state.tokens.prev.id)&&_.contains([\"[\",\"(\"],state.tokens.curr.id);if(isDangerous&&warning(\"W014\",state.tokens.curr,state.tokens.curr.id),advance(),initial&&(state.funct[\"(verb)\"]=state.tokens.curr.value,state.tokens.curr.beginsStmt=!0),initial===!0&&state.tokens.curr.fud)left=state.tokens.curr.fud();else for(state.tokens.curr.nud?left=state.tokens.curr.nud():error(\"E030\",state.tokens.curr,state.tokens.curr.id);(state.tokens.next.lbp>rbp||\"(template)\"===state.tokens.next.type)&&!isEndOfExpr();)isArray=\"Array\"===state.tokens.curr.value,isObject=\"Object\"===state.tokens.curr.value,left&&(left.value||left.first&&left.first.value)&&(\"new\"!==left.value||left.first&&left.first.value&&\".\"===left.first.value)&&(isArray=!1,left.value!==state.tokens.curr.value&&(isObject=!1)),advance(),isArray&&\"(\"===state.tokens.curr.id&&\")\"===state.tokens.next.id&&warning(\"W009\",state.tokens.curr),isObject&&\"(\"===state.tokens.curr.id&&\")\"===state.tokens.next.id&&warning(\"W010\",state.tokens.curr),left&&state.tokens.curr.led?left=state.tokens.curr.led(left):error(\"E033\",state.tokens.curr,state.tokens.curr.id);return isLetExpr&&state.funct[\"(scope)\"].unstack(),state.nameStack.pop(),left}function startLine(token){return token.startLine||token.line}function nobreaknonadjacent(left,right){left=left||state.tokens.curr,right=right||state.tokens.next,state.option.laxbreak||left.line===startLine(right)||warning(\"W014\",right,right.value)}function nolinebreak(t){t=t||state.tokens.curr,t.line!==startLine(state.tokens.next)&&warning(\"E022\",t,t.value)}function nobreakcomma(left,right){left.line!==startLine(right)&&(state.option.laxcomma||(comma.first&&(warning(\"I001\"),comma.first=!1),warning(\"W014\",left,right.value)))}function comma(opts){if(opts=opts||{},opts.peek?nobreakcomma(state.tokens.prev,state.tokens.curr):(nobreakcomma(state.tokens.curr,state.tokens.next),advance(\",\")),state.tokens.next.identifier&&(!opts.property||!state.inES5()))switch(state.tokens.next.value){case\"break\":case\"case\":case\"catch\":case\"continue\":case\"default\":case\"do\":case\"else\":case\"finally\":case\"for\":case\"if\":case\"in\":case\"instanceof\":case\"return\":case\"switch\":case\"throw\":case\"try\":case\"var\":case\"let\":case\"while\":case\"with\":return error(\"E024\",state.tokens.next,state.tokens.next.value),!1}if(\"(punctuator)\"===state.tokens.next.type)switch(state.tokens.next.value){case\"}\":case\"]\":case\",\":if(opts.allowTrailing)return!0;case\")\":return error(\"E024\",state.tokens.next,state.tokens.next.value),!1}return!0}function symbol(s,p){var x=state.syntax[s];return x&&\"object\"==typeof x||(state.syntax[s]=x={id:s,lbp:p,value:s}),x}function delim(s){var x=symbol(s,0);return x.delim=!0,x}function stmt(s,f){var x=delim(s);return x.identifier=x.reserved=!0,x.fud=f,x}function blockstmt(s,f){var x=stmt(s,f);return x.block=!0,x}function reserveName(x){var c=x.id.charAt(0);return(c>=\"a\"&&\"z\">=c||c>=\"A\"&&\"Z\">=c)&&(x.identifier=x.reserved=!0),x}function prefix(s,f){var x=symbol(s,150);return reserveName(x),x.nud=\"function\"==typeof f?f:function(){return this.arity=\"unary\",this.right=expression(150),(\"++\"===this.id||\"--\"===this.id)&&(state.option.plusplus?warning(\"W016\",this,this.id):!this.right||this.right.identifier&&!isReserved(this.right)||\".\"===this.right.id||\"[\"===this.right.id||warning(\"W017\",this),this.right&&this.right.isMetaProperty?error(\"E031\",this):this.right&&this.right.identifier&&state.funct[\"(scope)\"].block.modify(this.right.value,this)),this},x}function type(s,f){var x=delim(s);return x.type=s,x.nud=f,x}function reserve(name,func){var x=type(name,func);return x.identifier=!0,x.reserved=!0,x}function FutureReservedWord(name,meta){var x=type(name,meta&&meta.nud||function(){return this});return meta=meta||{},meta.isFutureReservedWord=!0,x.value=name,x.identifier=!0,x.reserved=!0,x.meta=meta,x}function reservevar(s,v){return reserve(s,function(){return\"function\"==typeof v&&v(this),this})}function infix(s,f,p,w){var x=symbol(s,p);return reserveName(x),x.infix=!0,x.led=function(left){return w||nobreaknonadjacent(state.tokens.prev,state.tokens.curr),\"in\"!==s&&\"instanceof\"!==s||\"!\"!==left.id||warning(\"W018\",left,\"!\"),\"function\"==typeof f?f(left,this):(this.left=left,this.right=expression(p),this)},x}function application(s){var x=symbol(s,42);return x.led=function(left){return nobreaknonadjacent(state.tokens.prev,state.tokens.curr),this.left=left,this.right=doFunction({type:\"arrow\",loneArg:left}),this},x}function relation(s,f){var x=symbol(s,100);return x.led=function(left){nobreaknonadjacent(state.tokens.prev,state.tokens.curr),this.left=left;var right=this.right=expression(100);return isIdentifier(left,\"NaN\")||isIdentifier(right,\"NaN\")?warning(\"W019\",this):f&&f.apply(this,[left,right]),left&&right||quit(\"E041\",state.tokens.curr.line),\"!\"===left.id&&warning(\"W018\",left,\"!\"),\"!\"===right.id&&warning(\"W018\",right,\"!\"),this},x}function isPoorRelation(node){return node&&(\"(number)\"===node.type&&0===+node.value||\"(string)\"===node.type&&\"\"===node.value||\"null\"===node.type&&!state.option.eqnull||\"true\"===node.type||\"false\"===node.type||\"undefined\"===node.type)}function isTypoTypeof(left,right,state){var values;return state.option.notypeof?!1:left&&right?(values=state.inES6()?typeofValues.es6:typeofValues.es3,\"(identifier)\"===right.type&&\"typeof\"===right.value&&\"(string)\"===left.type?!_.contains(values,left.value):!1):!1}function isGlobalEval(left,state){var isGlobal=!1;return\"this\"===left.type&&null===state.funct[\"(context)\"]?isGlobal=!0:\"(identifier)\"===left.type&&(state.option.node&&\"global\"===left.value?isGlobal=!0:!state.option.browser||\"window\"!==left.value&&\"document\"!==left.value||(isGlobal=!0)),isGlobal}function findNativePrototype(left){function walkPrototype(obj){return\"object\"==typeof obj?\"prototype\"===obj.right?obj:walkPrototype(obj.left):void 0}function walkNative(obj){for(;!obj.identifier&&\"object\"==typeof obj.left;)obj=obj.left;return obj.identifier&&natives.indexOf(obj.value)>=0?obj.value:void 0}var natives=[\"Array\",\"ArrayBuffer\",\"Boolean\",\"Collator\",\"DataView\",\"Date\",\"DateTimeFormat\",\"Error\",\"EvalError\",\"Float32Array\",\"Float64Array\",\"Function\",\"Infinity\",\"Intl\",\"Int16Array\",\"Int32Array\",\"Int8Array\",\"Iterator\",\"Number\",\"NumberFormat\",\"Object\",\"RangeError\",\"ReferenceError\",\"RegExp\",\"StopIteration\",\"String\",\"SyntaxError\",\"TypeError\",\"Uint16Array\",\"Uint32Array\",\"Uint8Array\",\"Uint8ClampedArray\",\"URIError\"],prototype=walkPrototype(left);return prototype?walkNative(prototype):void 0}function checkLeftSideAssign(left,assignToken,options){var allowDestructuring=options&&options.allowDestructuring;if(assignToken=assignToken||left,state.option.freeze){var nativeObject=findNativePrototype(left);nativeObject&&warning(\"W121\",left,nativeObject)}return left.identifier&&!left.isMetaProperty&&state.funct[\"(scope)\"].block.reassign(left.value,left),\".\"===left.id?((!left.left||\"arguments\"===left.left.value&&!state.isStrict())&&warning(\"E031\",assignToken),state.nameStack.set(state.tokens.prev),!0):\"{\"===left.id||\"[\"===left.id?(allowDestructuring&&state.tokens.curr.left.destructAssign?state.tokens.curr.left.destructAssign.forEach(function(t){t.id&&state.funct[\"(scope)\"].block.modify(t.id,t.token)}):\"{\"!==left.id&&left.left?\"arguments\"!==left.left.value||state.isStrict()||warning(\"E031\",assignToken):warning(\"E031\",assignToken),\"[\"===left.id&&state.nameStack.set(left.right),!0):left.isMetaProperty?(error(\"E031\",assignToken),!0):left.identifier&&!isReserved(left)?(\"exception\"===state.funct[\"(scope)\"].labeltype(left.value)&&warning(\"W022\",left),state.nameStack.set(left),!0):(left===state.syntax[\"function\"]&&warning(\"W023\",state.tokens.curr),!1)}function assignop(s,f,p){var x=infix(s,\"function\"==typeof f?f:function(left,that){return that.left=left,left&&checkLeftSideAssign(left,that,{allowDestructuring:!0})?(that.right=expression(10),that):(error(\"E031\",that),void 0)},p);return x.exps=!0,x.assign=!0,x}function bitwise(s,f,p){var x=symbol(s,p);return reserveName(x),x.led=\"function\"==typeof f?f:function(left){return state.option.bitwise&&warning(\"W016\",this,this.id),this.left=left,this.right=expression(p),this},x}function bitwiseassignop(s){return assignop(s,function(left,that){return state.option.bitwise&&warning(\"W016\",that,that.id),left&&checkLeftSideAssign(left,that)?(that.right=expression(10),that):(error(\"E031\",that),void 0)},20)}function suffix(s){var x=symbol(s,150);return x.led=function(left){return state.option.plusplus?warning(\"W016\",this,this.id):left.identifier&&!isReserved(left)||\".\"===left.id||\"[\"===left.id||warning(\"W017\",this),left.isMetaProperty?error(\"E031\",this):left&&left.identifier&&state.funct[\"(scope)\"].block.modify(left.value,left),this.left=left,this},x}function optionalidentifier(fnparam,prop,preserve){if(state.tokens.next.identifier){preserve||advance();var curr=state.tokens.curr,val=state.tokens.curr.value;return isReserved(curr)?prop&&state.inES5()?val:fnparam&&\"undefined\"===val?val:(warning(\"W024\",state.tokens.curr,state.tokens.curr.id),val):val}}function identifier(fnparam,prop){var i=optionalidentifier(fnparam,prop,!1);if(i)return i;if(\"...\"===state.tokens.next.value){if(state.inES6(!0)||warning(\"W119\",state.tokens.next,\"spread/rest operator\",\"6\"),advance(),checkPunctuator(state.tokens.next,\"...\"))for(warning(\"E024\",state.tokens.next,\"...\");checkPunctuator(state.tokens.next,\"...\");)advance();return state.tokens.next.identifier?identifier(fnparam,prop):(warning(\"E024\",state.tokens.curr,\"...\"),void 0)}error(\"E030\",state.tokens.next,state.tokens.next.value),\";\"!==state.tokens.next.id&&advance()}function reachable(controlToken){var t,i=0;if(\";\"===state.tokens.next.id&&!controlToken.inBracelessBlock)for(;;){do t=peek(i),i+=1;while(\"(end)\"!==t.id&&\"(comment)\"===t.id);if(t.reach)return;if(\"(endline)\"!==t.id){if(\"function\"===t.id){state.option.latedef===!0&&warning(\"W026\",t);break}warning(\"W027\",t,t.value,controlToken.value);break}}}function parseFinalSemicolon(){if(\";\"!==state.tokens.next.id){if(state.tokens.next.isUnclosed)return advance();var sameLine=startLine(state.tokens.next)===state.tokens.curr.line&&\"(end)\"!==state.tokens.next.id,blockEnd=checkPunctuator(state.tokens.next,\"}\");sameLine&&!blockEnd?errorAt(\"E058\",state.tokens.curr.line,state.tokens.curr.character):state.option.asi||(blockEnd&&!state.option.lastsemic||!sameLine)&&warningAt(\"W033\",state.tokens.curr.line,state.tokens.curr.character)}else advance(\";\")}function statement(){var r,i=indent,t=state.tokens.next,hasOwnScope=!1;if(\";\"===t.id)return advance(\";\"),void 0;var res=isReserved(t);if(res&&t.meta&&t.meta.isFutureReservedWord&&\":\"===peek().id&&(warning(\"W024\",t,t.id),res=!1),t.identifier&&!res&&\":\"===peek().id&&(advance(),advance(\":\"),hasOwnScope=!0,state.funct[\"(scope)\"].stack(),state.funct[\"(scope)\"].block.addBreakLabel(t.value,{token:state.tokens.curr}),state.tokens.next.labelled||\"{\"===state.tokens.next.value||warning(\"W028\",state.tokens.next,t.value,state.tokens.next.value),state.tokens.next.label=t.value,t=state.tokens.next),\"{\"===t.id){var iscase=\"case\"===state.funct[\"(verb)\"]&&\":\"===state.tokens.curr.value;return block(!0,!0,!1,!1,iscase),void 0}return r=expression(0,!0),!r||r.identifier&&\"function\"===r.value||\"(punctuator)\"===r.type&&r.left&&r.left.identifier&&\"function\"===r.left.value||state.isStrict()||\"global\"!==state.option.strict||warning(\"E007\"),t.block||(state.option.expr||r&&r.exps?state.option.nonew&&r&&r.left&&\"(\"===r.id&&\"new\"===r.left.id&&warning(\"W031\",t):warning(\"W030\",state.tokens.curr),parseFinalSemicolon()),indent=i,hasOwnScope&&state.funct[\"(scope)\"].unstack(),r}function statements(){for(var p,a=[];!state.tokens.next.reach&&\"(end)\"!==state.tokens.next.id;)\";\"===state.tokens.next.id?(p=peek(),(!p||\"(\"!==p.id&&\"[\"!==p.id)&&warning(\"W032\"),advance(\";\")):a.push(statement());return a}function directives(){for(var i,p,pn;\"(string)\"===state.tokens.next.id;){if(p=peek(0),\"(endline)\"===p.id){i=1;do pn=peek(i++);while(\"(endline)\"===pn.id);if(\";\"===pn.id)p=pn;else{if(\"[\"===pn.value||\".\"===pn.value)break;state.option.asi&&\"(\"!==pn.value||warning(\"W033\",state.tokens.next)}}else{if(\".\"===p.id||\"[\"===p.id)break;\";\"!==p.id&&warning(\"W033\",p)}advance();var directive=state.tokens.curr.value;(state.directive[directive]||\"use strict\"===directive&&\"implied\"===state.option.strict)&&warning(\"W034\",state.tokens.curr,directive),state.directive[directive]=!0,\";\"===p.id&&advance(\";\")}state.isStrict()&&(state.option[\"(explicitNewcap)\"]||(state.option.newcap=!0),state.option.undef=!0)}function block(ordinary,stmt,isfunc,isfatarrow,iscase){var a,m,t,line,d,b=inblock,old_indent=indent;inblock=ordinary,t=state.tokens.next;var metrics=state.funct[\"(metrics)\"];if(metrics.nestedBlockDepth+=1,metrics.verifyMaxNestedBlockDepthPerFunction(),\"{\"===state.tokens.next.id){if(advance(\"{\"),state.funct[\"(scope)\"].stack(),line=state.tokens.curr.line,\"}\"!==state.tokens.next.id){for(indent+=state.option.indent;!ordinary&&state.tokens.next.from>indent;)indent+=state.option.indent;if(isfunc){m={};for(d in state.directive)_.has(state.directive,d)&&(m[d]=state.directive[d]);directives(),state.option.strict&&state.funct[\"(context)\"][\"(global)\"]&&(m[\"use strict\"]||state.isStrict()||warning(\"E007\"))}a=statements(),metrics.statementCount+=a.length,indent-=state.option.indent}advance(\"}\",t),isfunc&&(state.funct[\"(scope)\"].validateParams(),m&&(state.directive=m)),state.funct[\"(scope)\"].unstack(),indent=old_indent}else if(ordinary)state.funct[\"(noblockscopedvar)\"]=\"for\"!==state.tokens.next.id,state.funct[\"(scope)\"].stack(),(!stmt||state.option.curly)&&warning(\"W116\",state.tokens.next,\"{\",state.tokens.next.value),state.tokens.next.inBracelessBlock=!0,indent+=state.option.indent,a=[statement()],indent-=state.option.indent,state.funct[\"(scope)\"].unstack(),delete state.funct[\"(noblockscopedvar)\"];else if(isfunc){if(state.funct[\"(scope)\"].stack(),m={},!stmt||isfatarrow||state.inMoz()||error(\"W118\",state.tokens.curr,\"function closure expressions\"),!stmt)for(d in state.directive)_.has(state.directive,d)&&(m[d]=state.directive[d]);expression(10),state.option.strict&&state.funct[\"(context)\"][\"(global)\"]&&(m[\"use strict\"]||state.isStrict()||warning(\"E007\")),state.funct[\"(scope)\"].unstack()}else error(\"E021\",state.tokens.next,\"{\",state.tokens.next.value);switch(state.funct[\"(verb)\"]){case\"break\":case\"continue\":case\"return\":case\"throw\":if(iscase)break;default:state.funct[\"(verb)\"]=null}return inblock=b,!ordinary||!state.option.noempty||a&&0!==a.length||warning(\"W035\",state.tokens.prev),metrics.nestedBlockDepth-=1,a}function countMember(m){membersOnly&&\"boolean\"!=typeof membersOnly[m]&&warning(\"W036\",state.tokens.curr,m),\"number\"==typeof member[m]?member[m]+=1:member[m]=1}function comprehensiveArrayExpression(){var res={};res.exps=!0,state.funct[\"(comparray)\"].stack();var reversed=!1;return\"for\"!==state.tokens.next.value&&(reversed=!0,state.inMoz()||warning(\"W116\",state.tokens.next,\"for\",state.tokens.next.value),state.funct[\"(comparray)\"].setState(\"use\"),res.right=expression(10)),advance(\"for\"),\"each\"===state.tokens.next.value&&(advance(\"each\"),state.inMoz()||warning(\"W118\",state.tokens.curr,\"for each\")),advance(\"(\"),state.funct[\"(comparray)\"].setState(\"define\"),res.left=expression(130),_.contains([\"in\",\"of\"],state.tokens.next.value)?advance():error(\"E045\",state.tokens.curr),state.funct[\"(comparray)\"].setState(\"generate\"),expression(10),advance(\")\"),\"if\"===state.tokens.next.value&&(advance(\"if\"),advance(\"(\"),state.funct[\"(comparray)\"].setState(\"filter\"),res.filter=expression(10),advance(\")\")),reversed||(state.funct[\"(comparray)\"].setState(\"use\"),res.right=expression(10)),advance(\"]\"),state.funct[\"(comparray)\"].unstack(),res}function isMethod(){return state.funct[\"(statement)\"]&&\"class\"===state.funct[\"(statement)\"].type||state.funct[\"(context)\"]&&\"class\"===state.funct[\"(context)\"][\"(verb)\"]}function isPropertyName(token){return token.identifier||\"(string)\"===token.id||\"(number)\"===token.id}function propertyName(preserveOrToken){var id,preserve=!0;return\"object\"==typeof preserveOrToken?id=preserveOrToken:(preserve=preserveOrToken,id=optionalidentifier(!1,!0,preserve)),id?\"object\"==typeof id&&(\"(string)\"===id.id||\"(identifier)\"===id.id?id=id.value:\"(number)\"===id.id&&(id=\"\"+id.value)):\"(string)\"===state.tokens.next.id?(id=state.tokens.next.value,preserve||advance()):\"(number)\"===state.tokens.next.id&&(id=\"\"+state.tokens.next.value,preserve||advance()),\"hasOwnProperty\"===id&&warning(\"W001\"),id}function functionparams(options){function addParam(addParamArgs){state.funct[\"(scope)\"].addParam.apply(state.funct[\"(scope)\"],addParamArgs)}var next,ident,t,paramsIds=[],tokens=[],pastDefault=!1,pastRest=!1,arity=0,loneArg=options&&options.loneArg;if(loneArg&&loneArg.identifier===!0)return state.funct[\"(scope)\"].addParam(loneArg.value,loneArg),{arity:1,params:[loneArg.value]};if(next=state.tokens.next,options&&options.parsedOpening||advance(\"(\"),\")\"===state.tokens.next.id)return advance(\")\"),void 0;for(;;){arity++;var currentParams=[];if(_.contains([\"{\",\"[\"],state.tokens.next.id)){tokens=destructuringPattern();for(t in tokens)t=tokens[t],t.id&&(paramsIds.push(t.id),currentParams.push([t.id,t.token]))}else if(checkPunctuator(state.tokens.next,\"...\")&&(pastRest=!0),ident=identifier(!0))paramsIds.push(ident),currentParams.push([ident,state.tokens.curr]);else for(;!checkPunctuators(state.tokens.next,[\",\",\")\"]);)advance();if(pastDefault&&\"=\"!==state.tokens.next.id&&error(\"W138\",state.tokens.current),\"=\"===state.tokens.next.id&&(state.inES6()||warning(\"W119\",state.tokens.next,\"default parameters\",\"6\"),advance(\"=\"),pastDefault=!0,expression(10)),currentParams.forEach(addParam),\",\"!==state.tokens.next.id)return advance(\")\",next),{arity:arity,params:paramsIds};pastRest&&warning(\"W131\",state.tokens.next),comma()}}function functor(name,token,overwrites){var funct={\"(name)\":name,\"(breakage)\":0,\"(loopage)\":0,\"(tokens)\":{},\"(properties)\":{},\"(catch)\":!1,\"(global)\":!1,\"(line)\":null,\"(character)\":null,\"(metrics)\":null,\"(statement)\":null,\"(context)\":null,\"(scope)\":null,\"(comparray)\":null,\"(generator)\":null,\"(arrow)\":null,\"(params)\":null};return token&&_.extend(funct,{\"(line)\":token.line,\"(character)\":token.character,\"(metrics)\":createMetrics(token)}),_.extend(funct,overwrites),funct[\"(context)\"]&&(funct[\"(scope)\"]=funct[\"(context)\"][\"(scope)\"],funct[\"(comparray)\"]=funct[\"(context)\"][\"(comparray)\"]),funct}function isFunctor(token){return\"(scope)\"in token}function hasParsedCode(funct){return funct[\"(global)\"]&&!funct[\"(verb)\"]}function doTemplateLiteral(left){function end(){if(state.tokens.curr.template&&state.tokens.curr.tail&&state.tokens.curr.context===ctx)return!0;var complete=state.tokens.next.template&&state.tokens.next.tail&&state.tokens.next.context===ctx;return complete&&advance(),complete||state.tokens.next.isUnclosed}var ctx=this.context,noSubst=this.noSubst,depth=this.depth;if(!noSubst)for(;!end();)!state.tokens.next.template||state.tokens.next.depth>depth?expression(0):advance();return{id:\"(template)\",type:\"(template)\",tag:left}}function doFunction(options){var f,token,name,statement,classExprBinding,isGenerator,isArrow,ignoreLoopFunc,oldOption=state.option,oldIgnored=state.ignored;options&&(name=options.name,statement=options.statement,classExprBinding=options.classExprBinding,isGenerator=\"generator\"===options.type,isArrow=\"arrow\"===options.type,ignoreLoopFunc=options.ignoreLoopFunc),state.option=Object.create(state.option),state.ignored=Object.create(state.ignored),state.funct=functor(name||state.nameStack.infer(),state.tokens.next,{\"(statement)\":statement,\"(context)\":state.funct,\"(arrow)\":isArrow,\"(generator)\":isGenerator}),f=state.funct,token=state.tokens.curr,token.funct=state.funct,functions.push(state.funct),state.funct[\"(scope)\"].stack(\"functionouter\");var internallyAccessibleName=name||classExprBinding;internallyAccessibleName&&state.funct[\"(scope)\"].block.add(internallyAccessibleName,classExprBinding?\"class\":\"function\",state.tokens.curr,!1),state.funct[\"(scope)\"].stack(\"functionparams\");var paramsInfo=functionparams(options);return paramsInfo?(state.funct[\"(params)\"]=paramsInfo.params,state.funct[\"(metrics)\"].arity=paramsInfo.arity,state.funct[\"(metrics)\"].verifyMaxParametersPerFunction()):state.funct[\"(metrics)\"].arity=0,isArrow&&(state.inES6(!0)||warning(\"W119\",state.tokens.curr,\"arrow function syntax (=>)\",\"6\"),options.loneArg||advance(\"=>\")),block(!1,!0,!0,isArrow),!state.option.noyield&&isGenerator&&\"yielded\"!==state.funct[\"(generator)\"]&&warning(\"W124\",state.tokens.curr),state.funct[\"(metrics)\"].verifyMaxStatementsPerFunction(),state.funct[\"(metrics)\"].verifyMaxComplexityPerFunction(),state.funct[\"(unusedOption)\"]=state.option.unused,state.option=oldOption,state.ignored=oldIgnored,state.funct[\"(last)\"]=state.tokens.curr.line,state.funct[\"(lastcharacter)\"]=state.tokens.curr.character,state.funct[\"(scope)\"].unstack(),state.funct[\"(scope)\"].unstack(),state.funct=state.funct[\"(context)\"],ignoreLoopFunc||state.option.loopfunc||!state.funct[\"(loopage)\"]||f[\"(isCapturing)\"]&&warning(\"W083\",token),f}function createMetrics(functionStartToken){return{statementCount:0,nestedBlockDepth:-1,ComplexityCount:1,arity:0,verifyMaxStatementsPerFunction:function(){state.option.maxstatements&&this.statementCount>state.option.maxstatements&&warning(\"W071\",functionStartToken,this.statementCount)\n},verifyMaxParametersPerFunction:function(){_.isNumber(state.option.maxparams)&&this.arity>state.option.maxparams&&warning(\"W072\",functionStartToken,this.arity)},verifyMaxNestedBlockDepthPerFunction:function(){state.option.maxdepth&&this.nestedBlockDepth>0&&this.nestedBlockDepth===state.option.maxdepth+1&&warning(\"W073\",null,this.nestedBlockDepth)},verifyMaxComplexityPerFunction:function(){var max=state.option.maxcomplexity,cc=this.ComplexityCount;max&&cc>max&&warning(\"W074\",functionStartToken,cc)}}}function increaseComplexityCount(){state.funct[\"(metrics)\"].ComplexityCount+=1}function checkCondAssignment(expr){var id,paren;switch(expr&&(id=expr.id,paren=expr.paren,\",\"===id&&(expr=expr.exprs[expr.exprs.length-1])&&(id=expr.id,paren=paren||expr.paren)),id){case\"=\":case\"+=\":case\"-=\":case\"*=\":case\"%=\":case\"&=\":case\"|=\":case\"^=\":case\"/=\":paren||state.option.boss||warning(\"W084\")}}function checkProperties(props){if(state.inES5())for(var name in props)props[name]&&props[name].setterToken&&!props[name].getterToken&&warning(\"W078\",props[name].setterToken)}function metaProperty(name,c){if(checkPunctuator(state.tokens.next,\".\")){var left=state.tokens.curr.id;advance(\".\");var id=identifier();return state.tokens.curr.isMetaProperty=!0,name!==id?error(\"E057\",state.tokens.prev,left,id):c(),state.tokens.curr}}function destructuringPattern(options){var isAssignment=options&&options.assignment;return state.inES6()||warning(\"W104\",state.tokens.curr,isAssignment?\"destructuring assignment\":\"destructuring binding\",\"6\"),destructuringPatternRecursive(options)}function destructuringPatternRecursive(options){var ids,identifiers=[],openingParsed=options&&options.openingParsed,isAssignment=options&&options.assignment,recursiveOptions=isAssignment?{assignment:isAssignment}:null,firstToken=openingParsed?state.tokens.curr:state.tokens.next,nextInnerDE=function(){var ident;if(checkPunctuators(state.tokens.next,[\"[\",\"{\"])){ids=destructuringPatternRecursive(recursiveOptions);for(var id in ids)id=ids[id],identifiers.push({id:id.id,token:id.token})}else if(checkPunctuator(state.tokens.next,\",\"))identifiers.push({id:null,token:state.tokens.curr});else{if(!checkPunctuator(state.tokens.next,\"(\")){var is_rest=checkPunctuator(state.tokens.next,\"...\");if(isAssignment){var identifierToken=is_rest?peek(0):state.tokens.next;identifierToken.identifier||warning(\"E030\",identifierToken,identifierToken.value);var assignTarget=expression(155);assignTarget&&(checkLeftSideAssign(assignTarget),assignTarget.identifier&&(ident=assignTarget.value))}else ident=identifier();return ident&&identifiers.push({id:ident,token:state.tokens.curr}),is_rest}advance(\"(\"),nextInnerDE(),advance(\")\")}return!1},assignmentProperty=function(){var id;checkPunctuator(state.tokens.next,\"[\")?(advance(\"[\"),expression(10),advance(\"]\"),advance(\":\"),nextInnerDE()):\"(string)\"===state.tokens.next.id||\"(number)\"===state.tokens.next.id?(advance(),advance(\":\"),nextInnerDE()):(id=identifier(),checkPunctuator(state.tokens.next,\":\")?(advance(\":\"),nextInnerDE()):id&&(isAssignment&&checkLeftSideAssign(state.tokens.curr),identifiers.push({id:id,token:state.tokens.curr})))};if(checkPunctuator(firstToken,\"[\")){openingParsed||advance(\"[\"),checkPunctuator(state.tokens.next,\"]\")&&warning(\"W137\",state.tokens.curr);for(var element_after_rest=!1;!checkPunctuator(state.tokens.next,\"]\");)nextInnerDE()&&!element_after_rest&&checkPunctuator(state.tokens.next,\",\")&&(warning(\"W130\",state.tokens.next),element_after_rest=!0),checkPunctuator(state.tokens.next,\"=\")&&(checkPunctuator(state.tokens.prev,\"...\")?advance(\"]\"):advance(\"=\"),\"undefined\"===state.tokens.next.id&&warning(\"W080\",state.tokens.prev,state.tokens.prev.value),expression(10)),checkPunctuator(state.tokens.next,\"]\")||advance(\",\");advance(\"]\")}else if(checkPunctuator(firstToken,\"{\")){for(openingParsed||advance(\"{\"),checkPunctuator(state.tokens.next,\"}\")&&warning(\"W137\",state.tokens.curr);!checkPunctuator(state.tokens.next,\"}\")&&(assignmentProperty(),checkPunctuator(state.tokens.next,\"=\")&&(advance(\"=\"),\"undefined\"===state.tokens.next.id&&warning(\"W080\",state.tokens.prev,state.tokens.prev.value),expression(10)),checkPunctuator(state.tokens.next,\"}\")||(advance(\",\"),!checkPunctuator(state.tokens.next,\"}\"))););advance(\"}\")}return identifiers}function destructuringPatternMatch(tokens,value){var first=value.first;first&&_.zip(tokens,Array.isArray(first)?first:[first]).forEach(function(val){var token=val[0],value=val[1];token&&value?token.first=value:token&&token.first&&!value&&warning(\"W080\",token.first,token.first.value)})}function blockVariableStatement(type,statement,context){var tokens,lone,value,letblock,prefix=context&&context.prefix,inexport=context&&context.inexport,isLet=\"let\"===type,isConst=\"const\"===type;for(state.inES6()||warning(\"W104\",state.tokens.curr,type,\"6\"),isLet&&\"(\"===state.tokens.next.value?(state.inMoz()||warning(\"W118\",state.tokens.next,\"let block\"),advance(\"(\"),state.funct[\"(scope)\"].stack(),letblock=!0):state.funct[\"(noblockscopedvar)\"]&&error(\"E048\",state.tokens.curr,isConst?\"Const\":\"Let\"),statement.first=[];;){var names=[];_.contains([\"{\",\"[\"],state.tokens.next.value)?(tokens=destructuringPattern(),lone=!1):(tokens=[{id:identifier(),token:state.tokens.curr}],lone=!0),!prefix&&isConst&&\"=\"!==state.tokens.next.id&&warning(\"E012\",state.tokens.curr,state.tokens.curr.value);for(var t in tokens)tokens.hasOwnProperty(t)&&(t=tokens[t],state.funct[\"(scope)\"].block.isGlobal()&&predefined[t.id]===!1&&warning(\"W079\",t.token,t.id),t.id&&!state.funct[\"(noblockscopedvar)\"]&&(state.funct[\"(scope)\"].addlabel(t.id,{type:type,token:t.token}),names.push(t.token),lone&&inexport&&state.funct[\"(scope)\"].setExported(t.token.value,t.token)));if(\"=\"===state.tokens.next.id&&(advance(\"=\"),prefix||\"undefined\"!==state.tokens.next.id||warning(\"W080\",state.tokens.prev,state.tokens.prev.value),!prefix&&\"=\"===peek(0).id&&state.tokens.next.identifier&&warning(\"W120\",state.tokens.next,state.tokens.next.value),value=expression(prefix?120:10),lone?tokens[0].first=value:destructuringPatternMatch(names,value)),statement.first=statement.first.concat(names),\",\"!==state.tokens.next.id)break;comma()}return letblock&&(advance(\")\"),block(!0,!0),statement.block=!0,state.funct[\"(scope)\"].unstack()),statement}function classdef(isStatement){return state.inES6()||warning(\"W104\",state.tokens.curr,\"class\",\"6\"),isStatement?(this.name=identifier(),state.funct[\"(scope)\"].addlabel(this.name,{type:\"class\",token:state.tokens.curr})):state.tokens.next.identifier&&\"extends\"!==state.tokens.next.value?(this.name=identifier(),this.namedExpr=!0):this.name=state.nameStack.infer(),classtail(this),this}function classtail(c){var wasInClassBody=state.inClassBody;\"extends\"===state.tokens.next.value&&(advance(\"extends\"),c.heritage=expression(10)),state.inClassBody=!0,advance(\"{\"),c.body=classbody(c),advance(\"}\"),state.inClassBody=wasInClassBody}function classbody(c){for(var name,isStatic,isGenerator,getset,computed,props=Object.create(null),staticProps=Object.create(null),i=0;\"}\"!==state.tokens.next.id;++i)if(name=state.tokens.next,isStatic=!1,isGenerator=!1,getset=null,\";\"!==name.id){if(\"*\"===name.id&&(isGenerator=!0,advance(\"*\"),name=state.tokens.next),\"[\"===name.id)name=computedPropertyName(),computed=!0;else{if(!isPropertyName(name)){warning(\"W052\",state.tokens.next,state.tokens.next.value||state.tokens.next.type),advance();continue}advance(),computed=!1,name.identifier&&\"static\"===name.value&&(checkPunctuator(state.tokens.next,\"*\")&&(isGenerator=!0,advance(\"*\")),(isPropertyName(state.tokens.next)||\"[\"===state.tokens.next.id)&&(computed=\"[\"===state.tokens.next.id,isStatic=!0,name=state.tokens.next,\"[\"===state.tokens.next.id?name=computedPropertyName():advance())),!name.identifier||\"get\"!==name.value&&\"set\"!==name.value||(isPropertyName(state.tokens.next)||\"[\"===state.tokens.next.id)&&(computed=\"[\"===state.tokens.next.id,getset=name,name=state.tokens.next,\"[\"===state.tokens.next.id?name=computedPropertyName():advance())}if(!checkPunctuator(state.tokens.next,\"(\")){for(error(\"E054\",state.tokens.next,state.tokens.next.value);\"}\"!==state.tokens.next.id&&!checkPunctuator(state.tokens.next,\"(\");)advance();\"(\"!==state.tokens.next.value&&doFunction({statement:c})}if(computed||(getset?saveAccessor(getset.value,isStatic?staticProps:props,name.value,name,!0,isStatic):(\"constructor\"===name.value?state.nameStack.set(c):state.nameStack.set(name),saveProperty(isStatic?staticProps:props,name.value,name,!0,isStatic))),getset&&\"constructor\"===name.value){var propDesc=\"get\"===getset.value?\"class getter method\":\"class setter method\";error(\"E049\",name,propDesc,\"constructor\")}else\"prototype\"===name.value&&error(\"E049\",name,\"class method\",\"prototype\");propertyName(name),doFunction({statement:c,type:isGenerator?\"generator\":null,classExprBinding:c.namedExpr?c.name:null})}else warning(\"W032\"),advance(\";\");checkProperties(props)}function saveProperty(props,name,tkn,isClass,isStatic){var msg=[\"key\",\"class method\",\"static class method\"];msg=msg[(isClass||!1)+(isStatic||!1)],tkn.identifier&&(name=tkn.value),props[name]&&\"__proto__\"!==name?warning(\"W075\",state.tokens.next,msg,name):props[name]=Object.create(null),props[name].basic=!0,props[name].basictkn=tkn}function saveAccessor(accessorType,props,name,tkn,isClass,isStatic){var flagName=\"get\"===accessorType?\"getterToken\":\"setterToken\",msg=\"\";isClass?(isStatic&&(msg+=\"static \"),msg+=accessorType+\"ter method\"):msg=\"key\",state.tokens.curr.accessorType=accessorType,state.nameStack.set(tkn),props[name]?(props[name].basic||props[name][flagName])&&\"__proto__\"!==name&&warning(\"W075\",state.tokens.next,msg,name):props[name]=Object.create(null),props[name][flagName]=tkn}function computedPropertyName(){advance(\"[\"),state.inES6()||warning(\"W119\",state.tokens.curr,\"computed property names\",\"6\");var value=expression(10);return advance(\"]\"),value}function checkPunctuators(token,values){return\"(punctuator)\"===token.type?_.contains(values,token.value):!1}function checkPunctuator(token,value){return\"(punctuator)\"===token.type&&token.value===value}function destructuringAssignOrJsonValue(){var block=lookupBlockType();block.notJson?(!state.inES6()&&block.isDestAssign&&warning(\"W104\",state.tokens.curr,\"destructuring assignment\",\"6\"),statements()):(state.option.laxbreak=!0,state.jsonMode=!0,jsonValue())}function jsonValue(){function jsonObject(){var o={},t=state.tokens.next;if(advance(\"{\"),\"}\"!==state.tokens.next.id)for(;;){if(\"(end)\"===state.tokens.next.id)error(\"E026\",state.tokens.next,t.line);else{if(\"}\"===state.tokens.next.id){warning(\"W094\",state.tokens.curr);break}\",\"===state.tokens.next.id?error(\"E028\",state.tokens.next):\"(string)\"!==state.tokens.next.id&&warning(\"W095\",state.tokens.next,state.tokens.next.value)}if(o[state.tokens.next.value]===!0?warning(\"W075\",state.tokens.next,\"key\",state.tokens.next.value):\"__proto__\"===state.tokens.next.value&&!state.option.proto||\"__iterator__\"===state.tokens.next.value&&!state.option.iterator?warning(\"W096\",state.tokens.next,state.tokens.next.value):o[state.tokens.next.value]=!0,advance(),advance(\":\"),jsonValue(),\",\"!==state.tokens.next.id)break;advance(\",\")}advance(\"}\")}function jsonArray(){var t=state.tokens.next;if(advance(\"[\"),\"]\"!==state.tokens.next.id)for(;;){if(\"(end)\"===state.tokens.next.id)error(\"E027\",state.tokens.next,t.line);else{if(\"]\"===state.tokens.next.id){warning(\"W094\",state.tokens.curr);break}\",\"===state.tokens.next.id&&error(\"E028\",state.tokens.next)}if(jsonValue(),\",\"!==state.tokens.next.id)break;advance(\",\")}advance(\"]\")}switch(state.tokens.next.id){case\"{\":jsonObject();break;case\"[\":jsonArray();break;case\"true\":case\"false\":case\"null\":case\"(number)\":case\"(string)\":advance();break;case\"-\":advance(\"-\"),advance(\"(number)\");break;default:error(\"E003\",state.tokens.next)}}var api,declared,functions,inblock,indent,lookahead,lex,member,membersOnly,predefined,stack,urls,bang={\"<\":!0,\"<=\":!0,\"==\":!0,\"===\":!0,\"!==\":!0,\"!=\":!0,\">\":!0,\">=\":!0,\"+\":!0,\"-\":!0,\"*\":!0,\"/\":!0,\"%\":!0},functionicity=[\"closure\",\"exception\",\"global\",\"label\",\"outer\",\"unused\",\"var\"],extraModules=[],emitter=new events.EventEmitter,typeofValues={};typeofValues.legacy=[\"xml\",\"unknown\"],typeofValues.es3=[\"undefined\",\"boolean\",\"number\",\"string\",\"function\",\"object\"],typeofValues.es3=typeofValues.es3.concat(typeofValues.legacy),typeofValues.es6=typeofValues.es3.concat(\"symbol\"),type(\"(number)\",function(){return this}),type(\"(string)\",function(){return this}),state.syntax[\"(identifier)\"]={type:\"(identifier)\",lbp:0,identifier:!0,nud:function(){var v=this.value;return\"=>\"===state.tokens.next.id?this:(state.funct[\"(comparray)\"].check(v)||state.funct[\"(scope)\"].block.use(v,state.tokens.curr),this)},led:function(){error(\"E033\",state.tokens.next,state.tokens.next.value)}};var baseTemplateSyntax={lbp:0,identifier:!1,template:!0};state.syntax[\"(template)\"]=_.extend({type:\"(template)\",nud:doTemplateLiteral,led:doTemplateLiteral,noSubst:!1},baseTemplateSyntax),state.syntax[\"(template middle)\"]=_.extend({type:\"(template middle)\",middle:!0,noSubst:!1},baseTemplateSyntax),state.syntax[\"(template tail)\"]=_.extend({type:\"(template tail)\",tail:!0,noSubst:!1},baseTemplateSyntax),state.syntax[\"(no subst template)\"]=_.extend({type:\"(template)\",nud:doTemplateLiteral,led:doTemplateLiteral,noSubst:!0,tail:!0},baseTemplateSyntax),type(\"(regexp)\",function(){return this}),delim(\"(endline)\"),delim(\"(begin)\"),delim(\"(end)\").reach=!0,delim(\"(error)\").reach=!0,delim(\"}\").reach=!0,delim(\")\"),delim(\"]\"),delim('\"').reach=!0,delim(\"'\").reach=!0,delim(\";\"),delim(\":\").reach=!0,delim(\"#\"),reserve(\"else\"),reserve(\"case\").reach=!0,reserve(\"catch\"),reserve(\"default\").reach=!0,reserve(\"finally\"),reservevar(\"arguments\",function(x){state.isStrict()&&state.funct[\"(global)\"]&&warning(\"E008\",x)}),reservevar(\"eval\"),reservevar(\"false\"),reservevar(\"Infinity\"),reservevar(\"null\"),reservevar(\"this\",function(x){state.isStrict()&&!isMethod()&&!state.option.validthis&&(state.funct[\"(statement)\"]&&state.funct[\"(name)\"].charAt(0)>\"Z\"||state.funct[\"(global)\"])&&warning(\"W040\",x)}),reservevar(\"true\"),reservevar(\"undefined\"),assignop(\"=\",\"assign\",20),assignop(\"+=\",\"assignadd\",20),assignop(\"-=\",\"assignsub\",20),assignop(\"*=\",\"assignmult\",20),assignop(\"/=\",\"assigndiv\",20).nud=function(){error(\"E014\")},assignop(\"%=\",\"assignmod\",20),bitwiseassignop(\"&=\"),bitwiseassignop(\"|=\"),bitwiseassignop(\"^=\"),bitwiseassignop(\"<<=\"),bitwiseassignop(\">>=\"),bitwiseassignop(\">>>=\"),infix(\",\",function(left,that){var expr;if(that.exprs=[left],state.option.nocomma&&warning(\"W127\"),!comma({peek:!0}))return that;for(;;){if(!(expr=expression(10)))break;if(that.exprs.push(expr),\",\"!==state.tokens.next.value||!comma())break}return that},10,!0),infix(\"?\",function(left,that){return increaseComplexityCount(),that.left=left,that.right=expression(10),advance(\":\"),that[\"else\"]=expression(10),that},30);var orPrecendence=40;infix(\"||\",function(left,that){return increaseComplexityCount(),that.left=left,that.right=expression(orPrecendence),that},orPrecendence),infix(\"&&\",\"and\",50),bitwise(\"|\",\"bitor\",70),bitwise(\"^\",\"bitxor\",80),bitwise(\"&\",\"bitand\",90),relation(\"==\",function(left,right){var eqnull=state.option.eqnull&&(\"null\"===(left&&left.value)||\"null\"===(right&&right.value));switch(!0){case!eqnull&&state.option.eqeqeq:this.from=this.character,warning(\"W116\",this,\"===\",\"==\");break;case isPoorRelation(left):warning(\"W041\",this,\"===\",left.value);break;case isPoorRelation(right):warning(\"W041\",this,\"===\",right.value);break;case isTypoTypeof(right,left,state):warning(\"W122\",this,right.value);break;case isTypoTypeof(left,right,state):warning(\"W122\",this,left.value)}return this}),relation(\"===\",function(left,right){return isTypoTypeof(right,left,state)?warning(\"W122\",this,right.value):isTypoTypeof(left,right,state)&&warning(\"W122\",this,left.value),this}),relation(\"!=\",function(left,right){var eqnull=state.option.eqnull&&(\"null\"===(left&&left.value)||\"null\"===(right&&right.value));return!eqnull&&state.option.eqeqeq?(this.from=this.character,warning(\"W116\",this,\"!==\",\"!=\")):isPoorRelation(left)?warning(\"W041\",this,\"!==\",left.value):isPoorRelation(right)?warning(\"W041\",this,\"!==\",right.value):isTypoTypeof(right,left,state)?warning(\"W122\",this,right.value):isTypoTypeof(left,right,state)&&warning(\"W122\",this,left.value),this}),relation(\"!==\",function(left,right){return isTypoTypeof(right,left,state)?warning(\"W122\",this,right.value):isTypoTypeof(left,right,state)&&warning(\"W122\",this,left.value),this}),relation(\"<\"),relation(\">\"),relation(\"<=\"),relation(\">=\"),bitwise(\"<<\",\"shiftleft\",120),bitwise(\">>\",\"shiftright\",120),bitwise(\">>>\",\"shiftrightunsigned\",120),infix(\"in\",\"in\",120),infix(\"instanceof\",\"instanceof\",120),infix(\"+\",function(left,that){var right;return that.left=left,that.right=right=expression(130),left&&right&&\"(string)\"===left.id&&\"(string)\"===right.id?(left.value+=right.value,left.character=right.character,!state.option.scripturl&&reg.javascriptURL.test(left.value)&&warning(\"W050\",left),left):that},130),prefix(\"+\",\"num\"),prefix(\"+++\",function(){return warning(\"W007\"),this.arity=\"unary\",this.right=expression(150),this}),infix(\"+++\",function(left){return warning(\"W007\"),this.left=left,this.right=expression(130),this},130),infix(\"-\",\"sub\",130),prefix(\"-\",\"neg\"),prefix(\"---\",function(){return warning(\"W006\"),this.arity=\"unary\",this.right=expression(150),this}),infix(\"---\",function(left){return warning(\"W006\"),this.left=left,this.right=expression(130),this},130),infix(\"*\",\"mult\",140),infix(\"/\",\"div\",140),infix(\"%\",\"mod\",140),suffix(\"++\"),prefix(\"++\",\"preinc\"),state.syntax[\"++\"].exps=!0,suffix(\"--\"),prefix(\"--\",\"predec\"),state.syntax[\"--\"].exps=!0,prefix(\"delete\",function(){var p=expression(10);return p?(\".\"!==p.id&&\"[\"!==p.id&&warning(\"W051\"),this.first=p,p.identifier&&!state.isStrict()&&(p.forgiveUndef=!0),this):this}).exps=!0,prefix(\"~\",function(){return state.option.bitwise&&warning(\"W016\",this,\"~\"),this.arity=\"unary\",this.right=expression(150),this}),prefix(\"...\",function(){return state.inES6(!0)||warning(\"W119\",this,\"spread/rest operator\",\"6\"),state.tokens.next.identifier||\"(string)\"===state.tokens.next.type||checkPunctuators(state.tokens.next,[\"[\",\"(\"])||error(\"E030\",state.tokens.next,state.tokens.next.value),expression(150),this}),prefix(\"!\",function(){return this.arity=\"unary\",this.right=expression(150),this.right||quit(\"E041\",this.line||0),bang[this.right.id]===!0&&warning(\"W018\",this,\"!\"),this}),prefix(\"typeof\",function(){var p=expression(150);return this.first=this.right=p,p||quit(\"E041\",this.line||0,this.character||0),p.identifier&&(p.forgiveUndef=!0),this}),prefix(\"new\",function(){var mp=metaProperty(\"target\",function(){state.inES6(!0)||warning(\"W119\",state.tokens.prev,\"new.target\",\"6\");for(var inFunction,c=state.funct;c&&(inFunction=!c[\"(global)\"],c[\"(arrow)\"]);)c=c[\"(context)\"];inFunction||warning(\"W136\",state.tokens.prev,\"new.target\")});if(mp)return mp;var i,c=expression(155);if(c&&\"function\"!==c.id)if(c.identifier)switch(c[\"new\"]=!0,c.value){case\"Number\":case\"String\":case\"Boolean\":case\"Math\":case\"JSON\":warning(\"W053\",state.tokens.prev,c.value);break;case\"Symbol\":state.inES6()&&warning(\"W053\",state.tokens.prev,c.value);break;case\"Function\":state.option.evil||warning(\"W054\");break;case\"Date\":case\"RegExp\":case\"this\":break;default:\"function\"!==c.id&&(i=c.value.substr(0,1),state.option.newcap&&(\"A\">i||i>\"Z\")&&!state.funct[\"(scope)\"].isPredefined(c.value)&&warning(\"W055\",state.tokens.curr))}else\".\"!==c.id&&\"[\"!==c.id&&\"(\"!==c.id&&warning(\"W056\",state.tokens.curr);else state.option.supernew||warning(\"W057\",this);return\"(\"===state.tokens.next.id||state.option.supernew||warning(\"W058\",state.tokens.curr,state.tokens.curr.value),this.first=this.right=c,this}),state.syntax[\"new\"].exps=!0,prefix(\"void\").exps=!0,infix(\".\",function(left,that){var m=identifier(!1,!0);return\"string\"==typeof m&&countMember(m),that.left=left,that.right=m,m&&\"hasOwnProperty\"===m&&\"=\"===state.tokens.next.value&&warning(\"W001\"),!left||\"arguments\"!==left.value||\"callee\"!==m&&\"caller\"!==m?state.option.evil||!left||\"document\"!==left.value||\"write\"!==m&&\"writeln\"!==m||warning(\"W060\",left):state.option.noarg?warning(\"W059\",left,m):state.isStrict()&&error(\"E008\"),state.option.evil||\"eval\"!==m&&\"execScript\"!==m||isGlobalEval(left,state)&&warning(\"W061\"),that},160,!0),infix(\"(\",function(left,that){state.option.immed&&left&&!left.immed&&\"function\"===left.id&&warning(\"W062\");var n=0,p=[];if(left&&\"(identifier)\"===left.type&&left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)&&-1===\"Array Number String Boolean Date Object Error Symbol\".indexOf(left.value)&&(\"Math\"===left.value?warning(\"W063\",left):state.option.newcap&&warning(\"W064\",left)),\")\"!==state.tokens.next.id)for(;p[p.length]=expression(10),n+=1,\",\"===state.tokens.next.id;)comma();return advance(\")\"),\"object\"==typeof left&&(state.inES5()||\"parseInt\"!==left.value||1!==n||warning(\"W065\",state.tokens.curr),state.option.evil||(\"eval\"===left.value||\"Function\"===left.value||\"execScript\"===left.value?(warning(\"W061\",left),p[0]&&\"(string)\"===[0].id&&addInternalSrc(left,p[0].value)):!p[0]||\"(string)\"!==p[0].id||\"setTimeout\"!==left.value&&\"setInterval\"!==left.value?!p[0]||\"(string)\"!==p[0].id||\".\"!==left.value||\"window\"!==left.left.value||\"setTimeout\"!==left.right&&\"setInterval\"!==left.right||(warning(\"W066\",left),addInternalSrc(left,p[0].value)):(warning(\"W066\",left),addInternalSrc(left,p[0].value))),left.identifier||\".\"===left.id||\"[\"===left.id||\"=>\"===left.id||\"(\"===left.id||\"&&\"===left.id||\"||\"===left.id||\"?\"===left.id||state.inES6()&&left[\"(name)\"]||warning(\"W067\",that)),that.left=left,that},155,!0).exps=!0,prefix(\"(\",function(){var pn1,ret,triggerFnExpr,first,last,pn=state.tokens.next,i=-1,parens=1,opening=state.tokens.curr,preceeding=state.tokens.prev,isNecessary=!state.option.singleGroups;do\"(\"===pn.value?parens+=1:\")\"===pn.value&&(parens-=1),i+=1,pn1=pn,pn=peek(i);while((0!==parens||\")\"!==pn1.value)&&\";\"!==pn.value&&\"(end)\"!==pn.type);if(\"function\"===state.tokens.next.id&&(triggerFnExpr=state.tokens.next.immed=!0),\"=>\"===pn.value)return doFunction({type:\"arrow\",parsedOpening:!0});var exprs=[];if(\")\"!==state.tokens.next.id)for(;exprs.push(expression(10)),\",\"===state.tokens.next.id;)state.option.nocomma&&warning(\"W127\"),comma();return advance(\")\",this),state.option.immed&&exprs[0]&&\"function\"===exprs[0].id&&\"(\"!==state.tokens.next.id&&\".\"!==state.tokens.next.id&&\"[\"!==state.tokens.next.id&&warning(\"W068\",this),exprs.length?(exprs.length>1?(ret=Object.create(state.syntax[\",\"]),ret.exprs=exprs,first=exprs[0],last=exprs[exprs.length-1],isNecessary||(isNecessary=preceeding.assign||preceeding.delim)):(ret=first=last=exprs[0],isNecessary||(isNecessary=opening.beginsStmt&&(\"{\"===ret.id||triggerFnExpr||isFunctor(ret))||triggerFnExpr&&(!isEndOfExpr()||\"}\"!==state.tokens.prev.id)||isFunctor(ret)&&!isEndOfExpr()||\"{\"===ret.id&&\"=>\"===preceeding.id||\"(number)\"===ret.type&&checkPunctuator(pn,\".\")&&/^\\d+$/.test(ret.value))),ret&&(!isNecessary&&(first.left||first.right||ret.exprs)&&(isNecessary=!isBeginOfExpr(preceeding)&&first.lbp<=preceeding.lbp||!isEndOfExpr()&&last.lbp<state.tokens.next.lbp),isNecessary||warning(\"W126\",opening),ret.paren=!0),ret):void 0}),application(\"=>\"),infix(\"[\",function(left,that){var s,e=expression(10);return e&&\"(string)\"===e.type&&(state.option.evil||\"eval\"!==e.value&&\"execScript\"!==e.value||isGlobalEval(left,state)&&warning(\"W061\"),countMember(e.value),!state.option.sub&&reg.identifier.test(e.value)&&(s=state.syntax[e.value],s&&isReserved(s)||warning(\"W069\",state.tokens.prev,e.value))),advance(\"]\",that),e&&\"hasOwnProperty\"===e.value&&\"=\"===state.tokens.next.value&&warning(\"W001\"),that.left=left,that.right=e,that},160,!0),prefix(\"[\",function(){var blocktype=lookupBlockType();if(blocktype.isCompArray)return state.option.esnext||state.inMoz()||warning(\"W118\",state.tokens.curr,\"array comprehension\"),comprehensiveArrayExpression();if(blocktype.isDestAssign)return this.destructAssign=destructuringPattern({openingParsed:!0,assignment:!0}),this;var b=state.tokens.curr.line!==startLine(state.tokens.next);for(this.first=[],b&&(indent+=state.option.indent,state.tokens.next.from===indent+state.option.indent&&(indent+=state.option.indent));\"(end)\"!==state.tokens.next.id;){for(;\",\"===state.tokens.next.id;){if(!state.option.elision){if(state.inES5()){warning(\"W128\");do advance(\",\");while(\",\"===state.tokens.next.id);continue}warning(\"W070\")}advance(\",\")}if(\"]\"===state.tokens.next.id)break;if(this.first.push(expression(10)),\",\"!==state.tokens.next.id)break;if(comma({allowTrailing:!0}),\"]\"===state.tokens.next.id&&!state.inES5()){warning(\"W070\",state.tokens.curr);break}}return b&&(indent-=state.option.indent),advance(\"]\",this),this}),function(x){x.nud=function(){var b,f,i,p,t,nextVal,isGeneratorMethod=!1,props=Object.create(null);b=state.tokens.curr.line!==startLine(state.tokens.next),b&&(indent+=state.option.indent,state.tokens.next.from===indent+state.option.indent&&(indent+=state.option.indent));var blocktype=lookupBlockType();if(blocktype.isDestAssign)return this.destructAssign=destructuringPattern({openingParsed:!0,assignment:!0}),this;for(;\"}\"!==state.tokens.next.id;){if(nextVal=state.tokens.next.value,!state.tokens.next.identifier||\",\"!==peekIgnoreEOL().id&&\"}\"!==peekIgnoreEOL().id)if(\":\"===peek().id||\"get\"!==nextVal&&\"set\"!==nextVal){if(\"*\"===state.tokens.next.value&&\"(punctuator)\"===state.tokens.next.type?(state.inES6()||warning(\"W104\",state.tokens.next,\"generator functions\",\"6\"),advance(\"*\"),isGeneratorMethod=!0):isGeneratorMethod=!1,\"[\"===state.tokens.next.id)i=computedPropertyName(),state.nameStack.set(i);else if(state.nameStack.set(state.tokens.next),i=propertyName(),saveProperty(props,i,state.tokens.next),\"string\"!=typeof i)break;\"(\"===state.tokens.next.value?(state.inES6()||warning(\"W104\",state.tokens.curr,\"concise methods\",\"6\"),doFunction({type:isGeneratorMethod?\"generator\":null})):(advance(\":\"),expression(10))}else advance(nextVal),state.inES5()||error(\"E034\"),i=propertyName(),i||state.inES6()||error(\"E035\"),i&&saveAccessor(nextVal,props,i,state.tokens.curr),t=state.tokens.next,f=doFunction(),p=f[\"(params)\"],\"get\"===nextVal&&i&&p?warning(\"W076\",t,p[0],i):\"set\"!==nextVal||!i||p&&1===p.length||warning(\"W077\",t,i);else state.inES6()||warning(\"W104\",state.tokens.next,\"object short notation\",\"6\"),i=propertyName(!0),saveProperty(props,i,state.tokens.next),expression(10);if(countMember(i),\",\"!==state.tokens.next.id)break;comma({allowTrailing:!0,property:!0}),\",\"===state.tokens.next.id?warning(\"W070\",state.tokens.curr):\"}\"!==state.tokens.next.id||state.inES5()||warning(\"W070\",state.tokens.curr)}return b&&(indent-=state.option.indent),advance(\"}\",this),checkProperties(props),this},x.fud=function(){error(\"E036\",state.tokens.curr)}}(delim(\"{\"));var conststatement=stmt(\"const\",function(context){return blockVariableStatement(\"const\",this,context)});conststatement.exps=!0;var letstatement=stmt(\"let\",function(context){return blockVariableStatement(\"let\",this,context)});letstatement.exps=!0;var varstatement=stmt(\"var\",function(context){var tokens,lone,value,prefix=context&&context.prefix,inexport=context&&context.inexport,implied=context&&context.implied,report=!(context&&context.ignore);for(this.first=[];;){var names=[];_.contains([\"{\",\"[\"],state.tokens.next.value)?(tokens=destructuringPattern(),lone=!1):(tokens=[{id:identifier(),token:state.tokens.curr}],lone=!0),prefix&&implied||!report||!state.option.varstmt||warning(\"W132\",this),this.first=this.first.concat(names);for(var t in tokens)tokens.hasOwnProperty(t)&&(t=tokens[t],!implied&&state.funct[\"(global)\"]&&(predefined[t.id]===!1?warning(\"W079\",t.token,t.id):state.option.futurehostile===!1&&(!state.inES5()&&vars.ecmaIdentifiers[5][t.id]===!1||!state.inES6()&&vars.ecmaIdentifiers[6][t.id]===!1)&&warning(\"W129\",t.token,t.id)),t.id&&(\"for\"===implied?(state.funct[\"(scope)\"].has(t.id)||report&&warning(\"W088\",t.token,t.id),state.funct[\"(scope)\"].block.use(t.id,t.token)):(state.funct[\"(scope)\"].addlabel(t.id,{type:\"var\",token:t.token}),lone&&inexport&&state.funct[\"(scope)\"].setExported(t.id,t.token)),names.push(t.token)));if(\"=\"===state.tokens.next.id&&(state.nameStack.set(state.tokens.curr),advance(\"=\"),prefix||!report||state.funct[\"(loopage)\"]||\"undefined\"!==state.tokens.next.id||warning(\"W080\",state.tokens.prev,state.tokens.prev.value),\"=\"===peek(0).id&&state.tokens.next.identifier&&(!prefix&&report&&!state.funct[\"(params)\"]||-1===state.funct[\"(params)\"].indexOf(state.tokens.next.value))&&warning(\"W120\",state.tokens.next,state.tokens.next.value),value=expression(prefix?120:10),lone?tokens[0].first=value:destructuringPatternMatch(names,value)),\",\"!==state.tokens.next.id)break;comma()}return this});varstatement.exps=!0,blockstmt(\"class\",function(){return classdef.call(this,!0)}),blockstmt(\"function\",function(context){var inexport=context&&context.inexport,generator=!1;\"*\"===state.tokens.next.value&&(advance(\"*\"),state.inES6({strict:!0})?generator=!0:warning(\"W119\",state.tokens.curr,\"function*\",\"6\")),inblock&&warning(\"W082\",state.tokens.curr);var i=optionalidentifier();return state.funct[\"(scope)\"].addlabel(i,{type:\"function\",token:state.tokens.curr}),void 0===i?warning(\"W025\"):inexport&&state.funct[\"(scope)\"].setExported(i,state.tokens.prev),doFunction({name:i,statement:this,type:generator?\"generator\":null,ignoreLoopFunc:inblock}),\"(\"===state.tokens.next.id&&state.tokens.next.line===state.tokens.curr.line&&error(\"E039\"),this}),prefix(\"function\",function(){var generator=!1;\"*\"===state.tokens.next.value&&(state.inES6()||warning(\"W119\",state.tokens.curr,\"function*\",\"6\"),advance(\"*\"),generator=!0);var i=optionalidentifier();return doFunction({name:i,type:generator?\"generator\":null}),this}),blockstmt(\"if\",function(){var t=state.tokens.next;increaseComplexityCount(),state.condition=!0,advance(\"(\");var expr=expression(0);checkCondAssignment(expr);var forinifcheck=null;state.option.forin&&state.forinifcheckneeded&&(state.forinifcheckneeded=!1,forinifcheck=state.forinifchecks[state.forinifchecks.length-1],forinifcheck.type=\"(punctuator)\"===expr.type&&\"!\"===expr.value?\"(negative)\":\"(positive)\"),advance(\")\",t),state.condition=!1;var s=block(!0,!0);return forinifcheck&&\"(negative)\"===forinifcheck.type&&s&&s[0]&&\"(identifier)\"===s[0].type&&\"continue\"===s[0].value&&(forinifcheck.type=\"(negative-with-continue)\"),\"else\"===state.tokens.next.id&&(advance(\"else\"),\"if\"===state.tokens.next.id||\"switch\"===state.tokens.next.id?statement():block(!0,!0)),this}),blockstmt(\"try\",function(){function doCatch(){if(advance(\"catch\"),advance(\"(\"),state.funct[\"(scope)\"].stack(\"catchparams\"),checkPunctuators(state.tokens.next,[\"[\",\"{\"])){var tokens=destructuringPattern();_.each(tokens,function(token){token.id&&state.funct[\"(scope)\"].addParam(token.id,token,\"exception\")})}else\"(identifier)\"!==state.tokens.next.type?warning(\"E030\",state.tokens.next,state.tokens.next.value):state.funct[\"(scope)\"].addParam(identifier(),state.tokens.curr,\"exception\");\"if\"===state.tokens.next.value&&(state.inMoz()||warning(\"W118\",state.tokens.curr,\"catch filter\"),advance(\"if\"),expression(0)),advance(\")\"),block(!1),state.funct[\"(scope)\"].unstack()}var b;for(block(!0);\"catch\"===state.tokens.next.id;)increaseComplexityCount(),b&&!state.inMoz()&&warning(\"W118\",state.tokens.next,\"multiple catch blocks\"),doCatch(),b=!0;return\"finally\"===state.tokens.next.id?(advance(\"finally\"),block(!0),void 0):(b||error(\"E021\",state.tokens.next,\"catch\",state.tokens.next.value),this)}),blockstmt(\"while\",function(){var t=state.tokens.next;return state.funct[\"(breakage)\"]+=1,state.funct[\"(loopage)\"]+=1,increaseComplexityCount(),advance(\"(\"),checkCondAssignment(expression(0)),advance(\")\",t),block(!0,!0),state.funct[\"(breakage)\"]-=1,state.funct[\"(loopage)\"]-=1,this}).labelled=!0,blockstmt(\"with\",function(){var t=state.tokens.next;return state.isStrict()?error(\"E010\",state.tokens.curr):state.option.withstmt||warning(\"W085\",state.tokens.curr),advance(\"(\"),expression(0),advance(\")\",t),block(!0,!0),this}),blockstmt(\"switch\",function(){var t=state.tokens.next,g=!1,noindent=!1;\nfor(state.funct[\"(breakage)\"]+=1,advance(\"(\"),checkCondAssignment(expression(0)),advance(\")\",t),t=state.tokens.next,advance(\"{\"),state.tokens.next.from===indent&&(noindent=!0),noindent||(indent+=state.option.indent),this.cases=[];;)switch(state.tokens.next.id){case\"case\":switch(state.funct[\"(verb)\"]){case\"yield\":case\"break\":case\"case\":case\"continue\":case\"return\":case\"switch\":case\"throw\":break;default:state.tokens.curr.caseFallsThrough||warning(\"W086\",state.tokens.curr,\"case\")}advance(\"case\"),this.cases.push(expression(0)),increaseComplexityCount(),g=!0,advance(\":\"),state.funct[\"(verb)\"]=\"case\";break;case\"default\":switch(state.funct[\"(verb)\"]){case\"yield\":case\"break\":case\"continue\":case\"return\":case\"throw\":break;default:this.cases.length&&(state.tokens.curr.caseFallsThrough||warning(\"W086\",state.tokens.curr,\"default\"))}advance(\"default\"),g=!0,advance(\":\");break;case\"}\":return noindent||(indent-=state.option.indent),advance(\"}\",t),state.funct[\"(breakage)\"]-=1,state.funct[\"(verb)\"]=void 0,void 0;case\"(end)\":return error(\"E023\",state.tokens.next,\"}\"),void 0;default:if(indent+=state.option.indent,g)switch(state.tokens.curr.id){case\",\":return error(\"E040\"),void 0;case\":\":g=!1,statements();break;default:return error(\"E025\",state.tokens.curr),void 0}else{if(\":\"!==state.tokens.curr.id)return error(\"E021\",state.tokens.next,\"case\",state.tokens.next.value),void 0;advance(\":\"),error(\"E024\",state.tokens.curr,\":\"),statements()}indent-=state.option.indent}return this}).labelled=!0,stmt(\"debugger\",function(){return state.option.debug||warning(\"W087\",this),this}).exps=!0,function(){var x=stmt(\"do\",function(){state.funct[\"(breakage)\"]+=1,state.funct[\"(loopage)\"]+=1,increaseComplexityCount(),this.first=block(!0,!0),advance(\"while\");var t=state.tokens.next;return advance(\"(\"),checkCondAssignment(expression(0)),advance(\")\",t),state.funct[\"(breakage)\"]-=1,state.funct[\"(loopage)\"]-=1,this});x.labelled=!0,x.exps=!0}(),blockstmt(\"for\",function(){var s,t=state.tokens.next,letscope=!1,foreachtok=null;\"each\"===t.value&&(foreachtok=t,advance(\"each\"),state.inMoz()||warning(\"W118\",state.tokens.curr,\"for each\")),increaseComplexityCount(),advance(\"(\");var nextop,comma,initializer,i=0,inof=[\"in\",\"of\"],level=0;checkPunctuators(state.tokens.next,[\"{\",\"[\"])&&++level;do{if(nextop=peek(i),++i,checkPunctuators(nextop,[\"{\",\"[\"])?++level:checkPunctuators(nextop,[\"}\",\"]\"])&&--level,0>level)break;0===level&&(!comma&&checkPunctuator(nextop,\",\")?comma=nextop:!initializer&&checkPunctuator(nextop,\"=\")&&(initializer=nextop))}while(level>0||!_.contains(inof,nextop.value)&&\";\"!==nextop.value&&\"(end)\"!==nextop.type);if(_.contains(inof,nextop.value)){state.inES6()||\"of\"!==nextop.value||warning(\"W104\",nextop,\"for of\",\"6\");var ok=!(initializer||comma);if(initializer&&error(\"W133\",comma,nextop.value,\"initializer is forbidden\"),comma&&error(\"W133\",comma,nextop.value,\"more than one ForBinding\"),\"var\"===state.tokens.next.id?(advance(\"var\"),state.tokens.curr.fud({prefix:!0})):\"let\"===state.tokens.next.id||\"const\"===state.tokens.next.id?(advance(state.tokens.next.id),letscope=!0,state.funct[\"(scope)\"].stack(),state.tokens.curr.fud({prefix:!0})):Object.create(varstatement).fud({prefix:!0,implied:\"for\",ignore:!ok}),advance(nextop.value),expression(20),advance(\")\",t),\"in\"===nextop.value&&state.option.forin&&(state.forinifcheckneeded=!0,void 0===state.forinifchecks&&(state.forinifchecks=[]),state.forinifchecks.push({type:\"(none)\"})),state.funct[\"(breakage)\"]+=1,state.funct[\"(loopage)\"]+=1,s=block(!0,!0),\"in\"===nextop.value&&state.option.forin){if(state.forinifchecks&&state.forinifchecks.length>0){var check=state.forinifchecks.pop();(s&&s.length>0&&(\"object\"!=typeof s[0]||\"if\"!==s[0].value)||\"(positive)\"===check.type&&s.length>1||\"(negative)\"===check.type)&&warning(\"W089\",this)}state.forinifcheckneeded=!1}state.funct[\"(breakage)\"]-=1,state.funct[\"(loopage)\"]-=1}else{if(foreachtok&&error(\"E045\",foreachtok),\";\"!==state.tokens.next.id)if(\"var\"===state.tokens.next.id)advance(\"var\"),state.tokens.curr.fud();else if(\"let\"===state.tokens.next.id)advance(\"let\"),letscope=!0,state.funct[\"(scope)\"].stack(),state.tokens.curr.fud();else for(;expression(0,\"for\"),\",\"===state.tokens.next.id;)comma();if(nolinebreak(state.tokens.curr),advance(\";\"),state.funct[\"(loopage)\"]+=1,\";\"!==state.tokens.next.id&&checkCondAssignment(expression(0)),nolinebreak(state.tokens.curr),advance(\";\"),\";\"===state.tokens.next.id&&error(\"E021\",state.tokens.next,\")\",\";\"),\")\"!==state.tokens.next.id)for(;expression(0,\"for\"),\",\"===state.tokens.next.id;)comma();advance(\")\",t),state.funct[\"(breakage)\"]+=1,block(!0,!0),state.funct[\"(breakage)\"]-=1,state.funct[\"(loopage)\"]-=1}return letscope&&state.funct[\"(scope)\"].unstack(),this}).labelled=!0,stmt(\"break\",function(){var v=state.tokens.next.value;return state.option.asi||nolinebreak(this),\";\"===state.tokens.next.id||state.tokens.next.reach||state.tokens.curr.line!==startLine(state.tokens.next)?0===state.funct[\"(breakage)\"]&&warning(\"W052\",state.tokens.next,this.value):(state.funct[\"(scope)\"].funct.hasBreakLabel(v)||warning(\"W090\",state.tokens.next,v),this.first=state.tokens.next,advance()),reachable(this),this}).exps=!0,stmt(\"continue\",function(){var v=state.tokens.next.value;return 0===state.funct[\"(breakage)\"]&&warning(\"W052\",state.tokens.next,this.value),state.funct[\"(loopage)\"]||warning(\"W052\",state.tokens.next,this.value),state.option.asi||nolinebreak(this),\";\"===state.tokens.next.id||state.tokens.next.reach||state.tokens.curr.line===startLine(state.tokens.next)&&(state.funct[\"(scope)\"].funct.hasBreakLabel(v)||warning(\"W090\",state.tokens.next,v),this.first=state.tokens.next,advance()),reachable(this),this}).exps=!0,stmt(\"return\",function(){return this.line===startLine(state.tokens.next)?\";\"===state.tokens.next.id||state.tokens.next.reach||(this.first=expression(0),!this.first||\"(punctuator)\"!==this.first.type||\"=\"!==this.first.value||this.first.paren||state.option.boss||warningAt(\"W093\",this.first.line,this.first.character)):\"(punctuator)\"===state.tokens.next.type&&[\"[\",\"{\",\"+\",\"-\"].indexOf(state.tokens.next.value)>-1&&nolinebreak(this),reachable(this),this}).exps=!0,function(x){x.exps=!0,x.lbp=25}(prefix(\"yield\",function(){var prev=state.tokens.prev;state.inES6(!0)&&!state.funct[\"(generator)\"]?\"(catch)\"===state.funct[\"(name)\"]&&state.funct[\"(context)\"][\"(generator)\"]||error(\"E046\",state.tokens.curr,\"yield\"):state.inES6()||warning(\"W104\",state.tokens.curr,\"yield\",\"6\"),state.funct[\"(generator)\"]=\"yielded\";var delegatingYield=!1;return\"*\"===state.tokens.next.value&&(delegatingYield=!0,advance(\"*\")),this.line!==startLine(state.tokens.next)&&state.inMoz()?state.option.asi||nolinebreak(this):((delegatingYield||\";\"!==state.tokens.next.id&&!state.option.asi&&!state.tokens.next.reach&&state.tokens.next.nud)&&(nobreaknonadjacent(state.tokens.curr,state.tokens.next),this.first=expression(10),\"(punctuator)\"!==this.first.type||\"=\"!==this.first.value||this.first.paren||state.option.boss||warningAt(\"W093\",this.first.line,this.first.character)),state.inMoz()&&\")\"!==state.tokens.next.id&&(prev.lbp>30||!prev.assign&&!isEndOfExpr()||\"yield\"===prev.id)&&error(\"E050\",this)),this})),stmt(\"throw\",function(){return nolinebreak(this),this.first=expression(20),reachable(this),this}).exps=!0,stmt(\"import\",function(){if(state.inES6()||warning(\"W119\",state.tokens.curr,\"import\",\"6\"),\"(string)\"===state.tokens.next.type)return advance(\"(string)\"),this;if(state.tokens.next.identifier){if(this.name=identifier(),state.funct[\"(scope)\"].addlabel(this.name,{type:\"const\",token:state.tokens.curr}),\",\"!==state.tokens.next.value)return advance(\"from\"),advance(\"(string)\"),this;advance(\",\")}if(\"*\"===state.tokens.next.id)advance(\"*\"),advance(\"as\"),state.tokens.next.identifier&&(this.name=identifier(),state.funct[\"(scope)\"].addlabel(this.name,{type:\"const\",token:state.tokens.curr}));else for(advance(\"{\");;){if(\"}\"===state.tokens.next.value){advance(\"}\");break}var importName;if(\"default\"===state.tokens.next.type?(importName=\"default\",advance(\"default\")):importName=identifier(),\"as\"===state.tokens.next.value&&(advance(\"as\"),importName=identifier()),state.funct[\"(scope)\"].addlabel(importName,{type:\"const\",token:state.tokens.curr}),\",\"!==state.tokens.next.value){if(\"}\"===state.tokens.next.value){advance(\"}\");break}error(\"E024\",state.tokens.next,state.tokens.next.value);break}advance(\",\")}return advance(\"from\"),advance(\"(string)\"),this}).exps=!0,stmt(\"export\",function(){var token,identifier,ok=!0;if(state.inES6()||(warning(\"W119\",state.tokens.curr,\"export\",\"6\"),ok=!1),state.funct[\"(scope)\"].block.isGlobal()||(error(\"E053\",state.tokens.curr),ok=!1),\"*\"===state.tokens.next.value)return advance(\"*\"),advance(\"from\"),advance(\"(string)\"),this;if(\"default\"===state.tokens.next.type){state.nameStack.set(state.tokens.next),advance(\"default\");var exportType=state.tokens.next.id;return(\"function\"===exportType||\"class\"===exportType)&&(this.block=!0),token=peek(),expression(10),identifier=token.value,this.block&&(state.funct[\"(scope)\"].addlabel(identifier,{type:exportType,token:token}),state.funct[\"(scope)\"].setExported(identifier,token)),this}if(\"{\"===state.tokens.next.value){advance(\"{\");for(var exportedTokens=[];;){if(state.tokens.next.identifier||error(\"E030\",state.tokens.next,state.tokens.next.value),advance(),exportedTokens.push(state.tokens.curr),\"as\"===state.tokens.next.value&&(advance(\"as\"),state.tokens.next.identifier||error(\"E030\",state.tokens.next,state.tokens.next.value),advance()),\",\"!==state.tokens.next.value){if(\"}\"===state.tokens.next.value){advance(\"}\");break}error(\"E024\",state.tokens.next,state.tokens.next.value);break}advance(\",\")}return\"from\"===state.tokens.next.value?(advance(\"from\"),advance(\"(string)\")):ok&&exportedTokens.forEach(function(token){state.funct[\"(scope)\"].setExported(token.value,token)}),this}if(\"var\"===state.tokens.next.id)advance(\"var\"),state.tokens.curr.fud({inexport:!0});else if(\"let\"===state.tokens.next.id)advance(\"let\"),state.tokens.curr.fud({inexport:!0});else if(\"const\"===state.tokens.next.id)advance(\"const\"),state.tokens.curr.fud({inexport:!0});else if(\"function\"===state.tokens.next.id)this.block=!0,advance(\"function\"),state.syntax[\"function\"].fud({inexport:!0});else if(\"class\"===state.tokens.next.id){this.block=!0,advance(\"class\");var classNameToken=state.tokens.next;state.syntax[\"class\"].fud(),state.funct[\"(scope)\"].setExported(classNameToken.value,classNameToken)}else error(\"E024\",state.tokens.next,state.tokens.next.value);return this}).exps=!0,FutureReservedWord(\"abstract\"),FutureReservedWord(\"boolean\"),FutureReservedWord(\"byte\"),FutureReservedWord(\"char\"),FutureReservedWord(\"class\",{es5:!0,nud:classdef}),FutureReservedWord(\"double\"),FutureReservedWord(\"enum\",{es5:!0}),FutureReservedWord(\"export\",{es5:!0}),FutureReservedWord(\"extends\",{es5:!0}),FutureReservedWord(\"final\"),FutureReservedWord(\"float\"),FutureReservedWord(\"goto\"),FutureReservedWord(\"implements\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"import\",{es5:!0}),FutureReservedWord(\"int\"),FutureReservedWord(\"interface\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"long\"),FutureReservedWord(\"native\"),FutureReservedWord(\"package\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"private\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"protected\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"public\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"short\"),FutureReservedWord(\"static\",{es5:!0,strictOnly:!0}),FutureReservedWord(\"super\",{es5:!0}),FutureReservedWord(\"synchronized\"),FutureReservedWord(\"transient\"),FutureReservedWord(\"volatile\");var lookupBlockType=function(){var pn,pn1,prev,i=-1,bracketStack=0,ret={};checkPunctuators(state.tokens.curr,[\"[\",\"{\"])&&(bracketStack+=1);do{if(prev=-1===i?state.tokens.curr:pn,pn=-1===i?state.tokens.next:peek(i),pn1=peek(i+1),i+=1,checkPunctuators(pn,[\"[\",\"{\"])?bracketStack+=1:checkPunctuators(pn,[\"]\",\"}\"])&&(bracketStack-=1),1===bracketStack&&pn.identifier&&\"for\"===pn.value&&!checkPunctuator(prev,\".\")){ret.isCompArray=!0,ret.notJson=!0;break}if(0===bracketStack&&checkPunctuators(pn,[\"}\",\"]\"])){if(\"=\"===pn1.value){ret.isDestAssign=!0,ret.notJson=!0;break}if(\".\"===pn1.value){ret.notJson=!0;break}}checkPunctuator(pn,\";\")&&(ret.isBlock=!0,ret.notJson=!0)}while(bracketStack>0&&\"(end)\"!==pn.id);return ret},arrayComprehension=function(){function declare(v){var l=_current.variables.filter(function(elt){return elt.value===v?(elt.undef=!1,v):void 0}).length;return 0!==l}function use(v){var l=_current.variables.filter(function(elt){return elt.value!==v||elt.undef?void 0:(elt.unused===!0&&(elt.unused=!1),v)}).length;return 0===l}var _current,CompArray=function(){this.mode=\"use\",this.variables=[]},_carrays=[];return{stack:function(){_current=new CompArray,_carrays.push(_current)},unstack:function(){_current.variables.filter(function(v){v.unused&&warning(\"W098\",v.token,v.raw_text||v.value),v.undef&&state.funct[\"(scope)\"].block.use(v.value,v.token)}),_carrays.splice(-1,1),_current=_carrays[_carrays.length-1]},setState:function(s){_.contains([\"use\",\"define\",\"generate\",\"filter\"],s)&&(_current.mode=s)},check:function(v){return _current?_current&&\"use\"===_current.mode?(use(v)&&_current.variables.push({funct:state.funct,token:state.tokens.curr,value:v,undef:!0,unused:!1}),!0):_current&&\"define\"===_current.mode?(declare(v)||_current.variables.push({funct:state.funct,token:state.tokens.curr,value:v,undef:!1,unused:!0}),!0):_current&&\"generate\"===_current.mode?(state.funct[\"(scope)\"].block.use(v,state.tokens.curr),!0):_current&&\"filter\"===_current.mode?(use(v)&&state.funct[\"(scope)\"].block.use(v,state.tokens.curr),!0):!1:void 0}}},escapeRegex=function(str){return str.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g,\"\\\\$&\")},itself=function(s,o,g){function each(obj,cb){obj&&(Array.isArray(obj)||\"object\"!=typeof obj||(obj=Object.keys(obj)),obj.forEach(cb))}var i,k,x,reIgnoreStr,reIgnore,optionKeys,newOptionObj={},newIgnoredObj={};o=_.clone(o),state.reset(),o&&o.scope?JSHINT.scope=o.scope:(JSHINT.errors=[],JSHINT.undefs=[],JSHINT.internals=[],JSHINT.blacklist={},JSHINT.scope=\"(main)\"),predefined=Object.create(null),combine(predefined,vars.ecmaIdentifiers[3]),combine(predefined,vars.reservedVars),combine(predefined,g||{}),declared=Object.create(null);var exported=Object.create(null);if(o)for(each(o.predef||null,function(item){var slice,prop;\"-\"===item[0]?(slice=item.slice(1),JSHINT.blacklist[slice]=slice,delete predefined[slice]):(prop=Object.getOwnPropertyDescriptor(o.predef,item),predefined[item]=prop?prop.value:!1)}),each(o.exported||null,function(item){exported[item]=!0}),delete o.predef,delete o.exported,optionKeys=Object.keys(o),x=0;optionKeys.length>x;x++)if(/^-W\\d{3}$/g.test(optionKeys[x]))newIgnoredObj[optionKeys[x].slice(1)]=!0;else{var optionKey=optionKeys[x];newOptionObj[optionKey]=o[optionKey],(\"esversion\"===optionKey&&5===o[optionKey]||\"es5\"===optionKey&&o[optionKey])&&warning(\"I003\"),\"newcap\"===optionKeys[x]&&o[optionKey]===!1&&(newOptionObj[\"(explicitNewcap)\"]=!0)}state.option=newOptionObj,state.ignored=newIgnoredObj,state.option.indent=state.option.indent||4,state.option.maxerr=state.option.maxerr||50,indent=1;var scopeManagerInst=scopeManager(state,predefined,exported,declared);if(scopeManagerInst.on(\"warning\",function(ev){warning.apply(null,[ev.code,ev.token].concat(ev.data))}),scopeManagerInst.on(\"error\",function(ev){error.apply(null,[ev.code,ev.token].concat(ev.data))}),state.funct=functor(\"(global)\",null,{\"(global)\":!0,\"(scope)\":scopeManagerInst,\"(comparray)\":arrayComprehension(),\"(metrics)\":createMetrics(state.tokens.next)}),functions=[state.funct],urls=[],stack=null,member={},membersOnly=null,inblock=!1,lookahead=[],!isString(s)&&!Array.isArray(s))return errorAt(\"E004\",0),!1;api={get isJSON(){return state.jsonMode},getOption:function(name){return state.option[name]||null},getCache:function(name){return state.cache[name]},setCache:function(name,value){state.cache[name]=value},warn:function(code,data){warningAt.apply(null,[code,data.line,data.char].concat(data.data))},on:function(names,listener){names.split(\" \").forEach(function(name){emitter.on(name,listener)}.bind(this))}},emitter.removeAllListeners(),(extraModules||[]).forEach(function(func){func(api)}),state.tokens.prev=state.tokens.curr=state.tokens.next=state.syntax[\"(begin)\"],o&&o.ignoreDelimiters&&(Array.isArray(o.ignoreDelimiters)||(o.ignoreDelimiters=[o.ignoreDelimiters]),o.ignoreDelimiters.forEach(function(delimiterPair){delimiterPair.start&&delimiterPair.end&&(reIgnoreStr=escapeRegex(delimiterPair.start)+\"[\\\\s\\\\S]*?\"+escapeRegex(delimiterPair.end),reIgnore=RegExp(reIgnoreStr,\"ig\"),s=s.replace(reIgnore,function(match){return match.replace(/./g,\" \")}))})),lex=new Lexer(s),lex.on(\"warning\",function(ev){warningAt.apply(null,[ev.code,ev.line,ev.character].concat(ev.data))}),lex.on(\"error\",function(ev){errorAt.apply(null,[ev.code,ev.line,ev.character].concat(ev.data))}),lex.on(\"fatal\",function(ev){quit(\"E041\",ev.line,ev.from)}),lex.on(\"Identifier\",function(ev){emitter.emit(\"Identifier\",ev)}),lex.on(\"String\",function(ev){emitter.emit(\"String\",ev)}),lex.on(\"Number\",function(ev){emitter.emit(\"Number\",ev)}),lex.start();for(var name in o)_.has(o,name)&&checkOption(name,state.tokens.curr);assume(),combine(predefined,g||{}),comma.first=!0;try{switch(advance(),state.tokens.next.id){case\"{\":case\"[\":destructuringAssignOrJsonValue();break;default:directives(),state.directive[\"use strict\"]&&\"global\"!==state.option.strict&&warning(\"W097\",state.tokens.prev),statements()}\"(end)\"!==state.tokens.next.id&&quit(\"E041\",state.tokens.curr.line),state.funct[\"(scope)\"].unstack()}catch(err){if(!err||\"JSHintError\"!==err.name)throw err;var nt=state.tokens.next||{};JSHINT.errors.push({scope:\"(main)\",raw:err.raw,code:err.code,reason:err.message,line:err.line||nt.line,character:err.character||nt.from},null)}if(\"(main)\"===JSHINT.scope)for(o=o||{},i=0;JSHINT.internals.length>i;i+=1)k=JSHINT.internals[i],o.scope=k.elem,itself(k.value,o,g);return 0===JSHINT.errors.length};return itself.addModule=function(func){extraModules.push(func)},itself.addModule(style.register),itself.data=function(){var fu,f,i,j,n,globals,data={functions:[],options:state.option};itself.errors.length&&(data.errors=itself.errors),state.jsonMode&&(data.json=!0);var impliedGlobals=state.funct[\"(scope)\"].getImpliedGlobals();for(impliedGlobals.length>0&&(data.implieds=impliedGlobals),urls.length>0&&(data.urls=urls),globals=state.funct[\"(scope)\"].getUsedOrDefinedGlobals(),globals.length>0&&(data.globals=globals),i=1;functions.length>i;i+=1){for(f=functions[i],fu={},j=0;functionicity.length>j;j+=1)fu[functionicity[j]]=[];for(j=0;functionicity.length>j;j+=1)0===fu[functionicity[j]].length&&delete fu[functionicity[j]];fu.name=f[\"(name)\"],fu.param=f[\"(params)\"],fu.line=f[\"(line)\"],fu.character=f[\"(character)\"],fu.last=f[\"(last)\"],fu.lastcharacter=f[\"(lastcharacter)\"],fu.metrics={complexity:f[\"(metrics)\"].ComplexityCount,parameters:f[\"(metrics)\"].arity,statements:f[\"(metrics)\"].statementCount},data.functions.push(fu)}var unuseds=state.funct[\"(scope)\"].getUnuseds();unuseds.length>0&&(data.unused=unuseds);for(n in member)if(\"number\"==typeof member[n]){data.member=member;break}return data},itself.jshint=itself,itself}();\"object\"==typeof exports&&exports&&(exports.JSHINT=JSHINT)},{\"../lodash\":\"/node_modules/jshint/lodash.js\",\"./lex.js\":\"/node_modules/jshint/src/lex.js\",\"./messages.js\":\"/node_modules/jshint/src/messages.js\",\"./options.js\":\"/node_modules/jshint/src/options.js\",\"./reg.js\":\"/node_modules/jshint/src/reg.js\",\"./scope-manager.js\":\"/node_modules/jshint/src/scope-manager.js\",\"./state.js\":\"/node_modules/jshint/src/state.js\",\"./style.js\":\"/node_modules/jshint/src/style.js\",\"./vars.js\":\"/node_modules/jshint/src/vars.js\",events:\"/node_modules/browserify/node_modules/events/events.js\"}],\"/node_modules/jshint/src/lex.js\":[function(_dereq_,module,exports){\"use strict\";function asyncTrigger(){var _checks=[];return{push:function(fn){_checks.push(fn)},check:function(){for(var check=0;_checks.length>check;++check)_checks[check]();_checks.splice(0,_checks.length)}}}function Lexer(source){var lines=source;\"string\"==typeof lines&&(lines=lines.replace(/\\r\\n/g,\"\\n\").replace(/\\r/g,\"\\n\").split(\"\\n\")),lines[0]&&\"#!\"===lines[0].substr(0,2)&&(-1!==lines[0].indexOf(\"node\")&&(state.option.node=!0),lines[0]=\"\"),this.emitter=new events.EventEmitter,this.source=source,this.setLines(lines),this.prereg=!0,this.line=0,this.char=1,this.from=1,this.input=\"\",this.inComment=!1,this.context=[],this.templateStarts=[];for(var i=0;state.option.indent>i;i+=1)state.tab+=\" \";this.ignoreLinterErrors=!1}var _=_dereq_(\"../lodash\"),events=_dereq_(\"events\"),reg=_dereq_(\"./reg.js\"),state=_dereq_(\"./state.js\").state,unicodeData=_dereq_(\"../data/ascii-identifier-data.js\"),asciiIdentifierStartTable=unicodeData.asciiIdentifierStartTable,asciiIdentifierPartTable=unicodeData.asciiIdentifierPartTable,Token={Identifier:1,Punctuator:2,NumericLiteral:3,StringLiteral:4,Comment:5,Keyword:6,NullLiteral:7,BooleanLiteral:8,RegExp:9,TemplateHead:10,TemplateMiddle:11,TemplateTail:12,NoSubstTemplate:13},Context={Block:1,Template:2};Lexer.prototype={_lines:[],inContext:function(ctxType){return this.context.length>0&&this.context[this.context.length-1].type===ctxType},pushContext:function(ctxType){this.context.push({type:ctxType})},popContext:function(){return this.context.pop()},isContext:function(context){return this.context.length>0&&this.context[this.context.length-1]===context},currentContext:function(){return this.context.length>0&&this.context[this.context.length-1]},getLines:function(){return this._lines=state.lines,this._lines},setLines:function(val){this._lines=val,state.lines=this._lines},peek:function(i){return this.input.charAt(i||0)},skip:function(i){i=i||1,this.char+=i,this.input=this.input.slice(i)},on:function(names,listener){names.split(\" \").forEach(function(name){this.emitter.on(name,listener)}.bind(this))},trigger:function(){this.emitter.emit.apply(this.emitter,Array.prototype.slice.call(arguments))},triggerAsync:function(type,args,checks,fn){checks.push(function(){fn()&&this.trigger(type,args)}.bind(this))},scanPunctuator:function(){var ch2,ch3,ch4,ch1=this.peek();switch(ch1){case\".\":if(/^[0-9]$/.test(this.peek(1)))return null;if(\".\"===this.peek(1)&&\".\"===this.peek(2))return{type:Token.Punctuator,value:\"...\"};case\"(\":case\")\":case\";\":case\",\":case\"[\":case\"]\":case\":\":case\"~\":case\"?\":return{type:Token.Punctuator,value:ch1};case\"{\":return this.pushContext(Context.Block),{type:Token.Punctuator,value:ch1};case\"}\":return this.inContext(Context.Block)&&this.popContext(),{type:Token.Punctuator,value:ch1};case\"#\":return{type:Token.Punctuator,value:ch1};case\"\":return null}return ch2=this.peek(1),ch3=this.peek(2),ch4=this.peek(3),\">\"===ch1&&\">\"===ch2&&\">\"===ch3&&\"=\"===ch4?{type:Token.Punctuator,value:\">>>=\"}:\"=\"===ch1&&\"=\"===ch2&&\"=\"===ch3?{type:Token.Punctuator,value:\"===\"}:\"!\"===ch1&&\"=\"===ch2&&\"=\"===ch3?{type:Token.Punctuator,value:\"!==\"}:\">\"===ch1&&\">\"===ch2&&\">\"===ch3?{type:Token.Punctuator,value:\">>>\"}:\"<\"===ch1&&\"<\"===ch2&&\"=\"===ch3?{type:Token.Punctuator,value:\"<<=\"}:\">\"===ch1&&\">\"===ch2&&\"=\"===ch3?{type:Token.Punctuator,value:\">>=\"}:\"=\"===ch1&&\">\"===ch2?{type:Token.Punctuator,value:ch1+ch2}:ch1===ch2&&\"+-<>&|\".indexOf(ch1)>=0?{type:Token.Punctuator,value:ch1+ch2}:\"<>=!+-*%&|^\".indexOf(ch1)>=0?\"=\"===ch2?{type:Token.Punctuator,value:ch1+ch2}:{type:Token.Punctuator,value:ch1}:\"/\"===ch1?\"=\"===ch2?{type:Token.Punctuator,value:\"/=\"}:{type:Token.Punctuator,value:\"/\"}:null},scanComments:function(){function commentToken(label,body,opt){var special=[\"jshint\",\"jslint\",\"members\",\"member\",\"globals\",\"global\",\"exported\"],isSpecial=!1,value=label+body,commentType=\"plain\";return opt=opt||{},opt.isMultiline&&(value+=\"*/\"),body=body.replace(/\\n/g,\" \"),\"/*\"===label&&reg.fallsThrough.test(body)&&(isSpecial=!0,commentType=\"falls through\"),special.forEach(function(str){if(!isSpecial&&(\"//\"!==label||\"jshint\"===str)&&(\" \"===body.charAt(str.length)&&body.substr(0,str.length)===str&&(isSpecial=!0,label+=str,body=body.substr(str.length)),isSpecial||\" \"!==body.charAt(0)||\" \"!==body.charAt(str.length+1)||body.substr(1,str.length)!==str||(isSpecial=!0,label=label+\" \"+str,body=body.substr(str.length+1)),isSpecial))switch(str){case\"member\":commentType=\"members\";break;case\"global\":commentType=\"globals\";break;default:var options=body.split(\":\").map(function(v){return v.replace(/^\\s+/,\"\").replace(/\\s+$/,\"\")});if(2===options.length)switch(options[0]){case\"ignore\":switch(options[1]){case\"start\":self.ignoringLinterErrors=!0,isSpecial=!1;break;case\"end\":self.ignoringLinterErrors=!1,isSpecial=!1}}commentType=str}}),{type:Token.Comment,commentType:commentType,value:value,body:body,isSpecial:isSpecial,isMultiline:opt.isMultiline||!1,isMalformed:opt.isMalformed||!1}}var ch1=this.peek(),ch2=this.peek(1),rest=this.input.substr(2),startLine=this.line,startChar=this.char,self=this;if(\"*\"===ch1&&\"/\"===ch2)return this.trigger(\"error\",{code:\"E018\",line:startLine,character:startChar}),this.skip(2),null;if(\"/\"!==ch1||\"*\"!==ch2&&\"/\"!==ch2)return null;if(\"/\"===ch2)return this.skip(this.input.length),commentToken(\"//\",rest);var body=\"\";if(\"*\"===ch2){for(this.inComment=!0,this.skip(2);\"*\"!==this.peek()||\"/\"!==this.peek(1);)if(\"\"===this.peek()){if(body+=\"\\n\",!this.nextLine())return this.trigger(\"error\",{code:\"E017\",line:startLine,character:startChar}),this.inComment=!1,commentToken(\"/*\",body,{isMultiline:!0,isMalformed:!0})}else body+=this.peek(),this.skip();return this.skip(2),this.inComment=!1,commentToken(\"/*\",body,{isMultiline:!0})}},scanKeyword:function(){var result=/^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input),keywords=[\"if\",\"in\",\"do\",\"var\",\"for\",\"new\",\"try\",\"let\",\"this\",\"else\",\"case\",\"void\",\"with\",\"enum\",\"while\",\"break\",\"catch\",\"throw\",\"const\",\"yield\",\"class\",\"super\",\"return\",\"typeof\",\"delete\",\"switch\",\"export\",\"import\",\"default\",\"finally\",\"extends\",\"function\",\"continue\",\"debugger\",\"instanceof\"];return result&&keywords.indexOf(result[0])>=0?{type:Token.Keyword,value:result[0]}:null},scanIdentifier:function(){function isNonAsciiIdentifierStart(code){return code>256}function isNonAsciiIdentifierPart(code){return code>256}function isHexDigit(str){return/^[0-9a-fA-F]$/.test(str)}function removeEscapeSequences(id){return id.replace(/\\\\u([0-9a-fA-F]{4})/g,function(m0,codepoint){return String.fromCharCode(parseInt(codepoint,16))})}var type,char,id=\"\",index=0,readUnicodeEscapeSequence=function(){if(index+=1,\"u\"!==this.peek(index))return null;var code,ch1=this.peek(index+1),ch2=this.peek(index+2),ch3=this.peek(index+3),ch4=this.peek(index+4);return isHexDigit(ch1)&&isHexDigit(ch2)&&isHexDigit(ch3)&&isHexDigit(ch4)?(code=parseInt(ch1+ch2+ch3+ch4,16),asciiIdentifierPartTable[code]||isNonAsciiIdentifierPart(code)?(index+=5,\"\\\\u\"+ch1+ch2+ch3+ch4):null):null}.bind(this),getIdentifierStart=function(){var chr=this.peek(index),code=chr.charCodeAt(0);return 92===code?readUnicodeEscapeSequence():128>code?asciiIdentifierStartTable[code]?(index+=1,chr):null:isNonAsciiIdentifierStart(code)?(index+=1,chr):null}.bind(this),getIdentifierPart=function(){var chr=this.peek(index),code=chr.charCodeAt(0);return 92===code?readUnicodeEscapeSequence():128>code?asciiIdentifierPartTable[code]?(index+=1,chr):null:isNonAsciiIdentifierPart(code)?(index+=1,chr):null}.bind(this);if(char=getIdentifierStart(),null===char)return null;for(id=char;char=getIdentifierPart(),null!==char;)id+=char;switch(id){case\"true\":case\"false\":type=Token.BooleanLiteral;break;case\"null\":type=Token.NullLiteral;break;default:type=Token.Identifier}return{type:type,value:removeEscapeSequences(id),text:id,tokenLength:id.length}},scanNumericLiteral:function(){function isDecimalDigit(str){return/^[0-9]$/.test(str)}function isOctalDigit(str){return/^[0-7]$/.test(str)}function isBinaryDigit(str){return/^[01]$/.test(str)}function isHexDigit(str){return/^[0-9a-fA-F]$/.test(str)}function isIdentifierStart(ch){return\"$\"===ch||\"_\"===ch||\"\\\\\"===ch||ch>=\"a\"&&\"z\">=ch||ch>=\"A\"&&\"Z\">=ch}var bad,index=0,value=\"\",length=this.input.length,char=this.peek(index),isAllowedDigit=isDecimalDigit,base=10,isLegacy=!1;if(\".\"!==char&&!isDecimalDigit(char))return null;if(\".\"!==char){for(value=this.peek(index),index+=1,char=this.peek(index),\"0\"===value&&((\"x\"===char||\"X\"===char)&&(isAllowedDigit=isHexDigit,base=16,index+=1,value+=char),(\"o\"===char||\"O\"===char)&&(isAllowedDigit=isOctalDigit,base=8,state.inES6(!0)||this.trigger(\"warning\",{code:\"W119\",line:this.line,character:this.char,data:[\"Octal integer literal\",\"6\"]}),index+=1,value+=char),(\"b\"===char||\"B\"===char)&&(isAllowedDigit=isBinaryDigit,base=2,state.inES6(!0)||this.trigger(\"warning\",{code:\"W119\",line:this.line,character:this.char,data:[\"Binary integer literal\",\"6\"]}),index+=1,value+=char),isOctalDigit(char)&&(isAllowedDigit=isOctalDigit,base=8,isLegacy=!0,bad=!1,index+=1,value+=char),!isOctalDigit(char)&&isDecimalDigit(char)&&(index+=1,value+=char));length>index;){if(char=this.peek(index),isLegacy&&isDecimalDigit(char))bad=!0;else if(!isAllowedDigit(char))break;value+=char,index+=1}if(isAllowedDigit!==isDecimalDigit)return!isLegacy&&2>=value.length?{type:Token.NumericLiteral,value:value,isMalformed:!0}:length>index&&(char=this.peek(index),isIdentifierStart(char))?null:{type:Token.NumericLiteral,value:value,base:base,isLegacy:isLegacy,isMalformed:!1}}if(\".\"===char)for(value+=char,index+=1;length>index&&(char=this.peek(index),isDecimalDigit(char));)value+=char,index+=1;if(\"e\"===char||\"E\"===char){if(value+=char,index+=1,char=this.peek(index),(\"+\"===char||\"-\"===char)&&(value+=this.peek(index),index+=1),char=this.peek(index),!isDecimalDigit(char))return null;for(value+=char,index+=1;length>index&&(char=this.peek(index),isDecimalDigit(char));)value+=char,index+=1}return length>index&&(char=this.peek(index),isIdentifierStart(char))?null:{type:Token.NumericLiteral,value:value,base:base,isMalformed:!isFinite(value)}},scanEscapeSequence:function(checks){var allowNewLine=!1,jump=1;this.skip();var char=this.peek();switch(char){case\"'\":this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\'\"]},checks,function(){return state.jsonMode});break;case\"b\":char=\"\\\\b\";break;case\"f\":char=\"\\\\f\";break;case\"n\":char=\"\\\\n\";break;case\"r\":char=\"\\\\r\";break;case\"t\":char=\"\\\\t\";break;case\"0\":char=\"\\\\0\";var n=parseInt(this.peek(1),10);this.triggerAsync(\"warning\",{code:\"W115\",line:this.line,character:this.char},checks,function(){return n>=0&&7>=n&&state.isStrict()});break;case\"u\":var hexCode=this.input.substr(1,4),code=parseInt(hexCode,16);isNaN(code)&&this.trigger(\"warning\",{code:\"W052\",line:this.line,character:this.char,data:[\"u\"+hexCode]}),char=String.fromCharCode(code),jump=5;break;case\"v\":this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\v\"]},checks,function(){return state.jsonMode}),char=\"\u000b\";break;case\"x\":var x=parseInt(this.input.substr(1,2),16);this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\x-\"]},checks,function(){return state.jsonMode}),char=String.fromCharCode(x),jump=3;break;case\"\\\\\":char=\"\\\\\\\\\";break;case'\"':char='\\\\\"';break;case\"/\":break;case\"\":allowNewLine=!0,char=\"\"}return{\"char\":char,jump:jump,allowNewLine:allowNewLine}},scanTemplateLiteral:function(checks){var tokenType,ch,value=\"\",startLine=this.line,startChar=this.char,depth=this.templateStarts.length;if(!state.inES6(!0))return null;if(\"`\"===this.peek())tokenType=Token.TemplateHead,this.templateStarts.push({line:this.line,\"char\":this.char}),depth=this.templateStarts.length,this.skip(1),this.pushContext(Context.Template);else{if(!this.inContext(Context.Template)||\"}\"!==this.peek())return null;tokenType=Token.TemplateMiddle}for(;\"`\"!==this.peek();){for(;\"\"===(ch=this.peek());)if(value+=\"\\n\",!this.nextLine()){var startPos=this.templateStarts.pop();return this.trigger(\"error\",{code:\"E052\",line:startPos.line,character:startPos.char}),{type:tokenType,value:value,startLine:startLine,startChar:startChar,isUnclosed:!0,depth:depth,context:this.popContext()}}if(\"$\"===ch&&\"{\"===this.peek(1))return value+=\"${\",this.skip(2),{type:tokenType,value:value,startLine:startLine,startChar:startChar,isUnclosed:!1,depth:depth,context:this.currentContext()};\nif(\"\\\\\"===ch){var escape=this.scanEscapeSequence(checks);value+=escape.char,this.skip(escape.jump)}else\"`\"!==ch&&(value+=ch,this.skip(1))}return tokenType=tokenType===Token.TemplateHead?Token.NoSubstTemplate:Token.TemplateTail,this.skip(1),this.templateStarts.pop(),{type:tokenType,value:value,startLine:startLine,startChar:startChar,isUnclosed:!1,depth:depth,context:this.popContext()}},scanStringLiteral:function(checks){var quote=this.peek();if('\"'!==quote&&\"'\"!==quote)return null;this.triggerAsync(\"warning\",{code:\"W108\",line:this.line,character:this.char},checks,function(){return state.jsonMode&&'\"'!==quote});var value=\"\",startLine=this.line,startChar=this.char,allowNewLine=!1;for(this.skip();this.peek()!==quote;)if(\"\"===this.peek()){if(allowNewLine?(allowNewLine=!1,this.triggerAsync(\"warning\",{code:\"W043\",line:this.line,character:this.char},checks,function(){return!state.option.multistr}),this.triggerAsync(\"warning\",{code:\"W042\",line:this.line,character:this.char},checks,function(){return state.jsonMode&&state.option.multistr})):this.trigger(\"warning\",{code:\"W112\",line:this.line,character:this.char}),!this.nextLine())return this.trigger(\"error\",{code:\"E029\",line:startLine,character:startChar}),{type:Token.StringLiteral,value:value,startLine:startLine,startChar:startChar,isUnclosed:!0,quote:quote}}else{allowNewLine=!1;var char=this.peek(),jump=1;if(\" \">char&&this.trigger(\"warning\",{code:\"W113\",line:this.line,character:this.char,data:[\"<non-printable>\"]}),\"\\\\\"===char){var parsed=this.scanEscapeSequence(checks);char=parsed.char,jump=parsed.jump,allowNewLine=parsed.allowNewLine}value+=char,this.skip(jump)}return this.skip(),{type:Token.StringLiteral,value:value,startLine:startLine,startChar:startChar,isUnclosed:!1,quote:quote}},scanRegExp:function(){var terminated,index=0,length=this.input.length,char=this.peek(),value=char,body=\"\",flags=[],malformed=!1,isCharSet=!1,scanUnexpectedChars=function(){\" \">char&&(malformed=!0,this.trigger(\"warning\",{code:\"W048\",line:this.line,character:this.char})),\"<\"===char&&(malformed=!0,this.trigger(\"warning\",{code:\"W049\",line:this.line,character:this.char,data:[char]}))}.bind(this);if(!this.prereg||\"/\"!==char)return null;for(index+=1,terminated=!1;length>index;)if(char=this.peek(index),value+=char,body+=char,isCharSet)\"]\"===char&&(\"\\\\\"!==this.peek(index-1)||\"\\\\\"===this.peek(index-2))&&(isCharSet=!1),\"\\\\\"===char&&(index+=1,char=this.peek(index),body+=char,value+=char,scanUnexpectedChars()),index+=1;else{if(\"\\\\\"===char){if(index+=1,char=this.peek(index),body+=char,value+=char,scanUnexpectedChars(),\"/\"===char){index+=1;continue}if(\"[\"===char){index+=1;continue}}if(\"[\"!==char){if(\"/\"===char){body=body.substr(0,body.length-1),terminated=!0,index+=1;break}index+=1}else isCharSet=!0,index+=1}if(!terminated)return this.trigger(\"error\",{code:\"E015\",line:this.line,character:this.from}),void this.trigger(\"fatal\",{line:this.line,from:this.from});for(;length>index&&(char=this.peek(index),/[gim]/.test(char));)flags.push(char),value+=char,index+=1;try{RegExp(body,flags.join(\"\"))}catch(err){malformed=!0,this.trigger(\"error\",{code:\"E016\",line:this.line,character:this.char,data:[err.message]})}return{type:Token.RegExp,value:value,flags:flags,isMalformed:malformed}},scanNonBreakingSpaces:function(){return state.option.nonbsp?this.input.search(/(\\u00A0)/):-1},scanUnsafeChars:function(){return this.input.search(reg.unsafeChars)},next:function(checks){this.from=this.char;var start;if(/\\s/.test(this.peek()))for(start=this.char;/\\s/.test(this.peek());)this.from+=1,this.skip();var match=this.scanComments()||this.scanStringLiteral(checks)||this.scanTemplateLiteral(checks);return match?match:(match=this.scanRegExp()||this.scanPunctuator()||this.scanKeyword()||this.scanIdentifier()||this.scanNumericLiteral(),match?(this.skip(match.tokenLength||match.value.length),match):null)},nextLine:function(){var char;if(this.line>=this.getLines().length)return!1;this.input=this.getLines()[this.line],this.line+=1,this.char=1,this.from=1;var inputTrimmed=this.input.trim(),startsWith=function(){return _.some(arguments,function(prefix){return 0===inputTrimmed.indexOf(prefix)})},endsWith=function(){return _.some(arguments,function(suffix){return-1!==inputTrimmed.indexOf(suffix,inputTrimmed.length-suffix.length)})};if(this.ignoringLinterErrors===!0&&(startsWith(\"/*\",\"//\")||this.inComment&&endsWith(\"*/\")||(this.input=\"\")),char=this.scanNonBreakingSpaces(),char>=0&&this.trigger(\"warning\",{code:\"W125\",line:this.line,character:char+1}),this.input=this.input.replace(/\\t/g,state.tab),char=this.scanUnsafeChars(),char>=0&&this.trigger(\"warning\",{code:\"W100\",line:this.line,character:char}),!this.ignoringLinterErrors&&state.option.maxlen&&state.option.maxlen<this.input.length){var inComment=this.inComment||startsWith.call(inputTrimmed,\"//\")||startsWith.call(inputTrimmed,\"/*\"),shouldTriggerError=!inComment||!reg.maxlenException.test(inputTrimmed);shouldTriggerError&&this.trigger(\"warning\",{code:\"W101\",line:this.line,character:this.input.length})}return!0},start:function(){this.nextLine()},token:function(){function isReserved(token,isProperty){if(!token.reserved)return!1;var meta=token.meta;if(meta&&meta.isFutureReservedWord&&state.inES5()){if(!meta.es5)return!1;if(meta.strictOnly&&!state.option.strict&&!state.isStrict())return!1;if(isProperty)return!1}return!0}for(var token,checks=asyncTrigger(),create=function(type,value,isProperty,token){var obj;if(\"(endline)\"!==type&&\"(end)\"!==type&&(this.prereg=!1),\"(punctuator)\"===type){switch(value){case\".\":case\")\":case\"~\":case\"#\":case\"]\":case\"++\":case\"--\":this.prereg=!1;break;default:this.prereg=!0}obj=Object.create(state.syntax[value]||state.syntax[\"(error)\"])}return\"(identifier)\"===type&&((\"return\"===value||\"case\"===value||\"typeof\"===value)&&(this.prereg=!0),_.has(state.syntax,value)&&(obj=Object.create(state.syntax[value]||state.syntax[\"(error)\"]),isReserved(obj,isProperty&&\"(identifier)\"===type)||(obj=null))),obj||(obj=Object.create(state.syntax[type])),obj.identifier=\"(identifier)\"===type,obj.type=obj.type||type,obj.value=value,obj.line=this.line,obj.character=this.char,obj.from=this.from,obj.identifier&&token&&(obj.raw_text=token.text||token.value),token&&token.startLine&&token.startLine!==this.line&&(obj.startLine=token.startLine),token&&token.context&&(obj.context=token.context),token&&token.depth&&(obj.depth=token.depth),token&&token.isUnclosed&&(obj.isUnclosed=token.isUnclosed),isProperty&&obj.identifier&&(obj.isProperty=isProperty),obj.check=checks.check,obj}.bind(this);;){if(!this.input.length)return this.nextLine()?create(\"(endline)\",\"\"):this.exhausted?null:(this.exhausted=!0,create(\"(end)\",\"\"));if(token=this.next(checks))switch(token.type){case Token.StringLiteral:return this.triggerAsync(\"String\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value,quote:token.quote},checks,function(){return!0}),create(\"(string)\",token.value,null,token);case Token.TemplateHead:return this.trigger(\"TemplateHead\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value}),create(\"(template)\",token.value,null,token);case Token.TemplateMiddle:return this.trigger(\"TemplateMiddle\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value}),create(\"(template middle)\",token.value,null,token);case Token.TemplateTail:return this.trigger(\"TemplateTail\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value}),create(\"(template tail)\",token.value,null,token);case Token.NoSubstTemplate:return this.trigger(\"NoSubstTemplate\",{line:this.line,\"char\":this.char,from:this.from,startLine:token.startLine,startChar:token.startChar,value:token.value}),create(\"(no subst template)\",token.value,null,token);case Token.Identifier:this.triggerAsync(\"Identifier\",{line:this.line,\"char\":this.char,from:this.form,name:token.value,raw_name:token.text,isProperty:\".\"===state.tokens.curr.id},checks,function(){return!0});case Token.Keyword:case Token.NullLiteral:case Token.BooleanLiteral:return create(\"(identifier)\",token.value,\".\"===state.tokens.curr.id,token);case Token.NumericLiteral:return token.isMalformed&&this.trigger(\"warning\",{code:\"W045\",line:this.line,character:this.char,data:[token.value]}),this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"0x-\"]},checks,function(){return 16===token.base&&state.jsonMode}),this.triggerAsync(\"warning\",{code:\"W115\",line:this.line,character:this.char},checks,function(){return state.isStrict()&&8===token.base&&token.isLegacy}),this.trigger(\"Number\",{line:this.line,\"char\":this.char,from:this.from,value:token.value,base:token.base,isMalformed:token.malformed}),create(\"(number)\",token.value);case Token.RegExp:return create(\"(regexp)\",token.value);case Token.Comment:if(state.tokens.curr.comment=!0,token.isSpecial)return{id:\"(comment)\",value:token.value,body:token.body,type:token.commentType,isSpecial:token.isSpecial,line:this.line,character:this.char,from:this.from};break;case\"\":break;default:return create(\"(punctuator)\",token.value)}else this.input.length&&(this.trigger(\"error\",{code:\"E024\",line:this.line,character:this.char,data:[this.peek()]}),this.input=\"\")}}},exports.Lexer=Lexer,exports.Context=Context},{\"../data/ascii-identifier-data.js\":\"/node_modules/jshint/data/ascii-identifier-data.js\",\"../lodash\":\"/node_modules/jshint/lodash.js\",\"./reg.js\":\"/node_modules/jshint/src/reg.js\",\"./state.js\":\"/node_modules/jshint/src/state.js\",events:\"/node_modules/browserify/node_modules/events/events.js\"}],\"/node_modules/jshint/src/messages.js\":[function(_dereq_,module,exports){\"use strict\";var _=_dereq_(\"../lodash\"),errors={E001:\"Bad option: '{a}'.\",E002:\"Bad option value.\",E003:\"Expected a JSON value.\",E004:\"Input is neither a string nor an array of strings.\",E005:\"Input is empty.\",E006:\"Unexpected early end of program.\",E007:'Missing \"use strict\" statement.',E008:\"Strict violation.\",E009:\"Option 'validthis' can't be used in a global scope.\",E010:\"'with' is not allowed in strict mode.\",E011:\"'{a}' has already been declared.\",E012:\"const '{a}' is initialized to 'undefined'.\",E013:\"Attempting to override '{a}' which is a constant.\",E014:\"A regular expression literal can be confused with '/='.\",E015:\"Unclosed regular expression.\",E016:\"Invalid regular expression.\",E017:\"Unclosed comment.\",E018:\"Unbegun comment.\",E019:\"Unmatched '{a}'.\",E020:\"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.\",E021:\"Expected '{a}' and instead saw '{b}'.\",E022:\"Line breaking error '{a}'.\",E023:\"Missing '{a}'.\",E024:\"Unexpected '{a}'.\",E025:\"Missing ':' on a case clause.\",E026:\"Missing '}' to match '{' from line {a}.\",E027:\"Missing ']' to match '[' from line {a}.\",E028:\"Illegal comma.\",E029:\"Unclosed string.\",E030:\"Expected an identifier and instead saw '{a}'.\",E031:\"Bad assignment.\",E032:\"Expected a small integer or 'false' and instead saw '{a}'.\",E033:\"Expected an operator and instead saw '{a}'.\",E034:\"get/set are ES5 features.\",E035:\"Missing property name.\",E036:\"Expected to see a statement and instead saw a block.\",E037:null,E038:null,E039:\"Function declarations are not invocable. Wrap the whole function invocation in parens.\",E040:\"Each value should have its own case label.\",E041:\"Unrecoverable syntax error.\",E042:\"Stopping.\",E043:\"Too many errors.\",E044:null,E045:\"Invalid for each loop.\",E046:\"A yield statement shall be within a generator function (with syntax: `function*`)\",E047:null,E048:\"{a} declaration not directly within block.\",E049:\"A {a} cannot be named '{b}'.\",E050:\"Mozilla acequires the yield expression to be parenthesized here.\",E051:null,E052:\"Unclosed template literal.\",E053:\"Export declaration must be in global scope.\",E054:\"Class properties must be methods. Expected '(' but instead saw '{a}'.\",E055:\"The '{a}' option cannot be set after any executable code.\",E056:\"'{a}' was used before it was declared, which is illegal for '{b}' variables.\",E057:\"Invalid meta property: '{a}.{b}'.\",E058:\"Missing semicolon.\"},warnings={W001:\"'hasOwnProperty' is a really bad name.\",W002:\"Value of '{a}' may be overwritten in IE 8 and earlier.\",W003:\"'{a}' was used before it was defined.\",W004:\"'{a}' is already defined.\",W005:\"A dot following a number can be confused with a decimal point.\",W006:\"Confusing minuses.\",W007:\"Confusing plusses.\",W008:\"A leading decimal point can be confused with a dot: '{a}'.\",W009:\"The array literal notation [] is preferable.\",W010:\"The object literal notation {} is preferable.\",W011:null,W012:null,W013:null,W014:\"Bad line breaking before '{a}'.\",W015:null,W016:\"Unexpected use of '{a}'.\",W017:\"Bad operand.\",W018:\"Confusing use of '{a}'.\",W019:\"Use the isNaN function to compare with NaN.\",W020:\"Read only.\",W021:\"Reassignment of '{a}', which is is a {b}. Use 'var' or 'let' to declare bindings that may change.\",W022:\"Do not assign to the exception parameter.\",W023:\"Expected an identifier in an assignment and instead saw a function invocation.\",W024:\"Expected an identifier and instead saw '{a}' (a reserved word).\",W025:\"Missing name in function declaration.\",W026:\"Inner functions should be listed at the top of the outer function.\",W027:\"Unreachable '{a}' after '{b}'.\",W028:\"Label '{a}' on {b} statement.\",W030:\"Expected an assignment or function call and instead saw an expression.\",W031:\"Do not use 'new' for side effects.\",W032:\"Unnecessary semicolon.\",W033:\"Missing semicolon.\",W034:'Unnecessary directive \"{a}\".',W035:\"Empty block.\",W036:\"Unexpected /*member '{a}'.\",W037:\"'{a}' is a statement label.\",W038:\"'{a}' used out of scope.\",W039:\"'{a}' is not allowed.\",W040:\"Possible strict violation.\",W041:\"Use '{a}' to compare with '{b}'.\",W042:\"Avoid EOL escaping.\",W043:\"Bad escaping of EOL. Use option multistr if needed.\",W044:\"Bad or unnecessary escaping.\",W045:\"Bad number '{a}'.\",W046:\"Don't use extra leading zeros '{a}'.\",W047:\"A trailing decimal point can be confused with a dot: '{a}'.\",W048:\"Unexpected control character in regular expression.\",W049:\"Unexpected escaped character '{a}' in regular expression.\",W050:\"JavaScript URL.\",W051:\"Variables should not be deleted.\",W052:\"Unexpected '{a}'.\",W053:\"Do not use {a} as a constructor.\",W054:\"The Function constructor is a form of eval.\",W055:\"A constructor name should start with an uppercase letter.\",W056:\"Bad constructor.\",W057:\"Weird construction. Is 'new' necessary?\",W058:\"Missing '()' invoking a constructor.\",W059:\"Avoid arguments.{a}.\",W060:\"document.write can be a form of eval.\",W061:\"eval can be harmful.\",W062:\"Wrap an immediate function invocation in parens to assist the reader in understanding that the expression is the result of a function, and not the function itself.\",W063:\"Math is not a function.\",W064:\"Missing 'new' prefix when invoking a constructor.\",W065:\"Missing radix parameter.\",W066:\"Implied eval. Consider passing a function instead of a string.\",W067:\"Bad invocation.\",W068:\"Wrapping non-IIFE function literals in parens is unnecessary.\",W069:\"['{a}'] is better written in dot notation.\",W070:\"Extra comma. (it breaks older versions of IE)\",W071:\"This function has too many statements. ({a})\",W072:\"This function has too many parameters. ({a})\",W073:\"Blocks are nested too deeply. ({a})\",W074:\"This function's cyclomatic complexity is too high. ({a})\",W075:\"Duplicate {a} '{b}'.\",W076:\"Unexpected parameter '{a}' in get {b} function.\",W077:\"Expected a single parameter in set {a} function.\",W078:\"Setter is defined without getter.\",W079:\"Redefinition of '{a}'.\",W080:\"It's not necessary to initialize '{a}' to 'undefined'.\",W081:null,W082:\"Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.\",W083:\"Don't make functions within a loop.\",W084:\"Assignment in conditional expression\",W085:\"Don't use 'with'.\",W086:\"Expected a 'break' statement before '{a}'.\",W087:\"Forgotten 'debugger' statement?\",W088:\"Creating global 'for' variable. Should be 'for (var {a} ...'.\",W089:\"The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.\",W090:\"'{a}' is not a statement label.\",W091:null,W093:\"Did you mean to return a conditional instead of an assignment?\",W094:\"Unexpected comma.\",W095:\"Expected a string and instead saw {a}.\",W096:\"The '{a}' key may produce unexpected results.\",W097:'Use the function form of \"use strict\".',W098:\"'{a}' is defined but never used.\",W099:null,W100:\"This character may get silently deleted by one or more browsers.\",W101:\"Line is too long.\",W102:null,W103:\"The '{a}' property is deprecated.\",W104:\"'{a}' is available in ES{b} (use 'esversion: {b}') or Mozilla JS extensions (use moz).\",W105:\"Unexpected {a} in '{b}'.\",W106:\"Identifier '{a}' is not in camel case.\",W107:\"Script URL.\",W108:\"Strings must use doublequote.\",W109:\"Strings must use singlequote.\",W110:\"Mixed double and single quotes.\",W112:\"Unclosed string.\",W113:\"Control character in string: {a}.\",W114:\"Avoid {a}.\",W115:\"Octal literals are not allowed in strict mode.\",W116:\"Expected '{a}' and instead saw '{b}'.\",W117:\"'{a}' is not defined.\",W118:\"'{a}' is only available in Mozilla JavaScript extensions (use moz option).\",W119:\"'{a}' is only available in ES{b} (use 'esversion: {b}').\",W120:\"You might be leaking a variable ({a}) here.\",W121:\"Extending prototype of native object: '{a}'.\",W122:\"Invalid typeof value '{a}'\",W123:\"'{a}' is already defined in outer scope.\",W124:\"A generator function shall contain a yield statement.\",W125:\"This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp\",W126:\"Unnecessary grouping operator.\",W127:\"Unexpected use of a comma operator.\",W128:\"Empty array elements acequire elision=true.\",W129:\"'{a}' is defined in a future version of JavaScript. Use a different variable name to avoid migration issues.\",W130:\"Invalid element after rest element.\",W131:\"Invalid parameter after rest parameter.\",W132:\"`var` declarations are forbidden. Use `let` or `const` instead.\",W133:\"Invalid for-{a} loop left-hand-side: {b}.\",W134:\"The '{a}' option is only available when linting ECMAScript {b} code.\",W135:\"{a} may not be supported by non-browser environments.\",W136:\"'{a}' must be in function scope.\",W137:\"Empty destructuring.\",W138:\"Regular parameters should not come after default parameters.\"},info={I001:\"Comma warnings can be turned off with 'laxcomma'.\",I002:null,I003:\"ES5 option is now set per default\"};exports.errors={},exports.warnings={},exports.info={},_.each(errors,function(desc,code){exports.errors[code]={code:code,desc:desc}}),_.each(warnings,function(desc,code){exports.warnings[code]={code:code,desc:desc}}),_.each(info,function(desc,code){exports.info[code]={code:code,desc:desc}})},{\"../lodash\":\"/node_modules/jshint/lodash.js\"}],\"/node_modules/jshint/src/name-stack.js\":[function(_dereq_,module){\"use strict\";function NameStack(){this._stack=[]}Object.defineProperty(NameStack.prototype,\"length\",{get:function(){return this._stack.length}}),NameStack.prototype.push=function(){this._stack.push(null)},NameStack.prototype.pop=function(){this._stack.pop()},NameStack.prototype.set=function(token){this._stack[this.length-1]=token},NameStack.prototype.infer=function(){var type,nameToken=this._stack[this.length-1],prefix=\"\";return nameToken&&\"class\"!==nameToken.type||(nameToken=this._stack[this.length-2]),nameToken?(type=nameToken.type,\"(string)\"!==type&&\"(number)\"!==type&&\"(identifier)\"!==type&&\"default\"!==type?\"(expression)\":(nameToken.accessorType&&(prefix=nameToken.accessorType+\" \"),prefix+nameToken.value)):\"(empty)\"},module.exports=NameStack},{}],\"/node_modules/jshint/src/options.js\":[function(_dereq_,module,exports){\"use strict\";exports.bool={enforcing:{bitwise:!0,freeze:!0,camelcase:!0,curly:!0,eqeqeq:!0,futurehostile:!0,notypeof:!0,es3:!0,es5:!0,forin:!0,funcscope:!0,immed:!0,iterator:!0,newcap:!0,noarg:!0,nocomma:!0,noempty:!0,nonbsp:!0,nonew:!0,undef:!0,singleGroups:!1,varstmt:!1,enforceall:!1},relaxing:{asi:!0,multistr:!0,debug:!0,boss:!0,evil:!0,globalstrict:!0,plusplus:!0,proto:!0,scripturl:!0,sub:!0,supernew:!0,laxbreak:!0,laxcomma:!0,validthis:!0,withstmt:!0,moz:!0,noyield:!0,eqnull:!0,lastsemic:!0,loopfunc:!0,expr:!0,esnext:!0,elision:!0},environments:{mootools:!0,couch:!0,jasmine:!0,jquery:!0,node:!0,qunit:!0,rhino:!0,shelljs:!0,prototypejs:!0,yui:!0,mocha:!0,module:!0,wsh:!0,worker:!0,nonstandard:!0,browser:!0,browserify:!0,devel:!0,dojo:!0,typed:!0,phantom:!0},obsolete:{onecase:!0,regexp:!0,regexdash:!0}},exports.val={maxlen:!1,indent:!1,maxerr:!1,predef:!1,globals:!1,quotmark:!1,scope:!1,maxstatements:!1,maxdepth:!1,maxparams:!1,maxcomplexity:!1,shadow:!1,strict:!0,unused:!0,latedef:!1,ignore:!1,ignoreDelimiters:!1,esversion:5},exports.inverted={bitwise:!0,forin:!0,newcap:!0,plusplus:!0,regexp:!0,undef:!0,eqeqeq:!0,strict:!0},exports.validNames=Object.keys(exports.val).concat(Object.keys(exports.bool.relaxing)).concat(Object.keys(exports.bool.enforcing)).concat(Object.keys(exports.bool.obsolete)).concat(Object.keys(exports.bool.environments)),exports.renamed={eqeq:\"eqeqeq\",windows:\"wsh\",sloppy:\"strict\"},exports.removed={nomen:!0,onevar:!0,passfail:!0,white:!0,gcl:!0,smarttabs:!0,trailing:!0},exports.noenforceall={varstmt:!0,strict:!0}},{}],\"/node_modules/jshint/src/reg.js\":[function(_dereq_,module,exports){\"use strict\";exports.unsafeString=/@cc|<\\/?|script|\\]\\s*\\]|<\\s*!|&lt/i,exports.unsafeChars=/[\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,exports.needEsc=/[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,exports.needEscGlobal=/[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,exports.starSlash=/\\*\\//,exports.identifier=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,exports.javascriptURL=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\\s*:/i,exports.fallsThrough=/^\\s*falls?\\sthrough\\s*$/,exports.maxlenException=/^(?:(?:\\/\\/|\\/\\*|\\*) ?)?[^ ]+$/},{}],\"/node_modules/jshint/src/scope-manager.js\":[function(_dereq_,module){\"use strict\";var _=_dereq_(\"../lodash\"),events=_dereq_(\"events\"),marker={},scopeManager=function(state,predefined,exported,declared){function _newScope(type){_current={\"(labels)\":Object.create(null),\"(usages)\":Object.create(null),\"(breakLabels)\":Object.create(null),\"(parent)\":_current,\"(type)\":type,\"(params)\":\"functionparams\"===type||\"catchparams\"===type?[]:null},_scopeStack.push(_current)}function warning(code,token){emitter.emit(\"warning\",{code:code,token:token,data:_.slice(arguments,2)})}function error(code,token){emitter.emit(\"warning\",{code:code,token:token,data:_.slice(arguments,2)})}function _setupUsages(labelName){_current[\"(usages)\"][labelName]||(_current[\"(usages)\"][labelName]={\"(modified)\":[],\"(reassigned)\":[],\"(tokens)\":[]})}function _checkForUnused(){if(\"functionparams\"===_current[\"(type)\"])return _checkParams(),void 0;var curentLabels=_current[\"(labels)\"];for(var labelName in curentLabels)curentLabels[labelName]&&\"exception\"!==curentLabels[labelName][\"(type)\"]&&curentLabels[labelName][\"(unused)\"]&&_warnUnused(labelName,curentLabels[labelName][\"(token)\"],\"var\")}function _checkParams(){var params=_current[\"(params)\"];if(params)for(var unused_opt,param=params.pop();param;){var label=_current[\"(labels)\"][param];if(unused_opt=_getUnusedOption(state.funct[\"(unusedOption)\"]),\"undefined\"===param)return;if(label[\"(unused)\"])_warnUnused(param,label[\"(token)\"],\"param\",state.funct[\"(unusedOption)\"]);else if(\"last-param\"===unused_opt)return;param=params.pop()}}function _getLabel(labelName){for(var i=_scopeStack.length-1;i>=0;--i){var scopeLabels=_scopeStack[i][\"(labels)\"];if(scopeLabels[labelName])return scopeLabels}}function usedSoFarInCurrentFunction(labelName){for(var i=_scopeStack.length-1;i>=0;i--){var current=_scopeStack[i];if(current[\"(usages)\"][labelName])return current[\"(usages)\"][labelName];if(current===_currentFunctBody)break}return!1}function _checkOuterShadow(labelName,token){if(\"outer\"===state.option.shadow)for(var isGlobal=\"global\"===_currentFunctBody[\"(type)\"],isNewFunction=\"functionparams\"===_current[\"(type)\"],outsideCurrentFunction=!isGlobal,i=0;_scopeStack.length>i;i++){var stackItem=_scopeStack[i];isNewFunction||_scopeStack[i+1]!==_currentFunctBody||(outsideCurrentFunction=!1),outsideCurrentFunction&&stackItem[\"(labels)\"][labelName]&&warning(\"W123\",token,labelName),stackItem[\"(breakLabels)\"][labelName]&&warning(\"W123\",token,labelName)}}function _latedefWarning(type,labelName,token){state.option.latedef&&(state.option.latedef===!0&&\"function\"===type||\"function\"!==type)&&warning(\"W003\",token,labelName)}var _current,_scopeStack=[];_newScope(\"global\"),_current[\"(predefined)\"]=predefined;var _currentFunctBody=_current,usedPredefinedAndGlobals=Object.create(null),impliedGlobals=Object.create(null),unuseds=[],emitter=new events.EventEmitter,_getUnusedOption=function(unused_opt){return void 0===unused_opt&&(unused_opt=state.option.unused),unused_opt===!0&&(unused_opt=\"last-param\"),unused_opt},_warnUnused=function(name,tkn,type,unused_opt){var line=tkn.line,chr=tkn.from,raw_name=tkn.raw_text||name;unused_opt=_getUnusedOption(unused_opt);var warnable_types={vars:[\"var\"],\"last-param\":[\"var\",\"param\"],strict:[\"var\",\"param\",\"last-param\"]};unused_opt&&warnable_types[unused_opt]&&-1!==warnable_types[unused_opt].indexOf(type)&&warning(\"W098\",{line:line,from:chr},raw_name),(unused_opt||\"var\"===type)&&unuseds.push({name:name,line:line,character:chr})},scopeManagerInst={on:function(names,listener){names.split(\" \").forEach(function(name){emitter.on(name,listener)})},isPredefined:function(labelName){return!this.has(labelName)&&_.has(_scopeStack[0][\"(predefined)\"],labelName)},stack:function(type){var previousScope=_current;_newScope(type),type||\"functionparams\"!==previousScope[\"(type)\"]||(_current[\"(isFuncBody)\"]=!0,_current[\"(context)\"]=_currentFunctBody,_currentFunctBody=_current)},unstack:function(){var i,j,subScope=_scopeStack.length>1?_scopeStack[_scopeStack.length-2]:null,isUnstackingFunctionBody=_current===_currentFunctBody,isUnstackingFunctionParams=\"functionparams\"===_current[\"(type)\"],isUnstackingFunctionOuter=\"functionouter\"===_current[\"(type)\"],currentUsages=_current[\"(usages)\"],currentLabels=_current[\"(labels)\"],usedLabelNameList=Object.keys(currentUsages);for(currentUsages.__proto__&&-1===usedLabelNameList.indexOf(\"__proto__\")&&usedLabelNameList.push(\"__proto__\"),i=0;usedLabelNameList.length>i;i++){var usedLabelName=usedLabelNameList[i],usage=currentUsages[usedLabelName],usedLabel=currentLabels[usedLabelName];if(usedLabel){var usedLabelType=usedLabel[\"(type)\"];if(usedLabel[\"(useOutsideOfScope)\"]&&!state.option.funcscope){var usedTokens=usage[\"(tokens)\"];if(usedTokens)for(j=0;usedTokens.length>j;j++)usedLabel[\"(function)\"]===usedTokens[j][\"(function)\"]&&error(\"W038\",usedTokens[j],usedLabelName)}if(_current[\"(labels)\"][usedLabelName][\"(unused)\"]=!1,\"const\"===usedLabelType&&usage[\"(modified)\"])for(j=0;usage[\"(modified)\"].length>j;j++)error(\"E013\",usage[\"(modified)\"][j],usedLabelName);if((\"function\"===usedLabelType||\"class\"===usedLabelType)&&usage[\"(reassigned)\"])for(j=0;usage[\"(reassigned)\"].length>j;j++)error(\"W021\",usage[\"(reassigned)\"][j],usedLabelName,usedLabelType)}else if(isUnstackingFunctionOuter&&(state.funct[\"(isCapturing)\"]=!0),subScope)if(subScope[\"(usages)\"][usedLabelName]){var subScopeUsage=subScope[\"(usages)\"][usedLabelName];subScopeUsage[\"(modified)\"]=subScopeUsage[\"(modified)\"].concat(usage[\"(modified)\"]),subScopeUsage[\"(tokens)\"]=subScopeUsage[\"(tokens)\"].concat(usage[\"(tokens)\"]),subScopeUsage[\"(reassigned)\"]=subScopeUsage[\"(reassigned)\"].concat(usage[\"(reassigned)\"]),subScopeUsage[\"(onlyUsedSubFunction)\"]=!1}else subScope[\"(usages)\"][usedLabelName]=usage,isUnstackingFunctionBody&&(subScope[\"(usages)\"][usedLabelName][\"(onlyUsedSubFunction)\"]=!0);else if(\"boolean\"==typeof _current[\"(predefined)\"][usedLabelName]){if(delete declared[usedLabelName],usedPredefinedAndGlobals[usedLabelName]=marker,_current[\"(predefined)\"][usedLabelName]===!1&&usage[\"(reassigned)\"])for(j=0;usage[\"(reassigned)\"].length>j;j++)warning(\"W020\",usage[\"(reassigned)\"][j])}else if(usage[\"(tokens)\"])for(j=0;usage[\"(tokens)\"].length>j;j++){var undefinedToken=usage[\"(tokens)\"][j];undefinedToken.forgiveUndef||(state.option.undef&&!undefinedToken.ignoreUndef&&warning(\"W117\",undefinedToken,usedLabelName),impliedGlobals[usedLabelName]?impliedGlobals[usedLabelName].line.push(undefinedToken.line):impliedGlobals[usedLabelName]={name:usedLabelName,line:[undefinedToken.line]})}}if(subScope||Object.keys(declared).forEach(function(labelNotUsed){_warnUnused(labelNotUsed,declared[labelNotUsed],\"var\")}),subScope&&!isUnstackingFunctionBody&&!isUnstackingFunctionParams&&!isUnstackingFunctionOuter){var labelNames=Object.keys(currentLabels);for(i=0;labelNames.length>i;i++){var defLabelName=labelNames[i];currentLabels[defLabelName][\"(blockscoped)\"]||\"exception\"===currentLabels[defLabelName][\"(type)\"]||this.funct.has(defLabelName,{excludeCurrent:!0})||(subScope[\"(labels)\"][defLabelName]=currentLabels[defLabelName],\"global\"!==_currentFunctBody[\"(type)\"]&&(subScope[\"(labels)\"][defLabelName][\"(useOutsideOfScope)\"]=!0),delete currentLabels[defLabelName])}}_checkForUnused(),_scopeStack.pop(),isUnstackingFunctionBody&&(_currentFunctBody=_scopeStack[_.findLastIndex(_scopeStack,function(scope){return scope[\"(isFuncBody)\"]||\"global\"===scope[\"(type)\"]})]),_current=subScope},addParam:function(labelName,token,type){if(type=type||\"param\",\"exception\"===type){var previouslyDefinedLabelType=this.funct.labeltype(labelName);previouslyDefinedLabelType&&\"exception\"!==previouslyDefinedLabelType&&(state.option.node||warning(\"W002\",state.tokens.next,labelName))}if(_.has(_current[\"(labels)\"],labelName)?_current[\"(labels)\"][labelName].duplicated=!0:(_checkOuterShadow(labelName,token,type),_current[\"(labels)\"][labelName]={\"(type)\":type,\"(token)\":token,\"(unused)\":!0},_current[\"(params)\"].push(labelName)),_.has(_current[\"(usages)\"],labelName)){var usage=_current[\"(usages)\"][labelName];usage[\"(onlyUsedSubFunction)\"]?_latedefWarning(type,labelName,token):warning(\"E056\",token,labelName,type)}},validateParams:function(){if(\"global\"!==_currentFunctBody[\"(type)\"]){var isStrict=state.isStrict(),currentFunctParamScope=_currentFunctBody[\"(parent)\"];currentFunctParamScope[\"(params)\"]&&currentFunctParamScope[\"(params)\"].forEach(function(labelName){var label=currentFunctParamScope[\"(labels)\"][labelName];label&&label.duplicated&&(isStrict?warning(\"E011\",label[\"(token)\"],labelName):state.option.shadow!==!0&&warning(\"W004\",label[\"(token)\"],labelName))})}},getUsedOrDefinedGlobals:function(){var list=Object.keys(usedPredefinedAndGlobals);return usedPredefinedAndGlobals.__proto__===marker&&-1===list.indexOf(\"__proto__\")&&list.push(\"__proto__\"),list},getImpliedGlobals:function(){var values=_.values(impliedGlobals),hasProto=!1;return impliedGlobals.__proto__&&(hasProto=values.some(function(value){return\"__proto__\"===value.name}),hasProto||values.push(impliedGlobals.__proto__)),values},getUnuseds:function(){return unuseds},has:function(labelName){return Boolean(_getLabel(labelName))},labeltype:function(labelName){var scopeLabels=_getLabel(labelName);return scopeLabels?scopeLabels[labelName][\"(type)\"]:null},addExported:function(labelName){var globalLabels=_scopeStack[0][\"(labels)\"];if(_.has(declared,labelName))delete declared[labelName];else if(_.has(globalLabels,labelName))globalLabels[labelName][\"(unused)\"]=!1;else{for(var i=1;_scopeStack.length>i;i++){var scope=_scopeStack[i];if(scope[\"(type)\"])break;if(_.has(scope[\"(labels)\"],labelName)&&!scope[\"(labels)\"][labelName][\"(blockscoped)\"])return scope[\"(labels)\"][labelName][\"(unused)\"]=!1,void 0}exported[labelName]=!0}},setExported:function(labelName,token){this.block.use(labelName,token)\n},addlabel:function(labelName,opts){var type=opts.type,token=opts.token,isblockscoped=\"let\"===type||\"const\"===type||\"class\"===type,isexported=\"global\"===(isblockscoped?_current:_currentFunctBody)[\"(type)\"]&&_.has(exported,labelName);if(_checkOuterShadow(labelName,token,type),isblockscoped){var declaredInCurrentScope=_current[\"(labels)\"][labelName];if(declaredInCurrentScope||_current!==_currentFunctBody||\"global\"===_current[\"(type)\"]||(declaredInCurrentScope=!!_currentFunctBody[\"(parent)\"][\"(labels)\"][labelName]),!declaredInCurrentScope&&_current[\"(usages)\"][labelName]){var usage=_current[\"(usages)\"][labelName];usage[\"(onlyUsedSubFunction)\"]?_latedefWarning(type,labelName,token):warning(\"E056\",token,labelName,type)}declaredInCurrentScope?warning(\"E011\",token,labelName):\"outer\"===state.option.shadow&&scopeManagerInst.funct.has(labelName)&&warning(\"W004\",token,labelName),scopeManagerInst.block.add(labelName,type,token,!isexported)}else{var declaredInCurrentFunctionScope=scopeManagerInst.funct.has(labelName);!declaredInCurrentFunctionScope&&usedSoFarInCurrentFunction(labelName)&&_latedefWarning(type,labelName,token),scopeManagerInst.funct.has(labelName,{onlyBlockscoped:!0})?warning(\"E011\",token,labelName):state.option.shadow!==!0&&declaredInCurrentFunctionScope&&\"__proto__\"!==labelName&&\"global\"!==_currentFunctBody[\"(type)\"]&&warning(\"W004\",token,labelName),scopeManagerInst.funct.add(labelName,type,token,!isexported),\"global\"===_currentFunctBody[\"(type)\"]&&(usedPredefinedAndGlobals[labelName]=marker)}},funct:{labeltype:function(labelName,options){for(var onlyBlockscoped=options&&options.onlyBlockscoped,excludeParams=options&&options.excludeParams,currentScopeIndex=_scopeStack.length-(options&&options.excludeCurrent?2:1),i=currentScopeIndex;i>=0;i--){var current=_scopeStack[i];if(current[\"(labels)\"][labelName]&&(!onlyBlockscoped||current[\"(labels)\"][labelName][\"(blockscoped)\"]))return current[\"(labels)\"][labelName][\"(type)\"];var scopeCheck=excludeParams?_scopeStack[i-1]:current;if(scopeCheck&&\"functionparams\"===scopeCheck[\"(type)\"])return null}return null},hasBreakLabel:function(labelName){for(var i=_scopeStack.length-1;i>=0;i--){var current=_scopeStack[i];if(current[\"(breakLabels)\"][labelName])return!0;if(\"functionparams\"===current[\"(type)\"])return!1}return!1},has:function(labelName,options){return Boolean(this.labeltype(labelName,options))},add:function(labelName,type,tok,unused){_current[\"(labels)\"][labelName]={\"(type)\":type,\"(token)\":tok,\"(blockscoped)\":!1,\"(function)\":_currentFunctBody,\"(unused)\":unused}}},block:{isGlobal:function(){return\"global\"===_current[\"(type)\"]},use:function(labelName,token){var paramScope=_currentFunctBody[\"(parent)\"];paramScope&&paramScope[\"(labels)\"][labelName]&&\"param\"===paramScope[\"(labels)\"][labelName][\"(type)\"]&&(scopeManagerInst.funct.has(labelName,{excludeParams:!0,onlyBlockscoped:!0})||(paramScope[\"(labels)\"][labelName][\"(unused)\"]=!1)),token&&(state.ignored.W117||state.option.undef===!1)&&(token.ignoreUndef=!0),_setupUsages(labelName),token&&(token[\"(function)\"]=_currentFunctBody,_current[\"(usages)\"][labelName][\"(tokens)\"].push(token))},reassign:function(labelName,token){this.modify(labelName,token),_current[\"(usages)\"][labelName][\"(reassigned)\"].push(token)},modify:function(labelName,token){_setupUsages(labelName),_current[\"(usages)\"][labelName][\"(modified)\"].push(token)},add:function(labelName,type,tok,unused){_current[\"(labels)\"][labelName]={\"(type)\":type,\"(token)\":tok,\"(blockscoped)\":!0,\"(unused)\":unused}},addBreakLabel:function(labelName,opts){var token=opts.token;scopeManagerInst.funct.hasBreakLabel(labelName)?warning(\"E011\",token,labelName):\"outer\"===state.option.shadow&&(scopeManagerInst.funct.has(labelName)?warning(\"W004\",token,labelName):_checkOuterShadow(labelName,token)),_current[\"(breakLabels)\"][labelName]=token}}};return scopeManagerInst};module.exports=scopeManager},{\"../lodash\":\"/node_modules/jshint/lodash.js\",events:\"/node_modules/browserify/node_modules/events/events.js\"}],\"/node_modules/jshint/src/state.js\":[function(_dereq_,module,exports){\"use strict\";var NameStack=_dereq_(\"./name-stack.js\"),state={syntax:{},isStrict:function(){return this.directive[\"use strict\"]||this.inClassBody||this.option.module||\"implied\"===this.option.strict},inMoz:function(){return this.option.moz},inES6:function(){return this.option.moz||this.option.esversion>=6},inES5:function(strict){return strict?!(this.option.esversion&&5!==this.option.esversion||this.option.moz):!this.option.esversion||this.option.esversion>=5||this.option.moz},reset:function(){this.tokens={prev:null,next:null,curr:null},this.option={},this.funct=null,this.ignored={},this.directive={},this.jsonMode=!1,this.jsonWarnings=[],this.lines=[],this.tab=\"\",this.cache={},this.ignoredLines={},this.forinifcheckneeded=!1,this.nameStack=new NameStack,this.inClassBody=!1}};exports.state=state},{\"./name-stack.js\":\"/node_modules/jshint/src/name-stack.js\"}],\"/node_modules/jshint/src/style.js\":[function(_dereq_,module,exports){\"use strict\";exports.register=function(linter){linter.on(\"Identifier\",function(data){linter.getOption(\"proto\")||\"__proto__\"===data.name&&linter.warn(\"W103\",{line:data.line,\"char\":data.char,data:[data.name,\"6\"]})}),linter.on(\"Identifier\",function(data){linter.getOption(\"iterator\")||\"__iterator__\"===data.name&&linter.warn(\"W103\",{line:data.line,\"char\":data.char,data:[data.name]})}),linter.on(\"Identifier\",function(data){linter.getOption(\"camelcase\")&&data.name.replace(/^_+|_+$/g,\"\").indexOf(\"_\")>-1&&!data.name.match(/^[A-Z0-9_]*$/)&&linter.warn(\"W106\",{line:data.line,\"char\":data.from,data:[data.name]})}),linter.on(\"String\",function(data){var code,quotmark=linter.getOption(\"quotmark\");quotmark&&(\"single\"===quotmark&&\"'\"!==data.quote&&(code=\"W109\"),\"double\"===quotmark&&'\"'!==data.quote&&(code=\"W108\"),quotmark===!0&&(linter.getCache(\"quotmark\")||linter.setCache(\"quotmark\",data.quote),linter.getCache(\"quotmark\")!==data.quote&&(code=\"W110\")),code&&linter.warn(code,{line:data.line,\"char\":data.char}))}),linter.on(\"Number\",function(data){\".\"===data.value.charAt(0)&&linter.warn(\"W008\",{line:data.line,\"char\":data.char,data:[data.value]}),\".\"===data.value.substr(data.value.length-1)&&linter.warn(\"W047\",{line:data.line,\"char\":data.char,data:[data.value]}),/^00+/.test(data.value)&&linter.warn(\"W046\",{line:data.line,\"char\":data.char,data:[data.value]})}),linter.on(\"String\",function(data){var re=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\\s*:/i;linter.getOption(\"scripturl\")||re.test(data.value)&&linter.warn(\"W107\",{line:data.line,\"char\":data.char})})}},{}],\"/node_modules/jshint/src/vars.js\":[function(_dereq_,module,exports){\"use strict\";exports.reservedVars={arguments:!1,NaN:!1},exports.ecmaIdentifiers={3:{Array:!1,Boolean:!1,Date:!1,decodeURI:!1,decodeURIComponent:!1,encodeURI:!1,encodeURIComponent:!1,Error:!1,eval:!1,EvalError:!1,Function:!1,hasOwnProperty:!1,isFinite:!1,isNaN:!1,Math:!1,Number:!1,Object:!1,parseInt:!1,parseFloat:!1,RangeError:!1,ReferenceError:!1,RegExp:!1,String:!1,SyntaxError:!1,TypeError:!1,URIError:!1},5:{JSON:!1},6:{Map:!1,Promise:!1,Proxy:!1,Reflect:!1,Set:!1,Symbol:!1,WeakMap:!1,WeakSet:!1}},exports.browser={Audio:!1,Blob:!1,addEventListener:!1,applicationCache:!1,atob:!1,blur:!1,btoa:!1,cancelAnimationFrame:!1,CanvasGradient:!1,CanvasPattern:!1,CanvasRenderingContext2D:!1,CSS:!1,clearInterval:!1,clearTimeout:!1,close:!1,closed:!1,Comment:!1,CustomEvent:!1,DOMParser:!1,defaultStatus:!1,Document:!1,document:!1,DocumentFragment:!1,Element:!1,ElementTimeControl:!1,Event:!1,event:!1,fetch:!1,FileReader:!1,FormData:!1,focus:!1,frames:!1,getComputedStyle:!1,HTMLElement:!1,HTMLAnchorElement:!1,HTMLBaseElement:!1,HTMLBlockquoteElement:!1,HTMLBodyElement:!1,HTMLBRElement:!1,HTMLButtonElement:!1,HTMLCanvasElement:!1,HTMLCollection:!1,HTMLDirectoryElement:!1,HTMLDivElement:!1,HTMLDListElement:!1,HTMLFieldSetElement:!1,HTMLFontElement:!1,HTMLFormElement:!1,HTMLFrameElement:!1,HTMLFrameSetElement:!1,HTMLHeadElement:!1,HTMLHeadingElement:!1,HTMLHRElement:!1,HTMLHtmlElement:!1,HTMLIFrameElement:!1,HTMLImageElement:!1,HTMLInputElement:!1,HTMLIsIndexElement:!1,HTMLLabelElement:!1,HTMLLayerElement:!1,HTMLLegendElement:!1,HTMLLIElement:!1,HTMLLinkElement:!1,HTMLMapElement:!1,HTMLMenuElement:!1,HTMLMetaElement:!1,HTMLModElement:!1,HTMLObjectElement:!1,HTMLOListElement:!1,HTMLOptGroupElement:!1,HTMLOptionElement:!1,HTMLParagraphElement:!1,HTMLParamElement:!1,HTMLPreElement:!1,HTMLQuoteElement:!1,HTMLScriptElement:!1,HTMLSelectElement:!1,HTMLStyleElement:!1,HTMLTableCaptionElement:!1,HTMLTableCellElement:!1,HTMLTableColElement:!1,HTMLTableElement:!1,HTMLTableRowElement:!1,HTMLTableSectionElement:!1,HTMLTemplateElement:!1,HTMLTextAreaElement:!1,HTMLTitleElement:!1,HTMLUListElement:!1,HTMLVideoElement:!1,history:!1,Image:!1,Intl:!1,length:!1,localStorage:!1,location:!1,matchMedia:!1,MessageChannel:!1,MessageEvent:!1,MessagePort:!1,MouseEvent:!1,moveBy:!1,moveTo:!1,MutationObserver:!1,name:!1,Node:!1,NodeFilter:!1,NodeList:!1,Notification:!1,navigator:!1,onbeforeunload:!0,onblur:!0,onerror:!0,onfocus:!0,onload:!0,onresize:!0,onunload:!0,open:!1,openDatabase:!1,opener:!1,Option:!1,parent:!1,performance:!1,print:!1,Range:!1,requestAnimationFrame:!1,removeEventListener:!1,resizeBy:!1,resizeTo:!1,screen:!1,scroll:!1,scrollBy:!1,scrollTo:!1,sessionStorage:!1,setInterval:!1,setTimeout:!1,SharedWorker:!1,status:!1,SVGAElement:!1,SVGAltGlyphDefElement:!1,SVGAltGlyphElement:!1,SVGAltGlyphItemElement:!1,SVGAngle:!1,SVGAnimateColorElement:!1,SVGAnimateElement:!1,SVGAnimateMotionElement:!1,SVGAnimateTransformElement:!1,SVGAnimatedAngle:!1,SVGAnimatedBoolean:!1,SVGAnimatedEnumeration:!1,SVGAnimatedInteger:!1,SVGAnimatedLength:!1,SVGAnimatedLengthList:!1,SVGAnimatedNumber:!1,SVGAnimatedNumberList:!1,SVGAnimatedPathData:!1,SVGAnimatedPoints:!1,SVGAnimatedPreserveAspectRatio:!1,SVGAnimatedRect:!1,SVGAnimatedString:!1,SVGAnimatedTransformList:!1,SVGAnimationElement:!1,SVGCSSRule:!1,SVGCircleElement:!1,SVGClipPathElement:!1,SVGColor:!1,SVGColorProfileElement:!1,SVGColorProfileRule:!1,SVGComponentTransferFunctionElement:!1,SVGCursorElement:!1,SVGDefsElement:!1,SVGDescElement:!1,SVGDocument:!1,SVGElement:!1,SVGElementInstance:!1,SVGElementInstanceList:!1,SVGEllipseElement:!1,SVGExternalResourcesRequired:!1,SVGFEBlendElement:!1,SVGFEColorMatrixElement:!1,SVGFEComponentTransferElement:!1,SVGFECompositeElement:!1,SVGFEConvolveMatrixElement:!1,SVGFEDiffuseLightingElement:!1,SVGFEDisplacementMapElement:!1,SVGFEDistantLightElement:!1,SVGFEFloodElement:!1,SVGFEFuncAElement:!1,SVGFEFuncBElement:!1,SVGFEFuncGElement:!1,SVGFEFuncRElement:!1,SVGFEGaussianBlurElement:!1,SVGFEImageElement:!1,SVGFEMergeElement:!1,SVGFEMergeNodeElement:!1,SVGFEMorphologyElement:!1,SVGFEOffsetElement:!1,SVGFEPointLightElement:!1,SVGFESpecularLightingElement:!1,SVGFESpotLightElement:!1,SVGFETileElement:!1,SVGFETurbulenceElement:!1,SVGFilterElement:!1,SVGFilterPrimitiveStandardAttributes:!1,SVGFitToViewBox:!1,SVGFontElement:!1,SVGFontFaceElement:!1,SVGFontFaceFormatElement:!1,SVGFontFaceNameElement:!1,SVGFontFaceSrcElement:!1,SVGFontFaceUriElement:!1,SVGForeignObjectElement:!1,SVGGElement:!1,SVGGlyphElement:!1,SVGGlyphRefElement:!1,SVGGradientElement:!1,SVGHKernElement:!1,SVGICCColor:!1,SVGImageElement:!1,SVGLangSpace:!1,SVGLength:!1,SVGLengthList:!1,SVGLineElement:!1,SVGLinearGradientElement:!1,SVGLocatable:!1,SVGMPathElement:!1,SVGMarkerElement:!1,SVGMaskElement:!1,SVGMatrix:!1,SVGMetadataElement:!1,SVGMissingGlyphElement:!1,SVGNumber:!1,SVGNumberList:!1,SVGPaint:!1,SVGPathElement:!1,SVGPathSeg:!1,SVGPathSegArcAbs:!1,SVGPathSegArcRel:!1,SVGPathSegClosePath:!1,SVGPathSegCurvetoCubicAbs:!1,SVGPathSegCurvetoCubicRel:!1,SVGPathSegCurvetoCubicSmoothAbs:!1,SVGPathSegCurvetoCubicSmoothRel:!1,SVGPathSegCurvetoQuadraticAbs:!1,SVGPathSegCurvetoQuadraticRel:!1,SVGPathSegCurvetoQuadraticSmoothAbs:!1,SVGPathSegCurvetoQuadraticSmoothRel:!1,SVGPathSegLinetoAbs:!1,SVGPathSegLinetoHorizontalAbs:!1,SVGPathSegLinetoHorizontalRel:!1,SVGPathSegLinetoRel:!1,SVGPathSegLinetoVerticalAbs:!1,SVGPathSegLinetoVerticalRel:!1,SVGPathSegList:!1,SVGPathSegMovetoAbs:!1,SVGPathSegMovetoRel:!1,SVGPatternElement:!1,SVGPoint:!1,SVGPointList:!1,SVGPolygonElement:!1,SVGPolylineElement:!1,SVGPreserveAspectRatio:!1,SVGRadialGradientElement:!1,SVGRect:!1,SVGRectElement:!1,SVGRenderingIntent:!1,SVGSVGElement:!1,SVGScriptElement:!1,SVGSetElement:!1,SVGStopElement:!1,SVGStringList:!1,SVGStylable:!1,SVGStyleElement:!1,SVGSwitchElement:!1,SVGSymbolElement:!1,SVGTRefElement:!1,SVGTSpanElement:!1,SVGTests:!1,SVGTextContentElement:!1,SVGTextElement:!1,SVGTextPathElement:!1,SVGTextPositioningElement:!1,SVGTitleElement:!1,SVGTransform:!1,SVGTransformList:!1,SVGTransformable:!1,SVGURIReference:!1,SVGUnitTypes:!1,SVGUseElement:!1,SVGVKernElement:!1,SVGViewElement:!1,SVGViewSpec:!1,SVGZoomAndPan:!1,Text:!1,TextDecoder:!1,TextEncoder:!1,TimeEvent:!1,top:!1,URL:!1,WebGLActiveInfo:!1,WebGLBuffer:!1,WebGLContextEvent:!1,WebGLFramebuffer:!1,WebGLProgram:!1,WebGLRenderbuffer:!1,WebGLRenderingContext:!1,WebGLShader:!1,WebGLShaderPrecisionFormat:!1,WebGLTexture:!1,WebGLUniformLocation:!1,WebSocket:!1,window:!1,Window:!1,Worker:!1,XDomainRequest:!1,XMLHttpRequest:!1,XMLSerializer:!1,XPathEvaluator:!1,XPathException:!1,XPathExpression:!1,XPathNamespace:!1,XPathNSResolver:!1,XPathResult:!1},exports.devel={alert:!1,confirm:!1,console:!1,Debug:!1,opera:!1,prompt:!1},exports.worker={importScripts:!0,postMessage:!0,self:!0,FileReaderSync:!0},exports.nonstandard={escape:!1,unescape:!1},exports.couch={require:!1,respond:!1,getRow:!1,emit:!1,send:!1,start:!1,sum:!1,log:!1,exports:!1,module:!1,provides:!1},exports.node={__filename:!1,__dirname:!1,GLOBAL:!1,global:!1,module:!1,acequire:!1,Buffer:!0,console:!0,exports:!0,process:!0,setTimeout:!0,clearTimeout:!0,setInterval:!0,clearInterval:!0,setImmediate:!0,clearImmediate:!0},exports.browserify={__filename:!1,__dirname:!1,global:!1,module:!1,acequire:!1,Buffer:!0,exports:!0,process:!0},exports.phantom={phantom:!0,acequire:!0,WebPage:!0,console:!0,exports:!0},exports.qunit={asyncTest:!1,deepEqual:!1,equal:!1,expect:!1,module:!1,notDeepEqual:!1,notEqual:!1,notPropEqual:!1,notStrictEqual:!1,ok:!1,propEqual:!1,QUnit:!1,raises:!1,start:!1,stop:!1,strictEqual:!1,test:!1,\"throws\":!1},exports.rhino={defineClass:!1,deserialize:!1,gc:!1,help:!1,importClass:!1,importPackage:!1,java:!1,load:!1,loadClass:!1,Packages:!1,print:!1,quit:!1,readFile:!1,readUrl:!1,runCommand:!1,seal:!1,serialize:!1,spawn:!1,sync:!1,toint32:!1,version:!1},exports.shelljs={target:!1,echo:!1,exit:!1,cd:!1,pwd:!1,ls:!1,find:!1,cp:!1,rm:!1,mv:!1,mkdir:!1,test:!1,cat:!1,sed:!1,grep:!1,which:!1,dirs:!1,pushd:!1,popd:!1,env:!1,exec:!1,chmod:!1,config:!1,error:!1,tempdir:!1},exports.typed={ArrayBuffer:!1,ArrayBufferView:!1,DataView:!1,Float32Array:!1,Float64Array:!1,Int16Array:!1,Int32Array:!1,Int8Array:!1,Uint16Array:!1,Uint32Array:!1,Uint8Array:!1,Uint8ClampedArray:!1},exports.wsh={ActiveXObject:!0,Enumerator:!0,GetObject:!0,ScriptEngine:!0,ScriptEngineBuildVersion:!0,ScriptEngineMajorVersion:!0,ScriptEngineMinorVersion:!0,VBArray:!0,WSH:!0,WScript:!0,XDomainRequest:!0},exports.dojo={dojo:!1,dijit:!1,dojox:!1,define:!1,require:!1},exports.jquery={$:!1,jQuery:!1},exports.mootools={$:!1,$$:!1,Asset:!1,Browser:!1,Chain:!1,Class:!1,Color:!1,Cookie:!1,Core:!1,Document:!1,DomReady:!1,DOMEvent:!1,DOMReady:!1,Drag:!1,Element:!1,Elements:!1,Event:!1,Events:!1,Fx:!1,Group:!1,Hash:!1,HtmlTable:!1,IFrame:!1,IframeShim:!1,InputValidator:!1,instanceOf:!1,Keyboard:!1,Locale:!1,Mask:!1,MooTools:!1,Native:!1,Options:!1,OverText:!1,Request:!1,Scroller:!1,Slick:!1,Slider:!1,Sortables:!1,Spinner:!1,Swiff:!1,Tips:!1,Type:!1,typeOf:!1,URI:!1,Window:!1},exports.prototypejs={$:!1,$$:!1,$A:!1,$F:!1,$H:!1,$R:!1,$break:!1,$continue:!1,$w:!1,Abstract:!1,Ajax:!1,Class:!1,Enumerable:!1,Element:!1,Event:!1,Field:!1,Form:!1,Hash:!1,Insertion:!1,ObjectRange:!1,PeriodicalExecuter:!1,Position:!1,Prototype:!1,Selector:!1,Template:!1,Toggle:!1,Try:!1,Autocompleter:!1,Builder:!1,Control:!1,Draggable:!1,Draggables:!1,Droppables:!1,Effect:!1,Sortable:!1,SortableObserver:!1,Sound:!1,Scriptaculous:!1},exports.yui={YUI:!1,Y:!1,YUI_config:!1},exports.mocha={mocha:!1,describe:!1,xdescribe:!1,it:!1,xit:!1,context:!1,xcontext:!1,before:!1,after:!1,beforeEach:!1,afterEach:!1,suite:!1,test:!1,setup:!1,teardown:!1,suiteSetup:!1,suiteTeardown:!1},exports.jasmine={jasmine:!1,describe:!1,xdescribe:!1,it:!1,xit:!1,beforeEach:!1,afterEach:!1,setFixtures:!1,loadFixtures:!1,spyOn:!1,expect:!1,runs:!1,waitsFor:!1,waits:!1,beforeAll:!1,afterAll:!1,fail:!1,fdescribe:!1,fit:!1,pending:!1}},{}]},{},[\"/node_modules/jshint/src/jshint.js\"])}),ace.define(\"ace/mode/javascript_worker\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/worker/mirror\",\"ace/mode/javascript/jshint\"],function(acequire,exports,module){\"use strict\";function startRegex(arr){return RegExp(\"^(\"+arr.join(\"|\")+\")\")}var oop=acequire(\"../lib/oop\"),Mirror=acequire(\"../worker/mirror\").Mirror,lint=acequire(\"./javascript/jshint\").JSHINT,disabledWarningsRe=startRegex([\"Bad for in variable '(.+)'.\",'Missing \"use strict\"']),errorsRe=startRegex([\"Unexpected\",\"Expected \",\"Confusing (plus|minus)\",\"\\\\{a\\\\} unterminated regular expression\",\"Unclosed \",\"Unmatched \",\"Unbegun comment\",\"Bad invocation\",\"Missing space after\",\"Missing operator at\"]),infoRe=startRegex([\"Expected an assignment\",\"Bad escapement of EOL\",\"Unexpected comma\",\"Unexpected space\",\"Missing radix parameter.\",\"A leading decimal point can\",\"\\\\['{a}'\\\\] is better written in dot notation.\",\"'{a}' used out of scope\"]),JavaScriptWorker=exports.JavaScriptWorker=function(sender){Mirror.call(this,sender),this.setTimeout(500),this.setOptions()};oop.inherits(JavaScriptWorker,Mirror),function(){this.setOptions=function(options){this.options=options||{esnext:!0,moz:!0,devel:!0,browser:!0,node:!0,laxcomma:!0,laxbreak:!0,lastsemic:!0,onevar:!1,passfail:!1,maxerr:100,expr:!0,multistr:!0,globalstrict:!0},this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.changeOptions=function(newOptions){oop.mixin(this.options,newOptions),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.isValidJS=function(str){try{eval(\"throw 0;\"+str)}catch(e){if(0===e)return!0}return!1},this.onUpdate=function(){var value=this.doc.getValue();if(value=value.replace(/^#!.*\\n/,\"\\n\"),!value)return this.sender.emit(\"annotate\",[]);var errors=[],maxErrorLevel=this.isValidJS(value)?\"warning\":\"error\";lint(value,this.options,this.options.globals);for(var results=lint.errors,errorAdded=!1,i=0;results.length>i;i++){var error=results[i];if(error){var raw=error.raw,type=\"warning\";if(\"Missing semicolon.\"==raw){var str=error.evidence.substr(error.character);str=str.charAt(str.search(/\\S/)),\"error\"==maxErrorLevel&&str&&/[\\w\\d{(['\"]/.test(str)?(error.reason='Missing \";\" before statement',type=\"error\"):type=\"info\"}else{if(disabledWarningsRe.test(raw))continue;infoRe.test(raw)?type=\"info\":errorsRe.test(raw)?(errorAdded=!0,type=maxErrorLevel):\"'{a}' is not defined.\"==raw?type=\"warning\":\"'{a}' is defined but never used.\"==raw&&(type=\"info\")}errors.push({row:error.line-1,column:error.character-1,text:error.reason,type:type,raw:raw})}}this.sender.emit(\"annotate\",errors)}}.call(JavaScriptWorker.prototype)}),ace.define(\"ace/lib/es5-shim\",[\"require\",\"exports\",\"module\"],function(){function Empty(){}function doesDefinePropertyWork(object){try{return Object.defineProperty(object,\"sentinel\",{}),\"sentinel\"in object}catch(exception){}}function toInteger(n){return n=+n,n!==n?n=0:0!==n&&n!==1/0&&n!==-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n))),n}Function.prototype.bind||(Function.prototype.bind=function(that){var target=this;if(\"function\"!=typeof target)throw new TypeError(\"Function.prototype.bind called on incompatible \"+target);var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var result=target.apply(this,args.concat(slice.call(arguments)));return Object(result)===result?result:this}return target.apply(that,args.concat(slice.call(arguments)))};return target.prototype&&(Empty.prototype=target.prototype,bound.prototype=new Empty,Empty.prototype=null),bound});var defineGetter,defineSetter,lookupGetter,lookupSetter,supportsAccessors,call=Function.prototype.call,prototypeOfArray=Array.prototype,prototypeOfObject=Object.prototype,slice=prototypeOfArray.slice,_toString=call.bind(prototypeOfObject.toString),owns=call.bind(prototypeOfObject.hasOwnProperty);if((supportsAccessors=owns(prototypeOfObject,\"__defineGetter__\"))&&(defineGetter=call.bind(prototypeOfObject.__defineGetter__),defineSetter=call.bind(prototypeOfObject.__defineSetter__),lookupGetter=call.bind(prototypeOfObject.__lookupGetter__),lookupSetter=call.bind(prototypeOfObject.__lookupSetter__)),2!=[1,2].splice(0).length)if(function(){function makeArray(l){var a=Array(l+2);return a[0]=a[1]=0,a}var lengthBefore,array=[];return array.splice.apply(array,makeArray(20)),array.splice.apply(array,makeArray(26)),lengthBefore=array.length,array.splice(5,0,\"XXX\"),lengthBefore+1==array.length,lengthBefore+1==array.length?!0:void 0}()){var array_splice=Array.prototype.splice;Array.prototype.splice=function(start,deleteCount){return arguments.length?array_splice.apply(this,[void 0===start?0:start,void 0===deleteCount?this.length-start:deleteCount].concat(slice.call(arguments,2))):[]}}else Array.prototype.splice=function(pos,removeCount){var length=this.length;pos>0?pos>length&&(pos=length):void 0==pos?pos=0:0>pos&&(pos=Math.max(length+pos,0)),length>pos+removeCount||(removeCount=length-pos);var removed=this.slice(pos,pos+removeCount),insert=slice.call(arguments,2),add=insert.length;if(pos===length)add&&this.push.apply(this,insert);else{var remove=Math.min(removeCount,length-pos),tailOldPos=pos+remove,tailNewPos=tailOldPos+add-remove,tailCount=length-tailOldPos,lengthAfterRemove=length-remove;if(tailOldPos>tailNewPos)for(var i=0;tailCount>i;++i)this[tailNewPos+i]=this[tailOldPos+i];else if(tailNewPos>tailOldPos)for(i=tailCount;i--;)this[tailNewPos+i]=this[tailOldPos+i];if(add&&pos===lengthAfterRemove)this.length=lengthAfterRemove,this.push.apply(this,insert);else for(this.length=lengthAfterRemove+add,i=0;add>i;++i)this[pos+i]=insert[i]}return removed};Array.isArray||(Array.isArray=function(obj){return\"[object Array]\"==_toString(obj)});var boxedString=Object(\"a\"),splitString=\"a\"!=boxedString[0]||!(0 in boxedString);if(Array.prototype.forEach||(Array.prototype.forEach=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,thisp=arguments[1],i=-1,length=self.length>>>0;if(\"[object Function]\"!=_toString(fun))throw new TypeError;for(;length>++i;)i in self&&fun.call(thisp,self[i],i,object)}),Array.prototype.map||(Array.prototype.map=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0,result=Array(length),thisp=arguments[1];if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");for(var i=0;length>i;i++)i in self&&(result[i]=fun.call(thisp,self[i],i,object));return result}),Array.prototype.filter||(Array.prototype.filter=function(fun){var value,object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0,result=[],thisp=arguments[1];if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");for(var i=0;length>i;i++)i in self&&(value=self[i],fun.call(thisp,value,i,object)&&result.push(value));return result}),Array.prototype.every||(Array.prototype.every=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0,thisp=arguments[1];if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");for(var i=0;length>i;i++)if(i in self&&!fun.call(thisp,self[i],i,object))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0,thisp=arguments[1];if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");for(var i=0;length>i;i++)if(i in self&&fun.call(thisp,self[i],i,object))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0;if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");if(!length&&1==arguments.length)throw new TypeError(\"reduce of empty array with no initial value\");var result,i=0;if(arguments.length>=2)result=arguments[1];else for(;;){if(i in self){result=self[i++];break}if(++i>=length)throw new TypeError(\"reduce of empty array with no initial value\")}for(;length>i;i++)i in self&&(result=fun.call(void 0,result,self[i],i,object));return result}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(fun){var object=toObject(this),self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):object,length=self.length>>>0;if(\"[object Function]\"!=_toString(fun))throw new TypeError(fun+\" is not a function\");if(!length&&1==arguments.length)throw new TypeError(\"reduceRight of empty array with no initial value\");var result,i=length-1;if(arguments.length>=2)result=arguments[1];else for(;;){if(i in self){result=self[i--];break}if(0>--i)throw new TypeError(\"reduceRight of empty array with no initial value\")}do i in this&&(result=fun.call(void 0,result,self[i],i,object));while(i--);return result}),Array.prototype.indexOf&&-1==[0,1].indexOf(1,2)||(Array.prototype.indexOf=function(sought){var self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):toObject(this),length=self.length>>>0;if(!length)return-1;var i=0;for(arguments.length>1&&(i=toInteger(arguments[1])),i=i>=0?i:Math.max(0,length+i);length>i;i++)if(i in self&&self[i]===sought)return i;return-1}),Array.prototype.lastIndexOf&&-1==[0,1].lastIndexOf(0,-3)||(Array.prototype.lastIndexOf=function(sought){var self=splitString&&\"[object String]\"==_toString(this)?this.split(\"\"):toObject(this),length=self.length>>>0;if(!length)return-1;var i=length-1;for(arguments.length>1&&(i=Math.min(i,toInteger(arguments[1]))),i=i>=0?i:length-Math.abs(i);i>=0;i--)if(i in self&&sought===self[i])return i;return-1}),Object.getPrototypeOf||(Object.getPrototypeOf=function(object){return object.__proto__||(object.constructor?object.constructor.prototype:prototypeOfObject)}),!Object.getOwnPropertyDescriptor){var ERR_NON_OBJECT=\"Object.getOwnPropertyDescriptor called on a non-object: \";Object.getOwnPropertyDescriptor=function(object,property){if(\"object\"!=typeof object&&\"function\"!=typeof object||null===object)throw new TypeError(ERR_NON_OBJECT+object);if(owns(object,property)){var descriptor,getter,setter;if(descriptor={enumerable:!0,configurable:!0},supportsAccessors){var prototype=object.__proto__;object.__proto__=prototypeOfObject;var getter=lookupGetter(object,property),setter=lookupSetter(object,property);if(object.__proto__=prototype,getter||setter)return getter&&(descriptor.get=getter),setter&&(descriptor.set=setter),descriptor}return descriptor.value=object[property],descriptor}}}if(Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(object){return Object.keys(object)}),!Object.create){var createEmpty;createEmpty=null===Object.prototype.__proto__?function(){return{__proto__:null}}:function(){var empty={};for(var i in empty)empty[i]=null;return empty.constructor=empty.hasOwnProperty=empty.propertyIsEnumerable=empty.isPrototypeOf=empty.toLocaleString=empty.toString=empty.valueOf=empty.__proto__=null,empty},Object.create=function(prototype,properties){var object;if(null===prototype)object=createEmpty();else{if(\"object\"!=typeof prototype)throw new TypeError(\"typeof prototype[\"+typeof prototype+\"] != 'object'\");var Type=function(){};Type.prototype=prototype,object=new Type,object.__proto__=prototype}return void 0!==properties&&Object.defineProperties(object,properties),object}}if(Object.defineProperty){var definePropertyWorksOnObject=doesDefinePropertyWork({}),definePropertyWorksOnDom=\"undefined\"==typeof document||doesDefinePropertyWork(document.createElement(\"div\"));if(!definePropertyWorksOnObject||!definePropertyWorksOnDom)var definePropertyFallback=Object.defineProperty}if(!Object.defineProperty||definePropertyFallback){var ERR_NON_OBJECT_DESCRIPTOR=\"Property description must be an object: \",ERR_NON_OBJECT_TARGET=\"Object.defineProperty called on non-object: \",ERR_ACCESSORS_NOT_SUPPORTED=\"getters & setters can not be defined on this javascript engine\";Object.defineProperty=function(object,property,descriptor){if(\"object\"!=typeof object&&\"function\"!=typeof object||null===object)throw new TypeError(ERR_NON_OBJECT_TARGET+object);if(\"object\"!=typeof descriptor&&\"function\"!=typeof descriptor||null===descriptor)throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR+descriptor);if(definePropertyFallback)try{return definePropertyFallback.call(Object,object,property,descriptor)}catch(exception){}if(owns(descriptor,\"value\"))if(supportsAccessors&&(lookupGetter(object,property)||lookupSetter(object,property))){var prototype=object.__proto__;object.__proto__=prototypeOfObject,delete object[property],object[property]=descriptor.value,object.__proto__=prototype}else object[property]=descriptor.value;else{if(!supportsAccessors)throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);owns(descriptor,\"get\")&&defineGetter(object,property,descriptor.get),owns(descriptor,\"set\")&&defineSetter(object,property,descriptor.set)}return object}}Object.defineProperties||(Object.defineProperties=function(object,properties){for(var property in properties)owns(properties,property)&&Object.defineProperty(object,property,properties[property]);return object}),Object.seal||(Object.seal=function(object){return object}),Object.freeze||(Object.freeze=function(object){return object});try{Object.freeze(function(){})}catch(exception){Object.freeze=function(freezeObject){return function(object){return\"function\"==typeof object?object:freezeObject(object)}}(Object.freeze)}if(Object.preventExtensions||(Object.preventExtensions=function(object){return object}),Object.isSealed||(Object.isSealed=function(){return!1}),Object.isFrozen||(Object.isFrozen=function(){return!1}),Object.isExtensible||(Object.isExtensible=function(object){if(Object(object)===object)throw new TypeError;for(var name=\"\";owns(object,name);)name+=\"?\";object[name]=!0;var returnValue=owns(object,name);return delete object[name],returnValue}),!Object.keys){var hasDontEnumBug=!0,dontEnums=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"],dontEnumsLength=dontEnums.length;for(var key in{toString:null})hasDontEnumBug=!1;Object.keys=function(object){if(\"object\"!=typeof object&&\"function\"!=typeof object||null===object)throw new TypeError(\"Object.keys called on a non-object\");var keys=[];for(var name in object)owns(object,name)&&keys.push(name);if(hasDontEnumBug)for(var i=0,ii=dontEnumsLength;ii>i;i++){var dontEnum=dontEnums[i];owns(object,dontEnum)&&keys.push(dontEnum)}return keys}}Date.now||(Date.now=function(){return(new Date).getTime()});var ws=\"\t\\n\u000b\\f\\r   ᠎              \\u2028\\u2029\";if(!String.prototype.trim||ws.trim()){ws=\"[\"+ws+\"]\";var trimBeginRegexp=RegExp(\"^\"+ws+ws+\"*\"),trimEndRegexp=RegExp(ws+ws+\"*$\");String.prototype.trim=function(){return(this+\"\").replace(trimBeginRegexp,\"\").replace(trimEndRegexp,\"\")}}var toObject=function(o){if(null==o)throw new TypeError(\"can't convert \"+o+\" to object\");return Object(o)}});";
+
 /***/ }),
 /* 110 */
-/*!**********************************************!*\
-  !*** ./node_modules/file-saver/FileSaver.js ***!
-  \**********************************************/
-/***/ (function(module, exports, __webpack_require__) {
+/*!***************************************!*\
+  !*** ./utils/FactionInvitationBox.js ***!
+  \***************************************/
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
 
-var __WEBPACK_AMD_DEFINE_RESULT__;/* FileSaver.js
- * A saveAs() FileSaver implementation.
- * 1.3.2
- * 2016-06-16 18:25:19
- *
- * By Eli Grey, http://eligrey.com
- * License: MIT
- *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
- */
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "factionInvitationBoxCreate", function() { return factionInvitationBoxCreate; });
+/* harmony import */ var _src_Faction_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../src/Faction.js */ 11);
+/* harmony import */ var _src_engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../src/engine.js */ 5);
+/* harmony import */ var _src_Player_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../src/Player.js */ 0);
+/* harmony import */ var _HelperFunctions_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./HelperFunctions.js */ 1);
 
-/*global self */
-/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
 
-/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
 
-var saveAs = saveAs || (function(view) {
-	"use strict";
-	// IE <10 is explicitly unsupported
-	if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
-		return;
-	}
-	var
-		  doc = view.document
-		  // only get URL when necessary in case Blob.js hasn't overridden it yet
-		, get_URL = function() {
-			return view.URL || view.webkitURL || view;
-		}
-		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
-		, can_use_save_link = "download" in save_link
-		, click = function(node) {
-			var event = new MouseEvent("click");
-			node.dispatchEvent(event);
-		}
-		, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
-		, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
-		, throw_outside = function(ex) {
-			(view.setImmediate || view.setTimeout)(function() {
-				throw ex;
-			}, 0);
-		}
-		, force_saveable_type = "application/octet-stream"
-		// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
-		, arbitrary_revoke_timeout = 1000 * 40 // in ms
-		, revoke = function(file) {
-			var revoker = function() {
-				if (typeof file === "string") { // file is an object URL
-					get_URL().revokeObjectURL(file);
-				} else { // file is a File
-					file.remove();
-				}
-			};
-			setTimeout(revoker, arbitrary_revoke_timeout);
-		}
-		, dispatch = function(filesaver, event_types, event) {
-			event_types = [].concat(event_types);
-			var i = event_types.length;
-			while (i--) {
-				var listener = filesaver["on" + event_types[i]];
-				if (typeof listener === "function") {
-					try {
-						listener.call(filesaver, event || filesaver);
-					} catch (ex) {
-						throw_outside(ex);
-					}
-				}
-			}
-		}
-		, auto_bom = function(blob) {
-			// prepend BOM for UTF-8 XML and text/* types (including HTML)
-			// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
-			if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
-				return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
-			}
-			return blob;
-		}
-		, FileSaver = function(blob, name, no_auto_bom) {
-			if (!no_auto_bom) {
-				blob = auto_bom(blob);
-			}
-			// First try a.download, then web filesystem, then object URLs
-			var
-				  filesaver = this
-				, type = blob.type
-				, force = type === force_saveable_type
-				, object_url
-				, dispatch_all = function() {
-					dispatch(filesaver, "writestart progress write writeend".split(" "));
-				}
-				// on any filesys errors revert to saving with object URLs
-				, fs_error = function() {
-					if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
-						// Safari doesn't allow downloading of blob urls
-						var reader = new FileReader();
-						reader.onloadend = function() {
-							var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
-							var popup = view.open(url, '_blank');
-							if(!popup) view.location.href = url;
-							url=undefined; // release reference before dispatching
-							filesaver.readyState = filesaver.DONE;
-							dispatch_all();
-						};
-						reader.readAsDataURL(blob);
-						filesaver.readyState = filesaver.INIT;
-						return;
-					}
-					// don't create more object URLs than needed
-					if (!object_url) {
-						object_url = get_URL().createObjectURL(blob);
-					}
-					if (force) {
-						view.location.href = object_url;
-					} else {
-						var opened = view.open(object_url, "_blank");
-						if (!opened) {
-							// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
-							view.location.href = object_url;
-						}
-					}
-					filesaver.readyState = filesaver.DONE;
-					dispatch_all();
-					revoke(object_url);
-				}
-			;
-			filesaver.readyState = filesaver.INIT;
 
-			if (can_use_save_link) {
-				object_url = get_URL().createObjectURL(blob);
-				setTimeout(function() {
-					save_link.href = object_url;
-					save_link.download = name;
-					click(save_link);
-					dispatch_all();
-					revoke(object_url);
-					filesaver.readyState = filesaver.DONE;
-				});
-				return;
-			}
 
-			fs_error();
-		}
-		, FS_proto = FileSaver.prototype
-		, saveAs = function(blob, name, no_auto_bom) {
-			return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
-		}
-	;
-	// IE 10+ (native saveAs)
-	if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
-		return function(blob, name, no_auto_bom) {
-			name = name || blob.name || "download";
-
-			if (!no_auto_bom) {
-				blob = auto_bom(blob);
-			}
-			return navigator.msSaveOrOpenBlob(blob, name);
-		};
-	}
-
-	FS_proto.abort = function(){};
-	FS_proto.readyState = FS_proto.INIT = 0;
-	FS_proto.WRITING = 1;
-	FS_proto.DONE = 2;
-
-	FS_proto.error =
-	FS_proto.onwritestart =
-	FS_proto.onprogress =
-	FS_proto.onwrite =
-	FS_proto.onabort =
-	FS_proto.onerror =
-	FS_proto.onwriteend =
-		null;
-
-	return saveAs;
-}(
-	   typeof self !== "undefined" && self
-	|| typeof window !== "undefined" && window
-	|| this.content
-));
-// `self` is undefined in Firefox for Android content script context
-// while `this` is nsIContentFrameMessageManager
-// with an attribute `content` that corresponds to the window
-
-if (typeof module !== "undefined" && module.exports) {
-  module.exports.saveAs = saveAs;
-} else if (("function" !== "undefined" && __webpack_require__(/*! !webpack amd define */ 77) !== null) && (__webpack_require__(/*! !webpack amd options */ 115) !== null)) {
-  !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {
-    return saveAs;
-  }).call(exports, __webpack_require__, exports, module),
-				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+/* Faction Invitation Pop-up box */
+function factionInvitationBoxClose() {
+    var factionInvitationBox = document.getElementById("faction-invitation-box-container");
+    factionInvitationBox.style.display = "none";
 }
 
+function factionInvitationBoxOpen() {
+    var factionInvitationBox = document.getElementById("faction-invitation-box-container");
+    factionInvitationBox.style.display = "block";
+}
+
+function factionInvitationSetText(txt) {
+    var textBox = document.getElementById("faction-invitation-box-text");
+    textBox.innerHTML = txt;
+}
+
+function factionInvitationSetMessage(msg) {
+    var msgBox = document.getElementById("faction-invitation-box-message");
+    msgBox.innerHTML = msg;
+}
+
+//ram argument is in GB
+function factionInvitationBoxCreate(faction) {
+    factionInvitationSetText("You have received a faction invitation from " + faction.name);
+    faction.alreadyInvited = true;
+    _src_Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].factionInvitations.push(faction.name);
+
+    if (_src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage === _src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.Factions) {
+        _src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].loadFactionsContent();
+    }
+
+    var newYesButton = Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_3__["clearEventListeners"])("faction-invitation-box-yes");
+    newYesButton.addEventListener("click", function() {
+        //Remove from invited factions
+        var i = _src_Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].factionInvitations.findIndex((facName)=>{return facName === faction.name});
+        if (i === -1) {
+            console.log("ERROR: Could not find faction in Player.factionInvitations");
+        } else {
+            _src_Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].factionInvitations.splice(i, 1);
+        }
+        Object(_src_Faction_js__WEBPACK_IMPORTED_MODULE_0__["joinFaction"])(faction);
+        factionInvitationBoxClose();
+        if (_src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage === _src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.Factions) {
+            _src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].loadFactionsContent();
+        }
+        return false;
+    });
+
+    var noButton = Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_3__["clearEventListeners"])("faction-invitation-box-no");
+    noButton.addEventListener("click", function() {
+        factionInvitationBoxClose();
+        return false;
+    });
+
+    factionInvitationBoxOpen();
+}
+
+
+
 
 /***/ }),
 /* 111 */
-/*!*****************************************!*\
-  !*** ./node_modules/jszip/lib/index.js ***!
-  \*****************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-/**
- * Representation a of zip file in js
- * @constructor
- */
-function JSZip() {
-    // if this constructor is used without `new`, it adds `new` before itself:
-    if(!(this instanceof JSZip)) {
-        return new JSZip();
-    }
-
-    if(arguments.length) {
-        throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");
-    }
-
-    // object containing the files :
-    // {
-    //   "folder/" : {...},
-    //   "folder/data.txt" : {...}
-    // }
-    this.files = {};
-
-    this.comment = null;
-
-    // Where we are in the hierarchy
-    this.root = "";
-    this.clone = function() {
-        var newObj = new JSZip();
-        for (var i in this) {
-            if (typeof this[i] !== "function") {
-                newObj[i] = this[i];
-            }
-        }
-        return newObj;
-    };
-}
-JSZip.prototype = __webpack_require__(/*! ./object */ 165);
-JSZip.prototype.loadAsync = __webpack_require__(/*! ./load */ 120);
-JSZip.support = __webpack_require__(/*! ./support */ 47);
-JSZip.defaults = __webpack_require__(/*! ./defaults */ 93);
-
-// TODO find a better way to handle this version,
-// a require('package.json').version doesn't work with webpack, see #327
-JSZip.version = "3.1.5";
-
-JSZip.loadAsync = function (content, options) {
-    return new JSZip().loadAsync(content, options);
-};
-
-JSZip.external = __webpack_require__(/*! ./external */ 57);
-module.exports = JSZip;
-
-
-/***/ }),
-/* 112 */
 /*!**********************************!*\
   !*** ./utils/InfiltrationBox.js ***!
   \**********************************/
@@ -68607,9 +68569,9 @@ module.exports = JSZip;
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "infiltrationBoxCreate", function() { return infiltrationBoxCreate; });
-/* harmony import */ var _src_BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../src/BitNode.js */ 16);
+/* harmony import */ var _src_BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../src/BitNode.js */ 15);
 /* harmony import */ var _src_Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../src/Constants.js */ 3);
-/* harmony import */ var _src_Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../src/Faction.js */ 14);
+/* harmony import */ var _src_Faction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../src/Faction.js */ 11);
 /* harmony import */ var _src_Player_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../src/Player.js */ 0);
 /* harmony import */ var _DialogBox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./DialogBox.js */ 6);
 /* harmony import */ var _HelperFunctions_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./HelperFunctions.js */ 1);
@@ -68729,7 +68691,7 @@ function infiltrationBoxCreate(inst) {
 
 
 /***/ }),
-/* 113 */
+/* 112 */
 /*!*****************************!*\
   !*** ./src/Infiltration.js ***!
   \*****************************/
@@ -68738,13 +68700,13 @@ function infiltrationBoxCreate(inst) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "beginInfiltration", function() { return beginInfiltration; });
-/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 16);
+/* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15);
 /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3);
 /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engine.js */ 5);
 /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Player.js */ 0);
 /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/DialogBox.js */ 6);
 /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1);
-/* harmony import */ var _utils_InfiltrationBox_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/InfiltrationBox.js */ 112);
+/* harmony import */ var _utils_InfiltrationBox_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/InfiltrationBox.js */ 111);
 /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2);
 
 
@@ -69573,10093 +69535,268 @@ function getInfiltrationEscapeChance(inst) {
 
 
 
+/***/ }),
+/* 113 */
+/*!**********************************************!*\
+  !*** ./node_modules/file-saver/FileSaver.js ***!
+  \**********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+var __WEBPACK_AMD_DEFINE_RESULT__;/* FileSaver.js
+ * A saveAs() FileSaver implementation.
+ * 1.3.2
+ * 2016-06-16 18:25:19
+ *
+ * By Eli Grey, http://eligrey.com
+ * License: MIT
+ *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
+ */
+
+/*global self */
+/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
+
+/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
+
+var saveAs = saveAs || (function(view) {
+	"use strict";
+	// IE <10 is explicitly unsupported
+	if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
+		return;
+	}
+	var
+		  doc = view.document
+		  // only get URL when necessary in case Blob.js hasn't overridden it yet
+		, get_URL = function() {
+			return view.URL || view.webkitURL || view;
+		}
+		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
+		, can_use_save_link = "download" in save_link
+		, click = function(node) {
+			var event = new MouseEvent("click");
+			node.dispatchEvent(event);
+		}
+		, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
+		, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
+		, throw_outside = function(ex) {
+			(view.setImmediate || view.setTimeout)(function() {
+				throw ex;
+			}, 0);
+		}
+		, force_saveable_type = "application/octet-stream"
+		// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
+		, arbitrary_revoke_timeout = 1000 * 40 // in ms
+		, revoke = function(file) {
+			var revoker = function() {
+				if (typeof file === "string") { // file is an object URL
+					get_URL().revokeObjectURL(file);
+				} else { // file is a File
+					file.remove();
+				}
+			};
+			setTimeout(revoker, arbitrary_revoke_timeout);
+		}
+		, dispatch = function(filesaver, event_types, event) {
+			event_types = [].concat(event_types);
+			var i = event_types.length;
+			while (i--) {
+				var listener = filesaver["on" + event_types[i]];
+				if (typeof listener === "function") {
+					try {
+						listener.call(filesaver, event || filesaver);
+					} catch (ex) {
+						throw_outside(ex);
+					}
+				}
+			}
+		}
+		, auto_bom = function(blob) {
+			// prepend BOM for UTF-8 XML and text/* types (including HTML)
+			// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
+			if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
+				return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
+			}
+			return blob;
+		}
+		, FileSaver = function(blob, name, no_auto_bom) {
+			if (!no_auto_bom) {
+				blob = auto_bom(blob);
+			}
+			// First try a.download, then web filesystem, then object URLs
+			var
+				  filesaver = this
+				, type = blob.type
+				, force = type === force_saveable_type
+				, object_url
+				, dispatch_all = function() {
+					dispatch(filesaver, "writestart progress write writeend".split(" "));
+				}
+				// on any filesys errors revert to saving with object URLs
+				, fs_error = function() {
+					if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
+						// Safari doesn't allow downloading of blob urls
+						var reader = new FileReader();
+						reader.onloadend = function() {
+							var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
+							var popup = view.open(url, '_blank');
+							if(!popup) view.location.href = url;
+							url=undefined; // release reference before dispatching
+							filesaver.readyState = filesaver.DONE;
+							dispatch_all();
+						};
+						reader.readAsDataURL(blob);
+						filesaver.readyState = filesaver.INIT;
+						return;
+					}
+					// don't create more object URLs than needed
+					if (!object_url) {
+						object_url = get_URL().createObjectURL(blob);
+					}
+					if (force) {
+						view.location.href = object_url;
+					} else {
+						var opened = view.open(object_url, "_blank");
+						if (!opened) {
+							// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
+							view.location.href = object_url;
+						}
+					}
+					filesaver.readyState = filesaver.DONE;
+					dispatch_all();
+					revoke(object_url);
+				}
+			;
+			filesaver.readyState = filesaver.INIT;
+
+			if (can_use_save_link) {
+				object_url = get_URL().createObjectURL(blob);
+				setTimeout(function() {
+					save_link.href = object_url;
+					save_link.download = name;
+					click(save_link);
+					dispatch_all();
+					revoke(object_url);
+					filesaver.readyState = filesaver.DONE;
+				});
+				return;
+			}
+
+			fs_error();
+		}
+		, FS_proto = FileSaver.prototype
+		, saveAs = function(blob, name, no_auto_bom) {
+			return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
+		}
+	;
+	// IE 10+ (native saveAs)
+	if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
+		return function(blob, name, no_auto_bom) {
+			name = name || blob.name || "download";
+
+			if (!no_auto_bom) {
+				blob = auto_bom(blob);
+			}
+			return navigator.msSaveOrOpenBlob(blob, name);
+		};
+	}
+
+	FS_proto.abort = function(){};
+	FS_proto.readyState = FS_proto.INIT = 0;
+	FS_proto.WRITING = 1;
+	FS_proto.DONE = 2;
+
+	FS_proto.error =
+	FS_proto.onwritestart =
+	FS_proto.onprogress =
+	FS_proto.onwrite =
+	FS_proto.onabort =
+	FS_proto.onerror =
+	FS_proto.onwriteend =
+		null;
+
+	return saveAs;
+}(
+	   typeof self !== "undefined" && self
+	|| typeof window !== "undefined" && window
+	|| this.content
+));
+// `self` is undefined in Firefox for Android content script context
+// while `this` is nsIContentFrameMessageManager
+// with an attribute `content` that corresponds to the window
+
+if (typeof module !== "undefined" && module.exports) {
+  module.exports.saveAs = saveAs;
+} else if (("function" !== "undefined" && __webpack_require__(/*! !webpack amd define */ 77) !== null) && (__webpack_require__(/*! !webpack amd options */ 116) !== null)) {
+  !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {
+    return saveAs;
+  }).call(exports, __webpack_require__, exports, module),
+				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+}
+
+
 /***/ }),
 /* 114 */
-/*!***************************************!*\
-  !*** ./utils/FactionInvitationBox.js ***!
-  \***************************************/
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/*!*****************************************!*\
+  !*** ./node_modules/jszip/lib/index.js ***!
+  \*****************************************/
+/***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "factionInvitationBoxCreate", function() { return factionInvitationBoxCreate; });
-/* harmony import */ var _src_Faction_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../src/Faction.js */ 14);
-/* harmony import */ var _src_engine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../src/engine.js */ 5);
-/* harmony import */ var _src_Player_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../src/Player.js */ 0);
-/* harmony import */ var _HelperFunctions_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./HelperFunctions.js */ 1);
 
 
-
-
-
-/* Faction Invitation Pop-up box */
-function factionInvitationBoxClose() {
-    var factionInvitationBox = document.getElementById("faction-invitation-box-container");
-    factionInvitationBox.style.display = "none";
-}
-
-function factionInvitationBoxOpen() {
-    var factionInvitationBox = document.getElementById("faction-invitation-box-container");
-    factionInvitationBox.style.display = "block";
-}
-
-function factionInvitationSetText(txt) {
-    var textBox = document.getElementById("faction-invitation-box-text");
-    textBox.innerHTML = txt;
-}
-
-function factionInvitationSetMessage(msg) {
-    var msgBox = document.getElementById("faction-invitation-box-message");
-    msgBox.innerHTML = msg;
-}
-
-//ram argument is in GB
-function factionInvitationBoxCreate(faction) {
-    factionInvitationSetText("You have received a faction invitation from " + faction.name);
-    faction.alreadyInvited = true;
-    _src_Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].factionInvitations.push(faction.name);
-
-    if (_src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage === _src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.Factions) {
-        _src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].loadFactionsContent();
+/**
+ * Representation a of zip file in js
+ * @constructor
+ */
+function JSZip() {
+    // if this constructor is used without `new`, it adds `new` before itself:
+    if(!(this instanceof JSZip)) {
+        return new JSZip();
     }
 
-    var newYesButton = Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_3__["clearEventListeners"])("faction-invitation-box-yes");
-    newYesButton.addEventListener("click", function() {
-        //Remove from invited factions
-        var i = _src_Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].factionInvitations.findIndex((facName)=>{return facName === faction.name});
-        if (i === -1) {
-            console.log("ERROR: Could not find faction in Player.factionInvitations");
-        } else {
-            _src_Player_js__WEBPACK_IMPORTED_MODULE_2__["Player"].factionInvitations.splice(i, 1);
-        }
-        Object(_src_Faction_js__WEBPACK_IMPORTED_MODULE_0__["joinFaction"])(faction);
-        factionInvitationBoxClose();
-        if (_src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].currentPage === _src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].Page.Factions) {
-            _src_engine_js__WEBPACK_IMPORTED_MODULE_1__["Engine"].loadFactionsContent();
-        }
-        return false;
-    });
+    if(arguments.length) {
+        throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");
+    }
 
-    var noButton = Object(_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_3__["clearEventListeners"])("faction-invitation-box-no");
-    noButton.addEventListener("click", function() {
-        factionInvitationBoxClose();
-        return false;
-    });
+    // object containing the files :
+    // {
+    //   "folder/" : {...},
+    //   "folder/data.txt" : {...}
+    // }
+    this.files = {};
 
-    factionInvitationBoxOpen();
+    this.comment = null;
+
+    // Where we are in the hierarchy
+    this.root = "";
+    this.clone = function() {
+        var newObj = new JSZip();
+        for (var i in this) {
+            if (typeof this[i] !== "function") {
+                newObj[i] = this[i];
+            }
+        }
+        return newObj;
+    };
 }
+JSZip.prototype = __webpack_require__(/*! ./object */ 167);
+JSZip.prototype.loadAsync = __webpack_require__(/*! ./load */ 121);
+JSZip.support = __webpack_require__(/*! ./support */ 50);
+JSZip.defaults = __webpack_require__(/*! ./defaults */ 93);
 
+// TODO find a better way to handle this version,
+// a require('package.json').version doesn't work with webpack, see #327
+JSZip.version = "3.1.5";
 
+JSZip.loadAsync = function (content, options) {
+    return new JSZip().loadAsync(content, options);
+};
+
+JSZip.external = __webpack_require__(/*! ./external */ 58);
+module.exports = JSZip;
 
 
 /***/ }),
 /* 115 */
-/*!****************************************!*\
-  !*** (webpack)/buildin/amd-options.js ***!
-  \****************************************/
-/***/ (function(module, exports) {
-
-/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
-module.exports = __webpack_amd_options__;
-
-/* WEBPACK VAR INJECTION */}.call(this, {}))
-
-/***/ }),
-/* 116 */
-/*!********************************************!*\
-  !*** ./node_modules/jszip/lib/zipEntry.js ***!
-  \********************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var readerFor = __webpack_require__(/*! ./reader/readerFor */ 82);
-var utils = __webpack_require__(/*! ./utils */ 31);
-var CompressedObject = __webpack_require__(/*! ./compressedObject */ 71);
-var crc32fn = __webpack_require__(/*! ./crc32 */ 70);
-var utf8 = __webpack_require__(/*! ./utf8 */ 56);
-var compressions = __webpack_require__(/*! ./compressions */ 89);
-var support = __webpack_require__(/*! ./support */ 47);
-
-var MADE_BY_DOS = 0x00;
-var MADE_BY_UNIX = 0x03;
-
-/**
- * Find a compression registered in JSZip.
- * @param {string} compressionMethod the method magic to find.
- * @return {Object|null} the JSZip compression object, null if none found.
- */
-var findCompression = function(compressionMethod) {
-    for (var method in compressions) {
-        if (!compressions.hasOwnProperty(method)) {
-            continue;
-        }
-        if (compressions[method].magic === compressionMethod) {
-            return compressions[method];
-        }
-    }
-    return null;
-};
-
-// class ZipEntry {{{
-/**
- * An entry in the zip file.
- * @constructor
- * @param {Object} options Options of the current file.
- * @param {Object} loadOptions Options for loading the stream.
- */
-function ZipEntry(options, loadOptions) {
-    this.options = options;
-    this.loadOptions = loadOptions;
-}
-ZipEntry.prototype = {
-    /**
-     * say if the file is encrypted.
-     * @return {boolean} true if the file is encrypted, false otherwise.
-     */
-    isEncrypted: function() {
-        // bit 1 is set
-        return (this.bitFlag & 0x0001) === 0x0001;
-    },
-    /**
-     * say if the file has utf-8 filename/comment.
-     * @return {boolean} true if the filename/comment is in utf-8, false otherwise.
-     */
-    useUTF8: function() {
-        // bit 11 is set
-        return (this.bitFlag & 0x0800) === 0x0800;
-    },
-    /**
-     * Read the local part of a zip file and add the info in this object.
-     * @param {DataReader} reader the reader to use.
-     */
-    readLocalPart: function(reader) {
-        var compression, localExtraFieldsLength;
-
-        // we already know everything from the central dir !
-        // If the central dir data are false, we are doomed.
-        // On the bright side, the local part is scary  : zip64, data descriptors, both, etc.
-        // The less data we get here, the more reliable this should be.
-        // Let's skip the whole header and dash to the data !
-        reader.skip(22);
-        // in some zip created on windows, the filename stored in the central dir contains \ instead of /.
-        // Strangely, the filename here is OK.
-        // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes
-        // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...
-        // Search "unzip mismatching "local" filename continuing with "central" filename version" on
-        // the internet.
-        //
-        // I think I see the logic here : the central directory is used to display
-        // content and the local directory is used to extract the files. Mixing / and \
-        // may be used to display \ to windows users and use / when extracting the files.
-        // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394
-        this.fileNameLength = reader.readInt(2);
-        localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir
-        // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding.
-        this.fileName = reader.readData(this.fileNameLength);
-        reader.skip(localExtraFieldsLength);
-
-        if (this.compressedSize === -1 || this.uncompressedSize === -1) {
-            throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)");
-        }
-
-        compression = findCompression(this.compressionMethod);
-        if (compression === null) { // no compression found
-            throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")");
-        }
-        this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize));
-    },
-
-    /**
-     * Read the central part of a zip file and add the info in this object.
-     * @param {DataReader} reader the reader to use.
-     */
-    readCentralPart: function(reader) {
-        this.versionMadeBy = reader.readInt(2);
-        reader.skip(2);
-        // this.versionNeeded = reader.readInt(2);
-        this.bitFlag = reader.readInt(2);
-        this.compressionMethod = reader.readString(2);
-        this.date = reader.readDate();
-        this.crc32 = reader.readInt(4);
-        this.compressedSize = reader.readInt(4);
-        this.uncompressedSize = reader.readInt(4);
-        var fileNameLength = reader.readInt(2);
-        this.extraFieldsLength = reader.readInt(2);
-        this.fileCommentLength = reader.readInt(2);
-        this.diskNumberStart = reader.readInt(2);
-        this.internalFileAttributes = reader.readInt(2);
-        this.externalFileAttributes = reader.readInt(4);
-        this.localHeaderOffset = reader.readInt(4);
-
-        if (this.isEncrypted()) {
-            throw new Error("Encrypted zip are not supported");
-        }
-
-        // will be read in the local part, see the comments there
-        reader.skip(fileNameLength);
-        this.readExtraFields(reader);
-        this.parseZIP64ExtraField(reader);
-        this.fileComment = reader.readData(this.fileCommentLength);
-    },
-
-    /**
-     * Parse the external file attributes and get the unix/dos permissions.
-     */
-    processAttributes: function () {
-        this.unixPermissions = null;
-        this.dosPermissions = null;
-        var madeBy = this.versionMadeBy >> 8;
-
-        // Check if we have the DOS directory flag set.
-        // We look for it in the DOS and UNIX permissions
-        // but some unknown platform could set it as a compatibility flag.
-        this.dir = this.externalFileAttributes & 0x0010 ? true : false;
-
-        if(madeBy === MADE_BY_DOS) {
-            // first 6 bits (0 to 5)
-            this.dosPermissions = this.externalFileAttributes & 0x3F;
-        }
-
-        if(madeBy === MADE_BY_UNIX) {
-            this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF;
-            // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8);
-        }
-
-        // fail safe : if the name ends with a / it probably means a folder
-        if (!this.dir && this.fileNameStr.slice(-1) === '/') {
-            this.dir = true;
-        }
-    },
-
-    /**
-     * Parse the ZIP64 extra field and merge the info in the current ZipEntry.
-     * @param {DataReader} reader the reader to use.
-     */
-    parseZIP64ExtraField: function(reader) {
-
-        if (!this.extraFields[0x0001]) {
-            return;
-        }
-
-        // should be something, preparing the extra reader
-        var extraReader = readerFor(this.extraFields[0x0001].value);
-
-        // I really hope that these 64bits integer can fit in 32 bits integer, because js
-        // won't let us have more.
-        if (this.uncompressedSize === utils.MAX_VALUE_32BITS) {
-            this.uncompressedSize = extraReader.readInt(8);
-        }
-        if (this.compressedSize === utils.MAX_VALUE_32BITS) {
-            this.compressedSize = extraReader.readInt(8);
-        }
-        if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) {
-            this.localHeaderOffset = extraReader.readInt(8);
-        }
-        if (this.diskNumberStart === utils.MAX_VALUE_32BITS) {
-            this.diskNumberStart = extraReader.readInt(4);
-        }
-    },
-    /**
-     * Read the central part of a zip file and add the info in this object.
-     * @param {DataReader} reader the reader to use.
-     */
-    readExtraFields: function(reader) {
-        var end = reader.index + this.extraFieldsLength,
-            extraFieldId,
-            extraFieldLength,
-            extraFieldValue;
-
-        if (!this.extraFields) {
-            this.extraFields = {};
-        }
-
-        while (reader.index < end) {
-            extraFieldId = reader.readInt(2);
-            extraFieldLength = reader.readInt(2);
-            extraFieldValue = reader.readData(extraFieldLength);
-
-            this.extraFields[extraFieldId] = {
-                id: extraFieldId,
-                length: extraFieldLength,
-                value: extraFieldValue
-            };
-        }
-    },
-    /**
-     * Apply an UTF8 transformation if needed.
-     */
-    handleUTF8: function() {
-        var decodeParamType = support.uint8array ? "uint8array" : "array";
-        if (this.useUTF8()) {
-            this.fileNameStr = utf8.utf8decode(this.fileName);
-            this.fileCommentStr = utf8.utf8decode(this.fileComment);
-        } else {
-            var upath = this.findExtraFieldUnicodePath();
-            if (upath !== null) {
-                this.fileNameStr = upath;
-            } else {
-                // ASCII text or unsupported code page
-                var fileNameByteArray =  utils.transformTo(decodeParamType, this.fileName);
-                this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray);
-            }
-
-            var ucomment = this.findExtraFieldUnicodeComment();
-            if (ucomment !== null) {
-                this.fileCommentStr = ucomment;
-            } else {
-                // ASCII text or unsupported code page
-                var commentByteArray =  utils.transformTo(decodeParamType, this.fileComment);
-                this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray);
-            }
-        }
-    },
-
-    /**
-     * Find the unicode path declared in the extra field, if any.
-     * @return {String} the unicode path, null otherwise.
-     */
-    findExtraFieldUnicodePath: function() {
-        var upathField = this.extraFields[0x7075];
-        if (upathField) {
-            var extraReader = readerFor(upathField.value);
-
-            // wrong version
-            if (extraReader.readInt(1) !== 1) {
-                return null;
-            }
-
-            // the crc of the filename changed, this field is out of date.
-            if (crc32fn(this.fileName) !== extraReader.readInt(4)) {
-                return null;
-            }
-
-            return utf8.utf8decode(extraReader.readData(upathField.length - 5));
-        }
-        return null;
-    },
-
-    /**
-     * Find the unicode comment declared in the extra field, if any.
-     * @return {String} the unicode comment, null otherwise.
-     */
-    findExtraFieldUnicodeComment: function() {
-        var ucommentField = this.extraFields[0x6375];
-        if (ucommentField) {
-            var extraReader = readerFor(ucommentField.value);
-
-            // wrong version
-            if (extraReader.readInt(1) !== 1) {
-                return null;
-            }
-
-            // the crc of the comment changed, this field is out of date.
-            if (crc32fn(this.fileComment) !== extraReader.readInt(4)) {
-                return null;
-            }
-
-            return utf8.utf8decode(extraReader.readData(ucommentField.length - 5));
-        }
-        return null;
-    }
-};
-module.exports = ZipEntry;
-
-
-/***/ }),
-/* 117 */
-/*!***********************************************************!*\
-  !*** ./node_modules/jszip/lib/reader/NodeBufferReader.js ***!
-  \***********************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var Uint8ArrayReader = __webpack_require__(/*! ./Uint8ArrayReader */ 79);
-var utils = __webpack_require__(/*! ../utils */ 31);
-
-function NodeBufferReader(data) {
-    Uint8ArrayReader.call(this, data);
-}
-utils.inherits(NodeBufferReader, Uint8ArrayReader);
-
-/**
- * @see DataReader.readData
- */
-NodeBufferReader.prototype.readData = function(size) {
-    this.checkOffset(size);
-    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
-    this.index += size;
-    return result;
-};
-module.exports = NodeBufferReader;
-
-
-/***/ }),
-/* 118 */
-/*!*******************************************************!*\
-  !*** ./node_modules/jszip/lib/reader/StringReader.js ***!
-  \*******************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var DataReader = __webpack_require__(/*! ./DataReader */ 80);
-var utils = __webpack_require__(/*! ../utils */ 31);
-
-function StringReader(data) {
-    DataReader.call(this, data);
-}
-utils.inherits(StringReader, DataReader);
-/**
- * @see DataReader.byteAt
- */
-StringReader.prototype.byteAt = function(i) {
-    return this.data.charCodeAt(this.zero + i);
-};
-/**
- * @see DataReader.lastIndexOfSignature
- */
-StringReader.prototype.lastIndexOfSignature = function(sig) {
-    return this.data.lastIndexOf(sig) - this.zero;
-};
-/**
- * @see DataReader.readAndCheckSignature
- */
-StringReader.prototype.readAndCheckSignature = function (sig) {
-    var data = this.readData(4);
-    return sig === data;
-};
-/**
- * @see DataReader.readData
- */
-StringReader.prototype.readData = function(size) {
-    this.checkOffset(size);
-    // this will work because the constructor applied the "& 0xff" mask.
-    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
-    this.index += size;
-    return result;
-};
-module.exports = StringReader;
-
-
-/***/ }),
-/* 119 */
-/*!**********************************************!*\
-  !*** ./node_modules/jszip/lib/zipEntries.js ***!
-  \**********************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var readerFor = __webpack_require__(/*! ./reader/readerFor */ 82);
-var utils = __webpack_require__(/*! ./utils */ 31);
-var sig = __webpack_require__(/*! ./signature */ 83);
-var ZipEntry = __webpack_require__(/*! ./zipEntry */ 116);
-var utf8 = __webpack_require__(/*! ./utf8 */ 56);
-var support = __webpack_require__(/*! ./support */ 47);
-//  class ZipEntries {{{
-/**
- * All the entries in the zip file.
- * @constructor
- * @param {Object} loadOptions Options for loading the stream.
- */
-function ZipEntries(loadOptions) {
-    this.files = [];
-    this.loadOptions = loadOptions;
-}
-ZipEntries.prototype = {
-    /**
-     * Check that the reader is on the specified signature.
-     * @param {string} expectedSignature the expected signature.
-     * @throws {Error} if it is an other signature.
-     */
-    checkSignature: function(expectedSignature) {
-        if (!this.reader.readAndCheckSignature(expectedSignature)) {
-            this.reader.index -= 4;
-            var signature = this.reader.readString(4);
-            throw new Error("Corrupted zip or bug: unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")");
-        }
-    },
-    /**
-     * Check if the given signature is at the given index.
-     * @param {number} askedIndex the index to check.
-     * @param {string} expectedSignature the signature to expect.
-     * @return {boolean} true if the signature is here, false otherwise.
-     */
-    isSignature: function(askedIndex, expectedSignature) {
-        var currentIndex = this.reader.index;
-        this.reader.setIndex(askedIndex);
-        var signature = this.reader.readString(4);
-        var result = signature === expectedSignature;
-        this.reader.setIndex(currentIndex);
-        return result;
-    },
-    /**
-     * Read the end of the central directory.
-     */
-    readBlockEndOfCentral: function() {
-        this.diskNumber = this.reader.readInt(2);
-        this.diskWithCentralDirStart = this.reader.readInt(2);
-        this.centralDirRecordsOnThisDisk = this.reader.readInt(2);
-        this.centralDirRecords = this.reader.readInt(2);
-        this.centralDirSize = this.reader.readInt(4);
-        this.centralDirOffset = this.reader.readInt(4);
-
-        this.zipCommentLength = this.reader.readInt(2);
-        // warning : the encoding depends of the system locale
-        // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded.
-        // On a windows machine, this field is encoded with the localized windows code page.
-        var zipComment = this.reader.readData(this.zipCommentLength);
-        var decodeParamType = support.uint8array ? "uint8array" : "array";
-        // To get consistent behavior with the generation part, we will assume that
-        // this is utf8 encoded unless specified otherwise.
-        var decodeContent = utils.transformTo(decodeParamType, zipComment);
-        this.zipComment = this.loadOptions.decodeFileName(decodeContent);
-    },
-    /**
-     * Read the end of the Zip 64 central directory.
-     * Not merged with the method readEndOfCentral :
-     * The end of central can coexist with its Zip64 brother,
-     * I don't want to read the wrong number of bytes !
-     */
-    readBlockZip64EndOfCentral: function() {
-        this.zip64EndOfCentralSize = this.reader.readInt(8);
-        this.reader.skip(4);
-        // this.versionMadeBy = this.reader.readString(2);
-        // this.versionNeeded = this.reader.readInt(2);
-        this.diskNumber = this.reader.readInt(4);
-        this.diskWithCentralDirStart = this.reader.readInt(4);
-        this.centralDirRecordsOnThisDisk = this.reader.readInt(8);
-        this.centralDirRecords = this.reader.readInt(8);
-        this.centralDirSize = this.reader.readInt(8);
-        this.centralDirOffset = this.reader.readInt(8);
-
-        this.zip64ExtensibleData = {};
-        var extraDataSize = this.zip64EndOfCentralSize - 44,
-            index = 0,
-            extraFieldId,
-            extraFieldLength,
-            extraFieldValue;
-        while (index < extraDataSize) {
-            extraFieldId = this.reader.readInt(2);
-            extraFieldLength = this.reader.readInt(4);
-            extraFieldValue = this.reader.readData(extraFieldLength);
-            this.zip64ExtensibleData[extraFieldId] = {
-                id: extraFieldId,
-                length: extraFieldLength,
-                value: extraFieldValue
-            };
-        }
-    },
-    /**
-     * Read the end of the Zip 64 central directory locator.
-     */
-    readBlockZip64EndOfCentralLocator: function() {
-        this.diskWithZip64CentralDirStart = this.reader.readInt(4);
-        this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);
-        this.disksCount = this.reader.readInt(4);
-        if (this.disksCount > 1) {
-            throw new Error("Multi-volumes zip are not supported");
-        }
-    },
-    /**
-     * Read the local files, based on the offset read in the central part.
-     */
-    readLocalFiles: function() {
-        var i, file;
-        for (i = 0; i < this.files.length; i++) {
-            file = this.files[i];
-            this.reader.setIndex(file.localHeaderOffset);
-            this.checkSignature(sig.LOCAL_FILE_HEADER);
-            file.readLocalPart(this.reader);
-            file.handleUTF8();
-            file.processAttributes();
-        }
-    },
-    /**
-     * Read the central directory.
-     */
-    readCentralDir: function() {
-        var file;
-
-        this.reader.setIndex(this.centralDirOffset);
-        while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) {
-            file = new ZipEntry({
-                zip64: this.zip64
-            }, this.loadOptions);
-            file.readCentralPart(this.reader);
-            this.files.push(file);
-        }
-
-        if (this.centralDirRecords !== this.files.length) {
-            if (this.centralDirRecords !== 0 && this.files.length === 0) {
-                // We expected some records but couldn't find ANY.
-                // This is really suspicious, as if something went wrong.
-                throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length);
-            } else {
-                // We found some records but not all.
-                // Something is wrong but we got something for the user: no error here.
-                // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length);
-            }
-        }
-    },
-    /**
-     * Read the end of central directory.
-     */
-    readEndOfCentral: function() {
-        var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END);
-        if (offset < 0) {
-            // Check if the content is a truncated zip or complete garbage.
-            // A "LOCAL_FILE_HEADER" is not required at the beginning (auto
-            // extractible zip for example) but it can give a good hint.
-            // If an ajax request was used without responseType, we will also
-            // get unreadable data.
-            var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER);
-
-            if (isGarbage) {
-                throw new Error("Can't find end of central directory : is this a zip file ? " +
-                                "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html");
-            } else {
-                throw new Error("Corrupted zip: can't find end of central directory");
-            }
-
-        }
-        this.reader.setIndex(offset);
-        var endOfCentralDirOffset = offset;
-        this.checkSignature(sig.CENTRAL_DIRECTORY_END);
-        this.readBlockEndOfCentral();
-
-
-        /* extract from the zip spec :
-            4)  If one of the fields in the end of central directory
-                record is too small to hold required data, the field
-                should be set to -1 (0xFFFF or 0xFFFFFFFF) and the
-                ZIP64 format record should be created.
-            5)  The end of central directory record and the
-                Zip64 end of central directory locator record must
-                reside on the same disk when splitting or spanning
-                an archive.
-         */
-        if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) {
-            this.zip64 = true;
-
-            /*
-            Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from
-            the zip file can fit into a 32bits integer. This cannot be solved : JavaScript represents
-            all numbers as 64-bit double precision IEEE 754 floating point numbers.
-            So, we have 53bits for integers and bitwise operations treat everything as 32bits.
-            see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators
-            and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5
-            */
-
-            // should look for a zip64 EOCD locator
-            offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
-            if (offset < 0) {
-                throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");
-            }
-            this.reader.setIndex(offset);
-            this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
-            this.readBlockZip64EndOfCentralLocator();
-
-            // now the zip64 EOCD record
-            if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) {
-                // console.warn("ZIP64 end of central directory not where expected.");
-                this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
-                if (this.relativeOffsetEndOfZip64CentralDir < 0) {
-                    throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");
-                }
-            }
-            this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);
-            this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
-            this.readBlockZip64EndOfCentral();
-        }
-
-        var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize;
-        if (this.zip64) {
-            expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator
-            expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize;
-        }
-
-        var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset;
-
-        if (extraBytes > 0) {
-            // console.warn(extraBytes, "extra bytes at beginning or within zipfile");
-            if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) {
-                // The offsets seem wrong, but we have something at the specified offset.
-                // So… we keep it.
-            } else {
-                // the offset is wrong, update the "zero" of the reader
-                // this happens if data has been prepended (crx files for example)
-                this.reader.zero = extraBytes;
-            }
-        } else if (extraBytes < 0) {
-            throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes.");
-        }
-    },
-    prepareReader: function(data) {
-        this.reader = readerFor(data);
-    },
-    /**
-     * Read a zip file and create ZipEntries.
-     * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file.
-     */
-    load: function(data) {
-        this.prepareReader(data);
-        this.readEndOfCentral();
-        this.readCentralDir();
-        this.readLocalFiles();
-    }
-};
-// }}} end of ZipEntries
-module.exports = ZipEntries;
-
-
-/***/ }),
-/* 120 */
-/*!****************************************!*\
-  !*** ./node_modules/jszip/lib/load.js ***!
-  \****************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var utils = __webpack_require__(/*! ./utils */ 31);
-var external = __webpack_require__(/*! ./external */ 57);
-var utf8 = __webpack_require__(/*! ./utf8 */ 56);
-var utils = __webpack_require__(/*! ./utils */ 31);
-var ZipEntries = __webpack_require__(/*! ./zipEntries */ 119);
-var Crc32Probe = __webpack_require__(/*! ./stream/Crc32Probe */ 90);
-var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ 62);
-
-/**
- * Check the CRC32 of an entry.
- * @param {ZipEntry} zipEntry the zip entry to check.
- * @return {Promise} the result.
- */
-function checkEntryCRC32(zipEntry) {
-    return new external.Promise(function (resolve, reject) {
-        var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());
-        worker.on("error", function (e) {
-            reject(e);
-        })
-        .on("end", function () {
-            if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {
-                reject(new Error("Corrupted zip : CRC32 mismatch"));
-            } else {
-                resolve();
-            }
-        })
-        .resume();
-    });
-}
-
-module.exports = function(data, options) {
-    var zip = this;
-    options = utils.extend(options || {}, {
-        base64: false,
-        checkCRC32: false,
-        optimizedBinaryString: false,
-        createFolders: false,
-        decodeFileName: utf8.utf8decode
-    });
-
-    if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {
-        return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file."));
-    }
-
-    return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64)
-    .then(function(data) {
-        var zipEntries = new ZipEntries(options);
-        zipEntries.load(data);
-        return zipEntries;
-    }).then(function checkCRC32(zipEntries) {
-        var promises = [external.Promise.resolve(zipEntries)];
-        var files = zipEntries.files;
-        if (options.checkCRC32) {
-            for (var i = 0; i < files.length; i++) {
-                promises.push(checkEntryCRC32(files[i]));
-            }
-        }
-        return external.Promise.all(promises);
-    }).then(function addFiles(results) {
-        var zipEntries = results.shift();
-        var files = zipEntries.files;
-        for (var i = 0; i < files.length; i++) {
-            var input = files[i];
-            zip.file(input.fileNameStr, input.decompressed, {
-                binary: true,
-                optimizedBinaryString: true,
-                date: input.date,
-                dir: input.dir,
-                comment : input.fileCommentStr.length ? input.fileCommentStr : null,
-                unixPermissions : input.unixPermissions,
-                dosPermissions : input.dosPermissions,
-                createFolders: options.createFolders
-            });
-        }
-        if (zipEntries.zipComment.length) {
-            zip.comment = zipEntries.zipComment;
-        }
-
-        return zip;
-    });
-};
-
-
-/***/ }),
-/* 121 */
-/*!*******************************************************************!*\
-  !*** ./node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js ***!
-  \*******************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-var utils = __webpack_require__(/*! ../utils */ 31);
-var GenericWorker = __webpack_require__(/*! ../stream/GenericWorker */ 37);
-
-/**
- * A worker that use a nodejs stream as source.
- * @constructor
- * @param {String} filename the name of the file entry for this stream.
- * @param {Readable} stream the nodejs stream.
- */
-function NodejsStreamInputAdapter(filename, stream) {
-    GenericWorker.call(this, "Nodejs stream input adapter for " + filename);
-    this._upstreamEnded = false;
-    this._bindStream(stream);
-}
-
-utils.inherits(NodejsStreamInputAdapter, GenericWorker);
-
-/**
- * Prepare the stream and bind the callbacks on it.
- * Do this ASAP on node 0.10 ! A lazy binding doesn't always work.
- * @param {Stream} stream the nodejs stream to use.
- */
-NodejsStreamInputAdapter.prototype._bindStream = function (stream) {
-    var self = this;
-    this._stream = stream;
-    stream.pause();
-    stream
-    .on("data", function (chunk) {
-        self.push({
-            data: chunk,
-            meta : {
-                percent : 0
-            }
-        });
-    })
-    .on("error", function (e) {
-        if(self.isPaused) {
-            this.generatedError = e;
-        } else {
-            self.error(e);
-        }
-    })
-    .on("end", function () {
-        if(self.isPaused) {
-            self._upstreamEnded = true;
-        } else {
-            self.end();
-        }
-    });
-};
-NodejsStreamInputAdapter.prototype.pause = function () {
-    if(!GenericWorker.prototype.pause.call(this)) {
-        return false;
-    }
-    this._stream.pause();
-    return true;
-};
-NodejsStreamInputAdapter.prototype.resume = function () {
-    if(!GenericWorker.prototype.resume.call(this)) {
-        return false;
-    }
-
-    if(this._upstreamEnded) {
-        this.end();
-    } else {
-        this._stream.resume();
-    }
-
-    return true;
-};
-
-module.exports = NodejsStreamInputAdapter;
-
-
-/***/ }),
-/* 122 */
-/*!**********************************************************!*\
-  !*** ./node_modules/jszip/lib/generate/ZipFileWorker.js ***!
-  \**********************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-var utils = __webpack_require__(/*! ../utils */ 31);
-var GenericWorker = __webpack_require__(/*! ../stream/GenericWorker */ 37);
-var utf8 = __webpack_require__(/*! ../utf8 */ 56);
-var crc32 = __webpack_require__(/*! ../crc32 */ 70);
-var signature = __webpack_require__(/*! ../signature */ 83);
-
-/**
- * Transform an integer into a string in hexadecimal.
- * @private
- * @param {number} dec the number to convert.
- * @param {number} bytes the number of bytes to generate.
- * @returns {string} the result.
- */
-var decToHex = function(dec, bytes) {
-    var hex = "", i;
-    for (i = 0; i < bytes; i++) {
-        hex += String.fromCharCode(dec & 0xff);
-        dec = dec >>> 8;
-    }
-    return hex;
-};
-
-/**
- * Generate the UNIX part of the external file attributes.
- * @param {Object} unixPermissions the unix permissions or null.
- * @param {Boolean} isDir true if the entry is a directory, false otherwise.
- * @return {Number} a 32 bit integer.
- *
- * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute :
- *
- * TTTTsstrwxrwxrwx0000000000ADVSHR
- * ^^^^____________________________ file type, see zipinfo.c (UNX_*)
- *     ^^^_________________________ setuid, setgid, sticky
- *        ^^^^^^^^^________________ permissions
- *                 ^^^^^^^^^^______ not used ?
- *                           ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only
- */
-var generateUnixExternalFileAttr = function (unixPermissions, isDir) {
-
-    var result = unixPermissions;
-    if (!unixPermissions) {
-        // I can't use octal values in strict mode, hence the hexa.
-        //  040775 => 0x41fd
-        // 0100664 => 0x81b4
-        result = isDir ? 0x41fd : 0x81b4;
-    }
-    return (result & 0xFFFF) << 16;
-};
-
-/**
- * Generate the DOS part of the external file attributes.
- * @param {Object} dosPermissions the dos permissions or null.
- * @param {Boolean} isDir true if the entry is a directory, false otherwise.
- * @return {Number} a 32 bit integer.
- *
- * Bit 0     Read-Only
- * Bit 1     Hidden
- * Bit 2     System
- * Bit 3     Volume Label
- * Bit 4     Directory
- * Bit 5     Archive
- */
-var generateDosExternalFileAttr = function (dosPermissions, isDir) {
-
-    // the dir flag is already set for compatibility
-    return (dosPermissions || 0)  & 0x3F;
-};
-
-/**
- * Generate the various parts used in the construction of the final zip file.
- * @param {Object} streamInfo the hash with informations about the compressed file.
- * @param {Boolean} streamedContent is the content streamed ?
- * @param {Boolean} streamingEnded is the stream finished ?
- * @param {number} offset the current offset from the start of the zip file.
- * @param {String} platform let's pretend we are this platform (change platform dependents fields)
- * @param {Function} encodeFileName the function to encode the file name / comment.
- * @return {Object} the zip parts.
- */
-var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) {
-    var file = streamInfo['file'],
-    compression = streamInfo['compression'],
-    useCustomEncoding = encodeFileName !== utf8.utf8encode,
-    encodedFileName = utils.transformTo("string", encodeFileName(file.name)),
-    utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)),
-    comment = file.comment,
-    encodedComment = utils.transformTo("string", encodeFileName(comment)),
-    utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)),
-    useUTF8ForFileName = utfEncodedFileName.length !== file.name.length,
-    useUTF8ForComment = utfEncodedComment.length !== comment.length,
-    dosTime,
-    dosDate,
-    extraFields = "",
-    unicodePathExtraField = "",
-    unicodeCommentExtraField = "",
-    dir = file.dir,
-    date = file.date;
-
-
-    var dataInfo = {
-        crc32 : 0,
-        compressedSize : 0,
-        uncompressedSize : 0
-    };
-
-    // if the content is streamed, the sizes/crc32 are only available AFTER
-    // the end of the stream.
-    if (!streamedContent || streamingEnded) {
-        dataInfo.crc32 = streamInfo['crc32'];
-        dataInfo.compressedSize = streamInfo['compressedSize'];
-        dataInfo.uncompressedSize = streamInfo['uncompressedSize'];
-    }
-
-    var bitflag = 0;
-    if (streamedContent) {
-        // Bit 3: the sizes/crc32 are set to zero in the local header.
-        // The correct values are put in the data descriptor immediately
-        // following the compressed data.
-        bitflag |= 0x0008;
-    }
-    if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) {
-        // Bit 11: Language encoding flag (EFS).
-        bitflag |= 0x0800;
-    }
-
-
-    var extFileAttr = 0;
-    var versionMadeBy = 0;
-    if (dir) {
-        // dos or unix, we set the dos dir flag
-        extFileAttr |= 0x00010;
-    }
-    if(platform === "UNIX") {
-        versionMadeBy = 0x031E; // UNIX, version 3.0
-        extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir);
-    } else { // DOS or other, fallback to DOS
-        versionMadeBy = 0x0014; // DOS, version 2.0
-        extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir);
-    }
-
-    // date
-    // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
-    // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
-    // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html
-
-    dosTime = date.getUTCHours();
-    dosTime = dosTime << 6;
-    dosTime = dosTime | date.getUTCMinutes();
-    dosTime = dosTime << 5;
-    dosTime = dosTime | date.getUTCSeconds() / 2;
-
-    dosDate = date.getUTCFullYear() - 1980;
-    dosDate = dosDate << 4;
-    dosDate = dosDate | (date.getUTCMonth() + 1);
-    dosDate = dosDate << 5;
-    dosDate = dosDate | date.getUTCDate();
-
-    if (useUTF8ForFileName) {
-        // set the unicode path extra field. unzip needs at least one extra
-        // field to correctly handle unicode path, so using the path is as good
-        // as any other information. This could improve the situation with
-        // other archive managers too.
-        // This field is usually used without the utf8 flag, with a non
-        // unicode path in the header (winrar, winzip). This helps (a bit)
-        // with the messy Windows' default compressed folders feature but
-        // breaks on p7zip which doesn't seek the unicode path extra field.
-        // So for now, UTF-8 everywhere !
-        unicodePathExtraField =
-            // Version
-            decToHex(1, 1) +
-            // NameCRC32
-            decToHex(crc32(encodedFileName), 4) +
-            // UnicodeName
-            utfEncodedFileName;
-
-        extraFields +=
-            // Info-ZIP Unicode Path Extra Field
-            "\x75\x70" +
-            // size
-            decToHex(unicodePathExtraField.length, 2) +
-            // content
-            unicodePathExtraField;
-    }
-
-    if(useUTF8ForComment) {
-
-        unicodeCommentExtraField =
-            // Version
-            decToHex(1, 1) +
-            // CommentCRC32
-            decToHex(crc32(encodedComment), 4) +
-            // UnicodeName
-            utfEncodedComment;
-
-        extraFields +=
-            // Info-ZIP Unicode Path Extra Field
-            "\x75\x63" +
-            // size
-            decToHex(unicodeCommentExtraField.length, 2) +
-            // content
-            unicodeCommentExtraField;
-    }
-
-    var header = "";
-
-    // version needed to extract
-    header += "\x0A\x00";
-    // general purpose bit flag
-    header += decToHex(bitflag, 2);
-    // compression method
-    header += compression.magic;
-    // last mod file time
-    header += decToHex(dosTime, 2);
-    // last mod file date
-    header += decToHex(dosDate, 2);
-    // crc-32
-    header += decToHex(dataInfo.crc32, 4);
-    // compressed size
-    header += decToHex(dataInfo.compressedSize, 4);
-    // uncompressed size
-    header += decToHex(dataInfo.uncompressedSize, 4);
-    // file name length
-    header += decToHex(encodedFileName.length, 2);
-    // extra field length
-    header += decToHex(extraFields.length, 2);
-
-
-    var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields;
-
-    var dirRecord = signature.CENTRAL_FILE_HEADER +
-        // version made by (00: DOS)
-        decToHex(versionMadeBy, 2) +
-        // file header (common to file and central directory)
-        header +
-        // file comment length
-        decToHex(encodedComment.length, 2) +
-        // disk number start
-        "\x00\x00" +
-        // internal file attributes TODO
-        "\x00\x00" +
-        // external file attributes
-        decToHex(extFileAttr, 4) +
-        // relative offset of local header
-        decToHex(offset, 4) +
-        // file name
-        encodedFileName +
-        // extra field
-        extraFields +
-        // file comment
-        encodedComment;
-
-    return {
-        fileRecord: fileRecord,
-        dirRecord: dirRecord
-    };
-};
-
-/**
- * Generate the EOCD record.
- * @param {Number} entriesCount the number of entries in the zip file.
- * @param {Number} centralDirLength the length (in bytes) of the central dir.
- * @param {Number} localDirLength the length (in bytes) of the local dir.
- * @param {String} comment the zip file comment as a binary string.
- * @param {Function} encodeFileName the function to encode the comment.
- * @return {String} the EOCD record.
- */
-var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) {
-    var dirEnd = "";
-    var encodedComment = utils.transformTo("string", encodeFileName(comment));
-
-    // end of central dir signature
-    dirEnd = signature.CENTRAL_DIRECTORY_END +
-        // number of this disk
-        "\x00\x00" +
-        // number of the disk with the start of the central directory
-        "\x00\x00" +
-        // total number of entries in the central directory on this disk
-        decToHex(entriesCount, 2) +
-        // total number of entries in the central directory
-        decToHex(entriesCount, 2) +
-        // size of the central directory   4 bytes
-        decToHex(centralDirLength, 4) +
-        // offset of start of central directory with respect to the starting disk number
-        decToHex(localDirLength, 4) +
-        // .ZIP file comment length
-        decToHex(encodedComment.length, 2) +
-        // .ZIP file comment
-        encodedComment;
-
-    return dirEnd;
-};
-
-/**
- * Generate data descriptors for a file entry.
- * @param {Object} streamInfo the hash generated by a worker, containing informations
- * on the file entry.
- * @return {String} the data descriptors.
- */
-var generateDataDescriptors = function (streamInfo) {
-    var descriptor = "";
-    descriptor = signature.DATA_DESCRIPTOR +
-        // crc-32                          4 bytes
-        decToHex(streamInfo['crc32'], 4) +
-        // compressed size                 4 bytes
-        decToHex(streamInfo['compressedSize'], 4) +
-        // uncompressed size               4 bytes
-        decToHex(streamInfo['uncompressedSize'], 4);
-
-    return descriptor;
-};
-
-
-/**
- * A worker to concatenate other workers to create a zip file.
- * @param {Boolean} streamFiles `true` to stream the content of the files,
- * `false` to accumulate it.
- * @param {String} comment the comment to use.
- * @param {String} platform the platform to use, "UNIX" or "DOS".
- * @param {Function} encodeFileName the function to encode file names and comments.
- */
-function ZipFileWorker(streamFiles, comment, platform, encodeFileName) {
-    GenericWorker.call(this, "ZipFileWorker");
-    // The number of bytes written so far. This doesn't count accumulated chunks.
-    this.bytesWritten = 0;
-    // The comment of the zip file
-    this.zipComment = comment;
-    // The platform "generating" the zip file.
-    this.zipPlatform = platform;
-    // the function to encode file names and comments.
-    this.encodeFileName = encodeFileName;
-    // Should we stream the content of the files ?
-    this.streamFiles = streamFiles;
-    // If `streamFiles` is false, we will need to accumulate the content of the
-    // files to calculate sizes / crc32 (and write them *before* the content).
-    // This boolean indicates if we are accumulating chunks (it will change a lot
-    // during the lifetime of this worker).
-    this.accumulate = false;
-    // The buffer receiving chunks when accumulating content.
-    this.contentBuffer = [];
-    // The list of generated directory records.
-    this.dirRecords = [];
-    // The offset (in bytes) from the beginning of the zip file for the current source.
-    this.currentSourceOffset = 0;
-    // The total number of entries in this zip file.
-    this.entriesCount = 0;
-    // the name of the file currently being added, null when handling the end of the zip file.
-    // Used for the emited metadata.
-    this.currentFile = null;
-
-
-
-    this._sources = [];
-}
-utils.inherits(ZipFileWorker, GenericWorker);
-
-/**
- * @see GenericWorker.push
- */
-ZipFileWorker.prototype.push = function (chunk) {
-
-    var currentFilePercent = chunk.meta.percent || 0;
-    var entriesCount = this.entriesCount;
-    var remainingFiles = this._sources.length;
-
-    if(this.accumulate) {
-        this.contentBuffer.push(chunk);
-    } else {
-        this.bytesWritten += chunk.data.length;
-
-        GenericWorker.prototype.push.call(this, {
-            data : chunk.data,
-            meta : {
-                currentFile : this.currentFile,
-                percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100
-            }
-        });
-    }
-};
-
-/**
- * The worker started a new source (an other worker).
- * @param {Object} streamInfo the streamInfo object from the new source.
- */
-ZipFileWorker.prototype.openedSource = function (streamInfo) {
-    this.currentSourceOffset = this.bytesWritten;
-    this.currentFile = streamInfo['file'].name;
-
-    var streamedContent = this.streamFiles && !streamInfo['file'].dir;
-
-    // don't stream folders (because they don't have any content)
-    if(streamedContent) {
-        var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
-        this.push({
-            data : record.fileRecord,
-            meta : {percent:0}
-        });
-    } else {
-        // we need to wait for the whole file before pushing anything
-        this.accumulate = true;
-    }
-};
-
-/**
- * The worker finished a source (an other worker).
- * @param {Object} streamInfo the streamInfo object from the finished source.
- */
-ZipFileWorker.prototype.closedSource = function (streamInfo) {
-    this.accumulate = false;
-    var streamedContent = this.streamFiles && !streamInfo['file'].dir;
-    var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
-
-    this.dirRecords.push(record.dirRecord);
-    if(streamedContent) {
-        // after the streamed file, we put data descriptors
-        this.push({
-            data : generateDataDescriptors(streamInfo),
-            meta : {percent:100}
-        });
-    } else {
-        // the content wasn't streamed, we need to push everything now
-        // first the file record, then the content
-        this.push({
-            data : record.fileRecord,
-            meta : {percent:0}
-        });
-        while(this.contentBuffer.length) {
-            this.push(this.contentBuffer.shift());
-        }
-    }
-    this.currentFile = null;
-};
-
-/**
- * @see GenericWorker.flush
- */
-ZipFileWorker.prototype.flush = function () {
-
-    var localDirLength = this.bytesWritten;
-    for(var i = 0; i < this.dirRecords.length; i++) {
-        this.push({
-            data : this.dirRecords[i],
-            meta : {percent:100}
-        });
-    }
-    var centralDirLength = this.bytesWritten - localDirLength;
-
-    var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName);
-
-    this.push({
-        data : dirEnd,
-        meta : {percent:100}
-    });
-};
-
-/**
- * Prepare the next source to be read.
- */
-ZipFileWorker.prototype.prepareNextSource = function () {
-    this.previous = this._sources.shift();
-    this.openedSource(this.previous.streamInfo);
-    if (this.isPaused) {
-        this.previous.pause();
-    } else {
-        this.previous.resume();
-    }
-};
-
-/**
- * @see GenericWorker.registerPrevious
- */
-ZipFileWorker.prototype.registerPrevious = function (previous) {
-    this._sources.push(previous);
-    var self = this;
-
-    previous.on('data', function (chunk) {
-        self.processChunk(chunk);
-    });
-    previous.on('end', function () {
-        self.closedSource(self.previous.streamInfo);
-        if(self._sources.length) {
-            self.prepareNextSource();
-        } else {
-            self.end();
-        }
-    });
-    previous.on('error', function (e) {
-        self.error(e);
-    });
-    return this;
-};
-
-/**
- * @see GenericWorker.resume
- */
-ZipFileWorker.prototype.resume = function () {
-    if(!GenericWorker.prototype.resume.call(this)) {
-        return false;
-    }
-
-    if (!this.previous && this._sources.length) {
-        this.prepareNextSource();
-        return true;
-    }
-    if (!this.previous && !this._sources.length && !this.generatedError) {
-        this.end();
-        return true;
-    }
-};
-
-/**
- * @see GenericWorker.error
- */
-ZipFileWorker.prototype.error = function (e) {
-    var sources = this._sources;
-    if(!GenericWorker.prototype.error.call(this, e)) {
-        return false;
-    }
-    for(var i = 0; i < sources.length; i++) {
-        try {
-            sources[i].error(e);
-        } catch(e) {
-            // the `error` exploded, nothing to do
-        }
-    }
-    return true;
-};
-
-/**
- * @see GenericWorker.lock
- */
-ZipFileWorker.prototype.lock = function () {
-    GenericWorker.prototype.lock.call(this);
-    var sources = this._sources;
-    for(var i = 0; i < sources.length; i++) {
-        sources[i].lock();
-    }
-};
-
-module.exports = ZipFileWorker;
-
-
-/***/ }),
-/* 123 */
-/*!************************************************!*\
-  !*** ./node_modules/pako/lib/zlib/gzheader.js ***!
-  \************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-// (C) 1995-2013 Jean-loup Gailly and Mark Adler
-// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//   claim that you wrote the original software. If you use this software
-//   in a product, an acknowledgment in the product documentation would be
-//   appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-//   misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-function GZheader() {
-  /* true if compressed data believed to be text */
-  this.text       = 0;
-  /* modification time */
-  this.time       = 0;
-  /* extra flags (not used when writing a gzip file) */
-  this.xflags     = 0;
-  /* operating system */
-  this.os         = 0;
-  /* pointer to extra field or Z_NULL if none */
-  this.extra      = null;
-  /* extra field length (valid if extra != Z_NULL) */
-  this.extra_len  = 0; // Actually, we don't need it in JS,
-                       // but leave for few code modifications
-
-  //
-  // Setup limits is not necessary because in js we should not preallocate memory
-  // for inflate use constant limit in 65536 bytes
-  //
-
-  /* space at extra (only when reading header) */
-  // this.extra_max  = 0;
-  /* pointer to zero-terminated file name or Z_NULL */
-  this.name       = '';
-  /* space at name (only when reading header) */
-  // this.name_max   = 0;
-  /* pointer to zero-terminated comment or Z_NULL */
-  this.comment    = '';
-  /* space at comment (only when reading header) */
-  // this.comm_max   = 0;
-  /* true if there was or will be a header crc */
-  this.hcrc       = 0;
-  /* true when done reading gzip header (not used when writing a gzip file) */
-  this.done       = false;
-}
-
-module.exports = GZheader;
-
-
-/***/ }),
-/* 124 */
-/*!************************************************!*\
-  !*** ./node_modules/pako/lib/zlib/inftrees.js ***!
-  \************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-// (C) 1995-2013 Jean-loup Gailly and Mark Adler
-// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//   claim that you wrote the original software. If you use this software
-//   in a product, an acknowledgment in the product documentation would be
-//   appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-//   misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-var utils = __webpack_require__(/*! ../utils/common */ 46);
-
-var MAXBITS = 15;
-var ENOUGH_LENS = 852;
-var ENOUGH_DISTS = 592;
-//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
-
-var CODES = 0;
-var LENS = 1;
-var DISTS = 2;
-
-var lbase = [ /* Length codes 257..285 base */
-  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
-];
-
-var lext = [ /* Length codes 257..285 extra */
-  16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
-  19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
-];
-
-var dbase = [ /* Distance codes 0..29 base */
-  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-  8193, 12289, 16385, 24577, 0, 0
-];
-
-var dext = [ /* Distance codes 0..29 extra */
-  16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
-  23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
-  28, 28, 29, 29, 64, 64
-];
-
-module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts)
-{
-  var bits = opts.bits;
-      //here = opts.here; /* table entry for duplication */
-
-  var len = 0;               /* a code's length in bits */
-  var sym = 0;               /* index of code symbols */
-  var min = 0, max = 0;          /* minimum and maximum code lengths */
-  var root = 0;              /* number of index bits for root table */
-  var curr = 0;              /* number of index bits for current table */
-  var drop = 0;              /* code bits to drop for sub-table */
-  var left = 0;                   /* number of prefix codes available */
-  var used = 0;              /* code entries in table used */
-  var huff = 0;              /* Huffman code */
-  var incr;              /* for incrementing code, index */
-  var fill;              /* index for replicating entries */
-  var low;               /* low bits for current root entry */
-  var mask;              /* mask for low root bits */
-  var next;             /* next available space in table */
-  var base = null;     /* base value table to use */
-  var base_index = 0;
-//  var shoextra;    /* extra bits table to use */
-  var end;                    /* use base and extra for symbol > end */
-  var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];    /* number of codes of each length */
-  var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];     /* offsets in table for each length */
-  var extra = null;
-  var extra_index = 0;
-
-  var here_bits, here_op, here_val;
-
-  /*
-   Process a set of code lengths to create a canonical Huffman code.  The
-   code lengths are lens[0..codes-1].  Each length corresponds to the
-   symbols 0..codes-1.  The Huffman code is generated by first sorting the
-   symbols by length from short to long, and retaining the symbol order
-   for codes with equal lengths.  Then the code starts with all zero bits
-   for the first code of the shortest length, and the codes are integer
-   increments for the same length, and zeros are appended as the length
-   increases.  For the deflate format, these bits are stored backwards
-   from their more natural integer increment ordering, and so when the
-   decoding tables are built in the large loop below, the integer codes
-   are incremented backwards.
-
-   This routine assumes, but does not check, that all of the entries in
-   lens[] are in the range 0..MAXBITS.  The caller must assure this.
-   1..MAXBITS is interpreted as that code length.  zero means that that
-   symbol does not occur in this code.
-
-   The codes are sorted by computing a count of codes for each length,
-   creating from that a table of starting indices for each length in the
-   sorted table, and then entering the symbols in order in the sorted
-   table.  The sorted table is work[], with that space being provided by
-   the caller.
-
-   The length counts are used for other purposes as well, i.e. finding
-   the minimum and maximum length codes, determining if there are any
-   codes at all, checking for a valid set of lengths, and looking ahead
-   at length counts to determine sub-table sizes when building the
-   decoding tables.
-   */
-
-  /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
-  for (len = 0; len <= MAXBITS; len++) {
-    count[len] = 0;
-  }
-  for (sym = 0; sym < codes; sym++) {
-    count[lens[lens_index + sym]]++;
-  }
-
-  /* bound code lengths, force root to be within code lengths */
-  root = bits;
-  for (max = MAXBITS; max >= 1; max--) {
-    if (count[max] !== 0) { break; }
-  }
-  if (root > max) {
-    root = max;
-  }
-  if (max === 0) {                     /* no symbols to code at all */
-    //table.op[opts.table_index] = 64;  //here.op = (var char)64;    /* invalid code marker */
-    //table.bits[opts.table_index] = 1;   //here.bits = (var char)1;
-    //table.val[opts.table_index++] = 0;   //here.val = (var short)0;
-    table[table_index++] = (1 << 24) | (64 << 16) | 0;
-
-
-    //table.op[opts.table_index] = 64;
-    //table.bits[opts.table_index] = 1;
-    //table.val[opts.table_index++] = 0;
-    table[table_index++] = (1 << 24) | (64 << 16) | 0;
-
-    opts.bits = 1;
-    return 0;     /* no symbols, but wait for decoding to report error */
-  }
-  for (min = 1; min < max; min++) {
-    if (count[min] !== 0) { break; }
-  }
-  if (root < min) {
-    root = min;
-  }
-
-  /* check for an over-subscribed or incomplete set of lengths */
-  left = 1;
-  for (len = 1; len <= MAXBITS; len++) {
-    left <<= 1;
-    left -= count[len];
-    if (left < 0) {
-      return -1;
-    }        /* over-subscribed */
-  }
-  if (left > 0 && (type === CODES || max !== 1)) {
-    return -1;                      /* incomplete set */
-  }
-
-  /* generate offsets into symbol table for each length for sorting */
-  offs[1] = 0;
-  for (len = 1; len < MAXBITS; len++) {
-    offs[len + 1] = offs[len] + count[len];
-  }
-
-  /* sort symbols by length, by symbol order within each length */
-  for (sym = 0; sym < codes; sym++) {
-    if (lens[lens_index + sym] !== 0) {
-      work[offs[lens[lens_index + sym]]++] = sym;
-    }
-  }
-
-  /*
-   Create and fill in decoding tables.  In this loop, the table being
-   filled is at next and has curr index bits.  The code being used is huff
-   with length len.  That code is converted to an index by dropping drop
-   bits off of the bottom.  For codes where len is less than drop + curr,
-   those top drop + curr - len bits are incremented through all values to
-   fill the table with replicated entries.
-
-   root is the number of index bits for the root table.  When len exceeds
-   root, sub-tables are created pointed to by the root entry with an index
-   of the low root bits of huff.  This is saved in low to check for when a
-   new sub-table should be started.  drop is zero when the root table is
-   being filled, and drop is root when sub-tables are being filled.
-
-   When a new sub-table is needed, it is necessary to look ahead in the
-   code lengths to determine what size sub-table is needed.  The length
-   counts are used for this, and so count[] is decremented as codes are
-   entered in the tables.
-
-   used keeps track of how many table entries have been allocated from the
-   provided *table space.  It is checked for LENS and DIST tables against
-   the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
-   the initial root table size constants.  See the comments in inftrees.h
-   for more information.
-
-   sym increments through all symbols, and the loop terminates when
-   all codes of length max, i.e. all codes, have been processed.  This
-   routine permits incomplete codes, so another loop after this one fills
-   in the rest of the decoding tables with invalid code markers.
-   */
-
-  /* set up for code type */
-  // poor man optimization - use if-else instead of switch,
-  // to avoid deopts in old v8
-  if (type === CODES) {
-    base = extra = work;    /* dummy value--not used */
-    end = 19;
-
-  } else if (type === LENS) {
-    base = lbase;
-    base_index -= 257;
-    extra = lext;
-    extra_index -= 257;
-    end = 256;
-
-  } else {                    /* DISTS */
-    base = dbase;
-    extra = dext;
-    end = -1;
-  }
-
-  /* initialize opts for loop */
-  huff = 0;                   /* starting code */
-  sym = 0;                    /* starting code symbol */
-  len = min;                  /* starting code length */
-  next = table_index;              /* current table to fill in */
-  curr = root;                /* current table index bits */
-  drop = 0;                   /* current bits to drop from code for index */
-  low = -1;                   /* trigger new sub-table when len > root */
-  used = 1 << root;          /* use root table entries */
-  mask = used - 1;            /* mask for comparing low */
-
-  /* check available table space */
-  if ((type === LENS && used > ENOUGH_LENS) ||
-    (type === DISTS && used > ENOUGH_DISTS)) {
-    return 1;
-  }
-
-  /* process all codes and make table entries */
-  for (;;) {
-    /* create table entry */
-    here_bits = len - drop;
-    if (work[sym] < end) {
-      here_op = 0;
-      here_val = work[sym];
-    }
-    else if (work[sym] > end) {
-      here_op = extra[extra_index + work[sym]];
-      here_val = base[base_index + work[sym]];
-    }
-    else {
-      here_op = 32 + 64;         /* end of block */
-      here_val = 0;
-    }
-
-    /* replicate for those indices with low len bits equal to huff */
-    incr = 1 << (len - drop);
-    fill = 1 << curr;
-    min = fill;                 /* save offset to next table */
-    do {
-      fill -= incr;
-      table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
-    } while (fill !== 0);
-
-    /* backwards increment the len-bit code huff */
-    incr = 1 << (len - 1);
-    while (huff & incr) {
-      incr >>= 1;
-    }
-    if (incr !== 0) {
-      huff &= incr - 1;
-      huff += incr;
-    } else {
-      huff = 0;
-    }
-
-    /* go to next symbol, update count, len */
-    sym++;
-    if (--count[len] === 0) {
-      if (len === max) { break; }
-      len = lens[lens_index + work[sym]];
-    }
-
-    /* create new sub-table if needed */
-    if (len > root && (huff & mask) !== low) {
-      /* if first time, transition to sub-tables */
-      if (drop === 0) {
-        drop = root;
-      }
-
-      /* increment past last table */
-      next += min;            /* here min is 1 << curr */
-
-      /* determine length of next table */
-      curr = len - drop;
-      left = 1 << curr;
-      while (curr + drop < max) {
-        left -= count[curr + drop];
-        if (left <= 0) { break; }
-        curr++;
-        left <<= 1;
-      }
-
-      /* check for enough space */
-      used += 1 << curr;
-      if ((type === LENS && used > ENOUGH_LENS) ||
-        (type === DISTS && used > ENOUGH_DISTS)) {
-        return 1;
-      }
-
-      /* point entry in root table to sub-table */
-      low = huff & mask;
-      /*table.op[low] = curr;
-      table.bits[low] = root;
-      table.val[low] = next - opts.table_index;*/
-      table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;
-    }
-  }
-
-  /* fill in remaining table entry if code is incomplete (guaranteed to have
-   at most one remaining entry, since if the code is incomplete, the
-   maximum code length that was allowed to get this far is one bit) */
-  if (huff !== 0) {
-    //table.op[next + huff] = 64;            /* invalid code marker */
-    //table.bits[next + huff] = len - drop;
-    //table.val[next + huff] = 0;
-    table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;
-  }
-
-  /* set return parameters */
-  //opts.table_index += used;
-  opts.bits = root;
-  return 0;
-};
-
-
-/***/ }),
-/* 125 */
-/*!***********************************************!*\
-  !*** ./node_modules/pako/lib/zlib/inffast.js ***!
-  \***********************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-// (C) 1995-2013 Jean-loup Gailly and Mark Adler
-// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//   claim that you wrote the original software. If you use this software
-//   in a product, an acknowledgment in the product documentation would be
-//   appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-//   misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-// See state defs from inflate.js
-var BAD = 30;       /* got a data error -- remain here until reset */
-var TYPE = 12;      /* i: waiting for type bits, including last-flag bit */
-
-/*
-   Decode literal, length, and distance codes and write out the resulting
-   literal and match bytes until either not enough input or output is
-   available, an end-of-block is encountered, or a data error is encountered.
-   When large enough input and output buffers are supplied to inflate(), for
-   example, a 16K input buffer and a 64K output buffer, more than 95% of the
-   inflate execution time is spent in this routine.
-
-   Entry assumptions:
-
-        state.mode === LEN
-        strm.avail_in >= 6
-        strm.avail_out >= 258
-        start >= strm.avail_out
-        state.bits < 8
-
-   On return, state.mode is one of:
-
-        LEN -- ran out of enough output space or enough available input
-        TYPE -- reached end of block code, inflate() to interpret next block
-        BAD -- error in block data
-
-   Notes:
-
-    - The maximum input bits used by a length/distance pair is 15 bits for the
-      length code, 5 bits for the length extra, 15 bits for the distance code,
-      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
-      Therefore if strm.avail_in >= 6, then there is enough input to avoid
-      checking for available input while decoding.
-
-    - The maximum bytes that a single length/distance pair can output is 258
-      bytes, which is the maximum length that can be coded.  inflate_fast()
-      requires strm.avail_out >= 258 for each loop to avoid checking for
-      output space.
- */
-module.exports = function inflate_fast(strm, start) {
-  var state;
-  var _in;                    /* local strm.input */
-  var last;                   /* have enough input while in < last */
-  var _out;                   /* local strm.output */
-  var beg;                    /* inflate()'s initial strm.output */
-  var end;                    /* while out < end, enough space available */
-//#ifdef INFLATE_STRICT
-  var dmax;                   /* maximum distance from zlib header */
-//#endif
-  var wsize;                  /* window size or zero if not using window */
-  var whave;                  /* valid bytes in the window */
-  var wnext;                  /* window write index */
-  // Use `s_window` instead `window`, avoid conflict with instrumentation tools
-  var s_window;               /* allocated sliding window, if wsize != 0 */
-  var hold;                   /* local strm.hold */
-  var bits;                   /* local strm.bits */
-  var lcode;                  /* local strm.lencode */
-  var dcode;                  /* local strm.distcode */
-  var lmask;                  /* mask for first level of length codes */
-  var dmask;                  /* mask for first level of distance codes */
-  var here;                   /* retrieved table entry */
-  var op;                     /* code bits, operation, extra bits, or */
-                              /*  window position, window bytes to copy */
-  var len;                    /* match length, unused bytes */
-  var dist;                   /* match distance */
-  var from;                   /* where to copy match from */
-  var from_source;
-
-
-  var input, output; // JS specific, because we have no pointers
-
-  /* copy state to local variables */
-  state = strm.state;
-  //here = state.here;
-  _in = strm.next_in;
-  input = strm.input;
-  last = _in + (strm.avail_in - 5);
-  _out = strm.next_out;
-  output = strm.output;
-  beg = _out - (start - strm.avail_out);
-  end = _out + (strm.avail_out - 257);
-//#ifdef INFLATE_STRICT
-  dmax = state.dmax;
-//#endif
-  wsize = state.wsize;
-  whave = state.whave;
-  wnext = state.wnext;
-  s_window = state.window;
-  hold = state.hold;
-  bits = state.bits;
-  lcode = state.lencode;
-  dcode = state.distcode;
-  lmask = (1 << state.lenbits) - 1;
-  dmask = (1 << state.distbits) - 1;
-
-
-  /* decode literals and length/distances until end-of-block or not enough
-     input data or output space */
-
-  top:
-  do {
-    if (bits < 15) {
-      hold += input[_in++] << bits;
-      bits += 8;
-      hold += input[_in++] << bits;
-      bits += 8;
-    }
-
-    here = lcode[hold & lmask];
-
-    dolen:
-    for (;;) { // Goto emulation
-      op = here >>> 24/*here.bits*/;
-      hold >>>= op;
-      bits -= op;
-      op = (here >>> 16) & 0xff/*here.op*/;
-      if (op === 0) {                          /* literal */
-        //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
-        //        "inflate:         literal '%c'\n" :
-        //        "inflate:         literal 0x%02x\n", here.val));
-        output[_out++] = here & 0xffff/*here.val*/;
-      }
-      else if (op & 16) {                     /* length base */
-        len = here & 0xffff/*here.val*/;
-        op &= 15;                           /* number of extra bits */
-        if (op) {
-          if (bits < op) {
-            hold += input[_in++] << bits;
-            bits += 8;
-          }
-          len += hold & ((1 << op) - 1);
-          hold >>>= op;
-          bits -= op;
-        }
-        //Tracevv((stderr, "inflate:         length %u\n", len));
-        if (bits < 15) {
-          hold += input[_in++] << bits;
-          bits += 8;
-          hold += input[_in++] << bits;
-          bits += 8;
-        }
-        here = dcode[hold & dmask];
-
-        dodist:
-        for (;;) { // goto emulation
-          op = here >>> 24/*here.bits*/;
-          hold >>>= op;
-          bits -= op;
-          op = (here >>> 16) & 0xff/*here.op*/;
-
-          if (op & 16) {                      /* distance base */
-            dist = here & 0xffff/*here.val*/;
-            op &= 15;                       /* number of extra bits */
-            if (bits < op) {
-              hold += input[_in++] << bits;
-              bits += 8;
-              if (bits < op) {
-                hold += input[_in++] << bits;
-                bits += 8;
-              }
-            }
-            dist += hold & ((1 << op) - 1);
-//#ifdef INFLATE_STRICT
-            if (dist > dmax) {
-              strm.msg = 'invalid distance too far back';
-              state.mode = BAD;
-              break top;
-            }
-//#endif
-            hold >>>= op;
-            bits -= op;
-            //Tracevv((stderr, "inflate:         distance %u\n", dist));
-            op = _out - beg;                /* max distance in output */
-            if (dist > op) {                /* see if copy from window */
-              op = dist - op;               /* distance back in window */
-              if (op > whave) {
-                if (state.sane) {
-                  strm.msg = 'invalid distance too far back';
-                  state.mode = BAD;
-                  break top;
-                }
-
-// (!) This block is disabled in zlib defaults,
-// don't enable it for binary compatibility
-//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
-//                if (len <= op - whave) {
-//                  do {
-//                    output[_out++] = 0;
-//                  } while (--len);
-//                  continue top;
-//                }
-//                len -= op - whave;
-//                do {
-//                  output[_out++] = 0;
-//                } while (--op > whave);
-//                if (op === 0) {
-//                  from = _out - dist;
-//                  do {
-//                    output[_out++] = output[from++];
-//                  } while (--len);
-//                  continue top;
-//                }
-//#endif
-              }
-              from = 0; // window index
-              from_source = s_window;
-              if (wnext === 0) {           /* very common case */
-                from += wsize - op;
-                if (op < len) {         /* some from window */
-                  len -= op;
-                  do {
-                    output[_out++] = s_window[from++];
-                  } while (--op);
-                  from = _out - dist;  /* rest from output */
-                  from_source = output;
-                }
-              }
-              else if (wnext < op) {      /* wrap around window */
-                from += wsize + wnext - op;
-                op -= wnext;
-                if (op < len) {         /* some from end of window */
-                  len -= op;
-                  do {
-                    output[_out++] = s_window[from++];
-                  } while (--op);
-                  from = 0;
-                  if (wnext < len) {  /* some from start of window */
-                    op = wnext;
-                    len -= op;
-                    do {
-                      output[_out++] = s_window[from++];
-                    } while (--op);
-                    from = _out - dist;      /* rest from output */
-                    from_source = output;
-                  }
-                }
-              }
-              else {                      /* contiguous in window */
-                from += wnext - op;
-                if (op < len) {         /* some from window */
-                  len -= op;
-                  do {
-                    output[_out++] = s_window[from++];
-                  } while (--op);
-                  from = _out - dist;  /* rest from output */
-                  from_source = output;
-                }
-              }
-              while (len > 2) {
-                output[_out++] = from_source[from++];
-                output[_out++] = from_source[from++];
-                output[_out++] = from_source[from++];
-                len -= 3;
-              }
-              if (len) {
-                output[_out++] = from_source[from++];
-                if (len > 1) {
-                  output[_out++] = from_source[from++];
-                }
-              }
-            }
-            else {
-              from = _out - dist;          /* copy direct from output */
-              do {                        /* minimum length is three */
-                output[_out++] = output[from++];
-                output[_out++] = output[from++];
-                output[_out++] = output[from++];
-                len -= 3;
-              } while (len > 2);
-              if (len) {
-                output[_out++] = output[from++];
-                if (len > 1) {
-                  output[_out++] = output[from++];
-                }
-              }
-            }
-          }
-          else if ((op & 64) === 0) {          /* 2nd level distance code */
-            here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
-            continue dodist;
-          }
-          else {
-            strm.msg = 'invalid distance code';
-            state.mode = BAD;
-            break top;
-          }
-
-          break; // need to emulate goto via "continue"
-        }
-      }
-      else if ((op & 64) === 0) {              /* 2nd level length code */
-        here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
-        continue dolen;
-      }
-      else if (op & 32) {                     /* end-of-block */
-        //Tracevv((stderr, "inflate:         end of block\n"));
-        state.mode = TYPE;
-        break top;
-      }
-      else {
-        strm.msg = 'invalid literal/length code';
-        state.mode = BAD;
-        break top;
-      }
-
-      break; // need to emulate goto via "continue"
-    }
-  } while (_in < last && _out < end);
-
-  /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
-  len = bits >> 3;
-  _in -= len;
-  bits -= len << 3;
-  hold &= (1 << bits) - 1;
-
-  /* update state and return */
-  strm.next_in = _in;
-  strm.next_out = _out;
-  strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));
-  strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
-  state.hold = hold;
-  state.bits = bits;
-  return;
-};
-
-
-/***/ }),
-/* 126 */
-/*!***********************************************!*\
-  !*** ./node_modules/pako/lib/zlib/inflate.js ***!
-  \***********************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-// (C) 1995-2013 Jean-loup Gailly and Mark Adler
-// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//   claim that you wrote the original software. If you use this software
-//   in a product, an acknowledgment in the product documentation would be
-//   appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-//   misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-var utils         = __webpack_require__(/*! ../utils/common */ 46);
-var adler32       = __webpack_require__(/*! ./adler32 */ 88);
-var crc32         = __webpack_require__(/*! ./crc32 */ 87);
-var inflate_fast  = __webpack_require__(/*! ./inffast */ 125);
-var inflate_table = __webpack_require__(/*! ./inftrees */ 124);
-
-var CODES = 0;
-var LENS = 1;
-var DISTS = 2;
-
-/* Public constants ==========================================================*/
-/* ===========================================================================*/
-
-
-/* Allowed flush values; see deflate() and inflate() below for details */
-//var Z_NO_FLUSH      = 0;
-//var Z_PARTIAL_FLUSH = 1;
-//var Z_SYNC_FLUSH    = 2;
-//var Z_FULL_FLUSH    = 3;
-var Z_FINISH        = 4;
-var Z_BLOCK         = 5;
-var Z_TREES         = 6;
-
-
-/* Return codes for the compression/decompression functions. Negative values
- * are errors, positive values are used for special but normal events.
- */
-var Z_OK            = 0;
-var Z_STREAM_END    = 1;
-var Z_NEED_DICT     = 2;
-//var Z_ERRNO         = -1;
-var Z_STREAM_ERROR  = -2;
-var Z_DATA_ERROR    = -3;
-var Z_MEM_ERROR     = -4;
-var Z_BUF_ERROR     = -5;
-//var Z_VERSION_ERROR = -6;
-
-/* The deflate compression method */
-var Z_DEFLATED  = 8;
-
-
-/* STATES ====================================================================*/
-/* ===========================================================================*/
-
-
-var    HEAD = 1;       /* i: waiting for magic header */
-var    FLAGS = 2;      /* i: waiting for method and flags (gzip) */
-var    TIME = 3;       /* i: waiting for modification time (gzip) */
-var    OS = 4;         /* i: waiting for extra flags and operating system (gzip) */
-var    EXLEN = 5;      /* i: waiting for extra length (gzip) */
-var    EXTRA = 6;      /* i: waiting for extra bytes (gzip) */
-var    NAME = 7;       /* i: waiting for end of file name (gzip) */
-var    COMMENT = 8;    /* i: waiting for end of comment (gzip) */
-var    HCRC = 9;       /* i: waiting for header crc (gzip) */
-var    DICTID = 10;    /* i: waiting for dictionary check value */
-var    DICT = 11;      /* waiting for inflateSetDictionary() call */
-var        TYPE = 12;      /* i: waiting for type bits, including last-flag bit */
-var        TYPEDO = 13;    /* i: same, but skip check to exit inflate on new block */
-var        STORED = 14;    /* i: waiting for stored size (length and complement) */
-var        COPY_ = 15;     /* i/o: same as COPY below, but only first time in */
-var        COPY = 16;      /* i/o: waiting for input or output to copy stored block */
-var        TABLE = 17;     /* i: waiting for dynamic block table lengths */
-var        LENLENS = 18;   /* i: waiting for code length code lengths */
-var        CODELENS = 19;  /* i: waiting for length/lit and distance code lengths */
-var            LEN_ = 20;      /* i: same as LEN below, but only first time in */
-var            LEN = 21;       /* i: waiting for length/lit/eob code */
-var            LENEXT = 22;    /* i: waiting for length extra bits */
-var            DIST = 23;      /* i: waiting for distance code */
-var            DISTEXT = 24;   /* i: waiting for distance extra bits */
-var            MATCH = 25;     /* o: waiting for output space to copy string */
-var            LIT = 26;       /* o: waiting for output space to write literal */
-var    CHECK = 27;     /* i: waiting for 32-bit check value */
-var    LENGTH = 28;    /* i: waiting for 32-bit length (gzip) */
-var    DONE = 29;      /* finished check, done -- remain here until reset */
-var    BAD = 30;       /* got a data error -- remain here until reset */
-var    MEM = 31;       /* got an inflate() memory error -- remain here until reset */
-var    SYNC = 32;      /* looking for synchronization bytes to restart inflate() */
-
-/* ===========================================================================*/
-
-
-
-var ENOUGH_LENS = 852;
-var ENOUGH_DISTS = 592;
-//var ENOUGH =  (ENOUGH_LENS+ENOUGH_DISTS);
-
-var MAX_WBITS = 15;
-/* 32K LZ77 window */
-var DEF_WBITS = MAX_WBITS;
-
-
-function zswap32(q) {
-  return  (((q >>> 24) & 0xff) +
-          ((q >>> 8) & 0xff00) +
-          ((q & 0xff00) << 8) +
-          ((q & 0xff) << 24));
-}
-
-
-function InflateState() {
-  this.mode = 0;             /* current inflate mode */
-  this.last = false;          /* true if processing last block */
-  this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */
-  this.havedict = false;      /* true if dictionary provided */
-  this.flags = 0;             /* gzip header method and flags (0 if zlib) */
-  this.dmax = 0;              /* zlib header max distance (INFLATE_STRICT) */
-  this.check = 0;             /* protected copy of check value */
-  this.total = 0;             /* protected copy of output count */
-  // TODO: may be {}
-  this.head = null;           /* where to save gzip header information */
-
-  /* sliding window */
-  this.wbits = 0;             /* log base 2 of requested window size */
-  this.wsize = 0;             /* window size or zero if not using window */
-  this.whave = 0;             /* valid bytes in the window */
-  this.wnext = 0;             /* window write index */
-  this.window = null;         /* allocated sliding window, if needed */
-
-  /* bit accumulator */
-  this.hold = 0;              /* input bit accumulator */
-  this.bits = 0;              /* number of bits in "in" */
-
-  /* for string and stored block copying */
-  this.length = 0;            /* literal or length of data to copy */
-  this.offset = 0;            /* distance back to copy string from */
-
-  /* for table and code decoding */
-  this.extra = 0;             /* extra bits needed */
-
-  /* fixed and dynamic code tables */
-  this.lencode = null;          /* starting table for length/literal codes */
-  this.distcode = null;         /* starting table for distance codes */
-  this.lenbits = 0;           /* index bits for lencode */
-  this.distbits = 0;          /* index bits for distcode */
-
-  /* dynamic table building */
-  this.ncode = 0;             /* number of code length code lengths */
-  this.nlen = 0;              /* number of length code lengths */
-  this.ndist = 0;             /* number of distance code lengths */
-  this.have = 0;              /* number of code lengths in lens[] */
-  this.next = null;              /* next available space in codes[] */
-
-  this.lens = new utils.Buf16(320); /* temporary storage for code lengths */
-  this.work = new utils.Buf16(288); /* work area for code table building */
-
-  /*
-   because we don't have pointers in js, we use lencode and distcode directly
-   as buffers so we don't need codes
-  */
-  //this.codes = new utils.Buf32(ENOUGH);       /* space for code tables */
-  this.lendyn = null;              /* dynamic table for length/literal codes (JS specific) */
-  this.distdyn = null;             /* dynamic table for distance codes (JS specific) */
-  this.sane = 0;                   /* if false, allow invalid distance too far */
-  this.back = 0;                   /* bits back of last unprocessed length/lit */
-  this.was = 0;                    /* initial length of match */
-}
-
-function inflateResetKeep(strm) {
-  var state;
-
-  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
-  state = strm.state;
-  strm.total_in = strm.total_out = state.total = 0;
-  strm.msg = ''; /*Z_NULL*/
-  if (state.wrap) {       /* to support ill-conceived Java test suite */
-    strm.adler = state.wrap & 1;
-  }
-  state.mode = HEAD;
-  state.last = 0;
-  state.havedict = 0;
-  state.dmax = 32768;
-  state.head = null/*Z_NULL*/;
-  state.hold = 0;
-  state.bits = 0;
-  //state.lencode = state.distcode = state.next = state.codes;
-  state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
-  state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
-
-  state.sane = 1;
-  state.back = -1;
-  //Tracev((stderr, "inflate: reset\n"));
-  return Z_OK;
-}
-
-function inflateReset(strm) {
-  var state;
-
-  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
-  state = strm.state;
-  state.wsize = 0;
-  state.whave = 0;
-  state.wnext = 0;
-  return inflateResetKeep(strm);
-
-}
-
-function inflateReset2(strm, windowBits) {
-  var wrap;
-  var state;
-
-  /* get the state */
-  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
-  state = strm.state;
-
-  /* extract wrap request from windowBits parameter */
-  if (windowBits < 0) {
-    wrap = 0;
-    windowBits = -windowBits;
-  }
-  else {
-    wrap = (windowBits >> 4) + 1;
-    if (windowBits < 48) {
-      windowBits &= 15;
-    }
-  }
-
-  /* set number of window bits, free window if different */
-  if (windowBits && (windowBits < 8 || windowBits > 15)) {
-    return Z_STREAM_ERROR;
-  }
-  if (state.window !== null && state.wbits !== windowBits) {
-    state.window = null;
-  }
-
-  /* update state and reset the rest of it */
-  state.wrap = wrap;
-  state.wbits = windowBits;
-  return inflateReset(strm);
-}
-
-function inflateInit2(strm, windowBits) {
-  var ret;
-  var state;
-
-  if (!strm) { return Z_STREAM_ERROR; }
-  //strm.msg = Z_NULL;                 /* in case we return an error */
-
-  state = new InflateState();
-
-  //if (state === Z_NULL) return Z_MEM_ERROR;
-  //Tracev((stderr, "inflate: allocated\n"));
-  strm.state = state;
-  state.window = null/*Z_NULL*/;
-  ret = inflateReset2(strm, windowBits);
-  if (ret !== Z_OK) {
-    strm.state = null/*Z_NULL*/;
-  }
-  return ret;
-}
-
-function inflateInit(strm) {
-  return inflateInit2(strm, DEF_WBITS);
-}
-
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding.  Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter.  This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time.  However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-var virgin = true;
-
-var lenfix, distfix; // We have no pointers in JS, so keep tables separate
-
-function fixedtables(state) {
-  /* build fixed huffman tables if first call (may not be thread safe) */
-  if (virgin) {
-    var sym;
-
-    lenfix = new utils.Buf32(512);
-    distfix = new utils.Buf32(32);
-
-    /* literal/length table */
-    sym = 0;
-    while (sym < 144) { state.lens[sym++] = 8; }
-    while (sym < 256) { state.lens[sym++] = 9; }
-    while (sym < 280) { state.lens[sym++] = 7; }
-    while (sym < 288) { state.lens[sym++] = 8; }
-
-    inflate_table(LENS,  state.lens, 0, 288, lenfix,   0, state.work, { bits: 9 });
-
-    /* distance table */
-    sym = 0;
-    while (sym < 32) { state.lens[sym++] = 5; }
-
-    inflate_table(DISTS, state.lens, 0, 32,   distfix, 0, state.work, { bits: 5 });
-
-    /* do this just once */
-    virgin = false;
-  }
-
-  state.lencode = lenfix;
-  state.lenbits = 9;
-  state.distcode = distfix;
-  state.distbits = 5;
-}
-
-
-/*
- Update the window with the last wsize (normally 32K) bytes written before
- returning.  If window does not exist yet, create it.  This is only called
- when a window is already in use, or when output has been written during this
- inflate call, but the end of the deflate stream has not been reached yet.
- It is also called to create a window for dictionary data when a dictionary
- is loaded.
-
- Providing output buffers larger than 32K to inflate() should provide a speed
- advantage, since only the last 32K of output is copied to the sliding window
- upon return from inflate(), and since all distances after the first 32K of
- output will fall in the output data, making match copies simpler and faster.
- The advantage may be dependent on the size of the processor's data caches.
- */
-function updatewindow(strm, src, end, copy) {
-  var dist;
-  var state = strm.state;
-
-  /* if it hasn't been done already, allocate space for the window */
-  if (state.window === null) {
-    state.wsize = 1 << state.wbits;
-    state.wnext = 0;
-    state.whave = 0;
-
-    state.window = new utils.Buf8(state.wsize);
-  }
-
-  /* copy state->wsize or less output bytes into the circular window */
-  if (copy >= state.wsize) {
-    utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
-    state.wnext = 0;
-    state.whave = state.wsize;
-  }
-  else {
-    dist = state.wsize - state.wnext;
-    if (dist > copy) {
-      dist = copy;
-    }
-    //zmemcpy(state->window + state->wnext, end - copy, dist);
-    utils.arraySet(state.window, src, end - copy, dist, state.wnext);
-    copy -= dist;
-    if (copy) {
-      //zmemcpy(state->window, end - copy, copy);
-      utils.arraySet(state.window, src, end - copy, copy, 0);
-      state.wnext = copy;
-      state.whave = state.wsize;
-    }
-    else {
-      state.wnext += dist;
-      if (state.wnext === state.wsize) { state.wnext = 0; }
-      if (state.whave < state.wsize) { state.whave += dist; }
-    }
-  }
-  return 0;
-}
-
-function inflate(strm, flush) {
-  var state;
-  var input, output;          // input/output buffers
-  var next;                   /* next input INDEX */
-  var put;                    /* next output INDEX */
-  var have, left;             /* available input and output */
-  var hold;                   /* bit buffer */
-  var bits;                   /* bits in bit buffer */
-  var _in, _out;              /* save starting available input and output */
-  var copy;                   /* number of stored or match bytes to copy */
-  var from;                   /* where to copy match bytes from */
-  var from_source;
-  var here = 0;               /* current decoding table entry */
-  var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
-  //var last;                   /* parent table entry */
-  var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
-  var len;                    /* length to copy for repeats, bits to drop */
-  var ret;                    /* return code */
-  var hbuf = new utils.Buf8(4);    /* buffer for gzip header crc calculation */
-  var opts;
-
-  var n; // temporary var for NEED_BITS
-
-  var order = /* permutation of code lengths */
-    [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
-
-
-  if (!strm || !strm.state || !strm.output ||
-      (!strm.input && strm.avail_in !== 0)) {
-    return Z_STREAM_ERROR;
-  }
-
-  state = strm.state;
-  if (state.mode === TYPE) { state.mode = TYPEDO; }    /* skip check */
-
-
-  //--- LOAD() ---
-  put = strm.next_out;
-  output = strm.output;
-  left = strm.avail_out;
-  next = strm.next_in;
-  input = strm.input;
-  have = strm.avail_in;
-  hold = state.hold;
-  bits = state.bits;
-  //---
-
-  _in = have;
-  _out = left;
-  ret = Z_OK;
-
-  inf_leave: // goto emulation
-  for (;;) {
-    switch (state.mode) {
-      case HEAD:
-        if (state.wrap === 0) {
-          state.mode = TYPEDO;
-          break;
-        }
-        //=== NEEDBITS(16);
-        while (bits < 16) {
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-        }
-        //===//
-        if ((state.wrap & 2) && hold === 0x8b1f) {  /* gzip header */
-          state.check = 0/*crc32(0L, Z_NULL, 0)*/;
-          //=== CRC2(state.check, hold);
-          hbuf[0] = hold & 0xff;
-          hbuf[1] = (hold >>> 8) & 0xff;
-          state.check = crc32(state.check, hbuf, 2, 0);
-          //===//
-
-          //=== INITBITS();
-          hold = 0;
-          bits = 0;
-          //===//
-          state.mode = FLAGS;
-          break;
-        }
-        state.flags = 0;           /* expect zlib header */
-        if (state.head) {
-          state.head.done = false;
-        }
-        if (!(state.wrap & 1) ||   /* check if zlib header allowed */
-          (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {
-          strm.msg = 'incorrect header check';
-          state.mode = BAD;
-          break;
-        }
-        if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {
-          strm.msg = 'unknown compression method';
-          state.mode = BAD;
-          break;
-        }
-        //--- DROPBITS(4) ---//
-        hold >>>= 4;
-        bits -= 4;
-        //---//
-        len = (hold & 0x0f)/*BITS(4)*/ + 8;
-        if (state.wbits === 0) {
-          state.wbits = len;
-        }
-        else if (len > state.wbits) {
-          strm.msg = 'invalid window size';
-          state.mode = BAD;
-          break;
-        }
-        state.dmax = 1 << len;
-        //Tracev((stderr, "inflate:   zlib header ok\n"));
-        strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
-        state.mode = hold & 0x200 ? DICTID : TYPE;
-        //=== INITBITS();
-        hold = 0;
-        bits = 0;
-        //===//
-        break;
-      case FLAGS:
-        //=== NEEDBITS(16); */
-        while (bits < 16) {
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-        }
-        //===//
-        state.flags = hold;
-        if ((state.flags & 0xff) !== Z_DEFLATED) {
-          strm.msg = 'unknown compression method';
-          state.mode = BAD;
-          break;
-        }
-        if (state.flags & 0xe000) {
-          strm.msg = 'unknown header flags set';
-          state.mode = BAD;
-          break;
-        }
-        if (state.head) {
-          state.head.text = ((hold >> 8) & 1);
-        }
-        if (state.flags & 0x0200) {
-          //=== CRC2(state.check, hold);
-          hbuf[0] = hold & 0xff;
-          hbuf[1] = (hold >>> 8) & 0xff;
-          state.check = crc32(state.check, hbuf, 2, 0);
-          //===//
-        }
-        //=== INITBITS();
-        hold = 0;
-        bits = 0;
-        //===//
-        state.mode = TIME;
-        /* falls through */
-      case TIME:
-        //=== NEEDBITS(32); */
-        while (bits < 32) {
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-        }
-        //===//
-        if (state.head) {
-          state.head.time = hold;
-        }
-        if (state.flags & 0x0200) {
-          //=== CRC4(state.check, hold)
-          hbuf[0] = hold & 0xff;
-          hbuf[1] = (hold >>> 8) & 0xff;
-          hbuf[2] = (hold >>> 16) & 0xff;
-          hbuf[3] = (hold >>> 24) & 0xff;
-          state.check = crc32(state.check, hbuf, 4, 0);
-          //===
-        }
-        //=== INITBITS();
-        hold = 0;
-        bits = 0;
-        //===//
-        state.mode = OS;
-        /* falls through */
-      case OS:
-        //=== NEEDBITS(16); */
-        while (bits < 16) {
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-        }
-        //===//
-        if (state.head) {
-          state.head.xflags = (hold & 0xff);
-          state.head.os = (hold >> 8);
-        }
-        if (state.flags & 0x0200) {
-          //=== CRC2(state.check, hold);
-          hbuf[0] = hold & 0xff;
-          hbuf[1] = (hold >>> 8) & 0xff;
-          state.check = crc32(state.check, hbuf, 2, 0);
-          //===//
-        }
-        //=== INITBITS();
-        hold = 0;
-        bits = 0;
-        //===//
-        state.mode = EXLEN;
-        /* falls through */
-      case EXLEN:
-        if (state.flags & 0x0400) {
-          //=== NEEDBITS(16); */
-          while (bits < 16) {
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-          }
-          //===//
-          state.length = hold;
-          if (state.head) {
-            state.head.extra_len = hold;
-          }
-          if (state.flags & 0x0200) {
-            //=== CRC2(state.check, hold);
-            hbuf[0] = hold & 0xff;
-            hbuf[1] = (hold >>> 8) & 0xff;
-            state.check = crc32(state.check, hbuf, 2, 0);
-            //===//
-          }
-          //=== INITBITS();
-          hold = 0;
-          bits = 0;
-          //===//
-        }
-        else if (state.head) {
-          state.head.extra = null/*Z_NULL*/;
-        }
-        state.mode = EXTRA;
-        /* falls through */
-      case EXTRA:
-        if (state.flags & 0x0400) {
-          copy = state.length;
-          if (copy > have) { copy = have; }
-          if (copy) {
-            if (state.head) {
-              len = state.head.extra_len - state.length;
-              if (!state.head.extra) {
-                // Use untyped array for more convenient processing later
-                state.head.extra = new Array(state.head.extra_len);
-              }
-              utils.arraySet(
-                state.head.extra,
-                input,
-                next,
-                // extra field is limited to 65536 bytes
-                // - no need for additional size check
-                copy,
-                /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
-                len
-              );
-              //zmemcpy(state.head.extra + len, next,
-              //        len + copy > state.head.extra_max ?
-              //        state.head.extra_max - len : copy);
-            }
-            if (state.flags & 0x0200) {
-              state.check = crc32(state.check, input, copy, next);
-            }
-            have -= copy;
-            next += copy;
-            state.length -= copy;
-          }
-          if (state.length) { break inf_leave; }
-        }
-        state.length = 0;
-        state.mode = NAME;
-        /* falls through */
-      case NAME:
-        if (state.flags & 0x0800) {
-          if (have === 0) { break inf_leave; }
-          copy = 0;
-          do {
-            // TODO: 2 or 1 bytes?
-            len = input[next + copy++];
-            /* use constant limit because in js we should not preallocate memory */
-            if (state.head && len &&
-                (state.length < 65536 /*state.head.name_max*/)) {
-              state.head.name += String.fromCharCode(len);
-            }
-          } while (len && copy < have);
-
-          if (state.flags & 0x0200) {
-            state.check = crc32(state.check, input, copy, next);
-          }
-          have -= copy;
-          next += copy;
-          if (len) { break inf_leave; }
-        }
-        else if (state.head) {
-          state.head.name = null;
-        }
-        state.length = 0;
-        state.mode = COMMENT;
-        /* falls through */
-      case COMMENT:
-        if (state.flags & 0x1000) {
-          if (have === 0) { break inf_leave; }
-          copy = 0;
-          do {
-            len = input[next + copy++];
-            /* use constant limit because in js we should not preallocate memory */
-            if (state.head && len &&
-                (state.length < 65536 /*state.head.comm_max*/)) {
-              state.head.comment += String.fromCharCode(len);
-            }
-          } while (len && copy < have);
-          if (state.flags & 0x0200) {
-            state.check = crc32(state.check, input, copy, next);
-          }
-          have -= copy;
-          next += copy;
-          if (len) { break inf_leave; }
-        }
-        else if (state.head) {
-          state.head.comment = null;
-        }
-        state.mode = HCRC;
-        /* falls through */
-      case HCRC:
-        if (state.flags & 0x0200) {
-          //=== NEEDBITS(16); */
-          while (bits < 16) {
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-          }
-          //===//
-          if (hold !== (state.check & 0xffff)) {
-            strm.msg = 'header crc mismatch';
-            state.mode = BAD;
-            break;
-          }
-          //=== INITBITS();
-          hold = 0;
-          bits = 0;
-          //===//
-        }
-        if (state.head) {
-          state.head.hcrc = ((state.flags >> 9) & 1);
-          state.head.done = true;
-        }
-        strm.adler = state.check = 0;
-        state.mode = TYPE;
-        break;
-      case DICTID:
-        //=== NEEDBITS(32); */
-        while (bits < 32) {
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-        }
-        //===//
-        strm.adler = state.check = zswap32(hold);
-        //=== INITBITS();
-        hold = 0;
-        bits = 0;
-        //===//
-        state.mode = DICT;
-        /* falls through */
-      case DICT:
-        if (state.havedict === 0) {
-          //--- RESTORE() ---
-          strm.next_out = put;
-          strm.avail_out = left;
-          strm.next_in = next;
-          strm.avail_in = have;
-          state.hold = hold;
-          state.bits = bits;
-          //---
-          return Z_NEED_DICT;
-        }
-        strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
-        state.mode = TYPE;
-        /* falls through */
-      case TYPE:
-        if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }
-        /* falls through */
-      case TYPEDO:
-        if (state.last) {
-          //--- BYTEBITS() ---//
-          hold >>>= bits & 7;
-          bits -= bits & 7;
-          //---//
-          state.mode = CHECK;
-          break;
-        }
-        //=== NEEDBITS(3); */
-        while (bits < 3) {
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-        }
-        //===//
-        state.last = (hold & 0x01)/*BITS(1)*/;
-        //--- DROPBITS(1) ---//
-        hold >>>= 1;
-        bits -= 1;
-        //---//
-
-        switch ((hold & 0x03)/*BITS(2)*/) {
-          case 0:                             /* stored block */
-            //Tracev((stderr, "inflate:     stored block%s\n",
-            //        state.last ? " (last)" : ""));
-            state.mode = STORED;
-            break;
-          case 1:                             /* fixed block */
-            fixedtables(state);
-            //Tracev((stderr, "inflate:     fixed codes block%s\n",
-            //        state.last ? " (last)" : ""));
-            state.mode = LEN_;             /* decode codes */
-            if (flush === Z_TREES) {
-              //--- DROPBITS(2) ---//
-              hold >>>= 2;
-              bits -= 2;
-              //---//
-              break inf_leave;
-            }
-            break;
-          case 2:                             /* dynamic block */
-            //Tracev((stderr, "inflate:     dynamic codes block%s\n",
-            //        state.last ? " (last)" : ""));
-            state.mode = TABLE;
-            break;
-          case 3:
-            strm.msg = 'invalid block type';
-            state.mode = BAD;
-        }
-        //--- DROPBITS(2) ---//
-        hold >>>= 2;
-        bits -= 2;
-        //---//
-        break;
-      case STORED:
-        //--- BYTEBITS() ---// /* go to byte boundary */
-        hold >>>= bits & 7;
-        bits -= bits & 7;
-        //---//
-        //=== NEEDBITS(32); */
-        while (bits < 32) {
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-        }
-        //===//
-        if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {
-          strm.msg = 'invalid stored block lengths';
-          state.mode = BAD;
-          break;
-        }
-        state.length = hold & 0xffff;
-        //Tracev((stderr, "inflate:       stored length %u\n",
-        //        state.length));
-        //=== INITBITS();
-        hold = 0;
-        bits = 0;
-        //===//
-        state.mode = COPY_;
-        if (flush === Z_TREES) { break inf_leave; }
-        /* falls through */
-      case COPY_:
-        state.mode = COPY;
-        /* falls through */
-      case COPY:
-        copy = state.length;
-        if (copy) {
-          if (copy > have) { copy = have; }
-          if (copy > left) { copy = left; }
-          if (copy === 0) { break inf_leave; }
-          //--- zmemcpy(put, next, copy); ---
-          utils.arraySet(output, input, next, copy, put);
-          //---//
-          have -= copy;
-          next += copy;
-          left -= copy;
-          put += copy;
-          state.length -= copy;
-          break;
-        }
-        //Tracev((stderr, "inflate:       stored end\n"));
-        state.mode = TYPE;
-        break;
-      case TABLE:
-        //=== NEEDBITS(14); */
-        while (bits < 14) {
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-        }
-        //===//
-        state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;
-        //--- DROPBITS(5) ---//
-        hold >>>= 5;
-        bits -= 5;
-        //---//
-        state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;
-        //--- DROPBITS(5) ---//
-        hold >>>= 5;
-        bits -= 5;
-        //---//
-        state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;
-        //--- DROPBITS(4) ---//
-        hold >>>= 4;
-        bits -= 4;
-        //---//
-//#ifndef PKZIP_BUG_WORKAROUND
-        if (state.nlen > 286 || state.ndist > 30) {
-          strm.msg = 'too many length or distance symbols';
-          state.mode = BAD;
-          break;
-        }
-//#endif
-        //Tracev((stderr, "inflate:       table sizes ok\n"));
-        state.have = 0;
-        state.mode = LENLENS;
-        /* falls through */
-      case LENLENS:
-        while (state.have < state.ncode) {
-          //=== NEEDBITS(3);
-          while (bits < 3) {
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-          }
-          //===//
-          state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);
-          //--- DROPBITS(3) ---//
-          hold >>>= 3;
-          bits -= 3;
-          //---//
-        }
-        while (state.have < 19) {
-          state.lens[order[state.have++]] = 0;
-        }
-        // We have separate tables & no pointers. 2 commented lines below not needed.
-        //state.next = state.codes;
-        //state.lencode = state.next;
-        // Switch to use dynamic table
-        state.lencode = state.lendyn;
-        state.lenbits = 7;
-
-        opts = { bits: state.lenbits };
-        ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
-        state.lenbits = opts.bits;
-
-        if (ret) {
-          strm.msg = 'invalid code lengths set';
-          state.mode = BAD;
-          break;
-        }
-        //Tracev((stderr, "inflate:       code lengths ok\n"));
-        state.have = 0;
-        state.mode = CODELENS;
-        /* falls through */
-      case CODELENS:
-        while (state.have < state.nlen + state.ndist) {
-          for (;;) {
-            here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/
-            here_bits = here >>> 24;
-            here_op = (here >>> 16) & 0xff;
-            here_val = here & 0xffff;
-
-            if ((here_bits) <= bits) { break; }
-            //--- PULLBYTE() ---//
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-            //---//
-          }
-          if (here_val < 16) {
-            //--- DROPBITS(here.bits) ---//
-            hold >>>= here_bits;
-            bits -= here_bits;
-            //---//
-            state.lens[state.have++] = here_val;
-          }
-          else {
-            if (here_val === 16) {
-              //=== NEEDBITS(here.bits + 2);
-              n = here_bits + 2;
-              while (bits < n) {
-                if (have === 0) { break inf_leave; }
-                have--;
-                hold += input[next++] << bits;
-                bits += 8;
-              }
-              //===//
-              //--- DROPBITS(here.bits) ---//
-              hold >>>= here_bits;
-              bits -= here_bits;
-              //---//
-              if (state.have === 0) {
-                strm.msg = 'invalid bit length repeat';
-                state.mode = BAD;
-                break;
-              }
-              len = state.lens[state.have - 1];
-              copy = 3 + (hold & 0x03);//BITS(2);
-              //--- DROPBITS(2) ---//
-              hold >>>= 2;
-              bits -= 2;
-              //---//
-            }
-            else if (here_val === 17) {
-              //=== NEEDBITS(here.bits + 3);
-              n = here_bits + 3;
-              while (bits < n) {
-                if (have === 0) { break inf_leave; }
-                have--;
-                hold += input[next++] << bits;
-                bits += 8;
-              }
-              //===//
-              //--- DROPBITS(here.bits) ---//
-              hold >>>= here_bits;
-              bits -= here_bits;
-              //---//
-              len = 0;
-              copy = 3 + (hold & 0x07);//BITS(3);
-              //--- DROPBITS(3) ---//
-              hold >>>= 3;
-              bits -= 3;
-              //---//
-            }
-            else {
-              //=== NEEDBITS(here.bits + 7);
-              n = here_bits + 7;
-              while (bits < n) {
-                if (have === 0) { break inf_leave; }
-                have--;
-                hold += input[next++] << bits;
-                bits += 8;
-              }
-              //===//
-              //--- DROPBITS(here.bits) ---//
-              hold >>>= here_bits;
-              bits -= here_bits;
-              //---//
-              len = 0;
-              copy = 11 + (hold & 0x7f);//BITS(7);
-              //--- DROPBITS(7) ---//
-              hold >>>= 7;
-              bits -= 7;
-              //---//
-            }
-            if (state.have + copy > state.nlen + state.ndist) {
-              strm.msg = 'invalid bit length repeat';
-              state.mode = BAD;
-              break;
-            }
-            while (copy--) {
-              state.lens[state.have++] = len;
-            }
-          }
-        }
-
-        /* handle error breaks in while */
-        if (state.mode === BAD) { break; }
-
-        /* check for end-of-block code (better have one) */
-        if (state.lens[256] === 0) {
-          strm.msg = 'invalid code -- missing end-of-block';
-          state.mode = BAD;
-          break;
-        }
-
-        /* build code tables -- note: do not change the lenbits or distbits
-           values here (9 and 6) without reading the comments in inftrees.h
-           concerning the ENOUGH constants, which depend on those values */
-        state.lenbits = 9;
-
-        opts = { bits: state.lenbits };
-        ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
-        // We have separate tables & no pointers. 2 commented lines below not needed.
-        // state.next_index = opts.table_index;
-        state.lenbits = opts.bits;
-        // state.lencode = state.next;
-
-        if (ret) {
-          strm.msg = 'invalid literal/lengths set';
-          state.mode = BAD;
-          break;
-        }
-
-        state.distbits = 6;
-        //state.distcode.copy(state.codes);
-        // Switch to use dynamic table
-        state.distcode = state.distdyn;
-        opts = { bits: state.distbits };
-        ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
-        // We have separate tables & no pointers. 2 commented lines below not needed.
-        // state.next_index = opts.table_index;
-        state.distbits = opts.bits;
-        // state.distcode = state.next;
-
-        if (ret) {
-          strm.msg = 'invalid distances set';
-          state.mode = BAD;
-          break;
-        }
-        //Tracev((stderr, 'inflate:       codes ok\n'));
-        state.mode = LEN_;
-        if (flush === Z_TREES) { break inf_leave; }
-        /* falls through */
-      case LEN_:
-        state.mode = LEN;
-        /* falls through */
-      case LEN:
-        if (have >= 6 && left >= 258) {
-          //--- RESTORE() ---
-          strm.next_out = put;
-          strm.avail_out = left;
-          strm.next_in = next;
-          strm.avail_in = have;
-          state.hold = hold;
-          state.bits = bits;
-          //---
-          inflate_fast(strm, _out);
-          //--- LOAD() ---
-          put = strm.next_out;
-          output = strm.output;
-          left = strm.avail_out;
-          next = strm.next_in;
-          input = strm.input;
-          have = strm.avail_in;
-          hold = state.hold;
-          bits = state.bits;
-          //---
-
-          if (state.mode === TYPE) {
-            state.back = -1;
-          }
-          break;
-        }
-        state.back = 0;
-        for (;;) {
-          here = state.lencode[hold & ((1 << state.lenbits) - 1)];  /*BITS(state.lenbits)*/
-          here_bits = here >>> 24;
-          here_op = (here >>> 16) & 0xff;
-          here_val = here & 0xffff;
-
-          if (here_bits <= bits) { break; }
-          //--- PULLBYTE() ---//
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-          //---//
-        }
-        if (here_op && (here_op & 0xf0) === 0) {
-          last_bits = here_bits;
-          last_op = here_op;
-          last_val = here_val;
-          for (;;) {
-            here = state.lencode[last_val +
-                    ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
-            here_bits = here >>> 24;
-            here_op = (here >>> 16) & 0xff;
-            here_val = here & 0xffff;
-
-            if ((last_bits + here_bits) <= bits) { break; }
-            //--- PULLBYTE() ---//
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-            //---//
-          }
-          //--- DROPBITS(last.bits) ---//
-          hold >>>= last_bits;
-          bits -= last_bits;
-          //---//
-          state.back += last_bits;
-        }
-        //--- DROPBITS(here.bits) ---//
-        hold >>>= here_bits;
-        bits -= here_bits;
-        //---//
-        state.back += here_bits;
-        state.length = here_val;
-        if (here_op === 0) {
-          //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
-          //        "inflate:         literal '%c'\n" :
-          //        "inflate:         literal 0x%02x\n", here.val));
-          state.mode = LIT;
-          break;
-        }
-        if (here_op & 32) {
-          //Tracevv((stderr, "inflate:         end of block\n"));
-          state.back = -1;
-          state.mode = TYPE;
-          break;
-        }
-        if (here_op & 64) {
-          strm.msg = 'invalid literal/length code';
-          state.mode = BAD;
-          break;
-        }
-        state.extra = here_op & 15;
-        state.mode = LENEXT;
-        /* falls through */
-      case LENEXT:
-        if (state.extra) {
-          //=== NEEDBITS(state.extra);
-          n = state.extra;
-          while (bits < n) {
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-          }
-          //===//
-          state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
-          //--- DROPBITS(state.extra) ---//
-          hold >>>= state.extra;
-          bits -= state.extra;
-          //---//
-          state.back += state.extra;
-        }
-        //Tracevv((stderr, "inflate:         length %u\n", state.length));
-        state.was = state.length;
-        state.mode = DIST;
-        /* falls through */
-      case DIST:
-        for (;;) {
-          here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/
-          here_bits = here >>> 24;
-          here_op = (here >>> 16) & 0xff;
-          here_val = here & 0xffff;
-
-          if ((here_bits) <= bits) { break; }
-          //--- PULLBYTE() ---//
-          if (have === 0) { break inf_leave; }
-          have--;
-          hold += input[next++] << bits;
-          bits += 8;
-          //---//
-        }
-        if ((here_op & 0xf0) === 0) {
-          last_bits = here_bits;
-          last_op = here_op;
-          last_val = here_val;
-          for (;;) {
-            here = state.distcode[last_val +
-                    ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
-            here_bits = here >>> 24;
-            here_op = (here >>> 16) & 0xff;
-            here_val = here & 0xffff;
-
-            if ((last_bits + here_bits) <= bits) { break; }
-            //--- PULLBYTE() ---//
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-            //---//
-          }
-          //--- DROPBITS(last.bits) ---//
-          hold >>>= last_bits;
-          bits -= last_bits;
-          //---//
-          state.back += last_bits;
-        }
-        //--- DROPBITS(here.bits) ---//
-        hold >>>= here_bits;
-        bits -= here_bits;
-        //---//
-        state.back += here_bits;
-        if (here_op & 64) {
-          strm.msg = 'invalid distance code';
-          state.mode = BAD;
-          break;
-        }
-        state.offset = here_val;
-        state.extra = (here_op) & 15;
-        state.mode = DISTEXT;
-        /* falls through */
-      case DISTEXT:
-        if (state.extra) {
-          //=== NEEDBITS(state.extra);
-          n = state.extra;
-          while (bits < n) {
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-          }
-          //===//
-          state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
-          //--- DROPBITS(state.extra) ---//
-          hold >>>= state.extra;
-          bits -= state.extra;
-          //---//
-          state.back += state.extra;
-        }
-//#ifdef INFLATE_STRICT
-        if (state.offset > state.dmax) {
-          strm.msg = 'invalid distance too far back';
-          state.mode = BAD;
-          break;
-        }
-//#endif
-        //Tracevv((stderr, "inflate:         distance %u\n", state.offset));
-        state.mode = MATCH;
-        /* falls through */
-      case MATCH:
-        if (left === 0) { break inf_leave; }
-        copy = _out - left;
-        if (state.offset > copy) {         /* copy from window */
-          copy = state.offset - copy;
-          if (copy > state.whave) {
-            if (state.sane) {
-              strm.msg = 'invalid distance too far back';
-              state.mode = BAD;
-              break;
-            }
-// (!) This block is disabled in zlib defaults,
-// don't enable it for binary compatibility
-//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
-//          Trace((stderr, "inflate.c too far\n"));
-//          copy -= state.whave;
-//          if (copy > state.length) { copy = state.length; }
-//          if (copy > left) { copy = left; }
-//          left -= copy;
-//          state.length -= copy;
-//          do {
-//            output[put++] = 0;
-//          } while (--copy);
-//          if (state.length === 0) { state.mode = LEN; }
-//          break;
-//#endif
-          }
-          if (copy > state.wnext) {
-            copy -= state.wnext;
-            from = state.wsize - copy;
-          }
-          else {
-            from = state.wnext - copy;
-          }
-          if (copy > state.length) { copy = state.length; }
-          from_source = state.window;
-        }
-        else {                              /* copy from output */
-          from_source = output;
-          from = put - state.offset;
-          copy = state.length;
-        }
-        if (copy > left) { copy = left; }
-        left -= copy;
-        state.length -= copy;
-        do {
-          output[put++] = from_source[from++];
-        } while (--copy);
-        if (state.length === 0) { state.mode = LEN; }
-        break;
-      case LIT:
-        if (left === 0) { break inf_leave; }
-        output[put++] = state.length;
-        left--;
-        state.mode = LEN;
-        break;
-      case CHECK:
-        if (state.wrap) {
-          //=== NEEDBITS(32);
-          while (bits < 32) {
-            if (have === 0) { break inf_leave; }
-            have--;
-            // Use '|' instead of '+' to make sure that result is signed
-            hold |= input[next++] << bits;
-            bits += 8;
-          }
-          //===//
-          _out -= left;
-          strm.total_out += _out;
-          state.total += _out;
-          if (_out) {
-            strm.adler = state.check =
-                /*UPDATE(state.check, put - _out, _out);*/
-                (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));
-
-          }
-          _out = left;
-          // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
-          if ((state.flags ? hold : zswap32(hold)) !== state.check) {
-            strm.msg = 'incorrect data check';
-            state.mode = BAD;
-            break;
-          }
-          //=== INITBITS();
-          hold = 0;
-          bits = 0;
-          //===//
-          //Tracev((stderr, "inflate:   check matches trailer\n"));
-        }
-        state.mode = LENGTH;
-        /* falls through */
-      case LENGTH:
-        if (state.wrap && state.flags) {
-          //=== NEEDBITS(32);
-          while (bits < 32) {
-            if (have === 0) { break inf_leave; }
-            have--;
-            hold += input[next++] << bits;
-            bits += 8;
-          }
-          //===//
-          if (hold !== (state.total & 0xffffffff)) {
-            strm.msg = 'incorrect length check';
-            state.mode = BAD;
-            break;
-          }
-          //=== INITBITS();
-          hold = 0;
-          bits = 0;
-          //===//
-          //Tracev((stderr, "inflate:   length matches trailer\n"));
-        }
-        state.mode = DONE;
-        /* falls through */
-      case DONE:
-        ret = Z_STREAM_END;
-        break inf_leave;
-      case BAD:
-        ret = Z_DATA_ERROR;
-        break inf_leave;
-      case MEM:
-        return Z_MEM_ERROR;
-      case SYNC:
-        /* falls through */
-      default:
-        return Z_STREAM_ERROR;
-    }
-  }
-
-  // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
-
-  /*
-     Return from inflate(), updating the total counts and the check value.
-     If there was no progress during the inflate() call, return a buffer
-     error.  Call updatewindow() to create and/or update the window state.
-     Note: a memory error from inflate() is non-recoverable.
-   */
-
-  //--- RESTORE() ---
-  strm.next_out = put;
-  strm.avail_out = left;
-  strm.next_in = next;
-  strm.avail_in = have;
-  state.hold = hold;
-  state.bits = bits;
-  //---
-
-  if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&
-                      (state.mode < CHECK || flush !== Z_FINISH))) {
-    if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
-      state.mode = MEM;
-      return Z_MEM_ERROR;
-    }
-  }
-  _in -= strm.avail_in;
-  _out -= strm.avail_out;
-  strm.total_in += _in;
-  strm.total_out += _out;
-  state.total += _out;
-  if (state.wrap && _out) {
-    strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/
-      (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));
-  }
-  strm.data_type = state.bits + (state.last ? 64 : 0) +
-                    (state.mode === TYPE ? 128 : 0) +
-                    (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
-  if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {
-    ret = Z_BUF_ERROR;
-  }
-  return ret;
-}
-
-function inflateEnd(strm) {
-
-  if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
-    return Z_STREAM_ERROR;
-  }
-
-  var state = strm.state;
-  if (state.window) {
-    state.window = null;
-  }
-  strm.state = null;
-  return Z_OK;
-}
-
-function inflateGetHeader(strm, head) {
-  var state;
-
-  /* check state */
-  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
-  state = strm.state;
-  if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }
-
-  /* save header structure */
-  state.head = head;
-  head.done = false;
-  return Z_OK;
-}
-
-function inflateSetDictionary(strm, dictionary) {
-  var dictLength = dictionary.length;
-
-  var state;
-  var dictid;
-  var ret;
-
-  /* check state */
-  if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
-  state = strm.state;
-
-  if (state.wrap !== 0 && state.mode !== DICT) {
-    return Z_STREAM_ERROR;
-  }
-
-  /* check for correct dictionary identifier */
-  if (state.mode === DICT) {
-    dictid = 1; /* adler32(0, null, 0)*/
-    /* dictid = adler32(dictid, dictionary, dictLength); */
-    dictid = adler32(dictid, dictionary, dictLength, 0);
-    if (dictid !== state.check) {
-      return Z_DATA_ERROR;
-    }
-  }
-  /* copy dictionary to window using updatewindow(), which will amend the
-   existing dictionary if appropriate */
-  ret = updatewindow(strm, dictionary, dictLength, dictLength);
-  if (ret) {
-    state.mode = MEM;
-    return Z_MEM_ERROR;
-  }
-  state.havedict = 1;
-  // Tracev((stderr, "inflate:   dictionary set\n"));
-  return Z_OK;
-}
-
-exports.inflateReset = inflateReset;
-exports.inflateReset2 = inflateReset2;
-exports.inflateResetKeep = inflateResetKeep;
-exports.inflateInit = inflateInit;
-exports.inflateInit2 = inflateInit2;
-exports.inflate = inflate;
-exports.inflateEnd = inflateEnd;
-exports.inflateGetHeader = inflateGetHeader;
-exports.inflateSetDictionary = inflateSetDictionary;
-exports.inflateInfo = 'pako inflate (from Nodeca project)';
-
-/* Not implemented
-exports.inflateCopy = inflateCopy;
-exports.inflateGetDictionary = inflateGetDictionary;
-exports.inflateMark = inflateMark;
-exports.inflatePrime = inflatePrime;
-exports.inflateSync = inflateSync;
-exports.inflateSyncPoint = inflateSyncPoint;
-exports.inflateUndermine = inflateUndermine;
-*/
-
-
-/***/ }),
-/* 127 */
-/*!******************************************!*\
-  !*** ./node_modules/pako/lib/inflate.js ***!
-  \******************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-
-var zlib_inflate = __webpack_require__(/*! ./zlib/inflate */ 126);
-var utils        = __webpack_require__(/*! ./utils/common */ 46);
-var strings      = __webpack_require__(/*! ./utils/strings */ 86);
-var c            = __webpack_require__(/*! ./zlib/constants */ 84);
-var msg          = __webpack_require__(/*! ./zlib/messages */ 69);
-var ZStream      = __webpack_require__(/*! ./zlib/zstream */ 85);
-var GZheader     = __webpack_require__(/*! ./zlib/gzheader */ 123);
-
-var toString = Object.prototype.toString;
-
-/**
- * class Inflate
- *
- * Generic JS-style wrapper for zlib calls. If you don't need
- * streaming behaviour - use more simple functions: [[inflate]]
- * and [[inflateRaw]].
- **/
-
-/* internal
- * inflate.chunks -> Array
- *
- * Chunks of output data, if [[Inflate#onData]] not overridden.
- **/
-
-/**
- * Inflate.result -> Uint8Array|Array|String
- *
- * Uncompressed result, generated by default [[Inflate#onData]]
- * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
- * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you
- * push a chunk with explicit flush (call [[Inflate#push]] with
- * `Z_SYNC_FLUSH` param).
- **/
-
-/**
- * Inflate.err -> Number
- *
- * Error code after inflate finished. 0 (Z_OK) on success.
- * Should be checked if broken data possible.
- **/
-
-/**
- * Inflate.msg -> String
- *
- * Error message, if [[Inflate.err]] != 0
- **/
-
-
-/**
- * new Inflate(options)
- * - options (Object): zlib inflate options.
- *
- * Creates new inflator instance with specified params. Throws exception
- * on bad params. Supported options:
- *
- * - `windowBits`
- * - `dictionary`
- *
- * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
- * for more information on these.
- *
- * Additional options, for internal needs:
- *
- * - `chunkSize` - size of generated data chunks (16K by default)
- * - `raw` (Boolean) - do raw inflate
- * - `to` (String) - if equal to 'string', then result will be converted
- *   from utf8 to utf16 (javascript) string. When string output requested,
- *   chunk length can differ from `chunkSize`, depending on content.
- *
- * By default, when no options set, autodetect deflate/gzip data format via
- * wrapper header.
- *
- * ##### Example:
- *
- * ```javascript
- * var pako = require('pako')
- *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
- *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
- *
- * var inflate = new pako.Inflate({ level: 3});
- *
- * inflate.push(chunk1, false);
- * inflate.push(chunk2, true);  // true -> last chunk
- *
- * if (inflate.err) { throw new Error(inflate.err); }
- *
- * console.log(inflate.result);
- * ```
- **/
-function Inflate(options) {
-  if (!(this instanceof Inflate)) return new Inflate(options);
-
-  this.options = utils.assign({
-    chunkSize: 16384,
-    windowBits: 0,
-    to: ''
-  }, options || {});
-
-  var opt = this.options;
-
-  // Force window size for `raw` data, if not set directly,
-  // because we have no header for autodetect.
-  if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
-    opt.windowBits = -opt.windowBits;
-    if (opt.windowBits === 0) { opt.windowBits = -15; }
-  }
-
-  // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
-  if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
-      !(options && options.windowBits)) {
-    opt.windowBits += 32;
-  }
-
-  // Gzip header has no info about windows size, we can do autodetect only
-  // for deflate. So, if window size not set, force it to max when gzip possible
-  if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
-    // bit 3 (16) -> gzipped data
-    // bit 4 (32) -> autodetect gzip/deflate
-    if ((opt.windowBits & 15) === 0) {
-      opt.windowBits |= 15;
-    }
-  }
-
-  this.err    = 0;      // error code, if happens (0 = Z_OK)
-  this.msg    = '';     // error message
-  this.ended  = false;  // used to avoid multiple onEnd() calls
-  this.chunks = [];     // chunks of compressed data
-
-  this.strm   = new ZStream();
-  this.strm.avail_out = 0;
-
-  var status  = zlib_inflate.inflateInit2(
-    this.strm,
-    opt.windowBits
-  );
-
-  if (status !== c.Z_OK) {
-    throw new Error(msg[status]);
-  }
-
-  this.header = new GZheader();
-
-  zlib_inflate.inflateGetHeader(this.strm, this.header);
-}
-
-/**
- * Inflate#push(data[, mode]) -> Boolean
- * - data (Uint8Array|Array|ArrayBuffer|String): input data
- * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
- *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
- *
- * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
- * new output chunks. Returns `true` on success. The last data block must have
- * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
- * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you
- * can use mode Z_SYNC_FLUSH, keeping the decompression context.
- *
- * On fail call [[Inflate#onEnd]] with error code and return false.
- *
- * We strongly recommend to use `Uint8Array` on input for best speed (output
- * format is detected automatically). Also, don't skip last param and always
- * use the same type in your code (boolean or number). That will improve JS speed.
- *
- * For regular `Array`-s make sure all elements are [0..255].
- *
- * ##### Example
- *
- * ```javascript
- * push(chunk, false); // push one of data chunks
- * ...
- * push(chunk, true);  // push last chunk
- * ```
- **/
-Inflate.prototype.push = function (data, mode) {
-  var strm = this.strm;
-  var chunkSize = this.options.chunkSize;
-  var dictionary = this.options.dictionary;
-  var status, _mode;
-  var next_out_utf8, tail, utf8str;
-  var dict;
-
-  // Flag to properly process Z_BUF_ERROR on testing inflate call
-  // when we check that all output data was flushed.
-  var allowBufError = false;
-
-  if (this.ended) { return false; }
-  _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);
-
-  // Convert data if needed
-  if (typeof data === 'string') {
-    // Only binary strings can be decompressed on practice
-    strm.input = strings.binstring2buf(data);
-  } else if (toString.call(data) === '[object ArrayBuffer]') {
-    strm.input = new Uint8Array(data);
-  } else {
-    strm.input = data;
-  }
-
-  strm.next_in = 0;
-  strm.avail_in = strm.input.length;
-
-  do {
-    if (strm.avail_out === 0) {
-      strm.output = new utils.Buf8(chunkSize);
-      strm.next_out = 0;
-      strm.avail_out = chunkSize;
-    }
-
-    status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH);    /* no bad return value */
-
-    if (status === c.Z_NEED_DICT && dictionary) {
-      // Convert data if needed
-      if (typeof dictionary === 'string') {
-        dict = strings.string2buf(dictionary);
-      } else if (toString.call(dictionary) === '[object ArrayBuffer]') {
-        dict = new Uint8Array(dictionary);
-      } else {
-        dict = dictionary;
-      }
-
-      status = zlib_inflate.inflateSetDictionary(this.strm, dict);
-
-    }
-
-    if (status === c.Z_BUF_ERROR && allowBufError === true) {
-      status = c.Z_OK;
-      allowBufError = false;
-    }
-
-    if (status !== c.Z_STREAM_END && status !== c.Z_OK) {
-      this.onEnd(status);
-      this.ended = true;
-      return false;
-    }
-
-    if (strm.next_out) {
-      if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) {
-
-        if (this.options.to === 'string') {
-
-          next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
-
-          tail = strm.next_out - next_out_utf8;
-          utf8str = strings.buf2string(strm.output, next_out_utf8);
-
-          // move tail
-          strm.next_out = tail;
-          strm.avail_out = chunkSize - tail;
-          if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); }
-
-          this.onData(utf8str);
-
-        } else {
-          this.onData(utils.shrinkBuf(strm.output, strm.next_out));
-        }
-      }
-    }
-
-    // When no more input data, we should check that internal inflate buffers
-    // are flushed. The only way to do it when avail_out = 0 - run one more
-    // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.
-    // Here we set flag to process this error properly.
-    //
-    // NOTE. Deflate does not return error in this case and does not needs such
-    // logic.
-    if (strm.avail_in === 0 && strm.avail_out === 0) {
-      allowBufError = true;
-    }
-
-  } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END);
-
-  if (status === c.Z_STREAM_END) {
-    _mode = c.Z_FINISH;
-  }
-
-  // Finalize on the last chunk.
-  if (_mode === c.Z_FINISH) {
-    status = zlib_inflate.inflateEnd(this.strm);
-    this.onEnd(status);
-    this.ended = true;
-    return status === c.Z_OK;
-  }
-
-  // callback interim results if Z_SYNC_FLUSH.
-  if (_mode === c.Z_SYNC_FLUSH) {
-    this.onEnd(c.Z_OK);
-    strm.avail_out = 0;
-    return true;
-  }
-
-  return true;
-};
-
-
-/**
- * Inflate#onData(chunk) -> Void
- * - chunk (Uint8Array|Array|String): output data. Type of array depends
- *   on js engine support. When string output requested, each chunk
- *   will be string.
- *
- * By default, stores data blocks in `chunks[]` property and glue
- * those in `onEnd`. Override this handler, if you need another behaviour.
- **/
-Inflate.prototype.onData = function (chunk) {
-  this.chunks.push(chunk);
-};
-
-
-/**
- * Inflate#onEnd(status) -> Void
- * - status (Number): inflate status. 0 (Z_OK) on success,
- *   other if not.
- *
- * Called either after you tell inflate that the input stream is
- * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
- * or if an error happened. By default - join collected chunks,
- * free memory and fill `results` / `err` properties.
- **/
-Inflate.prototype.onEnd = function (status) {
-  // On success - join
-  if (status === c.Z_OK) {
-    if (this.options.to === 'string') {
-      // Glue & convert here, until we teach pako to send
-      // utf8 aligned strings to onData
-      this.result = this.chunks.join('');
-    } else {
-      this.result = utils.flattenChunks(this.chunks);
-    }
-  }
-  this.chunks = [];
-  this.err = status;
-  this.msg = this.strm.msg;
-};
-
-
-/**
- * inflate(data[, options]) -> Uint8Array|Array|String
- * - data (Uint8Array|Array|String): input data to decompress.
- * - options (Object): zlib inflate options.
- *
- * Decompress `data` with inflate/ungzip and `options`. Autodetect
- * format via wrapper header by default. That's why we don't provide
- * separate `ungzip` method.
- *
- * Supported options are:
- *
- * - windowBits
- *
- * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
- * for more information.
- *
- * Sugar (options):
- *
- * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
- *   negative windowBits implicitly.
- * - `to` (String) - if equal to 'string', then result will be converted
- *   from utf8 to utf16 (javascript) string. When string output requested,
- *   chunk length can differ from `chunkSize`, depending on content.
- *
- *
- * ##### Example:
- *
- * ```javascript
- * var pako = require('pako')
- *   , input = pako.deflate([1,2,3,4,5,6,7,8,9])
- *   , output;
- *
- * try {
- *   output = pako.inflate(input);
- * } catch (err)
- *   console.log(err);
- * }
- * ```
- **/
-function inflate(input, options) {
-  var inflator = new Inflate(options);
-
-  inflator.push(input, true);
-
-  // That will never happens, if you don't cheat with options :)
-  if (inflator.err) { throw inflator.msg || msg[inflator.err]; }
-
-  return inflator.result;
-}
-
-
-/**
- * inflateRaw(data[, options]) -> Uint8Array|Array|String
- * - data (Uint8Array|Array|String): input data to decompress.
- * - options (Object): zlib inflate options.
- *
- * The same as [[inflate]], but creates raw data, without wrapper
- * (header and adler32 crc).
- **/
-function inflateRaw(input, options) {
-  options = options || {};
-  options.raw = true;
-  return inflate(input, options);
-}
-
-
-/**
- * ungzip(data[, options]) -> Uint8Array|Array|String
- * - data (Uint8Array|Array|String): input data to decompress.
- * - options (Object): zlib inflate options.
- *
- * Just shortcut to [[inflate]], because it autodetects format
- * by header.content. Done for convenience.
- **/
-
-
-exports.Inflate = Inflate;
-exports.inflate = inflate;
-exports.inflateRaw = inflateRaw;
-exports.ungzip  = inflate;
-
-
-/***/ }),
-/* 128 */
-/*!*********************************************!*\
-  !*** ./node_modules/pako/lib/zlib/trees.js ***!
-  \*********************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-// (C) 1995-2013 Jean-loup Gailly and Mark Adler
-// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//   claim that you wrote the original software. If you use this software
-//   in a product, an acknowledgment in the product documentation would be
-//   appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-//   misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-var utils = __webpack_require__(/*! ../utils/common */ 46);
-
-/* Public constants ==========================================================*/
-/* ===========================================================================*/
-
-
-//var Z_FILTERED          = 1;
-//var Z_HUFFMAN_ONLY      = 2;
-//var Z_RLE               = 3;
-var Z_FIXED               = 4;
-//var Z_DEFAULT_STRATEGY  = 0;
-
-/* Possible values of the data_type field (though see inflate()) */
-var Z_BINARY              = 0;
-var Z_TEXT                = 1;
-//var Z_ASCII             = 1; // = Z_TEXT
-var Z_UNKNOWN             = 2;
-
-/*============================================================================*/
-
-
-function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
-
-// From zutil.h
-
-var STORED_BLOCK = 0;
-var STATIC_TREES = 1;
-var DYN_TREES    = 2;
-/* The three kinds of block type */
-
-var MIN_MATCH    = 3;
-var MAX_MATCH    = 258;
-/* The minimum and maximum match lengths */
-
-// From deflate.h
-/* ===========================================================================
- * Internal compression state.
- */
-
-var LENGTH_CODES  = 29;
-/* number of length codes, not counting the special END_BLOCK code */
-
-var LITERALS      = 256;
-/* number of literal bytes 0..255 */
-
-var L_CODES       = LITERALS + 1 + LENGTH_CODES;
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-var D_CODES       = 30;
-/* number of distance codes */
-
-var BL_CODES      = 19;
-/* number of codes used to transfer the bit lengths */
-
-var HEAP_SIZE     = 2 * L_CODES + 1;
-/* maximum heap size */
-
-var MAX_BITS      = 15;
-/* All codes must not exceed MAX_BITS bits */
-
-var Buf_size      = 16;
-/* size of bit buffer in bi_buf */
-
-
-/* ===========================================================================
- * Constants
- */
-
-var MAX_BL_BITS = 7;
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-var END_BLOCK   = 256;
-/* end of block literal code */
-
-var REP_3_6     = 16;
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-var REPZ_3_10   = 17;
-/* repeat a zero length 3-10 times  (3 bits of repeat count) */
-
-var REPZ_11_138 = 18;
-/* repeat a zero length 11-138 times  (7 bits of repeat count) */
-
-/* eslint-disable comma-spacing,array-bracket-spacing */
-var extra_lbits =   /* extra bits for each length code */
-  [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];
-
-var extra_dbits =   /* extra bits for each distance code */
-  [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];
-
-var extra_blbits =  /* extra bits for each bit length code */
-  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
-
-var bl_order =
-  [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
-/* eslint-enable comma-spacing,array-bracket-spacing */
-
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-// We pre-fill arrays with 0 to avoid uninitialized gaps
-
-var DIST_CODE_LEN = 512; /* see definition of array dist_code below */
-
-// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
-var static_ltree  = new Array((L_CODES + 2) * 2);
-zero(static_ltree);
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-var static_dtree  = new Array(D_CODES * 2);
-zero(static_dtree);
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-var _dist_code    = new Array(DIST_CODE_LEN);
-zero(_dist_code);
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-var _length_code  = new Array(MAX_MATCH - MIN_MATCH + 1);
-zero(_length_code);
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-var base_length   = new Array(LENGTH_CODES);
-zero(base_length);
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-var base_dist     = new Array(D_CODES);
-zero(base_dist);
-/* First normalized distance for each code (0 = distance of 1) */
-
-
-function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
-
-  this.static_tree  = static_tree;  /* static tree or NULL */
-  this.extra_bits   = extra_bits;   /* extra bits for each code or NULL */
-  this.extra_base   = extra_base;   /* base index for extra_bits */
-  this.elems        = elems;        /* max number of elements in the tree */
-  this.max_length   = max_length;   /* max bit length for the codes */
-
-  // show if `static_tree` has data or dummy - needed for monomorphic objects
-  this.has_stree    = static_tree && static_tree.length;
-}
-
-
-var static_l_desc;
-var static_d_desc;
-var static_bl_desc;
-
-
-function TreeDesc(dyn_tree, stat_desc) {
-  this.dyn_tree = dyn_tree;     /* the dynamic tree */
-  this.max_code = 0;            /* largest code with non zero frequency */
-  this.stat_desc = stat_desc;   /* the corresponding static tree */
-}
-
-
-
-function d_code(dist) {
-  return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
-}
-
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-function put_short(s, w) {
-//    put_byte(s, (uch)((w) & 0xff));
-//    put_byte(s, (uch)((ush)(w) >> 8));
-  s.pending_buf[s.pending++] = (w) & 0xff;
-  s.pending_buf[s.pending++] = (w >>> 8) & 0xff;
-}
-
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-function send_bits(s, value, length) {
-  if (s.bi_valid > (Buf_size - length)) {
-    s.bi_buf |= (value << s.bi_valid) & 0xffff;
-    put_short(s, s.bi_buf);
-    s.bi_buf = value >> (Buf_size - s.bi_valid);
-    s.bi_valid += length - Buf_size;
-  } else {
-    s.bi_buf |= (value << s.bi_valid) & 0xffff;
-    s.bi_valid += length;
-  }
-}
-
-
-function send_code(s, c, tree) {
-  send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);
-}
-
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-function bi_reverse(code, len) {
-  var res = 0;
-  do {
-    res |= code & 1;
-    code >>>= 1;
-    res <<= 1;
-  } while (--len > 0);
-  return res >>> 1;
-}
-
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-function bi_flush(s) {
-  if (s.bi_valid === 16) {
-    put_short(s, s.bi_buf);
-    s.bi_buf = 0;
-    s.bi_valid = 0;
-
-  } else if (s.bi_valid >= 8) {
-    s.pending_buf[s.pending++] = s.bi_buf & 0xff;
-    s.bi_buf >>= 8;
-    s.bi_valid -= 8;
-  }
-}
-
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- *    above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- *     array bl_count contains the frequencies for each bit length.
- *     The length opt_len is updated; static_len is also updated if stree is
- *     not null.
- */
-function gen_bitlen(s, desc)
-//    deflate_state *s;
-//    tree_desc *desc;    /* the tree descriptor */
-{
-  var tree            = desc.dyn_tree;
-  var max_code        = desc.max_code;
-  var stree           = desc.stat_desc.static_tree;
-  var has_stree       = desc.stat_desc.has_stree;
-  var extra           = desc.stat_desc.extra_bits;
-  var base            = desc.stat_desc.extra_base;
-  var max_length      = desc.stat_desc.max_length;
-  var h;              /* heap index */
-  var n, m;           /* iterate over the tree elements */
-  var bits;           /* bit length */
-  var xbits;          /* extra bits */
-  var f;              /* frequency */
-  var overflow = 0;   /* number of elements with bit length too large */
-
-  for (bits = 0; bits <= MAX_BITS; bits++) {
-    s.bl_count[bits] = 0;
-  }
-
-  /* In a first pass, compute the optimal bit lengths (which may
-   * overflow in the case of the bit length tree).
-   */
-  tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */
-
-  for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
-    n = s.heap[h];
-    bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;
-    if (bits > max_length) {
-      bits = max_length;
-      overflow++;
-    }
-    tree[n * 2 + 1]/*.Len*/ = bits;
-    /* We overwrite tree[n].Dad which is no longer needed */
-
-    if (n > max_code) { continue; } /* not a leaf node */
-
-    s.bl_count[bits]++;
-    xbits = 0;
-    if (n >= base) {
-      xbits = extra[n - base];
-    }
-    f = tree[n * 2]/*.Freq*/;
-    s.opt_len += f * (bits + xbits);
-    if (has_stree) {
-      s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);
-    }
-  }
-  if (overflow === 0) { return; }
-
-  // Trace((stderr,"\nbit length overflow\n"));
-  /* This happens for example on obj2 and pic of the Calgary corpus */
-
-  /* Find the first bit length which could increase: */
-  do {
-    bits = max_length - 1;
-    while (s.bl_count[bits] === 0) { bits--; }
-    s.bl_count[bits]--;      /* move one leaf down the tree */
-    s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
-    s.bl_count[max_length]--;
-    /* The brother of the overflow item also moves one step up,
-     * but this does not affect bl_count[max_length]
-     */
-    overflow -= 2;
-  } while (overflow > 0);
-
-  /* Now recompute all bit lengths, scanning in increasing frequency.
-   * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
-   * lengths instead of fixing only the wrong ones. This idea is taken
-   * from 'ar' written by Haruhiko Okumura.)
-   */
-  for (bits = max_length; bits !== 0; bits--) {
-    n = s.bl_count[bits];
-    while (n !== 0) {
-      m = s.heap[--h];
-      if (m > max_code) { continue; }
-      if (tree[m * 2 + 1]/*.Len*/ !== bits) {
-        // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
-        s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;
-        tree[m * 2 + 1]/*.Len*/ = bits;
-      }
-      n--;
-    }
-  }
-}
-
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- *     zero code length.
- */
-function gen_codes(tree, max_code, bl_count)
-//    ct_data *tree;             /* the tree to decorate */
-//    int max_code;              /* largest code with non zero frequency */
-//    ushf *bl_count;            /* number of codes at each bit length */
-{
-  var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */
-  var code = 0;              /* running code value */
-  var bits;                  /* bit index */
-  var n;                     /* code index */
-
-  /* The distribution counts are first used to generate the code values
-   * without bit reversal.
-   */
-  for (bits = 1; bits <= MAX_BITS; bits++) {
-    next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
-  }
-  /* Check that the bit counts in bl_count are consistent. The last code
-   * must be all ones.
-   */
-  //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-  //        "inconsistent bit counts");
-  //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
-  for (n = 0;  n <= max_code; n++) {
-    var len = tree[n * 2 + 1]/*.Len*/;
-    if (len === 0) { continue; }
-    /* Now reverse the bits */
-    tree[n * 2]/*.Code*/ = bi_reverse(next_code[len]++, len);
-
-    //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
-    //     n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
-  }
-}
-
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-function tr_static_init() {
-  var n;        /* iterates over tree elements */
-  var bits;     /* bit counter */
-  var length;   /* length value */
-  var code;     /* code value */
-  var dist;     /* distance index */
-  var bl_count = new Array(MAX_BITS + 1);
-  /* number of codes at each bit length for an optimal tree */
-
-  // do check in _tr_init()
-  //if (static_init_done) return;
-
-  /* For some embedded targets, global variables are not initialized: */
-/*#ifdef NO_INIT_GLOBAL_POINTERS
-  static_l_desc.static_tree = static_ltree;
-  static_l_desc.extra_bits = extra_lbits;
-  static_d_desc.static_tree = static_dtree;
-  static_d_desc.extra_bits = extra_dbits;
-  static_bl_desc.extra_bits = extra_blbits;
-#endif*/
-
-  /* Initialize the mapping length (0..255) -> length code (0..28) */
-  length = 0;
-  for (code = 0; code < LENGTH_CODES - 1; code++) {
-    base_length[code] = length;
-    for (n = 0; n < (1 << extra_lbits[code]); n++) {
-      _length_code[length++] = code;
-    }
-  }
-  //Assert (length == 256, "tr_static_init: length != 256");
-  /* Note that the length 255 (match length 258) can be represented
-   * in two different ways: code 284 + 5 bits or code 285, so we
-   * overwrite length_code[255] to use the best encoding:
-   */
-  _length_code[length - 1] = code;
-
-  /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
-  dist = 0;
-  for (code = 0; code < 16; code++) {
-    base_dist[code] = dist;
-    for (n = 0; n < (1 << extra_dbits[code]); n++) {
-      _dist_code[dist++] = code;
-    }
-  }
-  //Assert (dist == 256, "tr_static_init: dist != 256");
-  dist >>= 7; /* from now on, all distances are divided by 128 */
-  for (; code < D_CODES; code++) {
-    base_dist[code] = dist << 7;
-    for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
-      _dist_code[256 + dist++] = code;
-    }
-  }
-  //Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
-  /* Construct the codes of the static literal tree */
-  for (bits = 0; bits <= MAX_BITS; bits++) {
-    bl_count[bits] = 0;
-  }
-
-  n = 0;
-  while (n <= 143) {
-    static_ltree[n * 2 + 1]/*.Len*/ = 8;
-    n++;
-    bl_count[8]++;
-  }
-  while (n <= 255) {
-    static_ltree[n * 2 + 1]/*.Len*/ = 9;
-    n++;
-    bl_count[9]++;
-  }
-  while (n <= 279) {
-    static_ltree[n * 2 + 1]/*.Len*/ = 7;
-    n++;
-    bl_count[7]++;
-  }
-  while (n <= 287) {
-    static_ltree[n * 2 + 1]/*.Len*/ = 8;
-    n++;
-    bl_count[8]++;
-  }
-  /* Codes 286 and 287 do not exist, but we must include them in the
-   * tree construction to get a canonical Huffman tree (longest code
-   * all ones)
-   */
-  gen_codes(static_ltree, L_CODES + 1, bl_count);
-
-  /* The static distance tree is trivial: */
-  for (n = 0; n < D_CODES; n++) {
-    static_dtree[n * 2 + 1]/*.Len*/ = 5;
-    static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);
-  }
-
-  // Now data ready and we can init static trees
-  static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
-  static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS);
-  static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0,         BL_CODES, MAX_BL_BITS);
-
-  //static_init_done = true;
-}
-
-
-/* ===========================================================================
- * Initialize a new block.
- */
-function init_block(s) {
-  var n; /* iterates over tree elements */
-
-  /* Initialize the trees. */
-  for (n = 0; n < L_CODES;  n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }
-  for (n = 0; n < D_CODES;  n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }
-  for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }
-
-  s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;
-  s.opt_len = s.static_len = 0;
-  s.last_lit = s.matches = 0;
-}
-
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-function bi_windup(s)
-{
-  if (s.bi_valid > 8) {
-    put_short(s, s.bi_buf);
-  } else if (s.bi_valid > 0) {
-    //put_byte(s, (Byte)s->bi_buf);
-    s.pending_buf[s.pending++] = s.bi_buf;
-  }
-  s.bi_buf = 0;
-  s.bi_valid = 0;
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-function copy_block(s, buf, len, header)
-//DeflateState *s;
-//charf    *buf;    /* the input data */
-//unsigned len;     /* its length */
-//int      header;  /* true if block header must be written */
-{
-  bi_windup(s);        /* align on byte boundary */
-
-  if (header) {
-    put_short(s, len);
-    put_short(s, ~len);
-  }
-//  while (len--) {
-//    put_byte(s, *buf++);
-//  }
-  utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);
-  s.pending += len;
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-function smaller(tree, n, m, depth) {
-  var _n2 = n * 2;
-  var _m2 = m * 2;
-  return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||
-         (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));
-}
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-function pqdownheap(s, tree, k)
-//    deflate_state *s;
-//    ct_data *tree;  /* the tree to restore */
-//    int k;               /* node to move down */
-{
-  var v = s.heap[k];
-  var j = k << 1;  /* left son of k */
-  while (j <= s.heap_len) {
-    /* Set j to the smallest of the two sons: */
-    if (j < s.heap_len &&
-      smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
-      j++;
-    }
-    /* Exit if v is smaller than both sons */
-    if (smaller(tree, v, s.heap[j], s.depth)) { break; }
-
-    /* Exchange v with the smallest son */
-    s.heap[k] = s.heap[j];
-    k = j;
-
-    /* And continue down the tree, setting j to the left son of k */
-    j <<= 1;
-  }
-  s.heap[k] = v;
-}
-
-
-// inlined manually
-// var SMALLEST = 1;
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-function compress_block(s, ltree, dtree)
-//    deflate_state *s;
-//    const ct_data *ltree; /* literal tree */
-//    const ct_data *dtree; /* distance tree */
-{
-  var dist;           /* distance of matched string */
-  var lc;             /* match length or unmatched char (if dist == 0) */
-  var lx = 0;         /* running index in l_buf */
-  var code;           /* the code to send */
-  var extra;          /* number of extra bits to send */
-
-  if (s.last_lit !== 0) {
-    do {
-      dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]);
-      lc = s.pending_buf[s.l_buf + lx];
-      lx++;
-
-      if (dist === 0) {
-        send_code(s, lc, ltree); /* send a literal byte */
-        //Tracecv(isgraph(lc), (stderr," '%c' ", lc));
-      } else {
-        /* Here, lc is the match length - MIN_MATCH */
-        code = _length_code[lc];
-        send_code(s, code + LITERALS + 1, ltree); /* send the length code */
-        extra = extra_lbits[code];
-        if (extra !== 0) {
-          lc -= base_length[code];
-          send_bits(s, lc, extra);       /* send the extra length bits */
-        }
-        dist--; /* dist is now the match distance - 1 */
-        code = d_code(dist);
-        //Assert (code < D_CODES, "bad d_code");
-
-        send_code(s, code, dtree);       /* send the distance code */
-        extra = extra_dbits[code];
-        if (extra !== 0) {
-          dist -= base_dist[code];
-          send_bits(s, dist, extra);   /* send the extra distance bits */
-        }
-      } /* literal or match pair ? */
-
-      /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
-      //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
-      //       "pendingBuf overflow");
-
-    } while (lx < s.last_lit);
-  }
-
-  send_code(s, END_BLOCK, ltree);
-}
-
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- *     and corresponding code. The length opt_len is updated; static_len is
- *     also updated if stree is not null. The field max_code is set.
- */
-function build_tree(s, desc)
-//    deflate_state *s;
-//    tree_desc *desc; /* the tree descriptor */
-{
-  var tree     = desc.dyn_tree;
-  var stree    = desc.stat_desc.static_tree;
-  var has_stree = desc.stat_desc.has_stree;
-  var elems    = desc.stat_desc.elems;
-  var n, m;          /* iterate over heap elements */
-  var max_code = -1; /* largest code with non zero frequency */
-  var node;          /* new node being created */
-
-  /* Construct the initial heap, with least frequent element in
-   * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-   * heap[0] is not used.
-   */
-  s.heap_len = 0;
-  s.heap_max = HEAP_SIZE;
-
-  for (n = 0; n < elems; n++) {
-    if (tree[n * 2]/*.Freq*/ !== 0) {
-      s.heap[++s.heap_len] = max_code = n;
-      s.depth[n] = 0;
-
-    } else {
-      tree[n * 2 + 1]/*.Len*/ = 0;
-    }
-  }
-
-  /* The pkzip format requires that at least one distance code exists,
-   * and that at least one bit should be sent even if there is only one
-   * possible code. So to avoid special checks later on we force at least
-   * two codes of non zero frequency.
-   */
-  while (s.heap_len < 2) {
-    node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
-    tree[node * 2]/*.Freq*/ = 1;
-    s.depth[node] = 0;
-    s.opt_len--;
-
-    if (has_stree) {
-      s.static_len -= stree[node * 2 + 1]/*.Len*/;
-    }
-    /* node is 0 or 1 so it does not have extra bits */
-  }
-  desc.max_code = max_code;
-
-  /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-   * establish sub-heaps of increasing lengths:
-   */
-  for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }
-
-  /* Construct the Huffman tree by repeatedly combining the least two
-   * frequent nodes.
-   */
-  node = elems;              /* next internal node of the tree */
-  do {
-    //pqremove(s, tree, n);  /* n = node of least frequency */
-    /*** pqremove ***/
-    n = s.heap[1/*SMALLEST*/];
-    s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];
-    pqdownheap(s, tree, 1/*SMALLEST*/);
-    /***/
-
-    m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */
-
-    s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */
-    s.heap[--s.heap_max] = m;
-
-    /* Create a new node father of n and m */
-    tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;
-    s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
-    tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;
-
-    /* and insert the new node in the heap */
-    s.heap[1/*SMALLEST*/] = node++;
-    pqdownheap(s, tree, 1/*SMALLEST*/);
-
-  } while (s.heap_len >= 2);
-
-  s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];
-
-  /* At this point, the fields freq and dad are set. We can now
-   * generate the bit lengths.
-   */
-  gen_bitlen(s, desc);
-
-  /* The field len is now set, we can generate the bit codes */
-  gen_codes(tree, max_code, s.bl_count);
-}
-
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-function scan_tree(s, tree, max_code)
-//    deflate_state *s;
-//    ct_data *tree;   /* the tree to be scanned */
-//    int max_code;    /* and its largest code of non zero frequency */
-{
-  var n;                     /* iterates over all tree elements */
-  var prevlen = -1;          /* last emitted length */
-  var curlen;                /* length of current code */
-
-  var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
-
-  var count = 0;             /* repeat count of the current code */
-  var max_count = 7;         /* max repeat count */
-  var min_count = 4;         /* min repeat count */
-
-  if (nextlen === 0) {
-    max_count = 138;
-    min_count = 3;
-  }
-  tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */
-
-  for (n = 0; n <= max_code; n++) {
-    curlen = nextlen;
-    nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
-
-    if (++count < max_count && curlen === nextlen) {
-      continue;
-
-    } else if (count < min_count) {
-      s.bl_tree[curlen * 2]/*.Freq*/ += count;
-
-    } else if (curlen !== 0) {
-
-      if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }
-      s.bl_tree[REP_3_6 * 2]/*.Freq*/++;
-
-    } else if (count <= 10) {
-      s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;
-
-    } else {
-      s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;
-    }
-
-    count = 0;
-    prevlen = curlen;
-
-    if (nextlen === 0) {
-      max_count = 138;
-      min_count = 3;
-
-    } else if (curlen === nextlen) {
-      max_count = 6;
-      min_count = 3;
-
-    } else {
-      max_count = 7;
-      min_count = 4;
-    }
-  }
-}
-
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-function send_tree(s, tree, max_code)
-//    deflate_state *s;
-//    ct_data *tree; /* the tree to be scanned */
-//    int max_code;       /* and its largest code of non zero frequency */
-{
-  var n;                     /* iterates over all tree elements */
-  var prevlen = -1;          /* last emitted length */
-  var curlen;                /* length of current code */
-
-  var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
-
-  var count = 0;             /* repeat count of the current code */
-  var max_count = 7;         /* max repeat count */
-  var min_count = 4;         /* min repeat count */
-
-  /* tree[max_code+1].Len = -1; */  /* guard already set */
-  if (nextlen === 0) {
-    max_count = 138;
-    min_count = 3;
-  }
-
-  for (n = 0; n <= max_code; n++) {
-    curlen = nextlen;
-    nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
-
-    if (++count < max_count && curlen === nextlen) {
-      continue;
-
-    } else if (count < min_count) {
-      do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);
-
-    } else if (curlen !== 0) {
-      if (curlen !== prevlen) {
-        send_code(s, curlen, s.bl_tree);
-        count--;
-      }
-      //Assert(count >= 3 && count <= 6, " 3_6?");
-      send_code(s, REP_3_6, s.bl_tree);
-      send_bits(s, count - 3, 2);
-
-    } else if (count <= 10) {
-      send_code(s, REPZ_3_10, s.bl_tree);
-      send_bits(s, count - 3, 3);
-
-    } else {
-      send_code(s, REPZ_11_138, s.bl_tree);
-      send_bits(s, count - 11, 7);
-    }
-
-    count = 0;
-    prevlen = curlen;
-    if (nextlen === 0) {
-      max_count = 138;
-      min_count = 3;
-
-    } else if (curlen === nextlen) {
-      max_count = 6;
-      min_count = 3;
-
-    } else {
-      max_count = 7;
-      min_count = 4;
-    }
-  }
-}
-
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-function build_bl_tree(s) {
-  var max_blindex;  /* index of last bit length code of non zero freq */
-
-  /* Determine the bit length frequencies for literal and distance trees */
-  scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
-  scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
-
-  /* Build the bit length tree: */
-  build_tree(s, s.bl_desc);
-  /* opt_len now includes the length of the tree representations, except
-   * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-   */
-
-  /* Determine the number of bit length codes to send. The pkzip format
-   * requires that at least 4 bit length codes be sent. (appnote.txt says
-   * 3 but the actual value used is 4.)
-   */
-  for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
-    if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {
-      break;
-    }
-  }
-  /* Update opt_len to include the bit length tree and counts */
-  s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
-  //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
-  //        s->opt_len, s->static_len));
-
-  return max_blindex;
-}
-
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-function send_all_trees(s, lcodes, dcodes, blcodes)
-//    deflate_state *s;
-//    int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
-  var rank;                    /* index in bl_order */
-
-  //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
-  //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
-  //        "too many codes");
-  //Tracev((stderr, "\nbl counts: "));
-  send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
-  send_bits(s, dcodes - 1,   5);
-  send_bits(s, blcodes - 4,  4); /* not -3 as stated in appnote.txt */
-  for (rank = 0; rank < blcodes; rank++) {
-    //Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
-    send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);
-  }
-  //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
-  send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */
-  //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
-  send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */
-  //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-
-/* ===========================================================================
- * Check if the data type is TEXT or BINARY, using the following algorithm:
- * - TEXT if the two conditions below are satisfied:
- *    a) There are no non-portable control characters belonging to the
- *       "black list" (0..6, 14..25, 28..31).
- *    b) There is at least one printable character belonging to the
- *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
- * - BINARY otherwise.
- * - The following partially-portable control characters form a
- *   "gray list" that is ignored in this detection algorithm:
- *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
-function detect_data_type(s) {
-  /* black_mask is the bit mask of black-listed bytes
-   * set bits 0..6, 14..25, and 28..31
-   * 0xf3ffc07f = binary 11110011111111111100000001111111
-   */
-  var black_mask = 0xf3ffc07f;
-  var n;
-
-  /* Check for non-textual ("black-listed") bytes. */
-  for (n = 0; n <= 31; n++, black_mask >>>= 1) {
-    if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {
-      return Z_BINARY;
-    }
-  }
-
-  /* Check for textual ("white-listed") bytes. */
-  if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||
-      s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {
-    return Z_TEXT;
-  }
-  for (n = 32; n < LITERALS; n++) {
-    if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
-      return Z_TEXT;
-    }
-  }
-
-  /* There are no "black-listed" or "white-listed" bytes:
-   * this stream either is empty or has tolerated ("gray-listed") bytes only.
-   */
-  return Z_BINARY;
-}
-
-
-var static_init_done = false;
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-function _tr_init(s)
-{
-
-  if (!static_init_done) {
-    tr_static_init();
-    static_init_done = true;
-  }
-
-  s.l_desc  = new TreeDesc(s.dyn_ltree, static_l_desc);
-  s.d_desc  = new TreeDesc(s.dyn_dtree, static_d_desc);
-  s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
-
-  s.bi_buf = 0;
-  s.bi_valid = 0;
-
-  /* Initialize the first block of the first file: */
-  init_block(s);
-}
-
-
-/* ===========================================================================
- * Send a stored block
- */
-function _tr_stored_block(s, buf, stored_len, last)
-//DeflateState *s;
-//charf *buf;       /* input block */
-//ulg stored_len;   /* length of input block */
-//int last;         /* one if this is the last block for a file */
-{
-  send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3);    /* send block type */
-  copy_block(s, buf, stored_len, true); /* with header */
-}
-
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- */
-function _tr_align(s) {
-  send_bits(s, STATIC_TREES << 1, 3);
-  send_code(s, END_BLOCK, static_ltree);
-  bi_flush(s);
-}
-
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-function _tr_flush_block(s, buf, stored_len, last)
-//DeflateState *s;
-//charf *buf;       /* input block, or NULL if too old */
-//ulg stored_len;   /* length of input block */
-//int last;         /* one if this is the last block for a file */
-{
-  var opt_lenb, static_lenb;  /* opt_len and static_len in bytes */
-  var max_blindex = 0;        /* index of last bit length code of non zero freq */
-
-  /* Build the Huffman trees unless a stored block is forced */
-  if (s.level > 0) {
-
-    /* Check if the file is binary or text */
-    if (s.strm.data_type === Z_UNKNOWN) {
-      s.strm.data_type = detect_data_type(s);
-    }
-
-    /* Construct the literal and distance trees */
-    build_tree(s, s.l_desc);
-    // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
-    //        s->static_len));
-
-    build_tree(s, s.d_desc);
-    // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
-    //        s->static_len));
-    /* At this point, opt_len and static_len are the total bit lengths of
-     * the compressed block data, excluding the tree representations.
-     */
-
-    /* Build the bit length tree for the above two trees, and get the index
-     * in bl_order of the last bit length code to send.
-     */
-    max_blindex = build_bl_tree(s);
-
-    /* Determine the best encoding. Compute the block lengths in bytes. */
-    opt_lenb = (s.opt_len + 3 + 7) >>> 3;
-    static_lenb = (s.static_len + 3 + 7) >>> 3;
-
-    // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
-    //        opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
-    //        s->last_lit));
-
-    if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }
-
-  } else {
-    // Assert(buf != (char*)0, "lost buf");
-    opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
-  }
-
-  if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {
-    /* 4: two words for the lengths */
-
-    /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-     * Otherwise we can't have processed more than WSIZE input bytes since
-     * the last block flush, because compression would have been
-     * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-     * transform a block into a stored block.
-     */
-    _tr_stored_block(s, buf, stored_len, last);
-
-  } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
-
-    send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
-    compress_block(s, static_ltree, static_dtree);
-
-  } else {
-    send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
-    send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
-    compress_block(s, s.dyn_ltree, s.dyn_dtree);
-  }
-  // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
-  /* The above check is made mod 2^32, for files larger than 512 MB
-   * and uLong implemented on 32 bits.
-   */
-  init_block(s);
-
-  if (last) {
-    bi_windup(s);
-  }
-  // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
-  //       s->compressed_len-7*last));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-function _tr_tally(s, dist, lc)
-//    deflate_state *s;
-//    unsigned dist;  /* distance of matched string */
-//    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
-  //var out_length, in_length, dcode;
-
-  s.pending_buf[s.d_buf + s.last_lit * 2]     = (dist >>> 8) & 0xff;
-  s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
-
-  s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
-  s.last_lit++;
-
-  if (dist === 0) {
-    /* lc is the unmatched char */
-    s.dyn_ltree[lc * 2]/*.Freq*/++;
-  } else {
-    s.matches++;
-    /* Here, lc is the match length - MIN_MATCH */
-    dist--;             /* dist = match distance - 1 */
-    //Assert((ush)dist < (ush)MAX_DIST(s) &&
-    //       (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
-    //       (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
-
-    s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;
-    s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;
-  }
-
-// (!) This block is disabled in zlib defaults,
-// don't enable it for binary compatibility
-
-//#ifdef TRUNCATE_BLOCK
-//  /* Try to guess if it is profitable to stop the current block here */
-//  if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
-//    /* Compute an upper bound for the compressed length */
-//    out_length = s.last_lit*8;
-//    in_length = s.strstart - s.block_start;
-//
-//    for (dcode = 0; dcode < D_CODES; dcode++) {
-//      out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
-//    }
-//    out_length >>>= 3;
-//    //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
-//    //       s->last_lit, in_length, out_length,
-//    //       100L - out_length*100L/in_length));
-//    if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
-//      return true;
-//    }
-//  }
-//#endif
-
-  return (s.last_lit === s.lit_bufsize - 1);
-  /* We avoid equality with lit_bufsize because of wraparound at 64K
-   * on 16 bit machines and because stored blocks are restricted to
-   * 64K-1 bytes.
-   */
-}
-
-exports._tr_init  = _tr_init;
-exports._tr_stored_block = _tr_stored_block;
-exports._tr_flush_block  = _tr_flush_block;
-exports._tr_tally = _tr_tally;
-exports._tr_align = _tr_align;
-
-
-/***/ }),
-/* 129 */
-/*!***********************************************!*\
-  !*** ./node_modules/pako/lib/zlib/deflate.js ***!
-  \***********************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-// (C) 1995-2013 Jean-loup Gailly and Mark Adler
-// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-//   claim that you wrote the original software. If you use this software
-//   in a product, an acknowledgment in the product documentation would be
-//   appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-//   misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-var utils   = __webpack_require__(/*! ../utils/common */ 46);
-var trees   = __webpack_require__(/*! ./trees */ 128);
-var adler32 = __webpack_require__(/*! ./adler32 */ 88);
-var crc32   = __webpack_require__(/*! ./crc32 */ 87);
-var msg     = __webpack_require__(/*! ./messages */ 69);
-
-/* Public constants ==========================================================*/
-/* ===========================================================================*/
-
-
-/* Allowed flush values; see deflate() and inflate() below for details */
-var Z_NO_FLUSH      = 0;
-var Z_PARTIAL_FLUSH = 1;
-//var Z_SYNC_FLUSH    = 2;
-var Z_FULL_FLUSH    = 3;
-var Z_FINISH        = 4;
-var Z_BLOCK         = 5;
-//var Z_TREES         = 6;
-
-
-/* Return codes for the compression/decompression functions. Negative values
- * are errors, positive values are used for special but normal events.
- */
-var Z_OK            = 0;
-var Z_STREAM_END    = 1;
-//var Z_NEED_DICT     = 2;
-//var Z_ERRNO         = -1;
-var Z_STREAM_ERROR  = -2;
-var Z_DATA_ERROR    = -3;
-//var Z_MEM_ERROR     = -4;
-var Z_BUF_ERROR     = -5;
-//var Z_VERSION_ERROR = -6;
-
-
-/* compression levels */
-//var Z_NO_COMPRESSION      = 0;
-//var Z_BEST_SPEED          = 1;
-//var Z_BEST_COMPRESSION    = 9;
-var Z_DEFAULT_COMPRESSION = -1;
-
-
-var Z_FILTERED            = 1;
-var Z_HUFFMAN_ONLY        = 2;
-var Z_RLE                 = 3;
-var Z_FIXED               = 4;
-var Z_DEFAULT_STRATEGY    = 0;
-
-/* Possible values of the data_type field (though see inflate()) */
-//var Z_BINARY              = 0;
-//var Z_TEXT                = 1;
-//var Z_ASCII               = 1; // = Z_TEXT
-var Z_UNKNOWN             = 2;
-
-
-/* The deflate compression method */
-var Z_DEFLATED  = 8;
-
-/*============================================================================*/
-
-
-var MAX_MEM_LEVEL = 9;
-/* Maximum value for memLevel in deflateInit2 */
-var MAX_WBITS = 15;
-/* 32K LZ77 window */
-var DEF_MEM_LEVEL = 8;
-
-
-var LENGTH_CODES  = 29;
-/* number of length codes, not counting the special END_BLOCK code */
-var LITERALS      = 256;
-/* number of literal bytes 0..255 */
-var L_CODES       = LITERALS + 1 + LENGTH_CODES;
-/* number of Literal or Length codes, including the END_BLOCK code */
-var D_CODES       = 30;
-/* number of distance codes */
-var BL_CODES      = 19;
-/* number of codes used to transfer the bit lengths */
-var HEAP_SIZE     = 2 * L_CODES + 1;
-/* maximum heap size */
-var MAX_BITS  = 15;
-/* All codes must not exceed MAX_BITS bits */
-
-var MIN_MATCH = 3;
-var MAX_MATCH = 258;
-var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
-
-var PRESET_DICT = 0x20;
-
-var INIT_STATE = 42;
-var EXTRA_STATE = 69;
-var NAME_STATE = 73;
-var COMMENT_STATE = 91;
-var HCRC_STATE = 103;
-var BUSY_STATE = 113;
-var FINISH_STATE = 666;
-
-var BS_NEED_MORE      = 1; /* block not completed, need more input or more output */
-var BS_BLOCK_DONE     = 2; /* block flush performed */
-var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */
-var BS_FINISH_DONE    = 4; /* finish done, accept no more input or output */
-
-var OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
-
-function err(strm, errorCode) {
-  strm.msg = msg[errorCode];
-  return errorCode;
-}
-
-function rank(f) {
-  return ((f) << 1) - ((f) > 4 ? 9 : 0);
-}
-
-function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
-
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->output buffer and copying into it.
- * (See also read_buf()).
- */
-function flush_pending(strm) {
-  var s = strm.state;
-
-  //_tr_flush_bits(s);
-  var len = s.pending;
-  if (len > strm.avail_out) {
-    len = strm.avail_out;
-  }
-  if (len === 0) { return; }
-
-  utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
-  strm.next_out += len;
-  s.pending_out += len;
-  strm.total_out += len;
-  strm.avail_out -= len;
-  s.pending -= len;
-  if (s.pending === 0) {
-    s.pending_out = 0;
-  }
-}
-
-
-function flush_block_only(s, last) {
-  trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
-  s.block_start = s.strstart;
-  flush_pending(s.strm);
-}
-
-
-function put_byte(s, b) {
-  s.pending_buf[s.pending++] = b;
-}
-
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-function putShortMSB(s, b) {
-//  put_byte(s, (Byte)(b >> 8));
-//  put_byte(s, (Byte)(b & 0xff));
-  s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
-  s.pending_buf[s.pending++] = b & 0xff;
-}
-
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read.  All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->input buffer and copying from it.
- * (See also flush_pending()).
- */
-function read_buf(strm, buf, start, size) {
-  var len = strm.avail_in;
-
-  if (len > size) { len = size; }
-  if (len === 0) { return 0; }
-
-  strm.avail_in -= len;
-
-  // zmemcpy(buf, strm->next_in, len);
-  utils.arraySet(buf, strm.input, strm.next_in, len, start);
-  if (strm.state.wrap === 1) {
-    strm.adler = adler32(strm.adler, buf, len, start);
-  }
-
-  else if (strm.state.wrap === 2) {
-    strm.adler = crc32(strm.adler, buf, len, start);
-  }
-
-  strm.next_in += len;
-  strm.total_in += len;
-
-  return len;
-}
-
-
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-function longest_match(s, cur_match) {
-  var chain_length = s.max_chain_length;      /* max hash chain length */
-  var scan = s.strstart; /* current string */
-  var match;                       /* matched string */
-  var len;                           /* length of current match */
-  var best_len = s.prev_length;              /* best match length so far */
-  var nice_match = s.nice_match;             /* stop if match long enough */
-  var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
-      s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;
-
-  var _win = s.window; // shortcut
-
-  var wmask = s.w_mask;
-  var prev  = s.prev;
-
-  /* Stop when cur_match becomes <= limit. To simplify the code,
-   * we prevent matches with the string of window index 0.
-   */
-
-  var strend = s.strstart + MAX_MATCH;
-  var scan_end1  = _win[scan + best_len - 1];
-  var scan_end   = _win[scan + best_len];
-
-  /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-   * It is easy to get rid of this optimization if necessary.
-   */
-  // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
-  /* Do not waste too much time if we already have a good match: */
-  if (s.prev_length >= s.good_match) {
-    chain_length >>= 2;
-  }
-  /* Do not look for matches beyond the end of the input. This is necessary
-   * to make deflate deterministic.
-   */
-  if (nice_match > s.lookahead) { nice_match = s.lookahead; }
-
-  // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
-  do {
-    // Assert(cur_match < s->strstart, "no future");
-    match = cur_match;
-
-    /* Skip to next match if the match length cannot increase
-     * or if the match length is less than 2.  Note that the checks below
-     * for insufficient lookahead only occur occasionally for performance
-     * reasons.  Therefore uninitialized memory will be accessed, and
-     * conditional jumps will be made that depend on those values.
-     * However the length of the match is limited to the lookahead, so
-     * the output of deflate is not affected by the uninitialized values.
-     */
-
-    if (_win[match + best_len]     !== scan_end  ||
-        _win[match + best_len - 1] !== scan_end1 ||
-        _win[match]                !== _win[scan] ||
-        _win[++match]              !== _win[scan + 1]) {
-      continue;
-    }
-
-    /* The check at best_len-1 can be removed because it will be made
-     * again later. (This heuristic is not always a win.)
-     * It is not necessary to compare scan[2] and match[2] since they
-     * are always equal when the other bytes match, given that
-     * the hash keys are equal and that HASH_BITS >= 8.
-     */
-    scan += 2;
-    match++;
-    // Assert(*scan == *match, "match[2]?");
-
-    /* We check for insufficient lookahead only every 8th comparison;
-     * the 256th check will be made at strstart+258.
-     */
-    do {
-      /*jshint noempty:false*/
-    } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
-             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
-             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
-             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
-             scan < strend);
-
-    // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
-    len = MAX_MATCH - (strend - scan);
-    scan = strend - MAX_MATCH;
-
-    if (len > best_len) {
-      s.match_start = cur_match;
-      best_len = len;
-      if (len >= nice_match) {
-        break;
-      }
-      scan_end1  = _win[scan + best_len - 1];
-      scan_end   = _win[scan + best_len];
-    }
-  } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
-
-  if (best_len <= s.lookahead) {
-    return best_len;
-  }
-  return s.lookahead;
-}
-
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- *    At least one byte has been read, or avail_in == 0; reads are
- *    performed for at least two bytes (required for the zip translate_eol
- *    option -- not supported here).
- */
-function fill_window(s) {
-  var _w_size = s.w_size;
-  var p, n, m, more, str;
-
-  //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
-
-  do {
-    more = s.window_size - s.lookahead - s.strstart;
-
-    // JS ints have 32 bit, block below not needed
-    /* Deal with !@#$% 64K limit: */
-    //if (sizeof(int) <= 2) {
-    //    if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
-    //        more = wsize;
-    //
-    //  } else if (more == (unsigned)(-1)) {
-    //        /* Very unlikely, but possible on 16 bit machine if
-    //         * strstart == 0 && lookahead == 1 (input done a byte at time)
-    //         */
-    //        more--;
-    //    }
-    //}
-
-
-    /* If the window is almost full and there is insufficient lookahead,
-     * move the upper half to the lower one to make room in the upper half.
-     */
-    if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
-
-      utils.arraySet(s.window, s.window, _w_size, _w_size, 0);
-      s.match_start -= _w_size;
-      s.strstart -= _w_size;
-      /* we now have strstart >= MAX_DIST */
-      s.block_start -= _w_size;
-
-      /* Slide the hash table (could be avoided with 32 bit values
-       at the expense of memory usage). We slide even when level == 0
-       to keep the hash table consistent if we switch back to level > 0
-       later. (Using level 0 permanently is not an optimal usage of
-       zlib, so we don't care about this pathological case.)
-       */
-
-      n = s.hash_size;
-      p = n;
-      do {
-        m = s.head[--p];
-        s.head[p] = (m >= _w_size ? m - _w_size : 0);
-      } while (--n);
-
-      n = _w_size;
-      p = n;
-      do {
-        m = s.prev[--p];
-        s.prev[p] = (m >= _w_size ? m - _w_size : 0);
-        /* If n is not on any hash chain, prev[n] is garbage but
-         * its value will never be used.
-         */
-      } while (--n);
-
-      more += _w_size;
-    }
-    if (s.strm.avail_in === 0) {
-      break;
-    }
-
-    /* If there was no sliding:
-     *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-     *    more == window_size - lookahead - strstart
-     * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-     * => more >= window_size - 2*WSIZE + 2
-     * In the BIG_MEM or MMAP case (not yet supported),
-     *   window_size == input_size + MIN_LOOKAHEAD  &&
-     *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-     * Otherwise, window_size == 2*WSIZE so more >= 2.
-     * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-     */
-    //Assert(more >= 2, "more < 2");
-    n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
-    s.lookahead += n;
-
-    /* Initialize the hash value now that we have some input: */
-    if (s.lookahead + s.insert >= MIN_MATCH) {
-      str = s.strstart - s.insert;
-      s.ins_h = s.window[str];
-
-      /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
-      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
-//#if MIN_MATCH != 3
-//        Call update_hash() MIN_MATCH-3 more times
-//#endif
-      while (s.insert) {
-        /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
-        s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
-
-        s.prev[str & s.w_mask] = s.head[s.ins_h];
-        s.head[s.ins_h] = str;
-        str++;
-        s.insert--;
-        if (s.lookahead + s.insert < MIN_MATCH) {
-          break;
-        }
-      }
-    }
-    /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
-     * but this is not important since only literal bytes will be emitted.
-     */
-
-  } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
-
-  /* If the WIN_INIT bytes after the end of the current data have never been
-   * written, then zero those bytes in order to avoid memory check reports of
-   * the use of uninitialized (or uninitialised as Julian writes) bytes by
-   * the longest match routines.  Update the high water mark for the next
-   * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
-   * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
-   */
-//  if (s.high_water < s.window_size) {
-//    var curr = s.strstart + s.lookahead;
-//    var init = 0;
-//
-//    if (s.high_water < curr) {
-//      /* Previous high water mark below current data -- zero WIN_INIT
-//       * bytes or up to end of window, whichever is less.
-//       */
-//      init = s.window_size - curr;
-//      if (init > WIN_INIT)
-//        init = WIN_INIT;
-//      zmemzero(s->window + curr, (unsigned)init);
-//      s->high_water = curr + init;
-//    }
-//    else if (s->high_water < (ulg)curr + WIN_INIT) {
-//      /* High water mark at or above current data, but below current data
-//       * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
-//       * to end of window, whichever is less.
-//       */
-//      init = (ulg)curr + WIN_INIT - s->high_water;
-//      if (init > s->window_size - s->high_water)
-//        init = s->window_size - s->high_water;
-//      zmemzero(s->window + s->high_water, (unsigned)init);
-//      s->high_water += init;
-//    }
-//  }
-//
-//  Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
-//    "not enough room for search");
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-function deflate_stored(s, flush) {
-  /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
-   * to pending_buf_size, and each stored block has a 5 byte header:
-   */
-  var max_block_size = 0xffff;
-
-  if (max_block_size > s.pending_buf_size - 5) {
-    max_block_size = s.pending_buf_size - 5;
-  }
-
-  /* Copy as much as possible from input to output: */
-  for (;;) {
-    /* Fill the window as much as possible: */
-    if (s.lookahead <= 1) {
-
-      //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
-      //  s->block_start >= (long)s->w_size, "slide too late");
-//      if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
-//        s.block_start >= s.w_size)) {
-//        throw  new Error("slide too late");
-//      }
-
-      fill_window(s);
-      if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
-        return BS_NEED_MORE;
-      }
-
-      if (s.lookahead === 0) {
-        break;
-      }
-      /* flush the current block */
-    }
-    //Assert(s->block_start >= 0L, "block gone");
-//    if (s.block_start < 0) throw new Error("block gone");
-
-    s.strstart += s.lookahead;
-    s.lookahead = 0;
-
-    /* Emit a stored block if pending_buf will be full: */
-    var max_start = s.block_start + max_block_size;
-
-    if (s.strstart === 0 || s.strstart >= max_start) {
-      /* strstart == 0 is possible when wraparound on 16-bit machine */
-      s.lookahead = s.strstart - max_start;
-      s.strstart = max_start;
-      /*** FLUSH_BLOCK(s, 0); ***/
-      flush_block_only(s, false);
-      if (s.strm.avail_out === 0) {
-        return BS_NEED_MORE;
-      }
-      /***/
-
-
-    }
-    /* Flush if we may have to slide, otherwise block_start may become
-     * negative and the data will be gone:
-     */
-    if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
-      /*** FLUSH_BLOCK(s, 0); ***/
-      flush_block_only(s, false);
-      if (s.strm.avail_out === 0) {
-        return BS_NEED_MORE;
-      }
-      /***/
-    }
-  }
-
-  s.insert = 0;
-
-  if (flush === Z_FINISH) {
-    /*** FLUSH_BLOCK(s, 1); ***/
-    flush_block_only(s, true);
-    if (s.strm.avail_out === 0) {
-      return BS_FINISH_STARTED;
-    }
-    /***/
-    return BS_FINISH_DONE;
-  }
-
-  if (s.strstart > s.block_start) {
-    /*** FLUSH_BLOCK(s, 0); ***/
-    flush_block_only(s, false);
-    if (s.strm.avail_out === 0) {
-      return BS_NEED_MORE;
-    }
-    /***/
-  }
-
-  return BS_NEED_MORE;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-function deflate_fast(s, flush) {
-  var hash_head;        /* head of the hash chain */
-  var bflush;           /* set if current block must be flushed */
-
-  for (;;) {
-    /* Make sure that we always have enough lookahead, except
-     * at the end of the input file. We need MAX_MATCH bytes
-     * for the next match, plus MIN_MATCH bytes to insert the
-     * string following the next match.
-     */
-    if (s.lookahead < MIN_LOOKAHEAD) {
-      fill_window(s);
-      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
-        return BS_NEED_MORE;
-      }
-      if (s.lookahead === 0) {
-        break; /* flush the current block */
-      }
-    }
-
-    /* Insert the string window[strstart .. strstart+2] in the
-     * dictionary, and set hash_head to the head of the hash chain:
-     */
-    hash_head = 0/*NIL*/;
-    if (s.lookahead >= MIN_MATCH) {
-      /*** INSERT_STRING(s, s.strstart, hash_head); ***/
-      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
-      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
-      s.head[s.ins_h] = s.strstart;
-      /***/
-    }
-
-    /* Find the longest match, discarding those <= prev_length.
-     * At this point we have always match_length < MIN_MATCH
-     */
-    if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
-      /* To simplify the code, we prevent matches with the string
-       * of window index 0 (in particular we have to avoid a match
-       * of the string with itself at the start of the input file).
-       */
-      s.match_length = longest_match(s, hash_head);
-      /* longest_match() sets match_start */
-    }
-    if (s.match_length >= MIN_MATCH) {
-      // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
-
-      /*** _tr_tally_dist(s, s.strstart - s.match_start,
-                     s.match_length - MIN_MATCH, bflush); ***/
-      bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
-
-      s.lookahead -= s.match_length;
-
-      /* Insert new strings in the hash table only if the match length
-       * is not too large. This saves time but degrades compression.
-       */
-      if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {
-        s.match_length--; /* string at strstart already in table */
-        do {
-          s.strstart++;
-          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
-          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
-          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
-          s.head[s.ins_h] = s.strstart;
-          /***/
-          /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-           * always MIN_MATCH bytes ahead.
-           */
-        } while (--s.match_length !== 0);
-        s.strstart++;
-      } else
-      {
-        s.strstart += s.match_length;
-        s.match_length = 0;
-        s.ins_h = s.window[s.strstart];
-        /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
-        s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
-
-//#if MIN_MATCH != 3
-//                Call UPDATE_HASH() MIN_MATCH-3 more times
-//#endif
-        /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
-         * matter since it will be recomputed at next deflate call.
-         */
-      }
-    } else {
-      /* No match, output a literal byte */
-      //Tracevv((stderr,"%c", s.window[s.strstart]));
-      /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
-      bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
-
-      s.lookahead--;
-      s.strstart++;
-    }
-    if (bflush) {
-      /*** FLUSH_BLOCK(s, 0); ***/
-      flush_block_only(s, false);
-      if (s.strm.avail_out === 0) {
-        return BS_NEED_MORE;
-      }
-      /***/
-    }
-  }
-  s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);
-  if (flush === Z_FINISH) {
-    /*** FLUSH_BLOCK(s, 1); ***/
-    flush_block_only(s, true);
-    if (s.strm.avail_out === 0) {
-      return BS_FINISH_STARTED;
-    }
-    /***/
-    return BS_FINISH_DONE;
-  }
-  if (s.last_lit) {
-    /*** FLUSH_BLOCK(s, 0); ***/
-    flush_block_only(s, false);
-    if (s.strm.avail_out === 0) {
-      return BS_NEED_MORE;
-    }
-    /***/
-  }
-  return BS_BLOCK_DONE;
-}
-
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-function deflate_slow(s, flush) {
-  var hash_head;          /* head of hash chain */
-  var bflush;              /* set if current block must be flushed */
-
-  var max_insert;
-
-  /* Process the input block. */
-  for (;;) {
-    /* Make sure that we always have enough lookahead, except
-     * at the end of the input file. We need MAX_MATCH bytes
-     * for the next match, plus MIN_MATCH bytes to insert the
-     * string following the next match.
-     */
-    if (s.lookahead < MIN_LOOKAHEAD) {
-      fill_window(s);
-      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
-        return BS_NEED_MORE;
-      }
-      if (s.lookahead === 0) { break; } /* flush the current block */
-    }
-
-    /* Insert the string window[strstart .. strstart+2] in the
-     * dictionary, and set hash_head to the head of the hash chain:
-     */
-    hash_head = 0/*NIL*/;
-    if (s.lookahead >= MIN_MATCH) {
-      /*** INSERT_STRING(s, s.strstart, hash_head); ***/
-      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
-      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
-      s.head[s.ins_h] = s.strstart;
-      /***/
-    }
-
-    /* Find the longest match, discarding those <= prev_length.
-     */
-    s.prev_length = s.match_length;
-    s.prev_match = s.match_start;
-    s.match_length = MIN_MATCH - 1;
-
-    if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
-        s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
-      /* To simplify the code, we prevent matches with the string
-       * of window index 0 (in particular we have to avoid a match
-       * of the string with itself at the start of the input file).
-       */
-      s.match_length = longest_match(s, hash_head);
-      /* longest_match() sets match_start */
-
-      if (s.match_length <= 5 &&
-         (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
-
-        /* If prev_match is also MIN_MATCH, match_start is garbage
-         * but we will ignore the current match anyway.
-         */
-        s.match_length = MIN_MATCH - 1;
-      }
-    }
-    /* If there was a match at the previous step and the current
-     * match is not better, output the previous match:
-     */
-    if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
-      max_insert = s.strstart + s.lookahead - MIN_MATCH;
-      /* Do not insert strings in hash table beyond this. */
-
-      //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
-
-      /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
-                     s.prev_length - MIN_MATCH, bflush);***/
-      bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);
-      /* Insert in hash table all strings up to the end of the match.
-       * strstart-1 and strstart are already inserted. If there is not
-       * enough lookahead, the last two strings are not inserted in
-       * the hash table.
-       */
-      s.lookahead -= s.prev_length - 1;
-      s.prev_length -= 2;
-      do {
-        if (++s.strstart <= max_insert) {
-          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
-          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
-          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
-          s.head[s.ins_h] = s.strstart;
-          /***/
-        }
-      } while (--s.prev_length !== 0);
-      s.match_available = 0;
-      s.match_length = MIN_MATCH - 1;
-      s.strstart++;
-
-      if (bflush) {
-        /*** FLUSH_BLOCK(s, 0); ***/
-        flush_block_only(s, false);
-        if (s.strm.avail_out === 0) {
-          return BS_NEED_MORE;
-        }
-        /***/
-      }
-
-    } else if (s.match_available) {
-      /* If there was no match at the previous position, output a
-       * single literal. If there was a match but the current match
-       * is longer, truncate the previous match to a single literal.
-       */
-      //Tracevv((stderr,"%c", s->window[s->strstart-1]));
-      /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
-      bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
-
-      if (bflush) {
-        /*** FLUSH_BLOCK_ONLY(s, 0) ***/
-        flush_block_only(s, false);
-        /***/
-      }
-      s.strstart++;
-      s.lookahead--;
-      if (s.strm.avail_out === 0) {
-        return BS_NEED_MORE;
-      }
-    } else {
-      /* There is no previous match to compare with, wait for
-       * the next step to decide.
-       */
-      s.match_available = 1;
-      s.strstart++;
-      s.lookahead--;
-    }
-  }
-  //Assert (flush != Z_NO_FLUSH, "no flush?");
-  if (s.match_available) {
-    //Tracevv((stderr,"%c", s->window[s->strstart-1]));
-    /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
-    bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
-
-    s.match_available = 0;
-  }
-  s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
-  if (flush === Z_FINISH) {
-    /*** FLUSH_BLOCK(s, 1); ***/
-    flush_block_only(s, true);
-    if (s.strm.avail_out === 0) {
-      return BS_FINISH_STARTED;
-    }
-    /***/
-    return BS_FINISH_DONE;
-  }
-  if (s.last_lit) {
-    /*** FLUSH_BLOCK(s, 0); ***/
-    flush_block_only(s, false);
-    if (s.strm.avail_out === 0) {
-      return BS_NEED_MORE;
-    }
-    /***/
-  }
-
-  return BS_BLOCK_DONE;
-}
-
-
-/* ===========================================================================
- * For Z_RLE, simply look for runs of bytes, generate matches only of distance
- * one.  Do not maintain a hash table.  (It will be regenerated if this run of
- * deflate switches away from Z_RLE.)
- */
-function deflate_rle(s, flush) {
-  var bflush;            /* set if current block must be flushed */
-  var prev;              /* byte at distance one to match */
-  var scan, strend;      /* scan goes up to strend for length of run */
-
-  var _win = s.window;
-
-  for (;;) {
-    /* Make sure that we always have enough lookahead, except
-     * at the end of the input file. We need MAX_MATCH bytes
-     * for the longest run, plus one for the unrolled loop.
-     */
-    if (s.lookahead <= MAX_MATCH) {
-      fill_window(s);
-      if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {
-        return BS_NEED_MORE;
-      }
-      if (s.lookahead === 0) { break; } /* flush the current block */
-    }
-
-    /* See how many times the previous byte repeats */
-    s.match_length = 0;
-    if (s.lookahead >= MIN_MATCH && s.strstart > 0) {
-      scan = s.strstart - 1;
-      prev = _win[scan];
-      if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
-        strend = s.strstart + MAX_MATCH;
-        do {
-          /*jshint noempty:false*/
-        } while (prev === _win[++scan] && prev === _win[++scan] &&
-                 prev === _win[++scan] && prev === _win[++scan] &&
-                 prev === _win[++scan] && prev === _win[++scan] &&
-                 prev === _win[++scan] && prev === _win[++scan] &&
-                 scan < strend);
-        s.match_length = MAX_MATCH - (strend - scan);
-        if (s.match_length > s.lookahead) {
-          s.match_length = s.lookahead;
-        }
-      }
-      //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
-    }
-
-    /* Emit match if have run of MIN_MATCH or longer, else emit literal */
-    if (s.match_length >= MIN_MATCH) {
-      //check_match(s, s.strstart, s.strstart - 1, s.match_length);
-
-      /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/
-      bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);
-
-      s.lookahead -= s.match_length;
-      s.strstart += s.match_length;
-      s.match_length = 0;
-    } else {
-      /* No match, output a literal byte */
-      //Tracevv((stderr,"%c", s->window[s->strstart]));
-      /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
-      bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
-
-      s.lookahead--;
-      s.strstart++;
-    }
-    if (bflush) {
-      /*** FLUSH_BLOCK(s, 0); ***/
-      flush_block_only(s, false);
-      if (s.strm.avail_out === 0) {
-        return BS_NEED_MORE;
-      }
-      /***/
-    }
-  }
-  s.insert = 0;
-  if (flush === Z_FINISH) {
-    /*** FLUSH_BLOCK(s, 1); ***/
-    flush_block_only(s, true);
-    if (s.strm.avail_out === 0) {
-      return BS_FINISH_STARTED;
-    }
-    /***/
-    return BS_FINISH_DONE;
-  }
-  if (s.last_lit) {
-    /*** FLUSH_BLOCK(s, 0); ***/
-    flush_block_only(s, false);
-    if (s.strm.avail_out === 0) {
-      return BS_NEED_MORE;
-    }
-    /***/
-  }
-  return BS_BLOCK_DONE;
-}
-
-/* ===========================================================================
- * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
- * (It will be regenerated if this run of deflate switches away from Huffman.)
- */
-function deflate_huff(s, flush) {
-  var bflush;             /* set if current block must be flushed */
-
-  for (;;) {
-    /* Make sure that we have a literal to write. */
-    if (s.lookahead === 0) {
-      fill_window(s);
-      if (s.lookahead === 0) {
-        if (flush === Z_NO_FLUSH) {
-          return BS_NEED_MORE;
-        }
-        break;      /* flush the current block */
-      }
-    }
-
-    /* Output a literal byte */
-    s.match_length = 0;
-    //Tracevv((stderr,"%c", s->window[s->strstart]));
-    /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
-    bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
-    s.lookahead--;
-    s.strstart++;
-    if (bflush) {
-      /*** FLUSH_BLOCK(s, 0); ***/
-      flush_block_only(s, false);
-      if (s.strm.avail_out === 0) {
-        return BS_NEED_MORE;
-      }
-      /***/
-    }
-  }
-  s.insert = 0;
-  if (flush === Z_FINISH) {
-    /*** FLUSH_BLOCK(s, 1); ***/
-    flush_block_only(s, true);
-    if (s.strm.avail_out === 0) {
-      return BS_FINISH_STARTED;
-    }
-    /***/
-    return BS_FINISH_DONE;
-  }
-  if (s.last_lit) {
-    /*** FLUSH_BLOCK(s, 0); ***/
-    flush_block_only(s, false);
-    if (s.strm.avail_out === 0) {
-      return BS_NEED_MORE;
-    }
-    /***/
-  }
-  return BS_BLOCK_DONE;
-}
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-function Config(good_length, max_lazy, nice_length, max_chain, func) {
-  this.good_length = good_length;
-  this.max_lazy = max_lazy;
-  this.nice_length = nice_length;
-  this.max_chain = max_chain;
-  this.func = func;
-}
-
-var configuration_table;
-
-configuration_table = [
-  /*      good lazy nice chain */
-  new Config(0, 0, 0, 0, deflate_stored),          /* 0 store only */
-  new Config(4, 4, 8, 4, deflate_fast),            /* 1 max speed, no lazy matches */
-  new Config(4, 5, 16, 8, deflate_fast),           /* 2 */
-  new Config(4, 6, 32, 32, deflate_fast),          /* 3 */
-
-  new Config(4, 4, 16, 16, deflate_slow),          /* 4 lazy matches */
-  new Config(8, 16, 32, 32, deflate_slow),         /* 5 */
-  new Config(8, 16, 128, 128, deflate_slow),       /* 6 */
-  new Config(8, 32, 128, 256, deflate_slow),       /* 7 */
-  new Config(32, 128, 258, 1024, deflate_slow),    /* 8 */
-  new Config(32, 258, 258, 4096, deflate_slow)     /* 9 max compression */
-];
-
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-function lm_init(s) {
-  s.window_size = 2 * s.w_size;
-
-  /*** CLEAR_HASH(s); ***/
-  zero(s.head); // Fill with NIL (= 0);
-
-  /* Set the default configuration parameters:
-   */
-  s.max_lazy_match = configuration_table[s.level].max_lazy;
-  s.good_match = configuration_table[s.level].good_length;
-  s.nice_match = configuration_table[s.level].nice_length;
-  s.max_chain_length = configuration_table[s.level].max_chain;
-
-  s.strstart = 0;
-  s.block_start = 0;
-  s.lookahead = 0;
-  s.insert = 0;
-  s.match_length = s.prev_length = MIN_MATCH - 1;
-  s.match_available = 0;
-  s.ins_h = 0;
-}
-
-
-function DeflateState() {
-  this.strm = null;            /* pointer back to this zlib stream */
-  this.status = 0;            /* as the name implies */
-  this.pending_buf = null;      /* output still pending */
-  this.pending_buf_size = 0;  /* size of pending_buf */
-  this.pending_out = 0;       /* next pending byte to output to the stream */
-  this.pending = 0;           /* nb of bytes in the pending buffer */
-  this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */
-  this.gzhead = null;         /* gzip header information to write */
-  this.gzindex = 0;           /* where in extra, name, or comment */
-  this.method = Z_DEFLATED; /* can only be DEFLATED */
-  this.last_flush = -1;   /* value of flush param for previous deflate call */
-
-  this.w_size = 0;  /* LZ77 window size (32K by default) */
-  this.w_bits = 0;  /* log2(w_size)  (8..16) */
-  this.w_mask = 0;  /* w_size - 1 */
-
-  this.window = null;
-  /* Sliding window. Input bytes are read into the second half of the window,
-   * and move to the first half later to keep a dictionary of at least wSize
-   * bytes. With this organization, matches are limited to a distance of
-   * wSize-MAX_MATCH bytes, but this ensures that IO is always
-   * performed with a length multiple of the block size.
-   */
-
-  this.window_size = 0;
-  /* Actual size of window: 2*wSize, except when the user input buffer
-   * is directly used as sliding window.
-   */
-
-  this.prev = null;
-  /* Link to older string with same hash index. To limit the size of this
-   * array to 64K, this link is maintained only for the last 32K strings.
-   * An index in this array is thus a window index modulo 32K.
-   */
-
-  this.head = null;   /* Heads of the hash chains or NIL. */
-
-  this.ins_h = 0;       /* hash index of string to be inserted */
-  this.hash_size = 0;   /* number of elements in hash table */
-  this.hash_bits = 0;   /* log2(hash_size) */
-  this.hash_mask = 0;   /* hash_size-1 */
-
-  this.hash_shift = 0;
-  /* Number of bits by which ins_h must be shifted at each input
-   * step. It must be such that after MIN_MATCH steps, the oldest
-   * byte no longer takes part in the hash key, that is:
-   *   hash_shift * MIN_MATCH >= hash_bits
-   */
-
-  this.block_start = 0;
-  /* Window position at the beginning of the current output block. Gets
-   * negative when the window is moved backwards.
-   */
-
-  this.match_length = 0;      /* length of best match */
-  this.prev_match = 0;        /* previous match */
-  this.match_available = 0;   /* set if previous match exists */
-  this.strstart = 0;          /* start of string to insert */
-  this.match_start = 0;       /* start of matching string */
-  this.lookahead = 0;         /* number of valid bytes ahead in window */
-
-  this.prev_length = 0;
-  /* Length of the best match at previous step. Matches not greater than this
-   * are discarded. This is used in the lazy match evaluation.
-   */
-
-  this.max_chain_length = 0;
-  /* To speed up deflation, hash chains are never searched beyond this
-   * length.  A higher limit improves compression ratio but degrades the
-   * speed.
-   */
-
-  this.max_lazy_match = 0;
-  /* Attempt to find a better match only when the current match is strictly
-   * smaller than this value. This mechanism is used only for compression
-   * levels >= 4.
-   */
-  // That's alias to max_lazy_match, don't use directly
-  //this.max_insert_length = 0;
-  /* Insert new strings in the hash table only if the match length is not
-   * greater than this length. This saves time but degrades compression.
-   * max_insert_length is used only for compression levels <= 3.
-   */
-
-  this.level = 0;     /* compression level (1..9) */
-  this.strategy = 0;  /* favor or force Huffman coding*/
-
-  this.good_match = 0;
-  /* Use a faster search when the previous match is longer than this */
-
-  this.nice_match = 0; /* Stop searching when current match exceeds this */
-
-              /* used by trees.c: */
-
-  /* Didn't use ct_data typedef below to suppress compiler warning */
-
-  // struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
-  // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
-  // struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
-
-  // Use flat array of DOUBLE size, with interleaved fata,
-  // because JS does not support effective
-  this.dyn_ltree  = new utils.Buf16(HEAP_SIZE * 2);
-  this.dyn_dtree  = new utils.Buf16((2 * D_CODES + 1) * 2);
-  this.bl_tree    = new utils.Buf16((2 * BL_CODES + 1) * 2);
-  zero(this.dyn_ltree);
-  zero(this.dyn_dtree);
-  zero(this.bl_tree);
-
-  this.l_desc   = null;         /* desc. for literal tree */
-  this.d_desc   = null;         /* desc. for distance tree */
-  this.bl_desc  = null;         /* desc. for bit length tree */
-
-  //ush bl_count[MAX_BITS+1];
-  this.bl_count = new utils.Buf16(MAX_BITS + 1);
-  /* number of codes at each bit length for an optimal tree */
-
-  //int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
-  this.heap = new utils.Buf16(2 * L_CODES + 1);  /* heap used to build the Huffman trees */
-  zero(this.heap);
-
-  this.heap_len = 0;               /* number of elements in the heap */
-  this.heap_max = 0;               /* element of largest frequency */
-  /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-   * The same heap array is used to build all trees.
-   */
-
-  this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1];
-  zero(this.depth);
-  /* Depth of each subtree used as tie breaker for trees of equal frequency
-   */
-
-  this.l_buf = 0;          /* buffer index for literals or lengths */
-
-  this.lit_bufsize = 0;
-  /* Size of match buffer for literals/lengths.  There are 4 reasons for
-   * limiting lit_bufsize to 64K:
-   *   - frequencies can be kept in 16 bit counters
-   *   - if compression is not successful for the first block, all input
-   *     data is still in the window so we can still emit a stored block even
-   *     when input comes from standard input.  (This can also be done for
-   *     all blocks if lit_bufsize is not greater than 32K.)
-   *   - if compression is not successful for a file smaller than 64K, we can
-   *     even emit a stored file instead of a stored block (saving 5 bytes).
-   *     This is applicable only for zip (not gzip or zlib).
-   *   - creating new Huffman trees less frequently may not provide fast
-   *     adaptation to changes in the input data statistics. (Take for
-   *     example a binary file with poorly compressible code followed by
-   *     a highly compressible string table.) Smaller buffer sizes give
-   *     fast adaptation but have of course the overhead of transmitting
-   *     trees more frequently.
-   *   - I can't count above 4
-   */
-
-  this.last_lit = 0;      /* running index in l_buf */
-
-  this.d_buf = 0;
-  /* Buffer index for distances. To simplify the code, d_buf and l_buf have
-   * the same number of elements. To use different lengths, an extra flag
-   * array would be necessary.
-   */
-
-  this.opt_len = 0;       /* bit length of current block with optimal trees */
-  this.static_len = 0;    /* bit length of current block with static trees */
-  this.matches = 0;       /* number of string matches in current block */
-  this.insert = 0;        /* bytes at end of window left to insert */
-
-
-  this.bi_buf = 0;
-  /* Output buffer. bits are inserted starting at the bottom (least
-   * significant bits).
-   */
-  this.bi_valid = 0;
-  /* Number of valid bits in bi_buf.  All bits above the last valid bit
-   * are always zero.
-   */
-
-  // Used for window memory init. We safely ignore it for JS. That makes
-  // sense only for pointers and memory check tools.
-  //this.high_water = 0;
-  /* High water mark offset in window for initialized bytes -- bytes above
-   * this are set to zero in order to avoid memory check warnings when
-   * longest match routines access bytes past the input.  This is then
-   * updated to the new high water mark.
-   */
-}
-
-
-function deflateResetKeep(strm) {
-  var s;
-
-  if (!strm || !strm.state) {
-    return err(strm, Z_STREAM_ERROR);
-  }
-
-  strm.total_in = strm.total_out = 0;
-  strm.data_type = Z_UNKNOWN;
-
-  s = strm.state;
-  s.pending = 0;
-  s.pending_out = 0;
-
-  if (s.wrap < 0) {
-    s.wrap = -s.wrap;
-    /* was made negative by deflate(..., Z_FINISH); */
-  }
-  s.status = (s.wrap ? INIT_STATE : BUSY_STATE);
-  strm.adler = (s.wrap === 2) ?
-    0  // crc32(0, Z_NULL, 0)
-  :
-    1; // adler32(0, Z_NULL, 0)
-  s.last_flush = Z_NO_FLUSH;
-  trees._tr_init(s);
-  return Z_OK;
-}
-
-
-function deflateReset(strm) {
-  var ret = deflateResetKeep(strm);
-  if (ret === Z_OK) {
-    lm_init(strm.state);
-  }
-  return ret;
-}
-
-
-function deflateSetHeader(strm, head) {
-  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
-  if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }
-  strm.state.gzhead = head;
-  return Z_OK;
-}
-
-
-function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
-  if (!strm) { // === Z_NULL
-    return Z_STREAM_ERROR;
-  }
-  var wrap = 1;
-
-  if (level === Z_DEFAULT_COMPRESSION) {
-    level = 6;
-  }
-
-  if (windowBits < 0) { /* suppress zlib wrapper */
-    wrap = 0;
-    windowBits = -windowBits;
-  }
-
-  else if (windowBits > 15) {
-    wrap = 2;           /* write gzip wrapper instead */
-    windowBits -= 16;
-  }
-
-
-  if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||
-    windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
-    strategy < 0 || strategy > Z_FIXED) {
-    return err(strm, Z_STREAM_ERROR);
-  }
-
-
-  if (windowBits === 8) {
-    windowBits = 9;
-  }
-  /* until 256-byte window bug fixed */
-
-  var s = new DeflateState();
-
-  strm.state = s;
-  s.strm = strm;
-
-  s.wrap = wrap;
-  s.gzhead = null;
-  s.w_bits = windowBits;
-  s.w_size = 1 << s.w_bits;
-  s.w_mask = s.w_size - 1;
-
-  s.hash_bits = memLevel + 7;
-  s.hash_size = 1 << s.hash_bits;
-  s.hash_mask = s.hash_size - 1;
-  s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);
-
-  s.window = new utils.Buf8(s.w_size * 2);
-  s.head = new utils.Buf16(s.hash_size);
-  s.prev = new utils.Buf16(s.w_size);
-
-  // Don't need mem init magic for JS.
-  //s.high_water = 0;  /* nothing written to s->window yet */
-
-  s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
-  s.pending_buf_size = s.lit_bufsize * 4;
-
-  //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
-  //s->pending_buf = (uchf *) overlay;
-  s.pending_buf = new utils.Buf8(s.pending_buf_size);
-
-  // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
-  //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
-  s.d_buf = 1 * s.lit_bufsize;
-
-  //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-  s.l_buf = (1 + 2) * s.lit_bufsize;
-
-  s.level = level;
-  s.strategy = strategy;
-  s.method = method;
-
-  return deflateReset(strm);
-}
-
-function deflateInit(strm, level) {
-  return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-}
-
-
-function deflate(strm, flush) {
-  var old_flush, s;
-  var beg, val; // for gzip header write only
-
-  if (!strm || !strm.state ||
-    flush > Z_BLOCK || flush < 0) {
-    return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
-  }
-
-  s = strm.state;
-
-  if (!strm.output ||
-      (!strm.input && strm.avail_in !== 0) ||
-      (s.status === FINISH_STATE && flush !== Z_FINISH)) {
-    return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);
-  }
-
-  s.strm = strm; /* just in case */
-  old_flush = s.last_flush;
-  s.last_flush = flush;
-
-  /* Write the header */
-  if (s.status === INIT_STATE) {
-
-    if (s.wrap === 2) { // GZIP header
-      strm.adler = 0;  //crc32(0L, Z_NULL, 0);
-      put_byte(s, 31);
-      put_byte(s, 139);
-      put_byte(s, 8);
-      if (!s.gzhead) { // s->gzhead == Z_NULL
-        put_byte(s, 0);
-        put_byte(s, 0);
-        put_byte(s, 0);
-        put_byte(s, 0);
-        put_byte(s, 0);
-        put_byte(s, s.level === 9 ? 2 :
-                    (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
-                     4 : 0));
-        put_byte(s, OS_CODE);
-        s.status = BUSY_STATE;
-      }
-      else {
-        put_byte(s, (s.gzhead.text ? 1 : 0) +
-                    (s.gzhead.hcrc ? 2 : 0) +
-                    (!s.gzhead.extra ? 0 : 4) +
-                    (!s.gzhead.name ? 0 : 8) +
-                    (!s.gzhead.comment ? 0 : 16)
-                );
-        put_byte(s, s.gzhead.time & 0xff);
-        put_byte(s, (s.gzhead.time >> 8) & 0xff);
-        put_byte(s, (s.gzhead.time >> 16) & 0xff);
-        put_byte(s, (s.gzhead.time >> 24) & 0xff);
-        put_byte(s, s.level === 9 ? 2 :
-                    (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
-                     4 : 0));
-        put_byte(s, s.gzhead.os & 0xff);
-        if (s.gzhead.extra && s.gzhead.extra.length) {
-          put_byte(s, s.gzhead.extra.length & 0xff);
-          put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);
-        }
-        if (s.gzhead.hcrc) {
-          strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
-        }
-        s.gzindex = 0;
-        s.status = EXTRA_STATE;
-      }
-    }
-    else // DEFLATE header
-    {
-      var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;
-      var level_flags = -1;
-
-      if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
-        level_flags = 0;
-      } else if (s.level < 6) {
-        level_flags = 1;
-      } else if (s.level === 6) {
-        level_flags = 2;
-      } else {
-        level_flags = 3;
-      }
-      header |= (level_flags << 6);
-      if (s.strstart !== 0) { header |= PRESET_DICT; }
-      header += 31 - (header % 31);
-
-      s.status = BUSY_STATE;
-      putShortMSB(s, header);
-
-      /* Save the adler32 of the preset dictionary: */
-      if (s.strstart !== 0) {
-        putShortMSB(s, strm.adler >>> 16);
-        putShortMSB(s, strm.adler & 0xffff);
-      }
-      strm.adler = 1; // adler32(0L, Z_NULL, 0);
-    }
-  }
-
-//#ifdef GZIP
-  if (s.status === EXTRA_STATE) {
-    if (s.gzhead.extra/* != Z_NULL*/) {
-      beg = s.pending;  /* start of bytes to update crc */
-
-      while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
-        if (s.pending === s.pending_buf_size) {
-          if (s.gzhead.hcrc && s.pending > beg) {
-            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
-          }
-          flush_pending(strm);
-          beg = s.pending;
-          if (s.pending === s.pending_buf_size) {
-            break;
-          }
-        }
-        put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
-        s.gzindex++;
-      }
-      if (s.gzhead.hcrc && s.pending > beg) {
-        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
-      }
-      if (s.gzindex === s.gzhead.extra.length) {
-        s.gzindex = 0;
-        s.status = NAME_STATE;
-      }
-    }
-    else {
-      s.status = NAME_STATE;
-    }
-  }
-  if (s.status === NAME_STATE) {
-    if (s.gzhead.name/* != Z_NULL*/) {
-      beg = s.pending;  /* start of bytes to update crc */
-      //int val;
-
-      do {
-        if (s.pending === s.pending_buf_size) {
-          if (s.gzhead.hcrc && s.pending > beg) {
-            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
-          }
-          flush_pending(strm);
-          beg = s.pending;
-          if (s.pending === s.pending_buf_size) {
-            val = 1;
-            break;
-          }
-        }
-        // JS specific: little magic to add zero terminator to end of string
-        if (s.gzindex < s.gzhead.name.length) {
-          val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
-        } else {
-          val = 0;
-        }
-        put_byte(s, val);
-      } while (val !== 0);
-
-      if (s.gzhead.hcrc && s.pending > beg) {
-        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
-      }
-      if (val === 0) {
-        s.gzindex = 0;
-        s.status = COMMENT_STATE;
-      }
-    }
-    else {
-      s.status = COMMENT_STATE;
-    }
-  }
-  if (s.status === COMMENT_STATE) {
-    if (s.gzhead.comment/* != Z_NULL*/) {
-      beg = s.pending;  /* start of bytes to update crc */
-      //int val;
-
-      do {
-        if (s.pending === s.pending_buf_size) {
-          if (s.gzhead.hcrc && s.pending > beg) {
-            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
-          }
-          flush_pending(strm);
-          beg = s.pending;
-          if (s.pending === s.pending_buf_size) {
-            val = 1;
-            break;
-          }
-        }
-        // JS specific: little magic to add zero terminator to end of string
-        if (s.gzindex < s.gzhead.comment.length) {
-          val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
-        } else {
-          val = 0;
-        }
-        put_byte(s, val);
-      } while (val !== 0);
-
-      if (s.gzhead.hcrc && s.pending > beg) {
-        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
-      }
-      if (val === 0) {
-        s.status = HCRC_STATE;
-      }
-    }
-    else {
-      s.status = HCRC_STATE;
-    }
-  }
-  if (s.status === HCRC_STATE) {
-    if (s.gzhead.hcrc) {
-      if (s.pending + 2 > s.pending_buf_size) {
-        flush_pending(strm);
-      }
-      if (s.pending + 2 <= s.pending_buf_size) {
-        put_byte(s, strm.adler & 0xff);
-        put_byte(s, (strm.adler >> 8) & 0xff);
-        strm.adler = 0; //crc32(0L, Z_NULL, 0);
-        s.status = BUSY_STATE;
-      }
-    }
-    else {
-      s.status = BUSY_STATE;
-    }
-  }
-//#endif
-
-  /* Flush as much pending output as possible */
-  if (s.pending !== 0) {
-    flush_pending(strm);
-    if (strm.avail_out === 0) {
-      /* Since avail_out is 0, deflate will be called again with
-       * more output space, but possibly with both pending and
-       * avail_in equal to zero. There won't be anything to do,
-       * but this is not an error situation so make sure we
-       * return OK instead of BUF_ERROR at next call of deflate:
-       */
-      s.last_flush = -1;
-      return Z_OK;
-    }
-
-    /* Make sure there is something to do and avoid duplicate consecutive
-     * flushes. For repeated and useless calls with Z_FINISH, we keep
-     * returning Z_STREAM_END instead of Z_BUF_ERROR.
-     */
-  } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&
-    flush !== Z_FINISH) {
-    return err(strm, Z_BUF_ERROR);
-  }
-
-  /* User must not provide more input after the first FINISH: */
-  if (s.status === FINISH_STATE && strm.avail_in !== 0) {
-    return err(strm, Z_BUF_ERROR);
-  }
-
-  /* Start a new block or continue the current one.
-   */
-  if (strm.avail_in !== 0 || s.lookahead !== 0 ||
-    (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {
-    var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :
-      (s.strategy === Z_RLE ? deflate_rle(s, flush) :
-        configuration_table[s.level].func(s, flush));
-
-    if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
-      s.status = FINISH_STATE;
-    }
-    if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
-      if (strm.avail_out === 0) {
-        s.last_flush = -1;
-        /* avoid BUF_ERROR next call, see above */
-      }
-      return Z_OK;
-      /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
-       * of deflate should use the same flush parameter to make sure
-       * that the flush is complete. So we don't have to output an
-       * empty block here, this will be done at next call. This also
-       * ensures that for a very small output buffer, we emit at most
-       * one empty block.
-       */
-    }
-    if (bstate === BS_BLOCK_DONE) {
-      if (flush === Z_PARTIAL_FLUSH) {
-        trees._tr_align(s);
-      }
-      else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
-
-        trees._tr_stored_block(s, 0, 0, false);
-        /* For a full flush, this empty block will be recognized
-         * as a special marker by inflate_sync().
-         */
-        if (flush === Z_FULL_FLUSH) {
-          /*** CLEAR_HASH(s); ***/             /* forget history */
-          zero(s.head); // Fill with NIL (= 0);
-
-          if (s.lookahead === 0) {
-            s.strstart = 0;
-            s.block_start = 0;
-            s.insert = 0;
-          }
-        }
-      }
-      flush_pending(strm);
-      if (strm.avail_out === 0) {
-        s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */
-        return Z_OK;
-      }
-    }
-  }
-  //Assert(strm->avail_out > 0, "bug2");
-  //if (strm.avail_out <= 0) { throw new Error("bug2");}
-
-  if (flush !== Z_FINISH) { return Z_OK; }
-  if (s.wrap <= 0) { return Z_STREAM_END; }
-
-  /* Write the trailer */
-  if (s.wrap === 2) {
-    put_byte(s, strm.adler & 0xff);
-    put_byte(s, (strm.adler >> 8) & 0xff);
-    put_byte(s, (strm.adler >> 16) & 0xff);
-    put_byte(s, (strm.adler >> 24) & 0xff);
-    put_byte(s, strm.total_in & 0xff);
-    put_byte(s, (strm.total_in >> 8) & 0xff);
-    put_byte(s, (strm.total_in >> 16) & 0xff);
-    put_byte(s, (strm.total_in >> 24) & 0xff);
-  }
-  else
-  {
-    putShortMSB(s, strm.adler >>> 16);
-    putShortMSB(s, strm.adler & 0xffff);
-  }
-
-  flush_pending(strm);
-  /* If avail_out is zero, the application will call deflate again
-   * to flush the rest.
-   */
-  if (s.wrap > 0) { s.wrap = -s.wrap; }
-  /* write the trailer only once! */
-  return s.pending !== 0 ? Z_OK : Z_STREAM_END;
-}
-
-function deflateEnd(strm) {
-  var status;
-
-  if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
-    return Z_STREAM_ERROR;
-  }
-
-  status = strm.state.status;
-  if (status !== INIT_STATE &&
-    status !== EXTRA_STATE &&
-    status !== NAME_STATE &&
-    status !== COMMENT_STATE &&
-    status !== HCRC_STATE &&
-    status !== BUSY_STATE &&
-    status !== FINISH_STATE
-  ) {
-    return err(strm, Z_STREAM_ERROR);
-  }
-
-  strm.state = null;
-
-  return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
-}
-
-
-/* =========================================================================
- * Initializes the compression dictionary from the given byte
- * sequence without producing any compressed output.
- */
-function deflateSetDictionary(strm, dictionary) {
-  var dictLength = dictionary.length;
-
-  var s;
-  var str, n;
-  var wrap;
-  var avail;
-  var next;
-  var input;
-  var tmpDict;
-
-  if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
-    return Z_STREAM_ERROR;
-  }
-
-  s = strm.state;
-  wrap = s.wrap;
-
-  if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {
-    return Z_STREAM_ERROR;
-  }
-
-  /* when using zlib wrappers, compute Adler-32 for provided dictionary */
-  if (wrap === 1) {
-    /* adler32(strm->adler, dictionary, dictLength); */
-    strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
-  }
-
-  s.wrap = 0;   /* avoid computing Adler-32 in read_buf */
-
-  /* if dictionary would fill window, just replace the history */
-  if (dictLength >= s.w_size) {
-    if (wrap === 0) {            /* already empty otherwise */
-      /*** CLEAR_HASH(s); ***/
-      zero(s.head); // Fill with NIL (= 0);
-      s.strstart = 0;
-      s.block_start = 0;
-      s.insert = 0;
-    }
-    /* use the tail */
-    // dictionary = dictionary.slice(dictLength - s.w_size);
-    tmpDict = new utils.Buf8(s.w_size);
-    utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
-    dictionary = tmpDict;
-    dictLength = s.w_size;
-  }
-  /* insert dictionary into window and hash */
-  avail = strm.avail_in;
-  next = strm.next_in;
-  input = strm.input;
-  strm.avail_in = dictLength;
-  strm.next_in = 0;
-  strm.input = dictionary;
-  fill_window(s);
-  while (s.lookahead >= MIN_MATCH) {
-    str = s.strstart;
-    n = s.lookahead - (MIN_MATCH - 1);
-    do {
-      /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
-      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
-
-      s.prev[str & s.w_mask] = s.head[s.ins_h];
-
-      s.head[s.ins_h] = str;
-      str++;
-    } while (--n);
-    s.strstart = str;
-    s.lookahead = MIN_MATCH - 1;
-    fill_window(s);
-  }
-  s.strstart += s.lookahead;
-  s.block_start = s.strstart;
-  s.insert = s.lookahead;
-  s.lookahead = 0;
-  s.match_length = s.prev_length = MIN_MATCH - 1;
-  s.match_available = 0;
-  strm.next_in = next;
-  strm.input = input;
-  strm.avail_in = avail;
-  s.wrap = wrap;
-  return Z_OK;
-}
-
-
-exports.deflateInit = deflateInit;
-exports.deflateInit2 = deflateInit2;
-exports.deflateReset = deflateReset;
-exports.deflateResetKeep = deflateResetKeep;
-exports.deflateSetHeader = deflateSetHeader;
-exports.deflate = deflate;
-exports.deflateEnd = deflateEnd;
-exports.deflateSetDictionary = deflateSetDictionary;
-exports.deflateInfo = 'pako deflate (from Nodeca project)';
-
-/* Not implemented
-exports.deflateBound = deflateBound;
-exports.deflateCopy = deflateCopy;
-exports.deflateParams = deflateParams;
-exports.deflatePending = deflatePending;
-exports.deflatePrime = deflatePrime;
-exports.deflateTune = deflateTune;
-*/
-
-
-/***/ }),
-/* 130 */
-/*!******************************************!*\
-  !*** ./node_modules/pako/lib/deflate.js ***!
-  \******************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-
-var zlib_deflate = __webpack_require__(/*! ./zlib/deflate */ 129);
-var utils        = __webpack_require__(/*! ./utils/common */ 46);
-var strings      = __webpack_require__(/*! ./utils/strings */ 86);
-var msg          = __webpack_require__(/*! ./zlib/messages */ 69);
-var ZStream      = __webpack_require__(/*! ./zlib/zstream */ 85);
-
-var toString = Object.prototype.toString;
-
-/* Public constants ==========================================================*/
-/* ===========================================================================*/
-
-var Z_NO_FLUSH      = 0;
-var Z_FINISH        = 4;
-
-var Z_OK            = 0;
-var Z_STREAM_END    = 1;
-var Z_SYNC_FLUSH    = 2;
-
-var Z_DEFAULT_COMPRESSION = -1;
-
-var Z_DEFAULT_STRATEGY    = 0;
-
-var Z_DEFLATED  = 8;
-
-/* ===========================================================================*/
-
-
-/**
- * class Deflate
- *
- * Generic JS-style wrapper for zlib calls. If you don't need
- * streaming behaviour - use more simple functions: [[deflate]],
- * [[deflateRaw]] and [[gzip]].
- **/
-
-/* internal
- * Deflate.chunks -> Array
- *
- * Chunks of output data, if [[Deflate#onData]] not overridden.
- **/
-
-/**
- * Deflate.result -> Uint8Array|Array
- *
- * Compressed result, generated by default [[Deflate#onData]]
- * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
- * (call [[Deflate#push]] with `Z_FINISH` / `true` param)  or if you
- * push a chunk with explicit flush (call [[Deflate#push]] with
- * `Z_SYNC_FLUSH` param).
- **/
-
-/**
- * Deflate.err -> Number
- *
- * Error code after deflate finished. 0 (Z_OK) on success.
- * You will not need it in real life, because deflate errors
- * are possible only on wrong options or bad `onData` / `onEnd`
- * custom handlers.
- **/
-
-/**
- * Deflate.msg -> String
- *
- * Error message, if [[Deflate.err]] != 0
- **/
-
-
-/**
- * new Deflate(options)
- * - options (Object): zlib deflate options.
- *
- * Creates new deflator instance with specified params. Throws exception
- * on bad params. Supported options:
- *
- * - `level`
- * - `windowBits`
- * - `memLevel`
- * - `strategy`
- * - `dictionary`
- *
- * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
- * for more information on these.
- *
- * Additional options, for internal needs:
- *
- * - `chunkSize` - size of generated data chunks (16K by default)
- * - `raw` (Boolean) - do raw deflate
- * - `gzip` (Boolean) - create gzip wrapper
- * - `to` (String) - if equal to 'string', then result will be "binary string"
- *    (each char code [0..255])
- * - `header` (Object) - custom header for gzip
- *   - `text` (Boolean) - true if compressed data believed to be text
- *   - `time` (Number) - modification time, unix timestamp
- *   - `os` (Number) - operation system code
- *   - `extra` (Array) - array of bytes with extra data (max 65536)
- *   - `name` (String) - file name (binary string)
- *   - `comment` (String) - comment (binary string)
- *   - `hcrc` (Boolean) - true if header crc should be added
- *
- * ##### Example:
- *
- * ```javascript
- * var pako = require('pako')
- *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
- *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
- *
- * var deflate = new pako.Deflate({ level: 3});
- *
- * deflate.push(chunk1, false);
- * deflate.push(chunk2, true);  // true -> last chunk
- *
- * if (deflate.err) { throw new Error(deflate.err); }
- *
- * console.log(deflate.result);
- * ```
- **/
-function Deflate(options) {
-  if (!(this instanceof Deflate)) return new Deflate(options);
-
-  this.options = utils.assign({
-    level: Z_DEFAULT_COMPRESSION,
-    method: Z_DEFLATED,
-    chunkSize: 16384,
-    windowBits: 15,
-    memLevel: 8,
-    strategy: Z_DEFAULT_STRATEGY,
-    to: ''
-  }, options || {});
-
-  var opt = this.options;
-
-  if (opt.raw && (opt.windowBits > 0)) {
-    opt.windowBits = -opt.windowBits;
-  }
-
-  else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
-    opt.windowBits += 16;
-  }
-
-  this.err    = 0;      // error code, if happens (0 = Z_OK)
-  this.msg    = '';     // error message
-  this.ended  = false;  // used to avoid multiple onEnd() calls
-  this.chunks = [];     // chunks of compressed data
-
-  this.strm = new ZStream();
-  this.strm.avail_out = 0;
-
-  var status = zlib_deflate.deflateInit2(
-    this.strm,
-    opt.level,
-    opt.method,
-    opt.windowBits,
-    opt.memLevel,
-    opt.strategy
-  );
-
-  if (status !== Z_OK) {
-    throw new Error(msg[status]);
-  }
-
-  if (opt.header) {
-    zlib_deflate.deflateSetHeader(this.strm, opt.header);
-  }
-
-  if (opt.dictionary) {
-    var dict;
-    // Convert data if needed
-    if (typeof opt.dictionary === 'string') {
-      // If we need to compress text, change encoding to utf8.
-      dict = strings.string2buf(opt.dictionary);
-    } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {
-      dict = new Uint8Array(opt.dictionary);
-    } else {
-      dict = opt.dictionary;
-    }
-
-    status = zlib_deflate.deflateSetDictionary(this.strm, dict);
-
-    if (status !== Z_OK) {
-      throw new Error(msg[status]);
-    }
-
-    this._dict_set = true;
-  }
-}
-
-/**
- * Deflate#push(data[, mode]) -> Boolean
- * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be
- *   converted to utf8 byte sequence.
- * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
- *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
- *
- * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
- * new compressed chunks. Returns `true` on success. The last data block must have
- * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
- * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you
- * can use mode Z_SYNC_FLUSH, keeping the compression context.
- *
- * On fail call [[Deflate#onEnd]] with error code and return false.
- *
- * We strongly recommend to use `Uint8Array` on input for best speed (output
- * array format is detected automatically). Also, don't skip last param and always
- * use the same type in your code (boolean or number). That will improve JS speed.
- *
- * For regular `Array`-s make sure all elements are [0..255].
- *
- * ##### Example
- *
- * ```javascript
- * push(chunk, false); // push one of data chunks
- * ...
- * push(chunk, true);  // push last chunk
- * ```
- **/
-Deflate.prototype.push = function (data, mode) {
-  var strm = this.strm;
-  var chunkSize = this.options.chunkSize;
-  var status, _mode;
-
-  if (this.ended) { return false; }
-
-  _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
-
-  // Convert data if needed
-  if (typeof data === 'string') {
-    // If we need to compress text, change encoding to utf8.
-    strm.input = strings.string2buf(data);
-  } else if (toString.call(data) === '[object ArrayBuffer]') {
-    strm.input = new Uint8Array(data);
-  } else {
-    strm.input = data;
-  }
-
-  strm.next_in = 0;
-  strm.avail_in = strm.input.length;
-
-  do {
-    if (strm.avail_out === 0) {
-      strm.output = new utils.Buf8(chunkSize);
-      strm.next_out = 0;
-      strm.avail_out = chunkSize;
-    }
-    status = zlib_deflate.deflate(strm, _mode);    /* no bad return value */
-
-    if (status !== Z_STREAM_END && status !== Z_OK) {
-      this.onEnd(status);
-      this.ended = true;
-      return false;
-    }
-    if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
-      if (this.options.to === 'string') {
-        this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
-      } else {
-        this.onData(utils.shrinkBuf(strm.output, strm.next_out));
-      }
-    }
-  } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
-
-  // Finalize on the last chunk.
-  if (_mode === Z_FINISH) {
-    status = zlib_deflate.deflateEnd(this.strm);
-    this.onEnd(status);
-    this.ended = true;
-    return status === Z_OK;
-  }
-
-  // callback interim results if Z_SYNC_FLUSH.
-  if (_mode === Z_SYNC_FLUSH) {
-    this.onEnd(Z_OK);
-    strm.avail_out = 0;
-    return true;
-  }
-
-  return true;
-};
-
-
-/**
- * Deflate#onData(chunk) -> Void
- * - chunk (Uint8Array|Array|String): output data. Type of array depends
- *   on js engine support. When string output requested, each chunk
- *   will be string.
- *
- * By default, stores data blocks in `chunks[]` property and glue
- * those in `onEnd`. Override this handler, if you need another behaviour.
- **/
-Deflate.prototype.onData = function (chunk) {
-  this.chunks.push(chunk);
-};
-
-
-/**
- * Deflate#onEnd(status) -> Void
- * - status (Number): deflate status. 0 (Z_OK) on success,
- *   other if not.
- *
- * Called once after you tell deflate that the input stream is
- * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
- * or if an error happened. By default - join collected chunks,
- * free memory and fill `results` / `err` properties.
- **/
-Deflate.prototype.onEnd = function (status) {
-  // On success - join
-  if (status === Z_OK) {
-    if (this.options.to === 'string') {
-      this.result = this.chunks.join('');
-    } else {
-      this.result = utils.flattenChunks(this.chunks);
-    }
-  }
-  this.chunks = [];
-  this.err = status;
-  this.msg = this.strm.msg;
-};
-
-
-/**
- * deflate(data[, options]) -> Uint8Array|Array|String
- * - data (Uint8Array|Array|String): input data to compress.
- * - options (Object): zlib deflate options.
- *
- * Compress `data` with deflate algorithm and `options`.
- *
- * Supported options are:
- *
- * - level
- * - windowBits
- * - memLevel
- * - strategy
- * - dictionary
- *
- * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
- * for more information on these.
- *
- * Sugar (options):
- *
- * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
- *   negative windowBits implicitly.
- * - `to` (String) - if equal to 'string', then result will be "binary string"
- *    (each char code [0..255])
- *
- * ##### Example:
- *
- * ```javascript
- * var pako = require('pako')
- *   , data = Uint8Array([1,2,3,4,5,6,7,8,9]);
- *
- * console.log(pako.deflate(data));
- * ```
- **/
-function deflate(input, options) {
-  var deflator = new Deflate(options);
-
-  deflator.push(input, true);
-
-  // That will never happens, if you don't cheat with options :)
-  if (deflator.err) { throw deflator.msg || msg[deflator.err]; }
-
-  return deflator.result;
-}
-
-
-/**
- * deflateRaw(data[, options]) -> Uint8Array|Array|String
- * - data (Uint8Array|Array|String): input data to compress.
- * - options (Object): zlib deflate options.
- *
- * The same as [[deflate]], but creates raw data, without wrapper
- * (header and adler32 crc).
- **/
-function deflateRaw(input, options) {
-  options = options || {};
-  options.raw = true;
-  return deflate(input, options);
-}
-
-
-/**
- * gzip(data[, options]) -> Uint8Array|Array|String
- * - data (Uint8Array|Array|String): input data to compress.
- * - options (Object): zlib deflate options.
- *
- * The same as [[deflate]], but create gzip wrapper instead of
- * deflate one.
- **/
-function gzip(input, options) {
-  options = options || {};
-  options.gzip = true;
-  return deflate(input, options);
-}
-
-
-exports.Deflate = Deflate;
-exports.deflate = deflate;
-exports.deflateRaw = deflateRaw;
-exports.gzip = gzip;
-
-
-/***/ }),
-/* 131 */
-/*!************************************!*\
-  !*** ./node_modules/pako/index.js ***!
-  \************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-// Top level file is just a mixin of submodules & constants
-
-
-var assign    = __webpack_require__(/*! ./lib/utils/common */ 46).assign;
-
-var deflate   = __webpack_require__(/*! ./lib/deflate */ 130);
-var inflate   = __webpack_require__(/*! ./lib/inflate */ 127);
-var constants = __webpack_require__(/*! ./lib/zlib/constants */ 84);
-
-var pako = {};
-
-assign(pako, deflate, inflate, constants);
-
-module.exports = pako;
-
-
-/***/ }),
-/* 132 */
-/*!*****************************************!*\
-  !*** ./node_modules/jszip/lib/flate.js ***!
-  \*****************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined');
-
-var pako = __webpack_require__(/*! pako */ 131);
-var utils = __webpack_require__(/*! ./utils */ 31);
-var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ 37);
-
-var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array";
-
-exports.magic = "\x08\x00";
-
-/**
- * Create a worker that uses pako to inflate/deflate.
- * @constructor
- * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate".
- * @param {Object} options the options to use when (de)compressing.
- */
-function FlateWorker(action, options) {
-    GenericWorker.call(this, "FlateWorker/" + action);
-
-    this._pako = null;
-    this._pakoAction = action;
-    this._pakoOptions = options;
-    // the `meta` object from the last chunk received
-    // this allow this worker to pass around metadata
-    this.meta = {};
-}
-
-utils.inherits(FlateWorker, GenericWorker);
-
-/**
- * @see GenericWorker.processChunk
- */
-FlateWorker.prototype.processChunk = function (chunk) {
-    this.meta = chunk.meta;
-    if (this._pako === null) {
-        this._createPako();
-    }
-    this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false);
-};
-
-/**
- * @see GenericWorker.flush
- */
-FlateWorker.prototype.flush = function () {
-    GenericWorker.prototype.flush.call(this);
-    if (this._pako === null) {
-        this._createPako();
-    }
-    this._pako.push([], true);
-};
-/**
- * @see GenericWorker.cleanUp
- */
-FlateWorker.prototype.cleanUp = function () {
-    GenericWorker.prototype.cleanUp.call(this);
-    this._pako = null;
-};
-
-/**
- * Create the _pako object.
- * TODO: lazy-loading this object isn't the best solution but it's the
- * quickest. The best solution is to lazy-load the worker list. See also the
- * issue #446.
- */
-FlateWorker.prototype._createPako = function () {
-    this._pako = new pako[this._pakoAction]({
-        raw: true,
-        level: this._pakoOptions.level || -1 // default compression
-    });
-    var self = this;
-    this._pako.onData = function(data) {
-        self.push({
-            data : data,
-            meta : self.meta
-        });
-    };
-};
-
-exports.compressWorker = function (compressionOptions) {
-    return new FlateWorker("Deflate", compressionOptions);
-};
-exports.uncompressWorker = function () {
-    return new FlateWorker("Inflate", {});
-};
-
-
-/***/ }),
-/* 133 */
-/*!**************************************************!*\
-  !*** ./node_modules/jszip/lib/generate/index.js ***!
-  \**************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-var compressions = __webpack_require__(/*! ../compressions */ 89);
-var ZipFileWorker = __webpack_require__(/*! ./ZipFileWorker */ 122);
-
-/**
- * Find the compression to use.
- * @param {String} fileCompression the compression defined at the file level, if any.
- * @param {String} zipCompression the compression defined at the load() level.
- * @return {Object} the compression object to use.
- */
-var getCompression = function (fileCompression, zipCompression) {
-
-    var compressionName = fileCompression || zipCompression;
-    var compression = compressions[compressionName];
-    if (!compression) {
-        throw new Error(compressionName + " is not a valid compression method !");
-    }
-    return compression;
-};
-
-/**
- * Create a worker to generate a zip file.
- * @param {JSZip} zip the JSZip instance at the right root level.
- * @param {Object} options to generate the zip file.
- * @param {String} comment the comment to use.
- */
-exports.generateWorker = function (zip, options, comment) {
-
-    var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName);
-    var entriesCount = 0;
-    try {
-
-        zip.forEach(function (relativePath, file) {
-            entriesCount++;
-            var compression = getCompression(file.options.compression, options.compression);
-            var compressionOptions = file.options.compressionOptions || options.compressionOptions || {};
-            var dir = file.dir, date = file.date;
-
-            file._compressWorker(compression, compressionOptions)
-            .withStreamInfo("file", {
-                name : relativePath,
-                dir : dir,
-                date : date,
-                comment : file.comment || "",
-                unixPermissions : file.unixPermissions,
-                dosPermissions : file.dosPermissions
-            })
-            .pipe(zipFileWorker);
-        });
-        zipFileWorker.entriesCount = entriesCount;
-    } catch (e) {
-        zipFileWorker.error(e);
-    }
-
-    return zipFileWorker;
-};
-
-
-/***/ }),
-/* 134 */
-/*!*********************************************!*\
-  !*** ./node_modules/jszip/lib/zipObject.js ***!
-  \*********************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-var StreamHelper = __webpack_require__(/*! ./stream/StreamHelper */ 94);
-var DataWorker = __webpack_require__(/*! ./stream/DataWorker */ 92);
-var utf8 = __webpack_require__(/*! ./utf8 */ 56);
-var CompressedObject = __webpack_require__(/*! ./compressedObject */ 71);
-var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ 37);
-
-/**
- * A simple object representing a file in the zip file.
- * @constructor
- * @param {string} name the name of the file
- * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data
- * @param {Object} options the options of the file
- */
-var ZipObject = function(name, data, options) {
-    this.name = name;
-    this.dir = options.dir;
-    this.date = options.date;
-    this.comment = options.comment;
-    this.unixPermissions = options.unixPermissions;
-    this.dosPermissions = options.dosPermissions;
-
-    this._data = data;
-    this._dataBinary = options.binary;
-    // keep only the compression
-    this.options = {
-        compression : options.compression,
-        compressionOptions : options.compressionOptions
-    };
-};
-
-ZipObject.prototype = {
-    /**
-     * Create an internal stream for the content of this object.
-     * @param {String} type the type of each chunk.
-     * @return StreamHelper the stream.
-     */
-    internalStream: function (type) {
-        var result = null, outputType = "string";
-        try {
-            if (!type) {
-                throw new Error("No output type specified.");
-            }
-            outputType = type.toLowerCase();
-            var askUnicodeString = outputType === "string" || outputType === "text";
-            if (outputType === "binarystring" || outputType === "text") {
-                outputType = "string";
-            }
-            result = this._decompressWorker();
-
-            var isUnicodeString = !this._dataBinary;
-
-            if (isUnicodeString && !askUnicodeString) {
-                result = result.pipe(new utf8.Utf8EncodeWorker());
-            }
-            if (!isUnicodeString && askUnicodeString) {
-                result = result.pipe(new utf8.Utf8DecodeWorker());
-            }
-        } catch (e) {
-            result = new GenericWorker("error");
-            result.error(e);
-        }
-
-        return new StreamHelper(result, outputType, "");
-    },
-
-    /**
-     * Prepare the content in the asked type.
-     * @param {String} type the type of the result.
-     * @param {Function} onUpdate a function to call on each internal update.
-     * @return Promise the promise of the result.
-     */
-    async: function (type, onUpdate) {
-        return this.internalStream(type).accumulate(onUpdate);
-    },
-
-    /**
-     * Prepare the content as a nodejs stream.
-     * @param {String} type the type of each chunk.
-     * @param {Function} onUpdate a function to call on each internal update.
-     * @return Stream the stream.
-     */
-    nodeStream: function (type, onUpdate) {
-        return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate);
-    },
-
-    /**
-     * Return a worker for the compressed content.
-     * @private
-     * @param {Object} compression the compression object to use.
-     * @param {Object} compressionOptions the options to use when compressing.
-     * @return Worker the worker.
-     */
-    _compressWorker: function (compression, compressionOptions) {
-        if (
-            this._data instanceof CompressedObject &&
-            this._data.compression.magic === compression.magic
-        ) {
-            return this._data.getCompressedWorker();
-        } else {
-            var result = this._decompressWorker();
-            if(!this._dataBinary) {
-                result = result.pipe(new utf8.Utf8EncodeWorker());
-            }
-            return CompressedObject.createWorkerFrom(result, compression, compressionOptions);
-        }
-    },
-    /**
-     * Return a worker for the decompressed content.
-     * @private
-     * @return Worker the worker.
-     */
-    _decompressWorker : function () {
-        if (this._data instanceof CompressedObject) {
-            return this._data.getContentWorker();
-        } else if (this._data instanceof GenericWorker) {
-            return this._data;
-        } else {
-            return new DataWorker(this._data);
-        }
-    }
-};
-
-var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"];
-var removedFn = function () {
-    throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
-};
-
-for(var i = 0; i < removedMethods.length; i++) {
-    ZipObject.prototype[removedMethods[i]] = removedFn;
-}
-module.exports = ZipObject;
-
-
-/***/ }),
-/* 135 */
-/*!********************************************************************!*\
-  !*** ./node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js ***!
-  \********************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-var Readable = __webpack_require__(/*! readable-stream */ 105).Readable;
-
-var utils = __webpack_require__(/*! ../utils */ 31);
-utils.inherits(NodejsStreamOutputAdapter, Readable);
-
-/**
-* A nodejs stream using a worker as source.
-* @see the SourceWrapper in http://nodejs.org/api/stream.html
-* @constructor
-* @param {StreamHelper} helper the helper wrapping the worker
-* @param {Object} options the nodejs stream options
-* @param {Function} updateCb the update callback.
-*/
-function NodejsStreamOutputAdapter(helper, options, updateCb) {
-    Readable.call(this, options);
-    this._helper = helper;
-
-    var self = this;
-    helper.on("data", function (data, meta) {
-        if (!self.push(data)) {
-            self._helper.pause();
-        }
-        if(updateCb) {
-            updateCb(meta);
-        }
-    })
-    .on("error", function(e) {
-        self.emit('error', e);
-    })
-    .on("end", function () {
-        self.push(null);
-    });
-}
-
-
-NodejsStreamOutputAdapter.prototype._read = function() {
-    this._helper.resume();
-};
-
-module.exports = NodejsStreamOutputAdapter;
-
-
-/***/ }),
-/* 136 */
-/*!********************************************************!*\
-  !*** ./node_modules/jszip/lib/stream/ConvertWorker.js ***!
-  \********************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-var GenericWorker = __webpack_require__(/*! ./GenericWorker */ 37);
-var utils = __webpack_require__(/*! ../utils */ 31);
-
-/**
- * A worker which convert chunks to a specified type.
- * @constructor
- * @param {String} destType the destination type.
- */
-function ConvertWorker(destType) {
-    GenericWorker.call(this, "ConvertWorker to " + destType);
-    this.destType = destType;
-}
-utils.inherits(ConvertWorker, GenericWorker);
-
-/**
- * @see GenericWorker.processChunk
- */
-ConvertWorker.prototype.processChunk = function (chunk) {
-    this.push({
-        data : utils.transformTo(this.destType, chunk.data),
-        meta : chunk.meta
-    });
-};
-module.exports = ConvertWorker;
-
-
-/***/ }),
-/* 137 */
-/*!***********************************************!*\
-  !*** ./node_modules/immediate/lib/browser.js ***!
-  \***********************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(global) {
-var Mutation = global.MutationObserver || global.WebKitMutationObserver;
-
-var scheduleDrain;
-
-{
-  if (Mutation) {
-    var called = 0;
-    var observer = new Mutation(nextTick);
-    var element = global.document.createTextNode('');
-    observer.observe(element, {
-      characterData: true
-    });
-    scheduleDrain = function () {
-      element.data = (called = ++called % 2);
-    };
-  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
-    var channel = new global.MessageChannel();
-    channel.port1.onmessage = nextTick;
-    scheduleDrain = function () {
-      channel.port2.postMessage(0);
-    };
-  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
-    scheduleDrain = function () {
-
-      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
-      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
-      var scriptEl = global.document.createElement('script');
-      scriptEl.onreadystatechange = function () {
-        nextTick();
-
-        scriptEl.onreadystatechange = null;
-        scriptEl.parentNode.removeChild(scriptEl);
-        scriptEl = null;
-      };
-      global.document.documentElement.appendChild(scriptEl);
-    };
-  } else {
-    scheduleDrain = function () {
-      setTimeout(nextTick, 0);
-    };
-  }
-}
-
-var draining;
-var queue = [];
-//named nextTick for less confusing stack traces
-function nextTick() {
-  draining = true;
-  var i, oldQueue;
-  var len = queue.length;
-  while (len) {
-    oldQueue = queue;
-    queue = [];
-    i = -1;
-    while (++i < len) {
-      oldQueue[i]();
-    }
-    len = queue.length;
-  }
-  draining = false;
-}
-
-module.exports = immediate;
-function immediate(task) {
-  if (queue.push(task) === 1 && !draining) {
-    scheduleDrain();
-  }
-}
-
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ 48)))
-
-/***/ }),
-/* 138 */
-/*!*****************************************!*\
-  !*** ./node_modules/lie/lib/browser.js ***!
-  \*****************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var immediate = __webpack_require__(/*! immediate */ 137);
-
-/* istanbul ignore next */
-function INTERNAL() {}
-
-var handlers = {};
-
-var REJECTED = ['REJECTED'];
-var FULFILLED = ['FULFILLED'];
-var PENDING = ['PENDING'];
-
-module.exports = Promise;
-
-function Promise(resolver) {
-  if (typeof resolver !== 'function') {
-    throw new TypeError('resolver must be a function');
-  }
-  this.state = PENDING;
-  this.queue = [];
-  this.outcome = void 0;
-  if (resolver !== INTERNAL) {
-    safelyResolveThenable(this, resolver);
-  }
-}
-
-Promise.prototype["catch"] = function (onRejected) {
-  return this.then(null, onRejected);
-};
-Promise.prototype.then = function (onFulfilled, onRejected) {
-  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
-    typeof onRejected !== 'function' && this.state === REJECTED) {
-    return this;
-  }
-  var promise = new this.constructor(INTERNAL);
-  if (this.state !== PENDING) {
-    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
-    unwrap(promise, resolver, this.outcome);
-  } else {
-    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
-  }
-
-  return promise;
-};
-function QueueItem(promise, onFulfilled, onRejected) {
-  this.promise = promise;
-  if (typeof onFulfilled === 'function') {
-    this.onFulfilled = onFulfilled;
-    this.callFulfilled = this.otherCallFulfilled;
-  }
-  if (typeof onRejected === 'function') {
-    this.onRejected = onRejected;
-    this.callRejected = this.otherCallRejected;
-  }
-}
-QueueItem.prototype.callFulfilled = function (value) {
-  handlers.resolve(this.promise, value);
-};
-QueueItem.prototype.otherCallFulfilled = function (value) {
-  unwrap(this.promise, this.onFulfilled, value);
-};
-QueueItem.prototype.callRejected = function (value) {
-  handlers.reject(this.promise, value);
-};
-QueueItem.prototype.otherCallRejected = function (value) {
-  unwrap(this.promise, this.onRejected, value);
-};
-
-function unwrap(promise, func, value) {
-  immediate(function () {
-    var returnValue;
-    try {
-      returnValue = func(value);
-    } catch (e) {
-      return handlers.reject(promise, e);
-    }
-    if (returnValue === promise) {
-      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
-    } else {
-      handlers.resolve(promise, returnValue);
-    }
-  });
-}
-
-handlers.resolve = function (self, value) {
-  var result = tryCatch(getThen, value);
-  if (result.status === 'error') {
-    return handlers.reject(self, result.value);
-  }
-  var thenable = result.value;
-
-  if (thenable) {
-    safelyResolveThenable(self, thenable);
-  } else {
-    self.state = FULFILLED;
-    self.outcome = value;
-    var i = -1;
-    var len = self.queue.length;
-    while (++i < len) {
-      self.queue[i].callFulfilled(value);
-    }
-  }
-  return self;
-};
-handlers.reject = function (self, error) {
-  self.state = REJECTED;
-  self.outcome = error;
-  var i = -1;
-  var len = self.queue.length;
-  while (++i < len) {
-    self.queue[i].callRejected(error);
-  }
-  return self;
-};
-
-function getThen(obj) {
-  // Make sure we only access the accessor once as required by the spec
-  var then = obj && obj.then;
-  if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') {
-    return function appyThen() {
-      then.apply(obj, arguments);
-    };
-  }
-}
-
-function safelyResolveThenable(self, thenable) {
-  // Either fulfill, reject or reject with error
-  var called = false;
-  function onError(value) {
-    if (called) {
-      return;
-    }
-    called = true;
-    handlers.reject(self, value);
-  }
-
-  function onSuccess(value) {
-    if (called) {
-      return;
-    }
-    called = true;
-    handlers.resolve(self, value);
-  }
-
-  function tryToUnwrap() {
-    thenable(onSuccess, onError);
-  }
-
-  var result = tryCatch(tryToUnwrap);
-  if (result.status === 'error') {
-    onError(result.value);
-  }
-}
-
-function tryCatch(func, value) {
-  var out = {};
-  try {
-    out.value = func(value);
-    out.status = 'success';
-  } catch (e) {
-    out.status = 'error';
-    out.value = e;
-  }
-  return out;
-}
-
-Promise.resolve = resolve;
-function resolve(value) {
-  if (value instanceof this) {
-    return value;
-  }
-  return handlers.resolve(new this(INTERNAL), value);
-}
-
-Promise.reject = reject;
-function reject(reason) {
-  var promise = new this(INTERNAL);
-  return handlers.reject(promise, reason);
-}
-
-Promise.all = all;
-function all(iterable) {
-  var self = this;
-  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
-    return this.reject(new TypeError('must be an array'));
-  }
-
-  var len = iterable.length;
-  var called = false;
-  if (!len) {
-    return this.resolve([]);
-  }
-
-  var values = new Array(len);
-  var resolved = 0;
-  var i = -1;
-  var promise = new this(INTERNAL);
-
-  while (++i < len) {
-    allResolver(iterable[i], i);
-  }
-  return promise;
-  function allResolver(value, i) {
-    self.resolve(value).then(resolveFromAll, function (error) {
-      if (!called) {
-        called = true;
-        handlers.reject(promise, error);
-      }
-    });
-    function resolveFromAll(outValue) {
-      values[i] = outValue;
-      if (++resolved === len && !called) {
-        called = true;
-        handlers.resolve(promise, values);
-      }
-    }
-  }
-}
-
-Promise.race = race;
-function race(iterable) {
-  var self = this;
-  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
-    return this.reject(new TypeError('must be an array'));
-  }
-
-  var len = iterable.length;
-  var called = false;
-  if (!len) {
-    return this.resolve([]);
-  }
-
-  var i = -1;
-  var promise = new this(INTERNAL);
-
-  while (++i < len) {
-    resolver(iterable[i]);
-  }
-  return promise;
-  function resolver(value) {
-    self.resolve(value).then(function (response) {
-      if (!called) {
-        called = true;
-        handlers.resolve(promise, response);
-      }
-    }, function (error) {
-      if (!called) {
-        called = true;
-        handlers.reject(promise, error);
-      }
-    });
-  }
-}
-
-
-/***/ }),
-/* 139 */
-/*!*************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_cof.js ***!
-  \*************************************************************************/
-/***/ (function(module, exports) {
-
-var toString = {}.toString;
-
-module.exports = function(it){
-  return toString.call(it).slice(8, -1);
-};
-
-/***/ }),
-/* 140 */
-/*!**************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_html.js ***!
-  \**************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-module.exports = __webpack_require__(/*! ./_global */ 61).document && document.documentElement;
-
-/***/ }),
-/* 141 */
-/*!****************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_invoke.js ***!
-  \****************************************************************************/
-/***/ (function(module, exports) {
-
-// fast apply, http://jsperf.lnkit.com/fast-apply/5
-module.exports = function(fn, args, that){
-  var un = that === undefined;
-  switch(args.length){
-    case 0: return un ? fn()
-                      : fn.call(that);
-    case 1: return un ? fn(args[0])
-                      : fn.call(that, args[0]);
-    case 2: return un ? fn(args[0], args[1])
-                      : fn.call(that, args[0], args[1]);
-    case 3: return un ? fn(args[0], args[1], args[2])
-                      : fn.call(that, args[0], args[1], args[2]);
-    case 4: return un ? fn(args[0], args[1], args[2], args[3])
-                      : fn.call(that, args[0], args[1], args[2], args[3]);
-  } return              fn.apply(that, args);
-};
-
-/***/ }),
-/* 142 */
-/*!**************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_task.js ***!
-  \**************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-var ctx                = __webpack_require__(/*! ./_ctx */ 97)
-  , invoke             = __webpack_require__(/*! ./_invoke */ 141)
-  , html               = __webpack_require__(/*! ./_html */ 140)
-  , cel                = __webpack_require__(/*! ./_dom-create */ 95)
-  , global             = __webpack_require__(/*! ./_global */ 61)
-  , process            = global.process
-  , setTask            = global.setImmediate
-  , clearTask          = global.clearImmediate
-  , MessageChannel     = global.MessageChannel
-  , counter            = 0
-  , queue              = {}
-  , ONREADYSTATECHANGE = 'onreadystatechange'
-  , defer, channel, port;
-var run = function(){
-  var id = +this;
-  if(queue.hasOwnProperty(id)){
-    var fn = queue[id];
-    delete queue[id];
-    fn();
-  }
-};
-var listener = function(event){
-  run.call(event.data);
-};
-// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
-if(!setTask || !clearTask){
-  setTask = function setImmediate(fn){
-    var args = [], i = 1;
-    while(arguments.length > i)args.push(arguments[i++]);
-    queue[++counter] = function(){
-      invoke(typeof fn == 'function' ? fn : Function(fn), args);
-    };
-    defer(counter);
-    return counter;
-  };
-  clearTask = function clearImmediate(id){
-    delete queue[id];
-  };
-  // Node.js 0.8-
-  if(__webpack_require__(/*! ./_cof */ 139)(process) == 'process'){
-    defer = function(id){
-      process.nextTick(ctx(run, id, 1));
-    };
-  // Browsers with MessageChannel, includes WebWorkers
-  } else if(MessageChannel){
-    channel = new MessageChannel;
-    port    = channel.port2;
-    channel.port1.onmessage = listener;
-    defer = ctx(port.postMessage, port, 1);
-  // Browsers with postMessage, skip WebWorkers
-  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
-  } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
-    defer = function(id){
-      global.postMessage(id + '', '*');
-    };
-    global.addEventListener('message', listener, false);
-  // IE8-
-  } else if(ONREADYSTATECHANGE in cel('script')){
-    defer = function(id){
-      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
-        html.removeChild(this);
-        run.call(id);
-      };
-    };
-  // Rest old browsers
-  } else {
-    defer = function(id){
-      setTimeout(ctx(run, id, 1), 0);
-    };
-  }
-}
-module.exports = {
-  set:   setTask,
-  clear: clearTask
-};
-
-/***/ }),
-/* 143 */
-/*!***********************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_property-desc.js ***!
-  \***********************************************************************************/
-/***/ (function(module, exports) {
-
-module.exports = function(bitmap, value){
-  return {
-    enumerable  : !(bitmap & 1),
-    configurable: !(bitmap & 2),
-    writable    : !(bitmap & 4),
-    value       : value
-  };
-};
-
-/***/ }),
-/* 144 */
-/*!**********************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_to-primitive.js ***!
-  \**********************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-// 7.1.1 ToPrimitive(input [, PreferredType])
-var isObject = __webpack_require__(/*! ./_is-object */ 73);
-// instead of the ES6 spec version, we didn't implement @@toPrimitive case
-// and the second argument - flag - preferred type is a string
-module.exports = function(it, S){
-  if(!isObject(it))return it;
-  var fn, val;
-  if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
-  if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;
-  if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
-  throw TypeError("Can't convert object to primitive value");
-};
-
-/***/ }),
-/* 145 */
-/*!************************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_ie8-dom-define.js ***!
-  \************************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-module.exports = !__webpack_require__(/*! ./_descriptors */ 72) && !__webpack_require__(/*! ./_fails */ 96)(function(){
-  return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ 95)('div'), 'a', {get: function(){ return 7; }}).a != 7;
-});
-
-/***/ }),
-/* 146 */
-/*!*******************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_an-object.js ***!
-  \*******************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-var isObject = __webpack_require__(/*! ./_is-object */ 73);
-module.exports = function(it){
-  if(!isObject(it))throw TypeError(it + ' is not an object!');
-  return it;
-};
-
-/***/ }),
-/* 147 */
-/*!*******************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_object-dp.js ***!
-  \*******************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-var anObject       = __webpack_require__(/*! ./_an-object */ 146)
-  , IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ 145)
-  , toPrimitive    = __webpack_require__(/*! ./_to-primitive */ 144)
-  , dP             = Object.defineProperty;
-
-exports.f = __webpack_require__(/*! ./_descriptors */ 72) ? Object.defineProperty : function defineProperty(O, P, Attributes){
-  anObject(O);
-  P = toPrimitive(P, true);
-  anObject(Attributes);
-  if(IE8_DOM_DEFINE)try {
-    return dP(O, P, Attributes);
-  } catch(e){ /* empty */ }
-  if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
-  if('value' in Attributes)O[P] = Attributes.value;
-  return O;
-};
-
-/***/ }),
-/* 148 */
-/*!**************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_hide.js ***!
-  \**************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-var dP         = __webpack_require__(/*! ./_object-dp */ 147)
-  , createDesc = __webpack_require__(/*! ./_property-desc */ 143);
-module.exports = __webpack_require__(/*! ./_descriptors */ 72) ? function(object, key, value){
-  return dP.f(object, key, createDesc(1, value));
-} : function(object, key, value){
-  object[key] = value;
-  return object;
-};
-
-/***/ }),
-/* 149 */
-/*!********************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_a-function.js ***!
-  \********************************************************************************/
-/***/ (function(module, exports) {
-
-module.exports = function(it){
-  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
-  return it;
-};
-
-/***/ }),
-/* 150 */
-/*!****************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_export.js ***!
-  \****************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-var global    = __webpack_require__(/*! ./_global */ 61)
-  , core      = __webpack_require__(/*! ./_core */ 98)
-  , ctx       = __webpack_require__(/*! ./_ctx */ 97)
-  , hide      = __webpack_require__(/*! ./_hide */ 148)
-  , PROTOTYPE = 'prototype';
-
-var $export = function(type, name, source){
-  var IS_FORCED = type & $export.F
-    , IS_GLOBAL = type & $export.G
-    , IS_STATIC = type & $export.S
-    , IS_PROTO  = type & $export.P
-    , IS_BIND   = type & $export.B
-    , IS_WRAP   = type & $export.W
-    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
-    , expProto  = exports[PROTOTYPE]
-    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]
-    , key, own, out;
-  if(IS_GLOBAL)source = name;
-  for(key in source){
-    // contains in native
-    own = !IS_FORCED && target && target[key] !== undefined;
-    if(own && key in exports)continue;
-    // export native or passed
-    out = own ? target[key] : source[key];
-    // prevent global pollution for namespaces
-    exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
-    // bind timers to global for call from export context
-    : IS_BIND && own ? ctx(out, global)
-    // wrap global constructors for prevent change them in library
-    : IS_WRAP && target[key] == out ? (function(C){
-      var F = function(a, b, c){
-        if(this instanceof C){
-          switch(arguments.length){
-            case 0: return new C;
-            case 1: return new C(a);
-            case 2: return new C(a, b);
-          } return new C(a, b, c);
-        } return C.apply(this, arguments);
-      };
-      F[PROTOTYPE] = C[PROTOTYPE];
-      return F;
-    // make static versions for prototype methods
-    })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
-    // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%
-    if(IS_PROTO){
-      (exports.virtual || (exports.virtual = {}))[key] = out;
-      // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%
-      if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);
-    }
-  }
-};
-// type bitmap
-$export.F = 1;   // forced
-$export.G = 2;   // global
-$export.S = 4;   // static
-$export.P = 8;   // proto
-$export.B = 16;  // bind
-$export.W = 32;  // wrap
-$export.U = 64;  // safe
-$export.R = 128; // real proto method for `library` 
-module.exports = $export;
-
-/***/ }),
-/* 151 */
-/*!**********************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/modules/web.immediate.js ***!
-  \**********************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-var $export = __webpack_require__(/*! ./_export */ 150)
-  , $task   = __webpack_require__(/*! ./_task */ 142);
-$export($export.G + $export.B, {
-  setImmediate:   $task.set,
-  clearImmediate: $task.clear
-});
-
-/***/ }),
-/* 152 */
-/*!*****************************************************************************!*\
-  !*** ./node_modules/jszip/node_modules/core-js/library/fn/set-immediate.js ***!
-  \*****************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-__webpack_require__(/*! ../modules/web.immediate */ 151);
-module.exports = __webpack_require__(/*! ../modules/_core */ 98).setImmediate;
-
-/***/ }),
-/* 153 */
-/*!*****************************************************!*\
-  !*** ./node_modules/readable-stream/passthrough.js ***!
-  \*****************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-module.exports = __webpack_require__(/*! ./readable */ 75).PassThrough
-
-
-/***/ }),
-/* 154 */
-/*!***************************************************!*\
-  !*** ./node_modules/readable-stream/transform.js ***!
-  \***************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-module.exports = __webpack_require__(/*! ./readable */ 75).Transform
-
-
-/***/ }),
-/* 155 */
-/*!********************************************************!*\
-  !*** ./node_modules/readable-stream/duplex-browser.js ***!
-  \********************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-module.exports = __webpack_require__(/*! ./lib/_stream_duplex.js */ 52);
-
-
-/***/ }),
-/* 156 */
-/*!**********************************************************!*\
-  !*** ./node_modules/readable-stream/writable-browser.js ***!
-  \**********************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-module.exports = __webpack_require__(/*! ./lib/_stream_writable.js */ 74);
-
-
-/***/ }),
-/* 157 */
-/*!*****************************************************************!*\
-  !*** ./node_modules/readable-stream/lib/_stream_passthrough.js ***!
-  \*****************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// a passthrough stream.
-// basically just the most minimal sort of Transform stream.
-// Every written chunk gets output as-is.
-
-
-
-module.exports = PassThrough;
-
-var Transform = __webpack_require__(/*! ./_stream_transform */ 100);
-
-/*<replacement>*/
-var util = __webpack_require__(/*! core-util-is */ 58);
-util.inherits = __webpack_require__(/*! inherits */ 55);
-/*</replacement>*/
-
-util.inherits(PassThrough, Transform);
-
-function PassThrough(options) {
-  if (!(this instanceof PassThrough)) return new PassThrough(options);
-
-  Transform.call(this, options);
-}
-
-PassThrough.prototype._transform = function (chunk, encoding, cb) {
-  cb(null, chunk);
-};
-
-/***/ }),
-/* 158 */
-/*!************************************************!*\
-  !*** ./node_modules/util-deprecate/browser.js ***!
-  \************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-/* WEBPACK VAR INJECTION */(function(global) {
-/**
- * Module exports.
- */
-
-module.exports = deprecate;
-
-/**
- * Mark that a method should not be used.
- * Returns a modified function which warns once by default.
- *
- * If `localStorage.noDeprecation = true` is set, then it is a no-op.
- *
- * If `localStorage.throwDeprecation = true` is set, then deprecated functions
- * will throw an Error when invoked.
- *
- * If `localStorage.traceDeprecation = true` is set, then deprecated functions
- * will invoke `console.trace()` instead of `console.error()`.
- *
- * @param {Function} fn - the function to deprecate
- * @param {String} msg - the string to print to the console when `fn` is invoked
- * @returns {Function} a new "deprecated" version of `fn`
- * @api public
- */
-
-function deprecate (fn, msg) {
-  if (config('noDeprecation')) {
-    return fn;
-  }
-
-  var warned = false;
-  function deprecated() {
-    if (!warned) {
-      if (config('throwDeprecation')) {
-        throw new Error(msg);
-      } else if (config('traceDeprecation')) {
-        console.trace(msg);
-      } else {
-        console.warn(msg);
-      }
-      warned = true;
-    }
-    return fn.apply(this, arguments);
-  }
-
-  return deprecated;
-}
-
-/**
- * Checks `localStorage` for boolean values for the given `name`.
- *
- * @param {String} name
- * @returns {Boolean}
- * @api private
- */
-
-function config (name) {
-  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
-  try {
-    if (!global.localStorage) return false;
-  } catch (_) {
-    return false;
-  }
-  var val = global.localStorage[name];
-  if (null == val) return false;
-  return String(val).toLowerCase() === 'true';
-}
-
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ 48)))
-
-/***/ }),
-/* 159 */
-/*!**********************!*\
-  !*** util (ignored) ***!
-  \**********************/
-/***/ (function(module, exports) {
-
-/* (ignored) */
-
-/***/ }),
-/* 160 */
-/*!*************************************************************************!*\
-  !*** ./node_modules/readable-stream/lib/internal/streams/BufferList.js ***!
-  \*************************************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var Buffer = __webpack_require__(/*! safe-buffer */ 63).Buffer;
-var util = __webpack_require__(/*! util */ 159);
-
-function copyBuffer(src, target, offset) {
-  src.copy(target, offset);
-}
-
-module.exports = function () {
-  function BufferList() {
-    _classCallCheck(this, BufferList);
-
-    this.head = null;
-    this.tail = null;
-    this.length = 0;
-  }
-
-  BufferList.prototype.push = function push(v) {
-    var entry = { data: v, next: null };
-    if (this.length > 0) this.tail.next = entry;else this.head = entry;
-    this.tail = entry;
-    ++this.length;
-  };
-
-  BufferList.prototype.unshift = function unshift(v) {
-    var entry = { data: v, next: this.head };
-    if (this.length === 0) this.tail = entry;
-    this.head = entry;
-    ++this.length;
-  };
-
-  BufferList.prototype.shift = function shift() {
-    if (this.length === 0) return;
-    var ret = this.head.data;
-    if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
-    --this.length;
-    return ret;
-  };
-
-  BufferList.prototype.clear = function clear() {
-    this.head = this.tail = null;
-    this.length = 0;
-  };
-
-  BufferList.prototype.join = function join(s) {
-    if (this.length === 0) return '';
-    var p = this.head;
-    var ret = '' + p.data;
-    while (p = p.next) {
-      ret += s + p.data;
-    }return ret;
-  };
-
-  BufferList.prototype.concat = function concat(n) {
-    if (this.length === 0) return Buffer.alloc(0);
-    if (this.length === 1) return this.head.data;
-    var ret = Buffer.allocUnsafe(n >>> 0);
-    var p = this.head;
-    var i = 0;
-    while (p) {
-      copyBuffer(p.data, ret, i);
-      i += p.data.length;
-      p = p.next;
-    }
-    return ret;
-  };
-
-  return BufferList;
-}();
-
-if (util && util.inspect && util.inspect.custom) {
-  module.exports.prototype[util.inspect.custom] = function () {
-    var obj = util.inspect({ length: this.length });
-    return this.constructor.name + ' ' + obj;
-  };
-}
-
-/***/ }),
-/* 161 */
-/*!**********************!*\
-  !*** util (ignored) ***!
-  \**********************/
-/***/ (function(module, exports) {
-
-/* (ignored) */
-
-/***/ }),
-/* 162 */
-/*!*************************************************!*\
-  !*** ./node_modules/stream-browserify/index.js ***!
-  \*************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-module.exports = Stream;
-
-var EE = __webpack_require__(/*! events */ 76).EventEmitter;
-var inherits = __webpack_require__(/*! inherits */ 55);
-
-inherits(Stream, EE);
-Stream.Readable = __webpack_require__(/*! readable-stream/readable.js */ 75);
-Stream.Writable = __webpack_require__(/*! readable-stream/writable.js */ 156);
-Stream.Duplex = __webpack_require__(/*! readable-stream/duplex.js */ 155);
-Stream.Transform = __webpack_require__(/*! readable-stream/transform.js */ 154);
-Stream.PassThrough = __webpack_require__(/*! readable-stream/passthrough.js */ 153);
-
-// Backwards-compat with node 0.4.x
-Stream.Stream = Stream;
-
-
-
-// old-style streams.  Note that the pipe method (the only relevant
-// part of this class) is overridden in the Readable class.
-
-function Stream() {
-  EE.call(this);
-}
-
-Stream.prototype.pipe = function(dest, options) {
-  var source = this;
-
-  function ondata(chunk) {
-    if (dest.writable) {
-      if (false === dest.write(chunk) && source.pause) {
-        source.pause();
-      }
-    }
-  }
-
-  source.on('data', ondata);
-
-  function ondrain() {
-    if (source.readable && source.resume) {
-      source.resume();
-    }
-  }
-
-  dest.on('drain', ondrain);
-
-  // If the 'end' option is not supplied, dest.end() will be called when
-  // source gets the 'end' or 'close' events.  Only dest.end() once.
-  if (!dest._isStdio && (!options || options.end !== false)) {
-    source.on('end', onend);
-    source.on('close', onclose);
-  }
-
-  var didOnEnd = false;
-  function onend() {
-    if (didOnEnd) return;
-    didOnEnd = true;
-
-    dest.end();
-  }
-
-
-  function onclose() {
-    if (didOnEnd) return;
-    didOnEnd = true;
-
-    if (typeof dest.destroy === 'function') dest.destroy();
-  }
-
-  // don't leave dangling pipes when there are errors.
-  function onerror(er) {
-    cleanup();
-    if (EE.listenerCount(this, 'error') === 0) {
-      throw er; // Unhandled stream error in pipe.
-    }
-  }
-
-  source.on('error', onerror);
-  dest.on('error', onerror);
-
-  // remove all the event listeners that were added.
-  function cleanup() {
-    source.removeListener('data', ondata);
-    dest.removeListener('drain', ondrain);
-
-    source.removeListener('end', onend);
-    source.removeListener('close', onclose);
-
-    source.removeListener('error', onerror);
-    dest.removeListener('error', onerror);
-
-    source.removeListener('end', cleanup);
-    source.removeListener('close', cleanup);
-
-    dest.removeListener('close', cleanup);
-  }
-
-  source.on('end', cleanup);
-  source.on('close', cleanup);
-
-  dest.on('close', cleanup);
-
-  dest.emit('pipe', source);
-
-  // Allow for unix-like usage: A.pipe(B).pipe(C)
-  return dest;
-};
-
-
-/***/ }),
-/* 163 */
-/*!***************************************!*\
-  !*** ./node_modules/ieee754/index.js ***!
-  \***************************************/
-/***/ (function(module, exports) {
-
-exports.read = function (buffer, offset, isLE, mLen, nBytes) {
-  var e, m
-  var eLen = nBytes * 8 - mLen - 1
-  var eMax = (1 << eLen) - 1
-  var eBias = eMax >> 1
-  var nBits = -7
-  var i = isLE ? (nBytes - 1) : 0
-  var d = isLE ? -1 : 1
-  var s = buffer[offset + i]
-
-  i += d
-
-  e = s & ((1 << (-nBits)) - 1)
-  s >>= (-nBits)
-  nBits += eLen
-  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
-
-  m = e & ((1 << (-nBits)) - 1)
-  e >>= (-nBits)
-  nBits += mLen
-  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
-
-  if (e === 0) {
-    e = 1 - eBias
-  } else if (e === eMax) {
-    return m ? NaN : ((s ? -1 : 1) * Infinity)
-  } else {
-    m = m + Math.pow(2, mLen)
-    e = e - eBias
-  }
-  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
-}
-
-exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
-  var e, m, c
-  var eLen = nBytes * 8 - mLen - 1
-  var eMax = (1 << eLen) - 1
-  var eBias = eMax >> 1
-  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
-  var i = isLE ? 0 : (nBytes - 1)
-  var d = isLE ? 1 : -1
-  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
-
-  value = Math.abs(value)
-
-  if (isNaN(value) || value === Infinity) {
-    m = isNaN(value) ? 1 : 0
-    e = eMax
-  } else {
-    e = Math.floor(Math.log(value) / Math.LN2)
-    if (value * (c = Math.pow(2, -e)) < 1) {
-      e--
-      c *= 2
-    }
-    if (e + eBias >= 1) {
-      value += rt / c
-    } else {
-      value += rt * Math.pow(2, 1 - eBias)
-    }
-    if (value * c >= 2) {
-      e++
-      c /= 2
-    }
-
-    if (e + eBias >= eMax) {
-      m = 0
-      e = eMax
-    } else if (e + eBias >= 1) {
-      m = (value * c - 1) * Math.pow(2, mLen)
-      e = e + eBias
-    } else {
-      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
-      e = 0
-    }
-  }
-
-  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
-
-  e = (e << mLen) | m
-  eLen += mLen
-  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
-
-  buffer[offset + i - d] |= s * 128
-}
-
-
-/***/ }),
-/* 164 */
-/*!*****************************************!*\
-  !*** ./node_modules/base64-js/index.js ***!
-  \*****************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-exports.byteLength = byteLength
-exports.toByteArray = toByteArray
-exports.fromByteArray = fromByteArray
-
-var lookup = []
-var revLookup = []
-var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
-
-var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
-for (var i = 0, len = code.length; i < len; ++i) {
-  lookup[i] = code[i]
-  revLookup[code.charCodeAt(i)] = i
-}
-
-// Support decoding URL-safe base64 strings, as Node.js does.
-// See: https://en.wikipedia.org/wiki/Base64#URL_applications
-revLookup['-'.charCodeAt(0)] = 62
-revLookup['_'.charCodeAt(0)] = 63
-
-function placeHoldersCount (b64) {
-  var len = b64.length
-  if (len % 4 > 0) {
-    throw new Error('Invalid string. Length must be a multiple of 4')
-  }
-
-  // the number of equal signs (place holders)
-  // if there are two placeholders, than the two characters before it
-  // represent one byte
-  // if there is only one, then the three characters before it represent 2 bytes
-  // this is just a cheap hack to not do indexOf twice
-  return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
-}
-
-function byteLength (b64) {
-  // base64 is 4/3 + up to two characters of the original data
-  return (b64.length * 3 / 4) - placeHoldersCount(b64)
-}
-
-function toByteArray (b64) {
-  var i, l, tmp, placeHolders, arr
-  var len = b64.length
-  placeHolders = placeHoldersCount(b64)
-
-  arr = new Arr((len * 3 / 4) - placeHolders)
-
-  // if there are placeholders, only get up to the last complete 4 chars
-  l = placeHolders > 0 ? len - 4 : len
-
-  var L = 0
-
-  for (i = 0; i < l; i += 4) {
-    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
-    arr[L++] = (tmp >> 16) & 0xFF
-    arr[L++] = (tmp >> 8) & 0xFF
-    arr[L++] = tmp & 0xFF
-  }
-
-  if (placeHolders === 2) {
-    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
-    arr[L++] = tmp & 0xFF
-  } else if (placeHolders === 1) {
-    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
-    arr[L++] = (tmp >> 8) & 0xFF
-    arr[L++] = tmp & 0xFF
-  }
-
-  return arr
-}
-
-function tripletToBase64 (num) {
-  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
-}
-
-function encodeChunk (uint8, start, end) {
-  var tmp
-  var output = []
-  for (var i = start; i < end; i += 3) {
-    tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF)
-    output.push(tripletToBase64(tmp))
-  }
-  return output.join('')
-}
-
-function fromByteArray (uint8) {
-  var tmp
-  var len = uint8.length
-  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
-  var output = ''
-  var parts = []
-  var maxChunkLength = 16383 // must be multiple of 3
-
-  // go through the array every three bytes, we'll deal with trailing stuff later
-  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
-    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
-  }
-
-  // pad the end with zeros, but make sure to not forget the extra bytes
-  if (extraBytes === 1) {
-    tmp = uint8[len - 1]
-    output += lookup[tmp >> 2]
-    output += lookup[(tmp << 4) & 0x3F]
-    output += '=='
-  } else if (extraBytes === 2) {
-    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
-    output += lookup[tmp >> 10]
-    output += lookup[(tmp >> 4) & 0x3F]
-    output += lookup[(tmp << 2) & 0x3F]
-    output += '='
-  }
-
-  parts.push(output)
-
-  return parts.join('')
-}
-
-
-/***/ }),
-/* 165 */
-/*!******************************************!*\
-  !*** ./node_modules/jszip/lib/object.js ***!
-  \******************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-var utf8 = __webpack_require__(/*! ./utf8 */ 56);
-var utils = __webpack_require__(/*! ./utils */ 31);
-var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ 37);
-var StreamHelper = __webpack_require__(/*! ./stream/StreamHelper */ 94);
-var defaults = __webpack_require__(/*! ./defaults */ 93);
-var CompressedObject = __webpack_require__(/*! ./compressedObject */ 71);
-var ZipObject = __webpack_require__(/*! ./zipObject */ 134);
-var generate = __webpack_require__(/*! ./generate */ 133);
-var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ 62);
-var NodejsStreamInputAdapter = __webpack_require__(/*! ./nodejs/NodejsStreamInputAdapter */ 121);
-
-
-/**
- * Add a file in the current folder.
- * @private
- * @param {string} name the name of the file
- * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file
- * @param {Object} originalOptions the options of the file
- * @return {Object} the new file.
- */
-var fileAdd = function(name, data, originalOptions) {
-    // be sure sub folders exist
-    var dataType = utils.getTypeOf(data),
-        parent;
-
-
-    /*
-     * Correct options.
-     */
-
-    var o = utils.extend(originalOptions || {}, defaults);
-    o.date = o.date || new Date();
-    if (o.compression !== null) {
-        o.compression = o.compression.toUpperCase();
-    }
-
-    if (typeof o.unixPermissions === "string") {
-        o.unixPermissions = parseInt(o.unixPermissions, 8);
-    }
-
-    // UNX_IFDIR  0040000 see zipinfo.c
-    if (o.unixPermissions && (o.unixPermissions & 0x4000)) {
-        o.dir = true;
-    }
-    // Bit 4    Directory
-    if (o.dosPermissions && (o.dosPermissions & 0x0010)) {
-        o.dir = true;
-    }
-
-    if (o.dir) {
-        name = forceTrailingSlash(name);
-    }
-    if (o.createFolders && (parent = parentFolder(name))) {
-        folderAdd.call(this, parent, true);
-    }
-
-    var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false;
-    if (!originalOptions || typeof originalOptions.binary === "undefined") {
-        o.binary = !isUnicodeString;
-    }
-
-
-    var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0;
-
-    if (isCompressedEmpty || o.dir || !data || data.length === 0) {
-        o.base64 = false;
-        o.binary = true;
-        data = "";
-        o.compression = "STORE";
-        dataType = "string";
-    }
-
-    /*
-     * Convert content to fit.
-     */
-
-    var zipObjectContent = null;
-    if (data instanceof CompressedObject || data instanceof GenericWorker) {
-        zipObjectContent = data;
-    } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {
-        zipObjectContent = new NodejsStreamInputAdapter(name, data);
-    } else {
-        zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64);
-    }
-
-    var object = new ZipObject(name, zipObjectContent, o);
-    this.files[name] = object;
-    /*
-    TODO: we can't throw an exception because we have async promises
-    (we can have a promise of a Date() for example) but returning a
-    promise is useless because file(name, data) returns the JSZip
-    object for chaining. Should we break that to allow the user
-    to catch the error ?
-
-    return external.Promise.resolve(zipObjectContent)
-    .then(function () {
-        return object;
-    });
-    */
-};
-
-/**
- * Find the parent folder of the path.
- * @private
- * @param {string} path the path to use
- * @return {string} the parent folder, or ""
- */
-var parentFolder = function (path) {
-    if (path.slice(-1) === '/') {
-        path = path.substring(0, path.length - 1);
-    }
-    var lastSlash = path.lastIndexOf('/');
-    return (lastSlash > 0) ? path.substring(0, lastSlash) : "";
-};
-
-/**
- * Returns the path with a slash at the end.
- * @private
- * @param {String} path the path to check.
- * @return {String} the path with a trailing slash.
- */
-var forceTrailingSlash = function(path) {
-    // Check the name ends with a /
-    if (path.slice(-1) !== "/") {
-        path += "/"; // IE doesn't like substr(-1)
-    }
-    return path;
-};
-
-/**
- * Add a (sub) folder in the current folder.
- * @private
- * @param {string} name the folder's name
- * @param {boolean=} [createFolders] If true, automatically create sub
- *  folders. Defaults to false.
- * @return {Object} the new folder.
- */
-var folderAdd = function(name, createFolders) {
-    createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders;
-
-    name = forceTrailingSlash(name);
-
-    // Does this folder already exist?
-    if (!this.files[name]) {
-        fileAdd.call(this, name, null, {
-            dir: true,
-            createFolders: createFolders
-        });
-    }
-    return this.files[name];
-};
-
-/**
-* Cross-window, cross-Node-context regular expression detection
-* @param  {Object}  object Anything
-* @return {Boolean}        true if the object is a regular expression,
-* false otherwise
-*/
-function isRegExp(object) {
-    return Object.prototype.toString.call(object) === "[object RegExp]";
-}
-
-// return the actual prototype of JSZip
-var out = {
-    /**
-     * @see loadAsync
-     */
-    load: function() {
-        throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
-    },
-
-
-    /**
-     * Call a callback function for each entry at this folder level.
-     * @param {Function} cb the callback function:
-     * function (relativePath, file) {...}
-     * It takes 2 arguments : the relative path and the file.
-     */
-    forEach: function(cb) {
-        var filename, relativePath, file;
-        for (filename in this.files) {
-            if (!this.files.hasOwnProperty(filename)) {
-                continue;
-            }
-            file = this.files[filename];
-            relativePath = filename.slice(this.root.length, filename.length);
-            if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root
-                cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn...
-            }
-        }
-    },
-
-    /**
-     * Filter nested files/folders with the specified function.
-     * @param {Function} search the predicate to use :
-     * function (relativePath, file) {...}
-     * It takes 2 arguments : the relative path and the file.
-     * @return {Array} An array of matching elements.
-     */
-    filter: function(search) {
-        var result = [];
-        this.forEach(function (relativePath, entry) {
-            if (search(relativePath, entry)) { // the file matches the function
-                result.push(entry);
-            }
-
-        });
-        return result;
-    },
-
-    /**
-     * Add a file to the zip file, or search a file.
-     * @param   {string|RegExp} name The name of the file to add (if data is defined),
-     * the name of the file to find (if no data) or a regex to match files.
-     * @param   {String|ArrayBuffer|Uint8Array|Buffer} data  The file data, either raw or base64 encoded
-     * @param   {Object} o     File options
-     * @return  {JSZip|Object|Array} this JSZip object (when adding a file),
-     * a file (when searching by string) or an array of files (when searching by regex).
-     */
-    file: function(name, data, o) {
-        if (arguments.length === 1) {
-            if (isRegExp(name)) {
-                var regexp = name;
-                return this.filter(function(relativePath, file) {
-                    return !file.dir && regexp.test(relativePath);
-                });
-            }
-            else { // text
-                var obj = this.files[this.root + name];
-                if (obj && !obj.dir) {
-                    return obj;
-                } else {
-                    return null;
-                }
-            }
-        }
-        else { // more than one argument : we have data !
-            name = this.root + name;
-            fileAdd.call(this, name, data, o);
-        }
-        return this;
-    },
-
-    /**
-     * Add a directory to the zip file, or search.
-     * @param   {String|RegExp} arg The name of the directory to add, or a regex to search folders.
-     * @return  {JSZip} an object with the new directory as the root, or an array containing matching folders.
-     */
-    folder: function(arg) {
-        if (!arg) {
-            return this;
-        }
-
-        if (isRegExp(arg)) {
-            return this.filter(function(relativePath, file) {
-                return file.dir && arg.test(relativePath);
-            });
-        }
-
-        // else, name is a new folder
-        var name = this.root + arg;
-        var newFolder = folderAdd.call(this, name);
-
-        // Allow chaining by returning a new object with this folder as the root
-        var ret = this.clone();
-        ret.root = newFolder.name;
-        return ret;
-    },
-
-    /**
-     * Delete a file, or a directory and all sub-files, from the zip
-     * @param {string} name the name of the file to delete
-     * @return {JSZip} this JSZip object
-     */
-    remove: function(name) {
-        name = this.root + name;
-        var file = this.files[name];
-        if (!file) {
-            // Look for any folders
-            if (name.slice(-1) !== "/") {
-                name += "/";
-            }
-            file = this.files[name];
-        }
-
-        if (file && !file.dir) {
-            // file
-            delete this.files[name];
-        } else {
-            // maybe a folder, delete recursively
-            var kids = this.filter(function(relativePath, file) {
-                return file.name.slice(0, name.length) === name;
-            });
-            for (var i = 0; i < kids.length; i++) {
-                delete this.files[kids[i].name];
-            }
-        }
-
-        return this;
-    },
-
-    /**
-     * Generate the complete zip file
-     * @param {Object} options the options to generate the zip file :
-     * - compression, "STORE" by default.
-     * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
-     * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file
-     */
-    generate: function(options) {
-        throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
-    },
-
-    /**
-     * Generate the complete zip file as an internal stream.
-     * @param {Object} options the options to generate the zip file :
-     * - compression, "STORE" by default.
-     * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
-     * @return {StreamHelper} the streamed zip file.
-     */
-    generateInternalStream: function(options) {
-      var worker, opts = {};
-      try {
-          opts = utils.extend(options || {}, {
-              streamFiles: false,
-              compression: "STORE",
-              compressionOptions : null,
-              type: "",
-              platform: "DOS",
-              comment: null,
-              mimeType: 'application/zip',
-              encodeFileName: utf8.utf8encode
-          });
-
-          opts.type = opts.type.toLowerCase();
-          opts.compression = opts.compression.toUpperCase();
-
-          // "binarystring" is prefered but the internals use "string".
-          if(opts.type === "binarystring") {
-            opts.type = "string";
-          }
-
-          if (!opts.type) {
-            throw new Error("No output type specified.");
-          }
-
-          utils.checkSupport(opts.type);
-
-          // accept nodejs `process.platform`
-          if(
-              opts.platform === 'darwin' ||
-              opts.platform === 'freebsd' ||
-              opts.platform === 'linux' ||
-              opts.platform === 'sunos'
-          ) {
-              opts.platform = "UNIX";
-          }
-          if (opts.platform === 'win32') {
-              opts.platform = "DOS";
-          }
-
-          var comment = opts.comment || this.comment || "";
-          worker = generate.generateWorker(this, opts, comment);
-      } catch (e) {
-        worker = new GenericWorker("error");
-        worker.error(e);
-      }
-      return new StreamHelper(worker, opts.type || "string", opts.mimeType);
-    },
-    /**
-     * Generate the complete zip file asynchronously.
-     * @see generateInternalStream
-     */
-    generateAsync: function(options, onUpdate) {
-        return this.generateInternalStream(options).accumulate(onUpdate);
-    },
-    /**
-     * Generate the complete zip file asynchronously.
-     * @see generateInternalStream
-     */
-    generateNodeStream: function(options, onUpdate) {
-        options = options || {};
-        if (!options.type) {
-            options.type = "nodebuffer";
-        }
-        return this.generateInternalStream(options).toNodejsStream(onUpdate);
-    }
-};
-module.exports = out;
-
-
-/***/ }),
-/* 166 */
-/*!***************************************************!*\
-  !*** ./node_modules/setimmediate/setImmediate.js ***!
-  \***************************************************/
-/***/ (function(module, exports, __webpack_require__) {
-
-/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
-    "use strict";
-
-    if (global.setImmediate) {
-        return;
-    }
-
-    var nextHandle = 1; // Spec says greater than zero
-    var tasksByHandle = {};
-    var currentlyRunningATask = false;
-    var doc = global.document;
-    var registerImmediate;
-
-    function setImmediate(callback) {
-      // Callback can either be a function or a string
-      if (typeof callback !== "function") {
-        callback = new Function("" + callback);
-      }
-      // Copy function arguments
-      var args = new Array(arguments.length - 1);
-      for (var i = 0; i < args.length; i++) {
-          args[i] = arguments[i + 1];
-      }
-      // Store and register the task
-      var task = { callback: callback, args: args };
-      tasksByHandle[nextHandle] = task;
-      registerImmediate(nextHandle);
-      return nextHandle++;
-    }
-
-    function clearImmediate(handle) {
-        delete tasksByHandle[handle];
-    }
-
-    function run(task) {
-        var callback = task.callback;
-        var args = task.args;
-        switch (args.length) {
-        case 0:
-            callback();
-            break;
-        case 1:
-            callback(args[0]);
-            break;
-        case 2:
-            callback(args[0], args[1]);
-            break;
-        case 3:
-            callback(args[0], args[1], args[2]);
-            break;
-        default:
-            callback.apply(undefined, args);
-            break;
-        }
-    }
-
-    function runIfPresent(handle) {
-        // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
-        // So if we're currently running a task, we'll need to delay this invocation.
-        if (currentlyRunningATask) {
-            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
-            // "too much recursion" error.
-            setTimeout(runIfPresent, 0, handle);
-        } else {
-            var task = tasksByHandle[handle];
-            if (task) {
-                currentlyRunningATask = true;
-                try {
-                    run(task);
-                } finally {
-                    clearImmediate(handle);
-                    currentlyRunningATask = false;
-                }
-            }
-        }
-    }
-
-    function installNextTickImplementation() {
-        registerImmediate = function(handle) {
-            process.nextTick(function () { runIfPresent(handle); });
-        };
-    }
-
-    function canUsePostMessage() {
-        // The test against `importScripts` prevents this implementation from being installed inside a web worker,
-        // where `global.postMessage` means something completely different and can't be used for this purpose.
-        if (global.postMessage && !global.importScripts) {
-            var postMessageIsAsynchronous = true;
-            var oldOnMessage = global.onmessage;
-            global.onmessage = function() {
-                postMessageIsAsynchronous = false;
-            };
-            global.postMessage("", "*");
-            global.onmessage = oldOnMessage;
-            return postMessageIsAsynchronous;
-        }
-    }
-
-    function installPostMessageImplementation() {
-        // Installs an event handler on `global` for the `message` event: see
-        // * https://developer.mozilla.org/en/DOM/window.postMessage
-        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
-
-        var messagePrefix = "setImmediate$" + Math.random() + "$";
-        var onGlobalMessage = function(event) {
-            if (event.source === global &&
-                typeof event.data === "string" &&
-                event.data.indexOf(messagePrefix) === 0) {
-                runIfPresent(+event.data.slice(messagePrefix.length));
-            }
-        };
-
-        if (global.addEventListener) {
-            global.addEventListener("message", onGlobalMessage, false);
-        } else {
-            global.attachEvent("onmessage", onGlobalMessage);
-        }
-
-        registerImmediate = function(handle) {
-            global.postMessage(messagePrefix + handle, "*");
-        };
-    }
-
-    function installMessageChannelImplementation() {
-        var channel = new MessageChannel();
-        channel.port1.onmessage = function(event) {
-            var handle = event.data;
-            runIfPresent(handle);
-        };
-
-        registerImmediate = function(handle) {
-            channel.port2.postMessage(handle);
-        };
-    }
-
-    function installReadyStateChangeImplementation() {
-        var html = doc.documentElement;
-        registerImmediate = function(handle) {
-            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
-            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
-            var script = doc.createElement("script");
-            script.onreadystatechange = function () {
-                runIfPresent(handle);
-                script.onreadystatechange = null;
-                html.removeChild(script);
-                script = null;
-            };
-            html.appendChild(script);
-        };
-    }
-
-    function installSetTimeoutImplementation() {
-        registerImmediate = function(handle) {
-            setTimeout(runIfPresent, 0, handle);
-        };
-    }
-
-    // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
-    var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
-    attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
-
-    // Don't get fooled by e.g. browserify environments.
-    if ({}.toString.call(global.process) === "[object process]") {
-        // For Node.js before 0.9
-        installNextTickImplementation();
-
-    } else if (canUsePostMessage()) {
-        // For non-IE10 modern browsers
-        installPostMessageImplementation();
-
-    } else if (global.MessageChannel) {
-        // For web workers, where supported
-        installMessageChannelImplementation();
-
-    } else if (doc && "onreadystatechange" in doc.createElement("script")) {
-        // For IE 6–8
-        installReadyStateChangeImplementation();
-
-    } else {
-        // For older browsers
-        installSetTimeoutImplementation();
-    }
-
-    attachTo.setImmediate = setImmediate;
-    attachTo.clearImmediate = clearImmediate;
-}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
-
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ 48), __webpack_require__(/*! ./../process/browser.js */ 60)))
-
-/***/ }),
-/* 167 */
 /*!******************************************************!*\
   !*** ./node_modules/bluebird/js/browser/bluebird.js ***!
   \******************************************************/
@@ -84967,7 +75104,10013 @@ module.exports = ret;
 
 },{"./es5":13}]},{},[4])(4)
 });                    ;if (typeof window !== 'undefined' && window !== null) {                               window.P = window.Promise;                                                     } else if (typeof self !== 'undefined' && self !== null) {                             self.P = self.Promise;                                                         }
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../process/browser.js */ 60), __webpack_require__(/*! ./../../../webpack/buildin/global.js */ 48), __webpack_require__(/*! ./../../../timers-browserify/main.js */ 107).setImmediate))
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../process/browser.js */ 60), __webpack_require__(/*! ./../../../webpack/buildin/global.js */ 49), __webpack_require__(/*! ./../../../timers-browserify/main.js */ 102).setImmediate))
+
+/***/ }),
+/* 116 */
+/*!****************************************!*\
+  !*** (webpack)/buildin/amd-options.js ***!
+  \****************************************/
+/***/ (function(module, exports) {
+
+/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
+module.exports = __webpack_amd_options__;
+
+/* WEBPACK VAR INJECTION */}.call(this, {}))
+
+/***/ }),
+/* 117 */
+/*!********************************************!*\
+  !*** ./node_modules/jszip/lib/zipEntry.js ***!
+  \********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var readerFor = __webpack_require__(/*! ./reader/readerFor */ 82);
+var utils = __webpack_require__(/*! ./utils */ 31);
+var CompressedObject = __webpack_require__(/*! ./compressedObject */ 71);
+var crc32fn = __webpack_require__(/*! ./crc32 */ 70);
+var utf8 = __webpack_require__(/*! ./utf8 */ 56);
+var compressions = __webpack_require__(/*! ./compressions */ 89);
+var support = __webpack_require__(/*! ./support */ 50);
+
+var MADE_BY_DOS = 0x00;
+var MADE_BY_UNIX = 0x03;
+
+/**
+ * Find a compression registered in JSZip.
+ * @param {string} compressionMethod the method magic to find.
+ * @return {Object|null} the JSZip compression object, null if none found.
+ */
+var findCompression = function(compressionMethod) {
+    for (var method in compressions) {
+        if (!compressions.hasOwnProperty(method)) {
+            continue;
+        }
+        if (compressions[method].magic === compressionMethod) {
+            return compressions[method];
+        }
+    }
+    return null;
+};
+
+// class ZipEntry {{{
+/**
+ * An entry in the zip file.
+ * @constructor
+ * @param {Object} options Options of the current file.
+ * @param {Object} loadOptions Options for loading the stream.
+ */
+function ZipEntry(options, loadOptions) {
+    this.options = options;
+    this.loadOptions = loadOptions;
+}
+ZipEntry.prototype = {
+    /**
+     * say if the file is encrypted.
+     * @return {boolean} true if the file is encrypted, false otherwise.
+     */
+    isEncrypted: function() {
+        // bit 1 is set
+        return (this.bitFlag & 0x0001) === 0x0001;
+    },
+    /**
+     * say if the file has utf-8 filename/comment.
+     * @return {boolean} true if the filename/comment is in utf-8, false otherwise.
+     */
+    useUTF8: function() {
+        // bit 11 is set
+        return (this.bitFlag & 0x0800) === 0x0800;
+    },
+    /**
+     * Read the local part of a zip file and add the info in this object.
+     * @param {DataReader} reader the reader to use.
+     */
+    readLocalPart: function(reader) {
+        var compression, localExtraFieldsLength;
+
+        // we already know everything from the central dir !
+        // If the central dir data are false, we are doomed.
+        // On the bright side, the local part is scary  : zip64, data descriptors, both, etc.
+        // The less data we get here, the more reliable this should be.
+        // Let's skip the whole header and dash to the data !
+        reader.skip(22);
+        // in some zip created on windows, the filename stored in the central dir contains \ instead of /.
+        // Strangely, the filename here is OK.
+        // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes
+        // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...
+        // Search "unzip mismatching "local" filename continuing with "central" filename version" on
+        // the internet.
+        //
+        // I think I see the logic here : the central directory is used to display
+        // content and the local directory is used to extract the files. Mixing / and \
+        // may be used to display \ to windows users and use / when extracting the files.
+        // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394
+        this.fileNameLength = reader.readInt(2);
+        localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir
+        // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding.
+        this.fileName = reader.readData(this.fileNameLength);
+        reader.skip(localExtraFieldsLength);
+
+        if (this.compressedSize === -1 || this.uncompressedSize === -1) {
+            throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)");
+        }
+
+        compression = findCompression(this.compressionMethod);
+        if (compression === null) { // no compression found
+            throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")");
+        }
+        this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize));
+    },
+
+    /**
+     * Read the central part of a zip file and add the info in this object.
+     * @param {DataReader} reader the reader to use.
+     */
+    readCentralPart: function(reader) {
+        this.versionMadeBy = reader.readInt(2);
+        reader.skip(2);
+        // this.versionNeeded = reader.readInt(2);
+        this.bitFlag = reader.readInt(2);
+        this.compressionMethod = reader.readString(2);
+        this.date = reader.readDate();
+        this.crc32 = reader.readInt(4);
+        this.compressedSize = reader.readInt(4);
+        this.uncompressedSize = reader.readInt(4);
+        var fileNameLength = reader.readInt(2);
+        this.extraFieldsLength = reader.readInt(2);
+        this.fileCommentLength = reader.readInt(2);
+        this.diskNumberStart = reader.readInt(2);
+        this.internalFileAttributes = reader.readInt(2);
+        this.externalFileAttributes = reader.readInt(4);
+        this.localHeaderOffset = reader.readInt(4);
+
+        if (this.isEncrypted()) {
+            throw new Error("Encrypted zip are not supported");
+        }
+
+        // will be read in the local part, see the comments there
+        reader.skip(fileNameLength);
+        this.readExtraFields(reader);
+        this.parseZIP64ExtraField(reader);
+        this.fileComment = reader.readData(this.fileCommentLength);
+    },
+
+    /**
+     * Parse the external file attributes and get the unix/dos permissions.
+     */
+    processAttributes: function () {
+        this.unixPermissions = null;
+        this.dosPermissions = null;
+        var madeBy = this.versionMadeBy >> 8;
+
+        // Check if we have the DOS directory flag set.
+        // We look for it in the DOS and UNIX permissions
+        // but some unknown platform could set it as a compatibility flag.
+        this.dir = this.externalFileAttributes & 0x0010 ? true : false;
+
+        if(madeBy === MADE_BY_DOS) {
+            // first 6 bits (0 to 5)
+            this.dosPermissions = this.externalFileAttributes & 0x3F;
+        }
+
+        if(madeBy === MADE_BY_UNIX) {
+            this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF;
+            // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8);
+        }
+
+        // fail safe : if the name ends with a / it probably means a folder
+        if (!this.dir && this.fileNameStr.slice(-1) === '/') {
+            this.dir = true;
+        }
+    },
+
+    /**
+     * Parse the ZIP64 extra field and merge the info in the current ZipEntry.
+     * @param {DataReader} reader the reader to use.
+     */
+    parseZIP64ExtraField: function(reader) {
+
+        if (!this.extraFields[0x0001]) {
+            return;
+        }
+
+        // should be something, preparing the extra reader
+        var extraReader = readerFor(this.extraFields[0x0001].value);
+
+        // I really hope that these 64bits integer can fit in 32 bits integer, because js
+        // won't let us have more.
+        if (this.uncompressedSize === utils.MAX_VALUE_32BITS) {
+            this.uncompressedSize = extraReader.readInt(8);
+        }
+        if (this.compressedSize === utils.MAX_VALUE_32BITS) {
+            this.compressedSize = extraReader.readInt(8);
+        }
+        if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) {
+            this.localHeaderOffset = extraReader.readInt(8);
+        }
+        if (this.diskNumberStart === utils.MAX_VALUE_32BITS) {
+            this.diskNumberStart = extraReader.readInt(4);
+        }
+    },
+    /**
+     * Read the central part of a zip file and add the info in this object.
+     * @param {DataReader} reader the reader to use.
+     */
+    readExtraFields: function(reader) {
+        var end = reader.index + this.extraFieldsLength,
+            extraFieldId,
+            extraFieldLength,
+            extraFieldValue;
+
+        if (!this.extraFields) {
+            this.extraFields = {};
+        }
+
+        while (reader.index < end) {
+            extraFieldId = reader.readInt(2);
+            extraFieldLength = reader.readInt(2);
+            extraFieldValue = reader.readData(extraFieldLength);
+
+            this.extraFields[extraFieldId] = {
+                id: extraFieldId,
+                length: extraFieldLength,
+                value: extraFieldValue
+            };
+        }
+    },
+    /**
+     * Apply an UTF8 transformation if needed.
+     */
+    handleUTF8: function() {
+        var decodeParamType = support.uint8array ? "uint8array" : "array";
+        if (this.useUTF8()) {
+            this.fileNameStr = utf8.utf8decode(this.fileName);
+            this.fileCommentStr = utf8.utf8decode(this.fileComment);
+        } else {
+            var upath = this.findExtraFieldUnicodePath();
+            if (upath !== null) {
+                this.fileNameStr = upath;
+            } else {
+                // ASCII text or unsupported code page
+                var fileNameByteArray =  utils.transformTo(decodeParamType, this.fileName);
+                this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray);
+            }
+
+            var ucomment = this.findExtraFieldUnicodeComment();
+            if (ucomment !== null) {
+                this.fileCommentStr = ucomment;
+            } else {
+                // ASCII text or unsupported code page
+                var commentByteArray =  utils.transformTo(decodeParamType, this.fileComment);
+                this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray);
+            }
+        }
+    },
+
+    /**
+     * Find the unicode path declared in the extra field, if any.
+     * @return {String} the unicode path, null otherwise.
+     */
+    findExtraFieldUnicodePath: function() {
+        var upathField = this.extraFields[0x7075];
+        if (upathField) {
+            var extraReader = readerFor(upathField.value);
+
+            // wrong version
+            if (extraReader.readInt(1) !== 1) {
+                return null;
+            }
+
+            // the crc of the filename changed, this field is out of date.
+            if (crc32fn(this.fileName) !== extraReader.readInt(4)) {
+                return null;
+            }
+
+            return utf8.utf8decode(extraReader.readData(upathField.length - 5));
+        }
+        return null;
+    },
+
+    /**
+     * Find the unicode comment declared in the extra field, if any.
+     * @return {String} the unicode comment, null otherwise.
+     */
+    findExtraFieldUnicodeComment: function() {
+        var ucommentField = this.extraFields[0x6375];
+        if (ucommentField) {
+            var extraReader = readerFor(ucommentField.value);
+
+            // wrong version
+            if (extraReader.readInt(1) !== 1) {
+                return null;
+            }
+
+            // the crc of the comment changed, this field is out of date.
+            if (crc32fn(this.fileComment) !== extraReader.readInt(4)) {
+                return null;
+            }
+
+            return utf8.utf8decode(extraReader.readData(ucommentField.length - 5));
+        }
+        return null;
+    }
+};
+module.exports = ZipEntry;
+
+
+/***/ }),
+/* 118 */
+/*!***********************************************************!*\
+  !*** ./node_modules/jszip/lib/reader/NodeBufferReader.js ***!
+  \***********************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var Uint8ArrayReader = __webpack_require__(/*! ./Uint8ArrayReader */ 79);
+var utils = __webpack_require__(/*! ../utils */ 31);
+
+function NodeBufferReader(data) {
+    Uint8ArrayReader.call(this, data);
+}
+utils.inherits(NodeBufferReader, Uint8ArrayReader);
+
+/**
+ * @see DataReader.readData
+ */
+NodeBufferReader.prototype.readData = function(size) {
+    this.checkOffset(size);
+    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
+    this.index += size;
+    return result;
+};
+module.exports = NodeBufferReader;
+
+
+/***/ }),
+/* 119 */
+/*!*******************************************************!*\
+  !*** ./node_modules/jszip/lib/reader/StringReader.js ***!
+  \*******************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var DataReader = __webpack_require__(/*! ./DataReader */ 80);
+var utils = __webpack_require__(/*! ../utils */ 31);
+
+function StringReader(data) {
+    DataReader.call(this, data);
+}
+utils.inherits(StringReader, DataReader);
+/**
+ * @see DataReader.byteAt
+ */
+StringReader.prototype.byteAt = function(i) {
+    return this.data.charCodeAt(this.zero + i);
+};
+/**
+ * @see DataReader.lastIndexOfSignature
+ */
+StringReader.prototype.lastIndexOfSignature = function(sig) {
+    return this.data.lastIndexOf(sig) - this.zero;
+};
+/**
+ * @see DataReader.readAndCheckSignature
+ */
+StringReader.prototype.readAndCheckSignature = function (sig) {
+    var data = this.readData(4);
+    return sig === data;
+};
+/**
+ * @see DataReader.readData
+ */
+StringReader.prototype.readData = function(size) {
+    this.checkOffset(size);
+    // this will work because the constructor applied the "& 0xff" mask.
+    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
+    this.index += size;
+    return result;
+};
+module.exports = StringReader;
+
+
+/***/ }),
+/* 120 */
+/*!**********************************************!*\
+  !*** ./node_modules/jszip/lib/zipEntries.js ***!
+  \**********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var readerFor = __webpack_require__(/*! ./reader/readerFor */ 82);
+var utils = __webpack_require__(/*! ./utils */ 31);
+var sig = __webpack_require__(/*! ./signature */ 83);
+var ZipEntry = __webpack_require__(/*! ./zipEntry */ 117);
+var utf8 = __webpack_require__(/*! ./utf8 */ 56);
+var support = __webpack_require__(/*! ./support */ 50);
+//  class ZipEntries {{{
+/**
+ * All the entries in the zip file.
+ * @constructor
+ * @param {Object} loadOptions Options for loading the stream.
+ */
+function ZipEntries(loadOptions) {
+    this.files = [];
+    this.loadOptions = loadOptions;
+}
+ZipEntries.prototype = {
+    /**
+     * Check that the reader is on the specified signature.
+     * @param {string} expectedSignature the expected signature.
+     * @throws {Error} if it is an other signature.
+     */
+    checkSignature: function(expectedSignature) {
+        if (!this.reader.readAndCheckSignature(expectedSignature)) {
+            this.reader.index -= 4;
+            var signature = this.reader.readString(4);
+            throw new Error("Corrupted zip or bug: unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")");
+        }
+    },
+    /**
+     * Check if the given signature is at the given index.
+     * @param {number} askedIndex the index to check.
+     * @param {string} expectedSignature the signature to expect.
+     * @return {boolean} true if the signature is here, false otherwise.
+     */
+    isSignature: function(askedIndex, expectedSignature) {
+        var currentIndex = this.reader.index;
+        this.reader.setIndex(askedIndex);
+        var signature = this.reader.readString(4);
+        var result = signature === expectedSignature;
+        this.reader.setIndex(currentIndex);
+        return result;
+    },
+    /**
+     * Read the end of the central directory.
+     */
+    readBlockEndOfCentral: function() {
+        this.diskNumber = this.reader.readInt(2);
+        this.diskWithCentralDirStart = this.reader.readInt(2);
+        this.centralDirRecordsOnThisDisk = this.reader.readInt(2);
+        this.centralDirRecords = this.reader.readInt(2);
+        this.centralDirSize = this.reader.readInt(4);
+        this.centralDirOffset = this.reader.readInt(4);
+
+        this.zipCommentLength = this.reader.readInt(2);
+        // warning : the encoding depends of the system locale
+        // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded.
+        // On a windows machine, this field is encoded with the localized windows code page.
+        var zipComment = this.reader.readData(this.zipCommentLength);
+        var decodeParamType = support.uint8array ? "uint8array" : "array";
+        // To get consistent behavior with the generation part, we will assume that
+        // this is utf8 encoded unless specified otherwise.
+        var decodeContent = utils.transformTo(decodeParamType, zipComment);
+        this.zipComment = this.loadOptions.decodeFileName(decodeContent);
+    },
+    /**
+     * Read the end of the Zip 64 central directory.
+     * Not merged with the method readEndOfCentral :
+     * The end of central can coexist with its Zip64 brother,
+     * I don't want to read the wrong number of bytes !
+     */
+    readBlockZip64EndOfCentral: function() {
+        this.zip64EndOfCentralSize = this.reader.readInt(8);
+        this.reader.skip(4);
+        // this.versionMadeBy = this.reader.readString(2);
+        // this.versionNeeded = this.reader.readInt(2);
+        this.diskNumber = this.reader.readInt(4);
+        this.diskWithCentralDirStart = this.reader.readInt(4);
+        this.centralDirRecordsOnThisDisk = this.reader.readInt(8);
+        this.centralDirRecords = this.reader.readInt(8);
+        this.centralDirSize = this.reader.readInt(8);
+        this.centralDirOffset = this.reader.readInt(8);
+
+        this.zip64ExtensibleData = {};
+        var extraDataSize = this.zip64EndOfCentralSize - 44,
+            index = 0,
+            extraFieldId,
+            extraFieldLength,
+            extraFieldValue;
+        while (index < extraDataSize) {
+            extraFieldId = this.reader.readInt(2);
+            extraFieldLength = this.reader.readInt(4);
+            extraFieldValue = this.reader.readData(extraFieldLength);
+            this.zip64ExtensibleData[extraFieldId] = {
+                id: extraFieldId,
+                length: extraFieldLength,
+                value: extraFieldValue
+            };
+        }
+    },
+    /**
+     * Read the end of the Zip 64 central directory locator.
+     */
+    readBlockZip64EndOfCentralLocator: function() {
+        this.diskWithZip64CentralDirStart = this.reader.readInt(4);
+        this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);
+        this.disksCount = this.reader.readInt(4);
+        if (this.disksCount > 1) {
+            throw new Error("Multi-volumes zip are not supported");
+        }
+    },
+    /**
+     * Read the local files, based on the offset read in the central part.
+     */
+    readLocalFiles: function() {
+        var i, file;
+        for (i = 0; i < this.files.length; i++) {
+            file = this.files[i];
+            this.reader.setIndex(file.localHeaderOffset);
+            this.checkSignature(sig.LOCAL_FILE_HEADER);
+            file.readLocalPart(this.reader);
+            file.handleUTF8();
+            file.processAttributes();
+        }
+    },
+    /**
+     * Read the central directory.
+     */
+    readCentralDir: function() {
+        var file;
+
+        this.reader.setIndex(this.centralDirOffset);
+        while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) {
+            file = new ZipEntry({
+                zip64: this.zip64
+            }, this.loadOptions);
+            file.readCentralPart(this.reader);
+            this.files.push(file);
+        }
+
+        if (this.centralDirRecords !== this.files.length) {
+            if (this.centralDirRecords !== 0 && this.files.length === 0) {
+                // We expected some records but couldn't find ANY.
+                // This is really suspicious, as if something went wrong.
+                throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length);
+            } else {
+                // We found some records but not all.
+                // Something is wrong but we got something for the user: no error here.
+                // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length);
+            }
+        }
+    },
+    /**
+     * Read the end of central directory.
+     */
+    readEndOfCentral: function() {
+        var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END);
+        if (offset < 0) {
+            // Check if the content is a truncated zip or complete garbage.
+            // A "LOCAL_FILE_HEADER" is not required at the beginning (auto
+            // extractible zip for example) but it can give a good hint.
+            // If an ajax request was used without responseType, we will also
+            // get unreadable data.
+            var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER);
+
+            if (isGarbage) {
+                throw new Error("Can't find end of central directory : is this a zip file ? " +
+                                "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html");
+            } else {
+                throw new Error("Corrupted zip: can't find end of central directory");
+            }
+
+        }
+        this.reader.setIndex(offset);
+        var endOfCentralDirOffset = offset;
+        this.checkSignature(sig.CENTRAL_DIRECTORY_END);
+        this.readBlockEndOfCentral();
+
+
+        /* extract from the zip spec :
+            4)  If one of the fields in the end of central directory
+                record is too small to hold required data, the field
+                should be set to -1 (0xFFFF or 0xFFFFFFFF) and the
+                ZIP64 format record should be created.
+            5)  The end of central directory record and the
+                Zip64 end of central directory locator record must
+                reside on the same disk when splitting or spanning
+                an archive.
+         */
+        if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) {
+            this.zip64 = true;
+
+            /*
+            Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from
+            the zip file can fit into a 32bits integer. This cannot be solved : JavaScript represents
+            all numbers as 64-bit double precision IEEE 754 floating point numbers.
+            So, we have 53bits for integers and bitwise operations treat everything as 32bits.
+            see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators
+            and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5
+            */
+
+            // should look for a zip64 EOCD locator
+            offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
+            if (offset < 0) {
+                throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");
+            }
+            this.reader.setIndex(offset);
+            this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
+            this.readBlockZip64EndOfCentralLocator();
+
+            // now the zip64 EOCD record
+            if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) {
+                // console.warn("ZIP64 end of central directory not where expected.");
+                this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
+                if (this.relativeOffsetEndOfZip64CentralDir < 0) {
+                    throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");
+                }
+            }
+            this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);
+            this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
+            this.readBlockZip64EndOfCentral();
+        }
+
+        var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize;
+        if (this.zip64) {
+            expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator
+            expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize;
+        }
+
+        var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset;
+
+        if (extraBytes > 0) {
+            // console.warn(extraBytes, "extra bytes at beginning or within zipfile");
+            if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) {
+                // The offsets seem wrong, but we have something at the specified offset.
+                // So… we keep it.
+            } else {
+                // the offset is wrong, update the "zero" of the reader
+                // this happens if data has been prepended (crx files for example)
+                this.reader.zero = extraBytes;
+            }
+        } else if (extraBytes < 0) {
+            throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes.");
+        }
+    },
+    prepareReader: function(data) {
+        this.reader = readerFor(data);
+    },
+    /**
+     * Read a zip file and create ZipEntries.
+     * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file.
+     */
+    load: function(data) {
+        this.prepareReader(data);
+        this.readEndOfCentral();
+        this.readCentralDir();
+        this.readLocalFiles();
+    }
+};
+// }}} end of ZipEntries
+module.exports = ZipEntries;
+
+
+/***/ }),
+/* 121 */
+/*!****************************************!*\
+  !*** ./node_modules/jszip/lib/load.js ***!
+  \****************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var utils = __webpack_require__(/*! ./utils */ 31);
+var external = __webpack_require__(/*! ./external */ 58);
+var utf8 = __webpack_require__(/*! ./utf8 */ 56);
+var utils = __webpack_require__(/*! ./utils */ 31);
+var ZipEntries = __webpack_require__(/*! ./zipEntries */ 120);
+var Crc32Probe = __webpack_require__(/*! ./stream/Crc32Probe */ 90);
+var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ 63);
+
+/**
+ * Check the CRC32 of an entry.
+ * @param {ZipEntry} zipEntry the zip entry to check.
+ * @return {Promise} the result.
+ */
+function checkEntryCRC32(zipEntry) {
+    return new external.Promise(function (resolve, reject) {
+        var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());
+        worker.on("error", function (e) {
+            reject(e);
+        })
+        .on("end", function () {
+            if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {
+                reject(new Error("Corrupted zip : CRC32 mismatch"));
+            } else {
+                resolve();
+            }
+        })
+        .resume();
+    });
+}
+
+module.exports = function(data, options) {
+    var zip = this;
+    options = utils.extend(options || {}, {
+        base64: false,
+        checkCRC32: false,
+        optimizedBinaryString: false,
+        createFolders: false,
+        decodeFileName: utf8.utf8decode
+    });
+
+    if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {
+        return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file."));
+    }
+
+    return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64)
+    .then(function(data) {
+        var zipEntries = new ZipEntries(options);
+        zipEntries.load(data);
+        return zipEntries;
+    }).then(function checkCRC32(zipEntries) {
+        var promises = [external.Promise.resolve(zipEntries)];
+        var files = zipEntries.files;
+        if (options.checkCRC32) {
+            for (var i = 0; i < files.length; i++) {
+                promises.push(checkEntryCRC32(files[i]));
+            }
+        }
+        return external.Promise.all(promises);
+    }).then(function addFiles(results) {
+        var zipEntries = results.shift();
+        var files = zipEntries.files;
+        for (var i = 0; i < files.length; i++) {
+            var input = files[i];
+            zip.file(input.fileNameStr, input.decompressed, {
+                binary: true,
+                optimizedBinaryString: true,
+                date: input.date,
+                dir: input.dir,
+                comment : input.fileCommentStr.length ? input.fileCommentStr : null,
+                unixPermissions : input.unixPermissions,
+                dosPermissions : input.dosPermissions,
+                createFolders: options.createFolders
+            });
+        }
+        if (zipEntries.zipComment.length) {
+            zip.comment = zipEntries.zipComment;
+        }
+
+        return zip;
+    });
+};
+
+
+/***/ }),
+/* 122 */
+/*!*******************************************************************!*\
+  !*** ./node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js ***!
+  \*******************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var utils = __webpack_require__(/*! ../utils */ 31);
+var GenericWorker = __webpack_require__(/*! ../stream/GenericWorker */ 37);
+
+/**
+ * A worker that use a nodejs stream as source.
+ * @constructor
+ * @param {String} filename the name of the file entry for this stream.
+ * @param {Readable} stream the nodejs stream.
+ */
+function NodejsStreamInputAdapter(filename, stream) {
+    GenericWorker.call(this, "Nodejs stream input adapter for " + filename);
+    this._upstreamEnded = false;
+    this._bindStream(stream);
+}
+
+utils.inherits(NodejsStreamInputAdapter, GenericWorker);
+
+/**
+ * Prepare the stream and bind the callbacks on it.
+ * Do this ASAP on node 0.10 ! A lazy binding doesn't always work.
+ * @param {Stream} stream the nodejs stream to use.
+ */
+NodejsStreamInputAdapter.prototype._bindStream = function (stream) {
+    var self = this;
+    this._stream = stream;
+    stream.pause();
+    stream
+    .on("data", function (chunk) {
+        self.push({
+            data: chunk,
+            meta : {
+                percent : 0
+            }
+        });
+    })
+    .on("error", function (e) {
+        if(self.isPaused) {
+            this.generatedError = e;
+        } else {
+            self.error(e);
+        }
+    })
+    .on("end", function () {
+        if(self.isPaused) {
+            self._upstreamEnded = true;
+        } else {
+            self.end();
+        }
+    });
+};
+NodejsStreamInputAdapter.prototype.pause = function () {
+    if(!GenericWorker.prototype.pause.call(this)) {
+        return false;
+    }
+    this._stream.pause();
+    return true;
+};
+NodejsStreamInputAdapter.prototype.resume = function () {
+    if(!GenericWorker.prototype.resume.call(this)) {
+        return false;
+    }
+
+    if(this._upstreamEnded) {
+        this.end();
+    } else {
+        this._stream.resume();
+    }
+
+    return true;
+};
+
+module.exports = NodejsStreamInputAdapter;
+
+
+/***/ }),
+/* 123 */
+/*!**********************************************************!*\
+  !*** ./node_modules/jszip/lib/generate/ZipFileWorker.js ***!
+  \**********************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var utils = __webpack_require__(/*! ../utils */ 31);
+var GenericWorker = __webpack_require__(/*! ../stream/GenericWorker */ 37);
+var utf8 = __webpack_require__(/*! ../utf8 */ 56);
+var crc32 = __webpack_require__(/*! ../crc32 */ 70);
+var signature = __webpack_require__(/*! ../signature */ 83);
+
+/**
+ * Transform an integer into a string in hexadecimal.
+ * @private
+ * @param {number} dec the number to convert.
+ * @param {number} bytes the number of bytes to generate.
+ * @returns {string} the result.
+ */
+var decToHex = function(dec, bytes) {
+    var hex = "", i;
+    for (i = 0; i < bytes; i++) {
+        hex += String.fromCharCode(dec & 0xff);
+        dec = dec >>> 8;
+    }
+    return hex;
+};
+
+/**
+ * Generate the UNIX part of the external file attributes.
+ * @param {Object} unixPermissions the unix permissions or null.
+ * @param {Boolean} isDir true if the entry is a directory, false otherwise.
+ * @return {Number} a 32 bit integer.
+ *
+ * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute :
+ *
+ * TTTTsstrwxrwxrwx0000000000ADVSHR
+ * ^^^^____________________________ file type, see zipinfo.c (UNX_*)
+ *     ^^^_________________________ setuid, setgid, sticky
+ *        ^^^^^^^^^________________ permissions
+ *                 ^^^^^^^^^^______ not used ?
+ *                           ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only
+ */
+var generateUnixExternalFileAttr = function (unixPermissions, isDir) {
+
+    var result = unixPermissions;
+    if (!unixPermissions) {
+        // I can't use octal values in strict mode, hence the hexa.
+        //  040775 => 0x41fd
+        // 0100664 => 0x81b4
+        result = isDir ? 0x41fd : 0x81b4;
+    }
+    return (result & 0xFFFF) << 16;
+};
+
+/**
+ * Generate the DOS part of the external file attributes.
+ * @param {Object} dosPermissions the dos permissions or null.
+ * @param {Boolean} isDir true if the entry is a directory, false otherwise.
+ * @return {Number} a 32 bit integer.
+ *
+ * Bit 0     Read-Only
+ * Bit 1     Hidden
+ * Bit 2     System
+ * Bit 3     Volume Label
+ * Bit 4     Directory
+ * Bit 5     Archive
+ */
+var generateDosExternalFileAttr = function (dosPermissions, isDir) {
+
+    // the dir flag is already set for compatibility
+    return (dosPermissions || 0)  & 0x3F;
+};
+
+/**
+ * Generate the various parts used in the construction of the final zip file.
+ * @param {Object} streamInfo the hash with informations about the compressed file.
+ * @param {Boolean} streamedContent is the content streamed ?
+ * @param {Boolean} streamingEnded is the stream finished ?
+ * @param {number} offset the current offset from the start of the zip file.
+ * @param {String} platform let's pretend we are this platform (change platform dependents fields)
+ * @param {Function} encodeFileName the function to encode the file name / comment.
+ * @return {Object} the zip parts.
+ */
+var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) {
+    var file = streamInfo['file'],
+    compression = streamInfo['compression'],
+    useCustomEncoding = encodeFileName !== utf8.utf8encode,
+    encodedFileName = utils.transformTo("string", encodeFileName(file.name)),
+    utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)),
+    comment = file.comment,
+    encodedComment = utils.transformTo("string", encodeFileName(comment)),
+    utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)),
+    useUTF8ForFileName = utfEncodedFileName.length !== file.name.length,
+    useUTF8ForComment = utfEncodedComment.length !== comment.length,
+    dosTime,
+    dosDate,
+    extraFields = "",
+    unicodePathExtraField = "",
+    unicodeCommentExtraField = "",
+    dir = file.dir,
+    date = file.date;
+
+
+    var dataInfo = {
+        crc32 : 0,
+        compressedSize : 0,
+        uncompressedSize : 0
+    };
+
+    // if the content is streamed, the sizes/crc32 are only available AFTER
+    // the end of the stream.
+    if (!streamedContent || streamingEnded) {
+        dataInfo.crc32 = streamInfo['crc32'];
+        dataInfo.compressedSize = streamInfo['compressedSize'];
+        dataInfo.uncompressedSize = streamInfo['uncompressedSize'];
+    }
+
+    var bitflag = 0;
+    if (streamedContent) {
+        // Bit 3: the sizes/crc32 are set to zero in the local header.
+        // The correct values are put in the data descriptor immediately
+        // following the compressed data.
+        bitflag |= 0x0008;
+    }
+    if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) {
+        // Bit 11: Language encoding flag (EFS).
+        bitflag |= 0x0800;
+    }
+
+
+    var extFileAttr = 0;
+    var versionMadeBy = 0;
+    if (dir) {
+        // dos or unix, we set the dos dir flag
+        extFileAttr |= 0x00010;
+    }
+    if(platform === "UNIX") {
+        versionMadeBy = 0x031E; // UNIX, version 3.0
+        extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir);
+    } else { // DOS or other, fallback to DOS
+        versionMadeBy = 0x0014; // DOS, version 2.0
+        extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir);
+    }
+
+    // date
+    // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
+    // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
+    // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html
+
+    dosTime = date.getUTCHours();
+    dosTime = dosTime << 6;
+    dosTime = dosTime | date.getUTCMinutes();
+    dosTime = dosTime << 5;
+    dosTime = dosTime | date.getUTCSeconds() / 2;
+
+    dosDate = date.getUTCFullYear() - 1980;
+    dosDate = dosDate << 4;
+    dosDate = dosDate | (date.getUTCMonth() + 1);
+    dosDate = dosDate << 5;
+    dosDate = dosDate | date.getUTCDate();
+
+    if (useUTF8ForFileName) {
+        // set the unicode path extra field. unzip needs at least one extra
+        // field to correctly handle unicode path, so using the path is as good
+        // as any other information. This could improve the situation with
+        // other archive managers too.
+        // This field is usually used without the utf8 flag, with a non
+        // unicode path in the header (winrar, winzip). This helps (a bit)
+        // with the messy Windows' default compressed folders feature but
+        // breaks on p7zip which doesn't seek the unicode path extra field.
+        // So for now, UTF-8 everywhere !
+        unicodePathExtraField =
+            // Version
+            decToHex(1, 1) +
+            // NameCRC32
+            decToHex(crc32(encodedFileName), 4) +
+            // UnicodeName
+            utfEncodedFileName;
+
+        extraFields +=
+            // Info-ZIP Unicode Path Extra Field
+            "\x75\x70" +
+            // size
+            decToHex(unicodePathExtraField.length, 2) +
+            // content
+            unicodePathExtraField;
+    }
+
+    if(useUTF8ForComment) {
+
+        unicodeCommentExtraField =
+            // Version
+            decToHex(1, 1) +
+            // CommentCRC32
+            decToHex(crc32(encodedComment), 4) +
+            // UnicodeName
+            utfEncodedComment;
+
+        extraFields +=
+            // Info-ZIP Unicode Path Extra Field
+            "\x75\x63" +
+            // size
+            decToHex(unicodeCommentExtraField.length, 2) +
+            // content
+            unicodeCommentExtraField;
+    }
+
+    var header = "";
+
+    // version needed to extract
+    header += "\x0A\x00";
+    // general purpose bit flag
+    header += decToHex(bitflag, 2);
+    // compression method
+    header += compression.magic;
+    // last mod file time
+    header += decToHex(dosTime, 2);
+    // last mod file date
+    header += decToHex(dosDate, 2);
+    // crc-32
+    header += decToHex(dataInfo.crc32, 4);
+    // compressed size
+    header += decToHex(dataInfo.compressedSize, 4);
+    // uncompressed size
+    header += decToHex(dataInfo.uncompressedSize, 4);
+    // file name length
+    header += decToHex(encodedFileName.length, 2);
+    // extra field length
+    header += decToHex(extraFields.length, 2);
+
+
+    var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields;
+
+    var dirRecord = signature.CENTRAL_FILE_HEADER +
+        // version made by (00: DOS)
+        decToHex(versionMadeBy, 2) +
+        // file header (common to file and central directory)
+        header +
+        // file comment length
+        decToHex(encodedComment.length, 2) +
+        // disk number start
+        "\x00\x00" +
+        // internal file attributes TODO
+        "\x00\x00" +
+        // external file attributes
+        decToHex(extFileAttr, 4) +
+        // relative offset of local header
+        decToHex(offset, 4) +
+        // file name
+        encodedFileName +
+        // extra field
+        extraFields +
+        // file comment
+        encodedComment;
+
+    return {
+        fileRecord: fileRecord,
+        dirRecord: dirRecord
+    };
+};
+
+/**
+ * Generate the EOCD record.
+ * @param {Number} entriesCount the number of entries in the zip file.
+ * @param {Number} centralDirLength the length (in bytes) of the central dir.
+ * @param {Number} localDirLength the length (in bytes) of the local dir.
+ * @param {String} comment the zip file comment as a binary string.
+ * @param {Function} encodeFileName the function to encode the comment.
+ * @return {String} the EOCD record.
+ */
+var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) {
+    var dirEnd = "";
+    var encodedComment = utils.transformTo("string", encodeFileName(comment));
+
+    // end of central dir signature
+    dirEnd = signature.CENTRAL_DIRECTORY_END +
+        // number of this disk
+        "\x00\x00" +
+        // number of the disk with the start of the central directory
+        "\x00\x00" +
+        // total number of entries in the central directory on this disk
+        decToHex(entriesCount, 2) +
+        // total number of entries in the central directory
+        decToHex(entriesCount, 2) +
+        // size of the central directory   4 bytes
+        decToHex(centralDirLength, 4) +
+        // offset of start of central directory with respect to the starting disk number
+        decToHex(localDirLength, 4) +
+        // .ZIP file comment length
+        decToHex(encodedComment.length, 2) +
+        // .ZIP file comment
+        encodedComment;
+
+    return dirEnd;
+};
+
+/**
+ * Generate data descriptors for a file entry.
+ * @param {Object} streamInfo the hash generated by a worker, containing informations
+ * on the file entry.
+ * @return {String} the data descriptors.
+ */
+var generateDataDescriptors = function (streamInfo) {
+    var descriptor = "";
+    descriptor = signature.DATA_DESCRIPTOR +
+        // crc-32                          4 bytes
+        decToHex(streamInfo['crc32'], 4) +
+        // compressed size                 4 bytes
+        decToHex(streamInfo['compressedSize'], 4) +
+        // uncompressed size               4 bytes
+        decToHex(streamInfo['uncompressedSize'], 4);
+
+    return descriptor;
+};
+
+
+/**
+ * A worker to concatenate other workers to create a zip file.
+ * @param {Boolean} streamFiles `true` to stream the content of the files,
+ * `false` to accumulate it.
+ * @param {String} comment the comment to use.
+ * @param {String} platform the platform to use, "UNIX" or "DOS".
+ * @param {Function} encodeFileName the function to encode file names and comments.
+ */
+function ZipFileWorker(streamFiles, comment, platform, encodeFileName) {
+    GenericWorker.call(this, "ZipFileWorker");
+    // The number of bytes written so far. This doesn't count accumulated chunks.
+    this.bytesWritten = 0;
+    // The comment of the zip file
+    this.zipComment = comment;
+    // The platform "generating" the zip file.
+    this.zipPlatform = platform;
+    // the function to encode file names and comments.
+    this.encodeFileName = encodeFileName;
+    // Should we stream the content of the files ?
+    this.streamFiles = streamFiles;
+    // If `streamFiles` is false, we will need to accumulate the content of the
+    // files to calculate sizes / crc32 (and write them *before* the content).
+    // This boolean indicates if we are accumulating chunks (it will change a lot
+    // during the lifetime of this worker).
+    this.accumulate = false;
+    // The buffer receiving chunks when accumulating content.
+    this.contentBuffer = [];
+    // The list of generated directory records.
+    this.dirRecords = [];
+    // The offset (in bytes) from the beginning of the zip file for the current source.
+    this.currentSourceOffset = 0;
+    // The total number of entries in this zip file.
+    this.entriesCount = 0;
+    // the name of the file currently being added, null when handling the end of the zip file.
+    // Used for the emited metadata.
+    this.currentFile = null;
+
+
+
+    this._sources = [];
+}
+utils.inherits(ZipFileWorker, GenericWorker);
+
+/**
+ * @see GenericWorker.push
+ */
+ZipFileWorker.prototype.push = function (chunk) {
+
+    var currentFilePercent = chunk.meta.percent || 0;
+    var entriesCount = this.entriesCount;
+    var remainingFiles = this._sources.length;
+
+    if(this.accumulate) {
+        this.contentBuffer.push(chunk);
+    } else {
+        this.bytesWritten += chunk.data.length;
+
+        GenericWorker.prototype.push.call(this, {
+            data : chunk.data,
+            meta : {
+                currentFile : this.currentFile,
+                percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100
+            }
+        });
+    }
+};
+
+/**
+ * The worker started a new source (an other worker).
+ * @param {Object} streamInfo the streamInfo object from the new source.
+ */
+ZipFileWorker.prototype.openedSource = function (streamInfo) {
+    this.currentSourceOffset = this.bytesWritten;
+    this.currentFile = streamInfo['file'].name;
+
+    var streamedContent = this.streamFiles && !streamInfo['file'].dir;
+
+    // don't stream folders (because they don't have any content)
+    if(streamedContent) {
+        var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
+        this.push({
+            data : record.fileRecord,
+            meta : {percent:0}
+        });
+    } else {
+        // we need to wait for the whole file before pushing anything
+        this.accumulate = true;
+    }
+};
+
+/**
+ * The worker finished a source (an other worker).
+ * @param {Object} streamInfo the streamInfo object from the finished source.
+ */
+ZipFileWorker.prototype.closedSource = function (streamInfo) {
+    this.accumulate = false;
+    var streamedContent = this.streamFiles && !streamInfo['file'].dir;
+    var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
+
+    this.dirRecords.push(record.dirRecord);
+    if(streamedContent) {
+        // after the streamed file, we put data descriptors
+        this.push({
+            data : generateDataDescriptors(streamInfo),
+            meta : {percent:100}
+        });
+    } else {
+        // the content wasn't streamed, we need to push everything now
+        // first the file record, then the content
+        this.push({
+            data : record.fileRecord,
+            meta : {percent:0}
+        });
+        while(this.contentBuffer.length) {
+            this.push(this.contentBuffer.shift());
+        }
+    }
+    this.currentFile = null;
+};
+
+/**
+ * @see GenericWorker.flush
+ */
+ZipFileWorker.prototype.flush = function () {
+
+    var localDirLength = this.bytesWritten;
+    for(var i = 0; i < this.dirRecords.length; i++) {
+        this.push({
+            data : this.dirRecords[i],
+            meta : {percent:100}
+        });
+    }
+    var centralDirLength = this.bytesWritten - localDirLength;
+
+    var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName);
+
+    this.push({
+        data : dirEnd,
+        meta : {percent:100}
+    });
+};
+
+/**
+ * Prepare the next source to be read.
+ */
+ZipFileWorker.prototype.prepareNextSource = function () {
+    this.previous = this._sources.shift();
+    this.openedSource(this.previous.streamInfo);
+    if (this.isPaused) {
+        this.previous.pause();
+    } else {
+        this.previous.resume();
+    }
+};
+
+/**
+ * @see GenericWorker.registerPrevious
+ */
+ZipFileWorker.prototype.registerPrevious = function (previous) {
+    this._sources.push(previous);
+    var self = this;
+
+    previous.on('data', function (chunk) {
+        self.processChunk(chunk);
+    });
+    previous.on('end', function () {
+        self.closedSource(self.previous.streamInfo);
+        if(self._sources.length) {
+            self.prepareNextSource();
+        } else {
+            self.end();
+        }
+    });
+    previous.on('error', function (e) {
+        self.error(e);
+    });
+    return this;
+};
+
+/**
+ * @see GenericWorker.resume
+ */
+ZipFileWorker.prototype.resume = function () {
+    if(!GenericWorker.prototype.resume.call(this)) {
+        return false;
+    }
+
+    if (!this.previous && this._sources.length) {
+        this.prepareNextSource();
+        return true;
+    }
+    if (!this.previous && !this._sources.length && !this.generatedError) {
+        this.end();
+        return true;
+    }
+};
+
+/**
+ * @see GenericWorker.error
+ */
+ZipFileWorker.prototype.error = function (e) {
+    var sources = this._sources;
+    if(!GenericWorker.prototype.error.call(this, e)) {
+        return false;
+    }
+    for(var i = 0; i < sources.length; i++) {
+        try {
+            sources[i].error(e);
+        } catch(e) {
+            // the `error` exploded, nothing to do
+        }
+    }
+    return true;
+};
+
+/**
+ * @see GenericWorker.lock
+ */
+ZipFileWorker.prototype.lock = function () {
+    GenericWorker.prototype.lock.call(this);
+    var sources = this._sources;
+    for(var i = 0; i < sources.length; i++) {
+        sources[i].lock();
+    }
+};
+
+module.exports = ZipFileWorker;
+
+
+/***/ }),
+/* 124 */
+/*!************************************************!*\
+  !*** ./node_modules/pako/lib/zlib/gzheader.js ***!
+  \************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// (C) 1995-2013 Jean-loup Gailly and Mark Adler
+// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+//   claim that you wrote the original software. If you use this software
+//   in a product, an acknowledgment in the product documentation would be
+//   appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//   misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+function GZheader() {
+  /* true if compressed data believed to be text */
+  this.text       = 0;
+  /* modification time */
+  this.time       = 0;
+  /* extra flags (not used when writing a gzip file) */
+  this.xflags     = 0;
+  /* operating system */
+  this.os         = 0;
+  /* pointer to extra field or Z_NULL if none */
+  this.extra      = null;
+  /* extra field length (valid if extra != Z_NULL) */
+  this.extra_len  = 0; // Actually, we don't need it in JS,
+                       // but leave for few code modifications
+
+  //
+  // Setup limits is not necessary because in js we should not preallocate memory
+  // for inflate use constant limit in 65536 bytes
+  //
+
+  /* space at extra (only when reading header) */
+  // this.extra_max  = 0;
+  /* pointer to zero-terminated file name or Z_NULL */
+  this.name       = '';
+  /* space at name (only when reading header) */
+  // this.name_max   = 0;
+  /* pointer to zero-terminated comment or Z_NULL */
+  this.comment    = '';
+  /* space at comment (only when reading header) */
+  // this.comm_max   = 0;
+  /* true if there was or will be a header crc */
+  this.hcrc       = 0;
+  /* true when done reading gzip header (not used when writing a gzip file) */
+  this.done       = false;
+}
+
+module.exports = GZheader;
+
+
+/***/ }),
+/* 125 */
+/*!************************************************!*\
+  !*** ./node_modules/pako/lib/zlib/inftrees.js ***!
+  \************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// (C) 1995-2013 Jean-loup Gailly and Mark Adler
+// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+//   claim that you wrote the original software. If you use this software
+//   in a product, an acknowledgment in the product documentation would be
+//   appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//   misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+var utils = __webpack_require__(/*! ../utils/common */ 48);
+
+var MAXBITS = 15;
+var ENOUGH_LENS = 852;
+var ENOUGH_DISTS = 592;
+//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
+
+var CODES = 0;
+var LENS = 1;
+var DISTS = 2;
+
+var lbase = [ /* Length codes 257..285 base */
+  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
+];
+
+var lext = [ /* Length codes 257..285 extra */
+  16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+  19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
+];
+
+var dbase = [ /* Distance codes 0..29 base */
+  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+  8193, 12289, 16385, 24577, 0, 0
+];
+
+var dext = [ /* Distance codes 0..29 extra */
+  16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+  23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+  28, 28, 29, 29, 64, 64
+];
+
+module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts)
+{
+  var bits = opts.bits;
+      //here = opts.here; /* table entry for duplication */
+
+  var len = 0;               /* a code's length in bits */
+  var sym = 0;               /* index of code symbols */
+  var min = 0, max = 0;          /* minimum and maximum code lengths */
+  var root = 0;              /* number of index bits for root table */
+  var curr = 0;              /* number of index bits for current table */
+  var drop = 0;              /* code bits to drop for sub-table */
+  var left = 0;                   /* number of prefix codes available */
+  var used = 0;              /* code entries in table used */
+  var huff = 0;              /* Huffman code */
+  var incr;              /* for incrementing code, index */
+  var fill;              /* index for replicating entries */
+  var low;               /* low bits for current root entry */
+  var mask;              /* mask for low root bits */
+  var next;             /* next available space in table */
+  var base = null;     /* base value table to use */
+  var base_index = 0;
+//  var shoextra;    /* extra bits table to use */
+  var end;                    /* use base and extra for symbol > end */
+  var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];    /* number of codes of each length */
+  var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];     /* offsets in table for each length */
+  var extra = null;
+  var extra_index = 0;
+
+  var here_bits, here_op, here_val;
+
+  /*
+   Process a set of code lengths to create a canonical Huffman code.  The
+   code lengths are lens[0..codes-1].  Each length corresponds to the
+   symbols 0..codes-1.  The Huffman code is generated by first sorting the
+   symbols by length from short to long, and retaining the symbol order
+   for codes with equal lengths.  Then the code starts with all zero bits
+   for the first code of the shortest length, and the codes are integer
+   increments for the same length, and zeros are appended as the length
+   increases.  For the deflate format, these bits are stored backwards
+   from their more natural integer increment ordering, and so when the
+   decoding tables are built in the large loop below, the integer codes
+   are incremented backwards.
+
+   This routine assumes, but does not check, that all of the entries in
+   lens[] are in the range 0..MAXBITS.  The caller must assure this.
+   1..MAXBITS is interpreted as that code length.  zero means that that
+   symbol does not occur in this code.
+
+   The codes are sorted by computing a count of codes for each length,
+   creating from that a table of starting indices for each length in the
+   sorted table, and then entering the symbols in order in the sorted
+   table.  The sorted table is work[], with that space being provided by
+   the caller.
+
+   The length counts are used for other purposes as well, i.e. finding
+   the minimum and maximum length codes, determining if there are any
+   codes at all, checking for a valid set of lengths, and looking ahead
+   at length counts to determine sub-table sizes when building the
+   decoding tables.
+   */
+
+  /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+  for (len = 0; len <= MAXBITS; len++) {
+    count[len] = 0;
+  }
+  for (sym = 0; sym < codes; sym++) {
+    count[lens[lens_index + sym]]++;
+  }
+
+  /* bound code lengths, force root to be within code lengths */
+  root = bits;
+  for (max = MAXBITS; max >= 1; max--) {
+    if (count[max] !== 0) { break; }
+  }
+  if (root > max) {
+    root = max;
+  }
+  if (max === 0) {                     /* no symbols to code at all */
+    //table.op[opts.table_index] = 64;  //here.op = (var char)64;    /* invalid code marker */
+    //table.bits[opts.table_index] = 1;   //here.bits = (var char)1;
+    //table.val[opts.table_index++] = 0;   //here.val = (var short)0;
+    table[table_index++] = (1 << 24) | (64 << 16) | 0;
+
+
+    //table.op[opts.table_index] = 64;
+    //table.bits[opts.table_index] = 1;
+    //table.val[opts.table_index++] = 0;
+    table[table_index++] = (1 << 24) | (64 << 16) | 0;
+
+    opts.bits = 1;
+    return 0;     /* no symbols, but wait for decoding to report error */
+  }
+  for (min = 1; min < max; min++) {
+    if (count[min] !== 0) { break; }
+  }
+  if (root < min) {
+    root = min;
+  }
+
+  /* check for an over-subscribed or incomplete set of lengths */
+  left = 1;
+  for (len = 1; len <= MAXBITS; len++) {
+    left <<= 1;
+    left -= count[len];
+    if (left < 0) {
+      return -1;
+    }        /* over-subscribed */
+  }
+  if (left > 0 && (type === CODES || max !== 1)) {
+    return -1;                      /* incomplete set */
+  }
+
+  /* generate offsets into symbol table for each length for sorting */
+  offs[1] = 0;
+  for (len = 1; len < MAXBITS; len++) {
+    offs[len + 1] = offs[len] + count[len];
+  }
+
+  /* sort symbols by length, by symbol order within each length */
+  for (sym = 0; sym < codes; sym++) {
+    if (lens[lens_index + sym] !== 0) {
+      work[offs[lens[lens_index + sym]]++] = sym;
+    }
+  }
+
+  /*
+   Create and fill in decoding tables.  In this loop, the table being
+   filled is at next and has curr index bits.  The code being used is huff
+   with length len.  That code is converted to an index by dropping drop
+   bits off of the bottom.  For codes where len is less than drop + curr,
+   those top drop + curr - len bits are incremented through all values to
+   fill the table with replicated entries.
+
+   root is the number of index bits for the root table.  When len exceeds
+   root, sub-tables are created pointed to by the root entry with an index
+   of the low root bits of huff.  This is saved in low to check for when a
+   new sub-table should be started.  drop is zero when the root table is
+   being filled, and drop is root when sub-tables are being filled.
+
+   When a new sub-table is needed, it is necessary to look ahead in the
+   code lengths to determine what size sub-table is needed.  The length
+   counts are used for this, and so count[] is decremented as codes are
+   entered in the tables.
+
+   used keeps track of how many table entries have been allocated from the
+   provided *table space.  It is checked for LENS and DIST tables against
+   the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+   the initial root table size constants.  See the comments in inftrees.h
+   for more information.
+
+   sym increments through all symbols, and the loop terminates when
+   all codes of length max, i.e. all codes, have been processed.  This
+   routine permits incomplete codes, so another loop after this one fills
+   in the rest of the decoding tables with invalid code markers.
+   */
+
+  /* set up for code type */
+  // poor man optimization - use if-else instead of switch,
+  // to avoid deopts in old v8
+  if (type === CODES) {
+    base = extra = work;    /* dummy value--not used */
+    end = 19;
+
+  } else if (type === LENS) {
+    base = lbase;
+    base_index -= 257;
+    extra = lext;
+    extra_index -= 257;
+    end = 256;
+
+  } else {                    /* DISTS */
+    base = dbase;
+    extra = dext;
+    end = -1;
+  }
+
+  /* initialize opts for loop */
+  huff = 0;                   /* starting code */
+  sym = 0;                    /* starting code symbol */
+  len = min;                  /* starting code length */
+  next = table_index;              /* current table to fill in */
+  curr = root;                /* current table index bits */
+  drop = 0;                   /* current bits to drop from code for index */
+  low = -1;                   /* trigger new sub-table when len > root */
+  used = 1 << root;          /* use root table entries */
+  mask = used - 1;            /* mask for comparing low */
+
+  /* check available table space */
+  if ((type === LENS && used > ENOUGH_LENS) ||
+    (type === DISTS && used > ENOUGH_DISTS)) {
+    return 1;
+  }
+
+  /* process all codes and make table entries */
+  for (;;) {
+    /* create table entry */
+    here_bits = len - drop;
+    if (work[sym] < end) {
+      here_op = 0;
+      here_val = work[sym];
+    }
+    else if (work[sym] > end) {
+      here_op = extra[extra_index + work[sym]];
+      here_val = base[base_index + work[sym]];
+    }
+    else {
+      here_op = 32 + 64;         /* end of block */
+      here_val = 0;
+    }
+
+    /* replicate for those indices with low len bits equal to huff */
+    incr = 1 << (len - drop);
+    fill = 1 << curr;
+    min = fill;                 /* save offset to next table */
+    do {
+      fill -= incr;
+      table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
+    } while (fill !== 0);
+
+    /* backwards increment the len-bit code huff */
+    incr = 1 << (len - 1);
+    while (huff & incr) {
+      incr >>= 1;
+    }
+    if (incr !== 0) {
+      huff &= incr - 1;
+      huff += incr;
+    } else {
+      huff = 0;
+    }
+
+    /* go to next symbol, update count, len */
+    sym++;
+    if (--count[len] === 0) {
+      if (len === max) { break; }
+      len = lens[lens_index + work[sym]];
+    }
+
+    /* create new sub-table if needed */
+    if (len > root && (huff & mask) !== low) {
+      /* if first time, transition to sub-tables */
+      if (drop === 0) {
+        drop = root;
+      }
+
+      /* increment past last table */
+      next += min;            /* here min is 1 << curr */
+
+      /* determine length of next table */
+      curr = len - drop;
+      left = 1 << curr;
+      while (curr + drop < max) {
+        left -= count[curr + drop];
+        if (left <= 0) { break; }
+        curr++;
+        left <<= 1;
+      }
+
+      /* check for enough space */
+      used += 1 << curr;
+      if ((type === LENS && used > ENOUGH_LENS) ||
+        (type === DISTS && used > ENOUGH_DISTS)) {
+        return 1;
+      }
+
+      /* point entry in root table to sub-table */
+      low = huff & mask;
+      /*table.op[low] = curr;
+      table.bits[low] = root;
+      table.val[low] = next - opts.table_index;*/
+      table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;
+    }
+  }
+
+  /* fill in remaining table entry if code is incomplete (guaranteed to have
+   at most one remaining entry, since if the code is incomplete, the
+   maximum code length that was allowed to get this far is one bit) */
+  if (huff !== 0) {
+    //table.op[next + huff] = 64;            /* invalid code marker */
+    //table.bits[next + huff] = len - drop;
+    //table.val[next + huff] = 0;
+    table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;
+  }
+
+  /* set return parameters */
+  //opts.table_index += used;
+  opts.bits = root;
+  return 0;
+};
+
+
+/***/ }),
+/* 126 */
+/*!***********************************************!*\
+  !*** ./node_modules/pako/lib/zlib/inffast.js ***!
+  \***********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// (C) 1995-2013 Jean-loup Gailly and Mark Adler
+// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+//   claim that you wrote the original software. If you use this software
+//   in a product, an acknowledgment in the product documentation would be
+//   appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//   misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+// See state defs from inflate.js
+var BAD = 30;       /* got a data error -- remain here until reset */
+var TYPE = 12;      /* i: waiting for type bits, including last-flag bit */
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state.mode === LEN
+        strm.avail_in >= 6
+        strm.avail_out >= 258
+        start >= strm.avail_out
+        state.bits < 8
+
+   On return, state.mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm.avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm.avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+module.exports = function inflate_fast(strm, start) {
+  var state;
+  var _in;                    /* local strm.input */
+  var last;                   /* have enough input while in < last */
+  var _out;                   /* local strm.output */
+  var beg;                    /* inflate()'s initial strm.output */
+  var end;                    /* while out < end, enough space available */
+//#ifdef INFLATE_STRICT
+  var dmax;                   /* maximum distance from zlib header */
+//#endif
+  var wsize;                  /* window size or zero if not using window */
+  var whave;                  /* valid bytes in the window */
+  var wnext;                  /* window write index */
+  // Use `s_window` instead `window`, avoid conflict with instrumentation tools
+  var s_window;               /* allocated sliding window, if wsize != 0 */
+  var hold;                   /* local strm.hold */
+  var bits;                   /* local strm.bits */
+  var lcode;                  /* local strm.lencode */
+  var dcode;                  /* local strm.distcode */
+  var lmask;                  /* mask for first level of length codes */
+  var dmask;                  /* mask for first level of distance codes */
+  var here;                   /* retrieved table entry */
+  var op;                     /* code bits, operation, extra bits, or */
+                              /*  window position, window bytes to copy */
+  var len;                    /* match length, unused bytes */
+  var dist;                   /* match distance */
+  var from;                   /* where to copy match from */
+  var from_source;
+
+
+  var input, output; // JS specific, because we have no pointers
+
+  /* copy state to local variables */
+  state = strm.state;
+  //here = state.here;
+  _in = strm.next_in;
+  input = strm.input;
+  last = _in + (strm.avail_in - 5);
+  _out = strm.next_out;
+  output = strm.output;
+  beg = _out - (start - strm.avail_out);
+  end = _out + (strm.avail_out - 257);
+//#ifdef INFLATE_STRICT
+  dmax = state.dmax;
+//#endif
+  wsize = state.wsize;
+  whave = state.whave;
+  wnext = state.wnext;
+  s_window = state.window;
+  hold = state.hold;
+  bits = state.bits;
+  lcode = state.lencode;
+  dcode = state.distcode;
+  lmask = (1 << state.lenbits) - 1;
+  dmask = (1 << state.distbits) - 1;
+
+
+  /* decode literals and length/distances until end-of-block or not enough
+     input data or output space */
+
+  top:
+  do {
+    if (bits < 15) {
+      hold += input[_in++] << bits;
+      bits += 8;
+      hold += input[_in++] << bits;
+      bits += 8;
+    }
+
+    here = lcode[hold & lmask];
+
+    dolen:
+    for (;;) { // Goto emulation
+      op = here >>> 24/*here.bits*/;
+      hold >>>= op;
+      bits -= op;
+      op = (here >>> 16) & 0xff/*here.op*/;
+      if (op === 0) {                          /* literal */
+        //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+        //        "inflate:         literal '%c'\n" :
+        //        "inflate:         literal 0x%02x\n", here.val));
+        output[_out++] = here & 0xffff/*here.val*/;
+      }
+      else if (op & 16) {                     /* length base */
+        len = here & 0xffff/*here.val*/;
+        op &= 15;                           /* number of extra bits */
+        if (op) {
+          if (bits < op) {
+            hold += input[_in++] << bits;
+            bits += 8;
+          }
+          len += hold & ((1 << op) - 1);
+          hold >>>= op;
+          bits -= op;
+        }
+        //Tracevv((stderr, "inflate:         length %u\n", len));
+        if (bits < 15) {
+          hold += input[_in++] << bits;
+          bits += 8;
+          hold += input[_in++] << bits;
+          bits += 8;
+        }
+        here = dcode[hold & dmask];
+
+        dodist:
+        for (;;) { // goto emulation
+          op = here >>> 24/*here.bits*/;
+          hold >>>= op;
+          bits -= op;
+          op = (here >>> 16) & 0xff/*here.op*/;
+
+          if (op & 16) {                      /* distance base */
+            dist = here & 0xffff/*here.val*/;
+            op &= 15;                       /* number of extra bits */
+            if (bits < op) {
+              hold += input[_in++] << bits;
+              bits += 8;
+              if (bits < op) {
+                hold += input[_in++] << bits;
+                bits += 8;
+              }
+            }
+            dist += hold & ((1 << op) - 1);
+//#ifdef INFLATE_STRICT
+            if (dist > dmax) {
+              strm.msg = 'invalid distance too far back';
+              state.mode = BAD;
+              break top;
+            }
+//#endif
+            hold >>>= op;
+            bits -= op;
+            //Tracevv((stderr, "inflate:         distance %u\n", dist));
+            op = _out - beg;                /* max distance in output */
+            if (dist > op) {                /* see if copy from window */
+              op = dist - op;               /* distance back in window */
+              if (op > whave) {
+                if (state.sane) {
+                  strm.msg = 'invalid distance too far back';
+                  state.mode = BAD;
+                  break top;
+                }
+
+// (!) This block is disabled in zlib defaults,
+// don't enable it for binary compatibility
+//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+//                if (len <= op - whave) {
+//                  do {
+//                    output[_out++] = 0;
+//                  } while (--len);
+//                  continue top;
+//                }
+//                len -= op - whave;
+//                do {
+//                  output[_out++] = 0;
+//                } while (--op > whave);
+//                if (op === 0) {
+//                  from = _out - dist;
+//                  do {
+//                    output[_out++] = output[from++];
+//                  } while (--len);
+//                  continue top;
+//                }
+//#endif
+              }
+              from = 0; // window index
+              from_source = s_window;
+              if (wnext === 0) {           /* very common case */
+                from += wsize - op;
+                if (op < len) {         /* some from window */
+                  len -= op;
+                  do {
+                    output[_out++] = s_window[from++];
+                  } while (--op);
+                  from = _out - dist;  /* rest from output */
+                  from_source = output;
+                }
+              }
+              else if (wnext < op) {      /* wrap around window */
+                from += wsize + wnext - op;
+                op -= wnext;
+                if (op < len) {         /* some from end of window */
+                  len -= op;
+                  do {
+                    output[_out++] = s_window[from++];
+                  } while (--op);
+                  from = 0;
+                  if (wnext < len) {  /* some from start of window */
+                    op = wnext;
+                    len -= op;
+                    do {
+                      output[_out++] = s_window[from++];
+                    } while (--op);
+                    from = _out - dist;      /* rest from output */
+                    from_source = output;
+                  }
+                }
+              }
+              else {                      /* contiguous in window */
+                from += wnext - op;
+                if (op < len) {         /* some from window */
+                  len -= op;
+                  do {
+                    output[_out++] = s_window[from++];
+                  } while (--op);
+                  from = _out - dist;  /* rest from output */
+                  from_source = output;
+                }
+              }
+              while (len > 2) {
+                output[_out++] = from_source[from++];
+                output[_out++] = from_source[from++];
+                output[_out++] = from_source[from++];
+                len -= 3;
+              }
+              if (len) {
+                output[_out++] = from_source[from++];
+                if (len > 1) {
+                  output[_out++] = from_source[from++];
+                }
+              }
+            }
+            else {
+              from = _out - dist;          /* copy direct from output */
+              do {                        /* minimum length is three */
+                output[_out++] = output[from++];
+                output[_out++] = output[from++];
+                output[_out++] = output[from++];
+                len -= 3;
+              } while (len > 2);
+              if (len) {
+                output[_out++] = output[from++];
+                if (len > 1) {
+                  output[_out++] = output[from++];
+                }
+              }
+            }
+          }
+          else if ((op & 64) === 0) {          /* 2nd level distance code */
+            here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
+            continue dodist;
+          }
+          else {
+            strm.msg = 'invalid distance code';
+            state.mode = BAD;
+            break top;
+          }
+
+          break; // need to emulate goto via "continue"
+        }
+      }
+      else if ((op & 64) === 0) {              /* 2nd level length code */
+        here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
+        continue dolen;
+      }
+      else if (op & 32) {                     /* end-of-block */
+        //Tracevv((stderr, "inflate:         end of block\n"));
+        state.mode = TYPE;
+        break top;
+      }
+      else {
+        strm.msg = 'invalid literal/length code';
+        state.mode = BAD;
+        break top;
+      }
+
+      break; // need to emulate goto via "continue"
+    }
+  } while (_in < last && _out < end);
+
+  /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+  len = bits >> 3;
+  _in -= len;
+  bits -= len << 3;
+  hold &= (1 << bits) - 1;
+
+  /* update state and return */
+  strm.next_in = _in;
+  strm.next_out = _out;
+  strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));
+  strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
+  state.hold = hold;
+  state.bits = bits;
+  return;
+};
+
+
+/***/ }),
+/* 127 */
+/*!***********************************************!*\
+  !*** ./node_modules/pako/lib/zlib/inflate.js ***!
+  \***********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// (C) 1995-2013 Jean-loup Gailly and Mark Adler
+// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+//   claim that you wrote the original software. If you use this software
+//   in a product, an acknowledgment in the product documentation would be
+//   appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//   misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+var utils         = __webpack_require__(/*! ../utils/common */ 48);
+var adler32       = __webpack_require__(/*! ./adler32 */ 88);
+var crc32         = __webpack_require__(/*! ./crc32 */ 87);
+var inflate_fast  = __webpack_require__(/*! ./inffast */ 126);
+var inflate_table = __webpack_require__(/*! ./inftrees */ 125);
+
+var CODES = 0;
+var LENS = 1;
+var DISTS = 2;
+
+/* Public constants ==========================================================*/
+/* ===========================================================================*/
+
+
+/* Allowed flush values; see deflate() and inflate() below for details */
+//var Z_NO_FLUSH      = 0;
+//var Z_PARTIAL_FLUSH = 1;
+//var Z_SYNC_FLUSH    = 2;
+//var Z_FULL_FLUSH    = 3;
+var Z_FINISH        = 4;
+var Z_BLOCK         = 5;
+var Z_TREES         = 6;
+
+
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+var Z_OK            = 0;
+var Z_STREAM_END    = 1;
+var Z_NEED_DICT     = 2;
+//var Z_ERRNO         = -1;
+var Z_STREAM_ERROR  = -2;
+var Z_DATA_ERROR    = -3;
+var Z_MEM_ERROR     = -4;
+var Z_BUF_ERROR     = -5;
+//var Z_VERSION_ERROR = -6;
+
+/* The deflate compression method */
+var Z_DEFLATED  = 8;
+
+
+/* STATES ====================================================================*/
+/* ===========================================================================*/
+
+
+var    HEAD = 1;       /* i: waiting for magic header */
+var    FLAGS = 2;      /* i: waiting for method and flags (gzip) */
+var    TIME = 3;       /* i: waiting for modification time (gzip) */
+var    OS = 4;         /* i: waiting for extra flags and operating system (gzip) */
+var    EXLEN = 5;      /* i: waiting for extra length (gzip) */
+var    EXTRA = 6;      /* i: waiting for extra bytes (gzip) */
+var    NAME = 7;       /* i: waiting for end of file name (gzip) */
+var    COMMENT = 8;    /* i: waiting for end of comment (gzip) */
+var    HCRC = 9;       /* i: waiting for header crc (gzip) */
+var    DICTID = 10;    /* i: waiting for dictionary check value */
+var    DICT = 11;      /* waiting for inflateSetDictionary() call */
+var        TYPE = 12;      /* i: waiting for type bits, including last-flag bit */
+var        TYPEDO = 13;    /* i: same, but skip check to exit inflate on new block */
+var        STORED = 14;    /* i: waiting for stored size (length and complement) */
+var        COPY_ = 15;     /* i/o: same as COPY below, but only first time in */
+var        COPY = 16;      /* i/o: waiting for input or output to copy stored block */
+var        TABLE = 17;     /* i: waiting for dynamic block table lengths */
+var        LENLENS = 18;   /* i: waiting for code length code lengths */
+var        CODELENS = 19;  /* i: waiting for length/lit and distance code lengths */
+var            LEN_ = 20;      /* i: same as LEN below, but only first time in */
+var            LEN = 21;       /* i: waiting for length/lit/eob code */
+var            LENEXT = 22;    /* i: waiting for length extra bits */
+var            DIST = 23;      /* i: waiting for distance code */
+var            DISTEXT = 24;   /* i: waiting for distance extra bits */
+var            MATCH = 25;     /* o: waiting for output space to copy string */
+var            LIT = 26;       /* o: waiting for output space to write literal */
+var    CHECK = 27;     /* i: waiting for 32-bit check value */
+var    LENGTH = 28;    /* i: waiting for 32-bit length (gzip) */
+var    DONE = 29;      /* finished check, done -- remain here until reset */
+var    BAD = 30;       /* got a data error -- remain here until reset */
+var    MEM = 31;       /* got an inflate() memory error -- remain here until reset */
+var    SYNC = 32;      /* looking for synchronization bytes to restart inflate() */
+
+/* ===========================================================================*/
+
+
+
+var ENOUGH_LENS = 852;
+var ENOUGH_DISTS = 592;
+//var ENOUGH =  (ENOUGH_LENS+ENOUGH_DISTS);
+
+var MAX_WBITS = 15;
+/* 32K LZ77 window */
+var DEF_WBITS = MAX_WBITS;
+
+
+function zswap32(q) {
+  return  (((q >>> 24) & 0xff) +
+          ((q >>> 8) & 0xff00) +
+          ((q & 0xff00) << 8) +
+          ((q & 0xff) << 24));
+}
+
+
+function InflateState() {
+  this.mode = 0;             /* current inflate mode */
+  this.last = false;          /* true if processing last block */
+  this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */
+  this.havedict = false;      /* true if dictionary provided */
+  this.flags = 0;             /* gzip header method and flags (0 if zlib) */
+  this.dmax = 0;              /* zlib header max distance (INFLATE_STRICT) */
+  this.check = 0;             /* protected copy of check value */
+  this.total = 0;             /* protected copy of output count */
+  // TODO: may be {}
+  this.head = null;           /* where to save gzip header information */
+
+  /* sliding window */
+  this.wbits = 0;             /* log base 2 of requested window size */
+  this.wsize = 0;             /* window size or zero if not using window */
+  this.whave = 0;             /* valid bytes in the window */
+  this.wnext = 0;             /* window write index */
+  this.window = null;         /* allocated sliding window, if needed */
+
+  /* bit accumulator */
+  this.hold = 0;              /* input bit accumulator */
+  this.bits = 0;              /* number of bits in "in" */
+
+  /* for string and stored block copying */
+  this.length = 0;            /* literal or length of data to copy */
+  this.offset = 0;            /* distance back to copy string from */
+
+  /* for table and code decoding */
+  this.extra = 0;             /* extra bits needed */
+
+  /* fixed and dynamic code tables */
+  this.lencode = null;          /* starting table for length/literal codes */
+  this.distcode = null;         /* starting table for distance codes */
+  this.lenbits = 0;           /* index bits for lencode */
+  this.distbits = 0;          /* index bits for distcode */
+
+  /* dynamic table building */
+  this.ncode = 0;             /* number of code length code lengths */
+  this.nlen = 0;              /* number of length code lengths */
+  this.ndist = 0;             /* number of distance code lengths */
+  this.have = 0;              /* number of code lengths in lens[] */
+  this.next = null;              /* next available space in codes[] */
+
+  this.lens = new utils.Buf16(320); /* temporary storage for code lengths */
+  this.work = new utils.Buf16(288); /* work area for code table building */
+
+  /*
+   because we don't have pointers in js, we use lencode and distcode directly
+   as buffers so we don't need codes
+  */
+  //this.codes = new utils.Buf32(ENOUGH);       /* space for code tables */
+  this.lendyn = null;              /* dynamic table for length/literal codes (JS specific) */
+  this.distdyn = null;             /* dynamic table for distance codes (JS specific) */
+  this.sane = 0;                   /* if false, allow invalid distance too far */
+  this.back = 0;                   /* bits back of last unprocessed length/lit */
+  this.was = 0;                    /* initial length of match */
+}
+
+function inflateResetKeep(strm) {
+  var state;
+
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  state = strm.state;
+  strm.total_in = strm.total_out = state.total = 0;
+  strm.msg = ''; /*Z_NULL*/
+  if (state.wrap) {       /* to support ill-conceived Java test suite */
+    strm.adler = state.wrap & 1;
+  }
+  state.mode = HEAD;
+  state.last = 0;
+  state.havedict = 0;
+  state.dmax = 32768;
+  state.head = null/*Z_NULL*/;
+  state.hold = 0;
+  state.bits = 0;
+  //state.lencode = state.distcode = state.next = state.codes;
+  state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
+  state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
+
+  state.sane = 1;
+  state.back = -1;
+  //Tracev((stderr, "inflate: reset\n"));
+  return Z_OK;
+}
+
+function inflateReset(strm) {
+  var state;
+
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  state = strm.state;
+  state.wsize = 0;
+  state.whave = 0;
+  state.wnext = 0;
+  return inflateResetKeep(strm);
+
+}
+
+function inflateReset2(strm, windowBits) {
+  var wrap;
+  var state;
+
+  /* get the state */
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  state = strm.state;
+
+  /* extract wrap request from windowBits parameter */
+  if (windowBits < 0) {
+    wrap = 0;
+    windowBits = -windowBits;
+  }
+  else {
+    wrap = (windowBits >> 4) + 1;
+    if (windowBits < 48) {
+      windowBits &= 15;
+    }
+  }
+
+  /* set number of window bits, free window if different */
+  if (windowBits && (windowBits < 8 || windowBits > 15)) {
+    return Z_STREAM_ERROR;
+  }
+  if (state.window !== null && state.wbits !== windowBits) {
+    state.window = null;
+  }
+
+  /* update state and reset the rest of it */
+  state.wrap = wrap;
+  state.wbits = windowBits;
+  return inflateReset(strm);
+}
+
+function inflateInit2(strm, windowBits) {
+  var ret;
+  var state;
+
+  if (!strm) { return Z_STREAM_ERROR; }
+  //strm.msg = Z_NULL;                 /* in case we return an error */
+
+  state = new InflateState();
+
+  //if (state === Z_NULL) return Z_MEM_ERROR;
+  //Tracev((stderr, "inflate: allocated\n"));
+  strm.state = state;
+  state.window = null/*Z_NULL*/;
+  ret = inflateReset2(strm, windowBits);
+  if (ret !== Z_OK) {
+    strm.state = null/*Z_NULL*/;
+  }
+  return ret;
+}
+
+function inflateInit(strm) {
+  return inflateInit2(strm, DEF_WBITS);
+}
+
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter.  This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time.  However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+var virgin = true;
+
+var lenfix, distfix; // We have no pointers in JS, so keep tables separate
+
+function fixedtables(state) {
+  /* build fixed huffman tables if first call (may not be thread safe) */
+  if (virgin) {
+    var sym;
+
+    lenfix = new utils.Buf32(512);
+    distfix = new utils.Buf32(32);
+
+    /* literal/length table */
+    sym = 0;
+    while (sym < 144) { state.lens[sym++] = 8; }
+    while (sym < 256) { state.lens[sym++] = 9; }
+    while (sym < 280) { state.lens[sym++] = 7; }
+    while (sym < 288) { state.lens[sym++] = 8; }
+
+    inflate_table(LENS,  state.lens, 0, 288, lenfix,   0, state.work, { bits: 9 });
+
+    /* distance table */
+    sym = 0;
+    while (sym < 32) { state.lens[sym++] = 5; }
+
+    inflate_table(DISTS, state.lens, 0, 32,   distfix, 0, state.work, { bits: 5 });
+
+    /* do this just once */
+    virgin = false;
+  }
+
+  state.lencode = lenfix;
+  state.lenbits = 9;
+  state.distcode = distfix;
+  state.distbits = 5;
+}
+
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning.  If window does not exist yet, create it.  This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+function updatewindow(strm, src, end, copy) {
+  var dist;
+  var state = strm.state;
+
+  /* if it hasn't been done already, allocate space for the window */
+  if (state.window === null) {
+    state.wsize = 1 << state.wbits;
+    state.wnext = 0;
+    state.whave = 0;
+
+    state.window = new utils.Buf8(state.wsize);
+  }
+
+  /* copy state->wsize or less output bytes into the circular window */
+  if (copy >= state.wsize) {
+    utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
+    state.wnext = 0;
+    state.whave = state.wsize;
+  }
+  else {
+    dist = state.wsize - state.wnext;
+    if (dist > copy) {
+      dist = copy;
+    }
+    //zmemcpy(state->window + state->wnext, end - copy, dist);
+    utils.arraySet(state.window, src, end - copy, dist, state.wnext);
+    copy -= dist;
+    if (copy) {
+      //zmemcpy(state->window, end - copy, copy);
+      utils.arraySet(state.window, src, end - copy, copy, 0);
+      state.wnext = copy;
+      state.whave = state.wsize;
+    }
+    else {
+      state.wnext += dist;
+      if (state.wnext === state.wsize) { state.wnext = 0; }
+      if (state.whave < state.wsize) { state.whave += dist; }
+    }
+  }
+  return 0;
+}
+
+function inflate(strm, flush) {
+  var state;
+  var input, output;          // input/output buffers
+  var next;                   /* next input INDEX */
+  var put;                    /* next output INDEX */
+  var have, left;             /* available input and output */
+  var hold;                   /* bit buffer */
+  var bits;                   /* bits in bit buffer */
+  var _in, _out;              /* save starting available input and output */
+  var copy;                   /* number of stored or match bytes to copy */
+  var from;                   /* where to copy match bytes from */
+  var from_source;
+  var here = 0;               /* current decoding table entry */
+  var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
+  //var last;                   /* parent table entry */
+  var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
+  var len;                    /* length to copy for repeats, bits to drop */
+  var ret;                    /* return code */
+  var hbuf = new utils.Buf8(4);    /* buffer for gzip header crc calculation */
+  var opts;
+
+  var n; // temporary var for NEED_BITS
+
+  var order = /* permutation of code lengths */
+    [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
+
+
+  if (!strm || !strm.state || !strm.output ||
+      (!strm.input && strm.avail_in !== 0)) {
+    return Z_STREAM_ERROR;
+  }
+
+  state = strm.state;
+  if (state.mode === TYPE) { state.mode = TYPEDO; }    /* skip check */
+
+
+  //--- LOAD() ---
+  put = strm.next_out;
+  output = strm.output;
+  left = strm.avail_out;
+  next = strm.next_in;
+  input = strm.input;
+  have = strm.avail_in;
+  hold = state.hold;
+  bits = state.bits;
+  //---
+
+  _in = have;
+  _out = left;
+  ret = Z_OK;
+
+  inf_leave: // goto emulation
+  for (;;) {
+    switch (state.mode) {
+      case HEAD:
+        if (state.wrap === 0) {
+          state.mode = TYPEDO;
+          break;
+        }
+        //=== NEEDBITS(16);
+        while (bits < 16) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        //===//
+        if ((state.wrap & 2) && hold === 0x8b1f) {  /* gzip header */
+          state.check = 0/*crc32(0L, Z_NULL, 0)*/;
+          //=== CRC2(state.check, hold);
+          hbuf[0] = hold & 0xff;
+          hbuf[1] = (hold >>> 8) & 0xff;
+          state.check = crc32(state.check, hbuf, 2, 0);
+          //===//
+
+          //=== INITBITS();
+          hold = 0;
+          bits = 0;
+          //===//
+          state.mode = FLAGS;
+          break;
+        }
+        state.flags = 0;           /* expect zlib header */
+        if (state.head) {
+          state.head.done = false;
+        }
+        if (!(state.wrap & 1) ||   /* check if zlib header allowed */
+          (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {
+          strm.msg = 'incorrect header check';
+          state.mode = BAD;
+          break;
+        }
+        if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {
+          strm.msg = 'unknown compression method';
+          state.mode = BAD;
+          break;
+        }
+        //--- DROPBITS(4) ---//
+        hold >>>= 4;
+        bits -= 4;
+        //---//
+        len = (hold & 0x0f)/*BITS(4)*/ + 8;
+        if (state.wbits === 0) {
+          state.wbits = len;
+        }
+        else if (len > state.wbits) {
+          strm.msg = 'invalid window size';
+          state.mode = BAD;
+          break;
+        }
+        state.dmax = 1 << len;
+        //Tracev((stderr, "inflate:   zlib header ok\n"));
+        strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
+        state.mode = hold & 0x200 ? DICTID : TYPE;
+        //=== INITBITS();
+        hold = 0;
+        bits = 0;
+        //===//
+        break;
+      case FLAGS:
+        //=== NEEDBITS(16); */
+        while (bits < 16) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        //===//
+        state.flags = hold;
+        if ((state.flags & 0xff) !== Z_DEFLATED) {
+          strm.msg = 'unknown compression method';
+          state.mode = BAD;
+          break;
+        }
+        if (state.flags & 0xe000) {
+          strm.msg = 'unknown header flags set';
+          state.mode = BAD;
+          break;
+        }
+        if (state.head) {
+          state.head.text = ((hold >> 8) & 1);
+        }
+        if (state.flags & 0x0200) {
+          //=== CRC2(state.check, hold);
+          hbuf[0] = hold & 0xff;
+          hbuf[1] = (hold >>> 8) & 0xff;
+          state.check = crc32(state.check, hbuf, 2, 0);
+          //===//
+        }
+        //=== INITBITS();
+        hold = 0;
+        bits = 0;
+        //===//
+        state.mode = TIME;
+        /* falls through */
+      case TIME:
+        //=== NEEDBITS(32); */
+        while (bits < 32) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        //===//
+        if (state.head) {
+          state.head.time = hold;
+        }
+        if (state.flags & 0x0200) {
+          //=== CRC4(state.check, hold)
+          hbuf[0] = hold & 0xff;
+          hbuf[1] = (hold >>> 8) & 0xff;
+          hbuf[2] = (hold >>> 16) & 0xff;
+          hbuf[3] = (hold >>> 24) & 0xff;
+          state.check = crc32(state.check, hbuf, 4, 0);
+          //===
+        }
+        //=== INITBITS();
+        hold = 0;
+        bits = 0;
+        //===//
+        state.mode = OS;
+        /* falls through */
+      case OS:
+        //=== NEEDBITS(16); */
+        while (bits < 16) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        //===//
+        if (state.head) {
+          state.head.xflags = (hold & 0xff);
+          state.head.os = (hold >> 8);
+        }
+        if (state.flags & 0x0200) {
+          //=== CRC2(state.check, hold);
+          hbuf[0] = hold & 0xff;
+          hbuf[1] = (hold >>> 8) & 0xff;
+          state.check = crc32(state.check, hbuf, 2, 0);
+          //===//
+        }
+        //=== INITBITS();
+        hold = 0;
+        bits = 0;
+        //===//
+        state.mode = EXLEN;
+        /* falls through */
+      case EXLEN:
+        if (state.flags & 0x0400) {
+          //=== NEEDBITS(16); */
+          while (bits < 16) {
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+          }
+          //===//
+          state.length = hold;
+          if (state.head) {
+            state.head.extra_len = hold;
+          }
+          if (state.flags & 0x0200) {
+            //=== CRC2(state.check, hold);
+            hbuf[0] = hold & 0xff;
+            hbuf[1] = (hold >>> 8) & 0xff;
+            state.check = crc32(state.check, hbuf, 2, 0);
+            //===//
+          }
+          //=== INITBITS();
+          hold = 0;
+          bits = 0;
+          //===//
+        }
+        else if (state.head) {
+          state.head.extra = null/*Z_NULL*/;
+        }
+        state.mode = EXTRA;
+        /* falls through */
+      case EXTRA:
+        if (state.flags & 0x0400) {
+          copy = state.length;
+          if (copy > have) { copy = have; }
+          if (copy) {
+            if (state.head) {
+              len = state.head.extra_len - state.length;
+              if (!state.head.extra) {
+                // Use untyped array for more convenient processing later
+                state.head.extra = new Array(state.head.extra_len);
+              }
+              utils.arraySet(
+                state.head.extra,
+                input,
+                next,
+                // extra field is limited to 65536 bytes
+                // - no need for additional size check
+                copy,
+                /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
+                len
+              );
+              //zmemcpy(state.head.extra + len, next,
+              //        len + copy > state.head.extra_max ?
+              //        state.head.extra_max - len : copy);
+            }
+            if (state.flags & 0x0200) {
+              state.check = crc32(state.check, input, copy, next);
+            }
+            have -= copy;
+            next += copy;
+            state.length -= copy;
+          }
+          if (state.length) { break inf_leave; }
+        }
+        state.length = 0;
+        state.mode = NAME;
+        /* falls through */
+      case NAME:
+        if (state.flags & 0x0800) {
+          if (have === 0) { break inf_leave; }
+          copy = 0;
+          do {
+            // TODO: 2 or 1 bytes?
+            len = input[next + copy++];
+            /* use constant limit because in js we should not preallocate memory */
+            if (state.head && len &&
+                (state.length < 65536 /*state.head.name_max*/)) {
+              state.head.name += String.fromCharCode(len);
+            }
+          } while (len && copy < have);
+
+          if (state.flags & 0x0200) {
+            state.check = crc32(state.check, input, copy, next);
+          }
+          have -= copy;
+          next += copy;
+          if (len) { break inf_leave; }
+        }
+        else if (state.head) {
+          state.head.name = null;
+        }
+        state.length = 0;
+        state.mode = COMMENT;
+        /* falls through */
+      case COMMENT:
+        if (state.flags & 0x1000) {
+          if (have === 0) { break inf_leave; }
+          copy = 0;
+          do {
+            len = input[next + copy++];
+            /* use constant limit because in js we should not preallocate memory */
+            if (state.head && len &&
+                (state.length < 65536 /*state.head.comm_max*/)) {
+              state.head.comment += String.fromCharCode(len);
+            }
+          } while (len && copy < have);
+          if (state.flags & 0x0200) {
+            state.check = crc32(state.check, input, copy, next);
+          }
+          have -= copy;
+          next += copy;
+          if (len) { break inf_leave; }
+        }
+        else if (state.head) {
+          state.head.comment = null;
+        }
+        state.mode = HCRC;
+        /* falls through */
+      case HCRC:
+        if (state.flags & 0x0200) {
+          //=== NEEDBITS(16); */
+          while (bits < 16) {
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+          }
+          //===//
+          if (hold !== (state.check & 0xffff)) {
+            strm.msg = 'header crc mismatch';
+            state.mode = BAD;
+            break;
+          }
+          //=== INITBITS();
+          hold = 0;
+          bits = 0;
+          //===//
+        }
+        if (state.head) {
+          state.head.hcrc = ((state.flags >> 9) & 1);
+          state.head.done = true;
+        }
+        strm.adler = state.check = 0;
+        state.mode = TYPE;
+        break;
+      case DICTID:
+        //=== NEEDBITS(32); */
+        while (bits < 32) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        //===//
+        strm.adler = state.check = zswap32(hold);
+        //=== INITBITS();
+        hold = 0;
+        bits = 0;
+        //===//
+        state.mode = DICT;
+        /* falls through */
+      case DICT:
+        if (state.havedict === 0) {
+          //--- RESTORE() ---
+          strm.next_out = put;
+          strm.avail_out = left;
+          strm.next_in = next;
+          strm.avail_in = have;
+          state.hold = hold;
+          state.bits = bits;
+          //---
+          return Z_NEED_DICT;
+        }
+        strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
+        state.mode = TYPE;
+        /* falls through */
+      case TYPE:
+        if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }
+        /* falls through */
+      case TYPEDO:
+        if (state.last) {
+          //--- BYTEBITS() ---//
+          hold >>>= bits & 7;
+          bits -= bits & 7;
+          //---//
+          state.mode = CHECK;
+          break;
+        }
+        //=== NEEDBITS(3); */
+        while (bits < 3) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        //===//
+        state.last = (hold & 0x01)/*BITS(1)*/;
+        //--- DROPBITS(1) ---//
+        hold >>>= 1;
+        bits -= 1;
+        //---//
+
+        switch ((hold & 0x03)/*BITS(2)*/) {
+          case 0:                             /* stored block */
+            //Tracev((stderr, "inflate:     stored block%s\n",
+            //        state.last ? " (last)" : ""));
+            state.mode = STORED;
+            break;
+          case 1:                             /* fixed block */
+            fixedtables(state);
+            //Tracev((stderr, "inflate:     fixed codes block%s\n",
+            //        state.last ? " (last)" : ""));
+            state.mode = LEN_;             /* decode codes */
+            if (flush === Z_TREES) {
+              //--- DROPBITS(2) ---//
+              hold >>>= 2;
+              bits -= 2;
+              //---//
+              break inf_leave;
+            }
+            break;
+          case 2:                             /* dynamic block */
+            //Tracev((stderr, "inflate:     dynamic codes block%s\n",
+            //        state.last ? " (last)" : ""));
+            state.mode = TABLE;
+            break;
+          case 3:
+            strm.msg = 'invalid block type';
+            state.mode = BAD;
+        }
+        //--- DROPBITS(2) ---//
+        hold >>>= 2;
+        bits -= 2;
+        //---//
+        break;
+      case STORED:
+        //--- BYTEBITS() ---// /* go to byte boundary */
+        hold >>>= bits & 7;
+        bits -= bits & 7;
+        //---//
+        //=== NEEDBITS(32); */
+        while (bits < 32) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        //===//
+        if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {
+          strm.msg = 'invalid stored block lengths';
+          state.mode = BAD;
+          break;
+        }
+        state.length = hold & 0xffff;
+        //Tracev((stderr, "inflate:       stored length %u\n",
+        //        state.length));
+        //=== INITBITS();
+        hold = 0;
+        bits = 0;
+        //===//
+        state.mode = COPY_;
+        if (flush === Z_TREES) { break inf_leave; }
+        /* falls through */
+      case COPY_:
+        state.mode = COPY;
+        /* falls through */
+      case COPY:
+        copy = state.length;
+        if (copy) {
+          if (copy > have) { copy = have; }
+          if (copy > left) { copy = left; }
+          if (copy === 0) { break inf_leave; }
+          //--- zmemcpy(put, next, copy); ---
+          utils.arraySet(output, input, next, copy, put);
+          //---//
+          have -= copy;
+          next += copy;
+          left -= copy;
+          put += copy;
+          state.length -= copy;
+          break;
+        }
+        //Tracev((stderr, "inflate:       stored end\n"));
+        state.mode = TYPE;
+        break;
+      case TABLE:
+        //=== NEEDBITS(14); */
+        while (bits < 14) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        //===//
+        state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;
+        //--- DROPBITS(5) ---//
+        hold >>>= 5;
+        bits -= 5;
+        //---//
+        state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;
+        //--- DROPBITS(5) ---//
+        hold >>>= 5;
+        bits -= 5;
+        //---//
+        state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;
+        //--- DROPBITS(4) ---//
+        hold >>>= 4;
+        bits -= 4;
+        //---//
+//#ifndef PKZIP_BUG_WORKAROUND
+        if (state.nlen > 286 || state.ndist > 30) {
+          strm.msg = 'too many length or distance symbols';
+          state.mode = BAD;
+          break;
+        }
+//#endif
+        //Tracev((stderr, "inflate:       table sizes ok\n"));
+        state.have = 0;
+        state.mode = LENLENS;
+        /* falls through */
+      case LENLENS:
+        while (state.have < state.ncode) {
+          //=== NEEDBITS(3);
+          while (bits < 3) {
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+          }
+          //===//
+          state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);
+          //--- DROPBITS(3) ---//
+          hold >>>= 3;
+          bits -= 3;
+          //---//
+        }
+        while (state.have < 19) {
+          state.lens[order[state.have++]] = 0;
+        }
+        // We have separate tables & no pointers. 2 commented lines below not needed.
+        //state.next = state.codes;
+        //state.lencode = state.next;
+        // Switch to use dynamic table
+        state.lencode = state.lendyn;
+        state.lenbits = 7;
+
+        opts = { bits: state.lenbits };
+        ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
+        state.lenbits = opts.bits;
+
+        if (ret) {
+          strm.msg = 'invalid code lengths set';
+          state.mode = BAD;
+          break;
+        }
+        //Tracev((stderr, "inflate:       code lengths ok\n"));
+        state.have = 0;
+        state.mode = CODELENS;
+        /* falls through */
+      case CODELENS:
+        while (state.have < state.nlen + state.ndist) {
+          for (;;) {
+            here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/
+            here_bits = here >>> 24;
+            here_op = (here >>> 16) & 0xff;
+            here_val = here & 0xffff;
+
+            if ((here_bits) <= bits) { break; }
+            //--- PULLBYTE() ---//
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+            //---//
+          }
+          if (here_val < 16) {
+            //--- DROPBITS(here.bits) ---//
+            hold >>>= here_bits;
+            bits -= here_bits;
+            //---//
+            state.lens[state.have++] = here_val;
+          }
+          else {
+            if (here_val === 16) {
+              //=== NEEDBITS(here.bits + 2);
+              n = here_bits + 2;
+              while (bits < n) {
+                if (have === 0) { break inf_leave; }
+                have--;
+                hold += input[next++] << bits;
+                bits += 8;
+              }
+              //===//
+              //--- DROPBITS(here.bits) ---//
+              hold >>>= here_bits;
+              bits -= here_bits;
+              //---//
+              if (state.have === 0) {
+                strm.msg = 'invalid bit length repeat';
+                state.mode = BAD;
+                break;
+              }
+              len = state.lens[state.have - 1];
+              copy = 3 + (hold & 0x03);//BITS(2);
+              //--- DROPBITS(2) ---//
+              hold >>>= 2;
+              bits -= 2;
+              //---//
+            }
+            else if (here_val === 17) {
+              //=== NEEDBITS(here.bits + 3);
+              n = here_bits + 3;
+              while (bits < n) {
+                if (have === 0) { break inf_leave; }
+                have--;
+                hold += input[next++] << bits;
+                bits += 8;
+              }
+              //===//
+              //--- DROPBITS(here.bits) ---//
+              hold >>>= here_bits;
+              bits -= here_bits;
+              //---//
+              len = 0;
+              copy = 3 + (hold & 0x07);//BITS(3);
+              //--- DROPBITS(3) ---//
+              hold >>>= 3;
+              bits -= 3;
+              //---//
+            }
+            else {
+              //=== NEEDBITS(here.bits + 7);
+              n = here_bits + 7;
+              while (bits < n) {
+                if (have === 0) { break inf_leave; }
+                have--;
+                hold += input[next++] << bits;
+                bits += 8;
+              }
+              //===//
+              //--- DROPBITS(here.bits) ---//
+              hold >>>= here_bits;
+              bits -= here_bits;
+              //---//
+              len = 0;
+              copy = 11 + (hold & 0x7f);//BITS(7);
+              //--- DROPBITS(7) ---//
+              hold >>>= 7;
+              bits -= 7;
+              //---//
+            }
+            if (state.have + copy > state.nlen + state.ndist) {
+              strm.msg = 'invalid bit length repeat';
+              state.mode = BAD;
+              break;
+            }
+            while (copy--) {
+              state.lens[state.have++] = len;
+            }
+          }
+        }
+
+        /* handle error breaks in while */
+        if (state.mode === BAD) { break; }
+
+        /* check for end-of-block code (better have one) */
+        if (state.lens[256] === 0) {
+          strm.msg = 'invalid code -- missing end-of-block';
+          state.mode = BAD;
+          break;
+        }
+
+        /* build code tables -- note: do not change the lenbits or distbits
+           values here (9 and 6) without reading the comments in inftrees.h
+           concerning the ENOUGH constants, which depend on those values */
+        state.lenbits = 9;
+
+        opts = { bits: state.lenbits };
+        ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
+        // We have separate tables & no pointers. 2 commented lines below not needed.
+        // state.next_index = opts.table_index;
+        state.lenbits = opts.bits;
+        // state.lencode = state.next;
+
+        if (ret) {
+          strm.msg = 'invalid literal/lengths set';
+          state.mode = BAD;
+          break;
+        }
+
+        state.distbits = 6;
+        //state.distcode.copy(state.codes);
+        // Switch to use dynamic table
+        state.distcode = state.distdyn;
+        opts = { bits: state.distbits };
+        ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
+        // We have separate tables & no pointers. 2 commented lines below not needed.
+        // state.next_index = opts.table_index;
+        state.distbits = opts.bits;
+        // state.distcode = state.next;
+
+        if (ret) {
+          strm.msg = 'invalid distances set';
+          state.mode = BAD;
+          break;
+        }
+        //Tracev((stderr, 'inflate:       codes ok\n'));
+        state.mode = LEN_;
+        if (flush === Z_TREES) { break inf_leave; }
+        /* falls through */
+      case LEN_:
+        state.mode = LEN;
+        /* falls through */
+      case LEN:
+        if (have >= 6 && left >= 258) {
+          //--- RESTORE() ---
+          strm.next_out = put;
+          strm.avail_out = left;
+          strm.next_in = next;
+          strm.avail_in = have;
+          state.hold = hold;
+          state.bits = bits;
+          //---
+          inflate_fast(strm, _out);
+          //--- LOAD() ---
+          put = strm.next_out;
+          output = strm.output;
+          left = strm.avail_out;
+          next = strm.next_in;
+          input = strm.input;
+          have = strm.avail_in;
+          hold = state.hold;
+          bits = state.bits;
+          //---
+
+          if (state.mode === TYPE) {
+            state.back = -1;
+          }
+          break;
+        }
+        state.back = 0;
+        for (;;) {
+          here = state.lencode[hold & ((1 << state.lenbits) - 1)];  /*BITS(state.lenbits)*/
+          here_bits = here >>> 24;
+          here_op = (here >>> 16) & 0xff;
+          here_val = here & 0xffff;
+
+          if (here_bits <= bits) { break; }
+          //--- PULLBYTE() ---//
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+          //---//
+        }
+        if (here_op && (here_op & 0xf0) === 0) {
+          last_bits = here_bits;
+          last_op = here_op;
+          last_val = here_val;
+          for (;;) {
+            here = state.lencode[last_val +
+                    ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
+            here_bits = here >>> 24;
+            here_op = (here >>> 16) & 0xff;
+            here_val = here & 0xffff;
+
+            if ((last_bits + here_bits) <= bits) { break; }
+            //--- PULLBYTE() ---//
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+            //---//
+          }
+          //--- DROPBITS(last.bits) ---//
+          hold >>>= last_bits;
+          bits -= last_bits;
+          //---//
+          state.back += last_bits;
+        }
+        //--- DROPBITS(here.bits) ---//
+        hold >>>= here_bits;
+        bits -= here_bits;
+        //---//
+        state.back += here_bits;
+        state.length = here_val;
+        if (here_op === 0) {
+          //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+          //        "inflate:         literal '%c'\n" :
+          //        "inflate:         literal 0x%02x\n", here.val));
+          state.mode = LIT;
+          break;
+        }
+        if (here_op & 32) {
+          //Tracevv((stderr, "inflate:         end of block\n"));
+          state.back = -1;
+          state.mode = TYPE;
+          break;
+        }
+        if (here_op & 64) {
+          strm.msg = 'invalid literal/length code';
+          state.mode = BAD;
+          break;
+        }
+        state.extra = here_op & 15;
+        state.mode = LENEXT;
+        /* falls through */
+      case LENEXT:
+        if (state.extra) {
+          //=== NEEDBITS(state.extra);
+          n = state.extra;
+          while (bits < n) {
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+          }
+          //===//
+          state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
+          //--- DROPBITS(state.extra) ---//
+          hold >>>= state.extra;
+          bits -= state.extra;
+          //---//
+          state.back += state.extra;
+        }
+        //Tracevv((stderr, "inflate:         length %u\n", state.length));
+        state.was = state.length;
+        state.mode = DIST;
+        /* falls through */
+      case DIST:
+        for (;;) {
+          here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/
+          here_bits = here >>> 24;
+          here_op = (here >>> 16) & 0xff;
+          here_val = here & 0xffff;
+
+          if ((here_bits) <= bits) { break; }
+          //--- PULLBYTE() ---//
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+          //---//
+        }
+        if ((here_op & 0xf0) === 0) {
+          last_bits = here_bits;
+          last_op = here_op;
+          last_val = here_val;
+          for (;;) {
+            here = state.distcode[last_val +
+                    ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
+            here_bits = here >>> 24;
+            here_op = (here >>> 16) & 0xff;
+            here_val = here & 0xffff;
+
+            if ((last_bits + here_bits) <= bits) { break; }
+            //--- PULLBYTE() ---//
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+            //---//
+          }
+          //--- DROPBITS(last.bits) ---//
+          hold >>>= last_bits;
+          bits -= last_bits;
+          //---//
+          state.back += last_bits;
+        }
+        //--- DROPBITS(here.bits) ---//
+        hold >>>= here_bits;
+        bits -= here_bits;
+        //---//
+        state.back += here_bits;
+        if (here_op & 64) {
+          strm.msg = 'invalid distance code';
+          state.mode = BAD;
+          break;
+        }
+        state.offset = here_val;
+        state.extra = (here_op) & 15;
+        state.mode = DISTEXT;
+        /* falls through */
+      case DISTEXT:
+        if (state.extra) {
+          //=== NEEDBITS(state.extra);
+          n = state.extra;
+          while (bits < n) {
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+          }
+          //===//
+          state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
+          //--- DROPBITS(state.extra) ---//
+          hold >>>= state.extra;
+          bits -= state.extra;
+          //---//
+          state.back += state.extra;
+        }
+//#ifdef INFLATE_STRICT
+        if (state.offset > state.dmax) {
+          strm.msg = 'invalid distance too far back';
+          state.mode = BAD;
+          break;
+        }
+//#endif
+        //Tracevv((stderr, "inflate:         distance %u\n", state.offset));
+        state.mode = MATCH;
+        /* falls through */
+      case MATCH:
+        if (left === 0) { break inf_leave; }
+        copy = _out - left;
+        if (state.offset > copy) {         /* copy from window */
+          copy = state.offset - copy;
+          if (copy > state.whave) {
+            if (state.sane) {
+              strm.msg = 'invalid distance too far back';
+              state.mode = BAD;
+              break;
+            }
+// (!) This block is disabled in zlib defaults,
+// don't enable it for binary compatibility
+//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+//          Trace((stderr, "inflate.c too far\n"));
+//          copy -= state.whave;
+//          if (copy > state.length) { copy = state.length; }
+//          if (copy > left) { copy = left; }
+//          left -= copy;
+//          state.length -= copy;
+//          do {
+//            output[put++] = 0;
+//          } while (--copy);
+//          if (state.length === 0) { state.mode = LEN; }
+//          break;
+//#endif
+          }
+          if (copy > state.wnext) {
+            copy -= state.wnext;
+            from = state.wsize - copy;
+          }
+          else {
+            from = state.wnext - copy;
+          }
+          if (copy > state.length) { copy = state.length; }
+          from_source = state.window;
+        }
+        else {                              /* copy from output */
+          from_source = output;
+          from = put - state.offset;
+          copy = state.length;
+        }
+        if (copy > left) { copy = left; }
+        left -= copy;
+        state.length -= copy;
+        do {
+          output[put++] = from_source[from++];
+        } while (--copy);
+        if (state.length === 0) { state.mode = LEN; }
+        break;
+      case LIT:
+        if (left === 0) { break inf_leave; }
+        output[put++] = state.length;
+        left--;
+        state.mode = LEN;
+        break;
+      case CHECK:
+        if (state.wrap) {
+          //=== NEEDBITS(32);
+          while (bits < 32) {
+            if (have === 0) { break inf_leave; }
+            have--;
+            // Use '|' instead of '+' to make sure that result is signed
+            hold |= input[next++] << bits;
+            bits += 8;
+          }
+          //===//
+          _out -= left;
+          strm.total_out += _out;
+          state.total += _out;
+          if (_out) {
+            strm.adler = state.check =
+                /*UPDATE(state.check, put - _out, _out);*/
+                (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));
+
+          }
+          _out = left;
+          // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
+          if ((state.flags ? hold : zswap32(hold)) !== state.check) {
+            strm.msg = 'incorrect data check';
+            state.mode = BAD;
+            break;
+          }
+          //=== INITBITS();
+          hold = 0;
+          bits = 0;
+          //===//
+          //Tracev((stderr, "inflate:   check matches trailer\n"));
+        }
+        state.mode = LENGTH;
+        /* falls through */
+      case LENGTH:
+        if (state.wrap && state.flags) {
+          //=== NEEDBITS(32);
+          while (bits < 32) {
+            if (have === 0) { break inf_leave; }
+            have--;
+            hold += input[next++] << bits;
+            bits += 8;
+          }
+          //===//
+          if (hold !== (state.total & 0xffffffff)) {
+            strm.msg = 'incorrect length check';
+            state.mode = BAD;
+            break;
+          }
+          //=== INITBITS();
+          hold = 0;
+          bits = 0;
+          //===//
+          //Tracev((stderr, "inflate:   length matches trailer\n"));
+        }
+        state.mode = DONE;
+        /* falls through */
+      case DONE:
+        ret = Z_STREAM_END;
+        break inf_leave;
+      case BAD:
+        ret = Z_DATA_ERROR;
+        break inf_leave;
+      case MEM:
+        return Z_MEM_ERROR;
+      case SYNC:
+        /* falls through */
+      default:
+        return Z_STREAM_ERROR;
+    }
+  }
+
+  // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
+
+  /*
+     Return from inflate(), updating the total counts and the check value.
+     If there was no progress during the inflate() call, return a buffer
+     error.  Call updatewindow() to create and/or update the window state.
+     Note: a memory error from inflate() is non-recoverable.
+   */
+
+  //--- RESTORE() ---
+  strm.next_out = put;
+  strm.avail_out = left;
+  strm.next_in = next;
+  strm.avail_in = have;
+  state.hold = hold;
+  state.bits = bits;
+  //---
+
+  if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&
+                      (state.mode < CHECK || flush !== Z_FINISH))) {
+    if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
+      state.mode = MEM;
+      return Z_MEM_ERROR;
+    }
+  }
+  _in -= strm.avail_in;
+  _out -= strm.avail_out;
+  strm.total_in += _in;
+  strm.total_out += _out;
+  state.total += _out;
+  if (state.wrap && _out) {
+    strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/
+      (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));
+  }
+  strm.data_type = state.bits + (state.last ? 64 : 0) +
+                    (state.mode === TYPE ? 128 : 0) +
+                    (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
+  if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {
+    ret = Z_BUF_ERROR;
+  }
+  return ret;
+}
+
+function inflateEnd(strm) {
+
+  if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
+    return Z_STREAM_ERROR;
+  }
+
+  var state = strm.state;
+  if (state.window) {
+    state.window = null;
+  }
+  strm.state = null;
+  return Z_OK;
+}
+
+function inflateGetHeader(strm, head) {
+  var state;
+
+  /* check state */
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  state = strm.state;
+  if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }
+
+  /* save header structure */
+  state.head = head;
+  head.done = false;
+  return Z_OK;
+}
+
+function inflateSetDictionary(strm, dictionary) {
+  var dictLength = dictionary.length;
+
+  var state;
+  var dictid;
+  var ret;
+
+  /* check state */
+  if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
+  state = strm.state;
+
+  if (state.wrap !== 0 && state.mode !== DICT) {
+    return Z_STREAM_ERROR;
+  }
+
+  /* check for correct dictionary identifier */
+  if (state.mode === DICT) {
+    dictid = 1; /* adler32(0, null, 0)*/
+    /* dictid = adler32(dictid, dictionary, dictLength); */
+    dictid = adler32(dictid, dictionary, dictLength, 0);
+    if (dictid !== state.check) {
+      return Z_DATA_ERROR;
+    }
+  }
+  /* copy dictionary to window using updatewindow(), which will amend the
+   existing dictionary if appropriate */
+  ret = updatewindow(strm, dictionary, dictLength, dictLength);
+  if (ret) {
+    state.mode = MEM;
+    return Z_MEM_ERROR;
+  }
+  state.havedict = 1;
+  // Tracev((stderr, "inflate:   dictionary set\n"));
+  return Z_OK;
+}
+
+exports.inflateReset = inflateReset;
+exports.inflateReset2 = inflateReset2;
+exports.inflateResetKeep = inflateResetKeep;
+exports.inflateInit = inflateInit;
+exports.inflateInit2 = inflateInit2;
+exports.inflate = inflate;
+exports.inflateEnd = inflateEnd;
+exports.inflateGetHeader = inflateGetHeader;
+exports.inflateSetDictionary = inflateSetDictionary;
+exports.inflateInfo = 'pako inflate (from Nodeca project)';
+
+/* Not implemented
+exports.inflateCopy = inflateCopy;
+exports.inflateGetDictionary = inflateGetDictionary;
+exports.inflateMark = inflateMark;
+exports.inflatePrime = inflatePrime;
+exports.inflateSync = inflateSync;
+exports.inflateSyncPoint = inflateSyncPoint;
+exports.inflateUndermine = inflateUndermine;
+*/
+
+
+/***/ }),
+/* 128 */
+/*!******************************************!*\
+  !*** ./node_modules/pako/lib/inflate.js ***!
+  \******************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+
+var zlib_inflate = __webpack_require__(/*! ./zlib/inflate */ 127);
+var utils        = __webpack_require__(/*! ./utils/common */ 48);
+var strings      = __webpack_require__(/*! ./utils/strings */ 86);
+var c            = __webpack_require__(/*! ./zlib/constants */ 84);
+var msg          = __webpack_require__(/*! ./zlib/messages */ 69);
+var ZStream      = __webpack_require__(/*! ./zlib/zstream */ 85);
+var GZheader     = __webpack_require__(/*! ./zlib/gzheader */ 124);
+
+var toString = Object.prototype.toString;
+
+/**
+ * class Inflate
+ *
+ * Generic JS-style wrapper for zlib calls. If you don't need
+ * streaming behaviour - use more simple functions: [[inflate]]
+ * and [[inflateRaw]].
+ **/
+
+/* internal
+ * inflate.chunks -> Array
+ *
+ * Chunks of output data, if [[Inflate#onData]] not overridden.
+ **/
+
+/**
+ * Inflate.result -> Uint8Array|Array|String
+ *
+ * Uncompressed result, generated by default [[Inflate#onData]]
+ * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
+ * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you
+ * push a chunk with explicit flush (call [[Inflate#push]] with
+ * `Z_SYNC_FLUSH` param).
+ **/
+
+/**
+ * Inflate.err -> Number
+ *
+ * Error code after inflate finished. 0 (Z_OK) on success.
+ * Should be checked if broken data possible.
+ **/
+
+/**
+ * Inflate.msg -> String
+ *
+ * Error message, if [[Inflate.err]] != 0
+ **/
+
+
+/**
+ * new Inflate(options)
+ * - options (Object): zlib inflate options.
+ *
+ * Creates new inflator instance with specified params. Throws exception
+ * on bad params. Supported options:
+ *
+ * - `windowBits`
+ * - `dictionary`
+ *
+ * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
+ * for more information on these.
+ *
+ * Additional options, for internal needs:
+ *
+ * - `chunkSize` - size of generated data chunks (16K by default)
+ * - `raw` (Boolean) - do raw inflate
+ * - `to` (String) - if equal to 'string', then result will be converted
+ *   from utf8 to utf16 (javascript) string. When string output requested,
+ *   chunk length can differ from `chunkSize`, depending on content.
+ *
+ * By default, when no options set, autodetect deflate/gzip data format via
+ * wrapper header.
+ *
+ * ##### Example:
+ *
+ * ```javascript
+ * var pako = require('pako')
+ *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
+ *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
+ *
+ * var inflate = new pako.Inflate({ level: 3});
+ *
+ * inflate.push(chunk1, false);
+ * inflate.push(chunk2, true);  // true -> last chunk
+ *
+ * if (inflate.err) { throw new Error(inflate.err); }
+ *
+ * console.log(inflate.result);
+ * ```
+ **/
+function Inflate(options) {
+  if (!(this instanceof Inflate)) return new Inflate(options);
+
+  this.options = utils.assign({
+    chunkSize: 16384,
+    windowBits: 0,
+    to: ''
+  }, options || {});
+
+  var opt = this.options;
+
+  // Force window size for `raw` data, if not set directly,
+  // because we have no header for autodetect.
+  if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
+    opt.windowBits = -opt.windowBits;
+    if (opt.windowBits === 0) { opt.windowBits = -15; }
+  }
+
+  // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
+  if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
+      !(options && options.windowBits)) {
+    opt.windowBits += 32;
+  }
+
+  // Gzip header has no info about windows size, we can do autodetect only
+  // for deflate. So, if window size not set, force it to max when gzip possible
+  if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
+    // bit 3 (16) -> gzipped data
+    // bit 4 (32) -> autodetect gzip/deflate
+    if ((opt.windowBits & 15) === 0) {
+      opt.windowBits |= 15;
+    }
+  }
+
+  this.err    = 0;      // error code, if happens (0 = Z_OK)
+  this.msg    = '';     // error message
+  this.ended  = false;  // used to avoid multiple onEnd() calls
+  this.chunks = [];     // chunks of compressed data
+
+  this.strm   = new ZStream();
+  this.strm.avail_out = 0;
+
+  var status  = zlib_inflate.inflateInit2(
+    this.strm,
+    opt.windowBits
+  );
+
+  if (status !== c.Z_OK) {
+    throw new Error(msg[status]);
+  }
+
+  this.header = new GZheader();
+
+  zlib_inflate.inflateGetHeader(this.strm, this.header);
+}
+
+/**
+ * Inflate#push(data[, mode]) -> Boolean
+ * - data (Uint8Array|Array|ArrayBuffer|String): input data
+ * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
+ *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
+ *
+ * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
+ * new output chunks. Returns `true` on success. The last data block must have
+ * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
+ * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you
+ * can use mode Z_SYNC_FLUSH, keeping the decompression context.
+ *
+ * On fail call [[Inflate#onEnd]] with error code and return false.
+ *
+ * We strongly recommend to use `Uint8Array` on input for best speed (output
+ * format is detected automatically). Also, don't skip last param and always
+ * use the same type in your code (boolean or number). That will improve JS speed.
+ *
+ * For regular `Array`-s make sure all elements are [0..255].
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * push(chunk, false); // push one of data chunks
+ * ...
+ * push(chunk, true);  // push last chunk
+ * ```
+ **/
+Inflate.prototype.push = function (data, mode) {
+  var strm = this.strm;
+  var chunkSize = this.options.chunkSize;
+  var dictionary = this.options.dictionary;
+  var status, _mode;
+  var next_out_utf8, tail, utf8str;
+  var dict;
+
+  // Flag to properly process Z_BUF_ERROR on testing inflate call
+  // when we check that all output data was flushed.
+  var allowBufError = false;
+
+  if (this.ended) { return false; }
+  _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);
+
+  // Convert data if needed
+  if (typeof data === 'string') {
+    // Only binary strings can be decompressed on practice
+    strm.input = strings.binstring2buf(data);
+  } else if (toString.call(data) === '[object ArrayBuffer]') {
+    strm.input = new Uint8Array(data);
+  } else {
+    strm.input = data;
+  }
+
+  strm.next_in = 0;
+  strm.avail_in = strm.input.length;
+
+  do {
+    if (strm.avail_out === 0) {
+      strm.output = new utils.Buf8(chunkSize);
+      strm.next_out = 0;
+      strm.avail_out = chunkSize;
+    }
+
+    status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH);    /* no bad return value */
+
+    if (status === c.Z_NEED_DICT && dictionary) {
+      // Convert data if needed
+      if (typeof dictionary === 'string') {
+        dict = strings.string2buf(dictionary);
+      } else if (toString.call(dictionary) === '[object ArrayBuffer]') {
+        dict = new Uint8Array(dictionary);
+      } else {
+        dict = dictionary;
+      }
+
+      status = zlib_inflate.inflateSetDictionary(this.strm, dict);
+
+    }
+
+    if (status === c.Z_BUF_ERROR && allowBufError === true) {
+      status = c.Z_OK;
+      allowBufError = false;
+    }
+
+    if (status !== c.Z_STREAM_END && status !== c.Z_OK) {
+      this.onEnd(status);
+      this.ended = true;
+      return false;
+    }
+
+    if (strm.next_out) {
+      if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) {
+
+        if (this.options.to === 'string') {
+
+          next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
+
+          tail = strm.next_out - next_out_utf8;
+          utf8str = strings.buf2string(strm.output, next_out_utf8);
+
+          // move tail
+          strm.next_out = tail;
+          strm.avail_out = chunkSize - tail;
+          if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); }
+
+          this.onData(utf8str);
+
+        } else {
+          this.onData(utils.shrinkBuf(strm.output, strm.next_out));
+        }
+      }
+    }
+
+    // When no more input data, we should check that internal inflate buffers
+    // are flushed. The only way to do it when avail_out = 0 - run one more
+    // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.
+    // Here we set flag to process this error properly.
+    //
+    // NOTE. Deflate does not return error in this case and does not needs such
+    // logic.
+    if (strm.avail_in === 0 && strm.avail_out === 0) {
+      allowBufError = true;
+    }
+
+  } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END);
+
+  if (status === c.Z_STREAM_END) {
+    _mode = c.Z_FINISH;
+  }
+
+  // Finalize on the last chunk.
+  if (_mode === c.Z_FINISH) {
+    status = zlib_inflate.inflateEnd(this.strm);
+    this.onEnd(status);
+    this.ended = true;
+    return status === c.Z_OK;
+  }
+
+  // callback interim results if Z_SYNC_FLUSH.
+  if (_mode === c.Z_SYNC_FLUSH) {
+    this.onEnd(c.Z_OK);
+    strm.avail_out = 0;
+    return true;
+  }
+
+  return true;
+};
+
+
+/**
+ * Inflate#onData(chunk) -> Void
+ * - chunk (Uint8Array|Array|String): output data. Type of array depends
+ *   on js engine support. When string output requested, each chunk
+ *   will be string.
+ *
+ * By default, stores data blocks in `chunks[]` property and glue
+ * those in `onEnd`. Override this handler, if you need another behaviour.
+ **/
+Inflate.prototype.onData = function (chunk) {
+  this.chunks.push(chunk);
+};
+
+
+/**
+ * Inflate#onEnd(status) -> Void
+ * - status (Number): inflate status. 0 (Z_OK) on success,
+ *   other if not.
+ *
+ * Called either after you tell inflate that the input stream is
+ * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
+ * or if an error happened. By default - join collected chunks,
+ * free memory and fill `results` / `err` properties.
+ **/
+Inflate.prototype.onEnd = function (status) {
+  // On success - join
+  if (status === c.Z_OK) {
+    if (this.options.to === 'string') {
+      // Glue & convert here, until we teach pako to send
+      // utf8 aligned strings to onData
+      this.result = this.chunks.join('');
+    } else {
+      this.result = utils.flattenChunks(this.chunks);
+    }
+  }
+  this.chunks = [];
+  this.err = status;
+  this.msg = this.strm.msg;
+};
+
+
+/**
+ * inflate(data[, options]) -> Uint8Array|Array|String
+ * - data (Uint8Array|Array|String): input data to decompress.
+ * - options (Object): zlib inflate options.
+ *
+ * Decompress `data` with inflate/ungzip and `options`. Autodetect
+ * format via wrapper header by default. That's why we don't provide
+ * separate `ungzip` method.
+ *
+ * Supported options are:
+ *
+ * - windowBits
+ *
+ * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
+ * for more information.
+ *
+ * Sugar (options):
+ *
+ * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
+ *   negative windowBits implicitly.
+ * - `to` (String) - if equal to 'string', then result will be converted
+ *   from utf8 to utf16 (javascript) string. When string output requested,
+ *   chunk length can differ from `chunkSize`, depending on content.
+ *
+ *
+ * ##### Example:
+ *
+ * ```javascript
+ * var pako = require('pako')
+ *   , input = pako.deflate([1,2,3,4,5,6,7,8,9])
+ *   , output;
+ *
+ * try {
+ *   output = pako.inflate(input);
+ * } catch (err)
+ *   console.log(err);
+ * }
+ * ```
+ **/
+function inflate(input, options) {
+  var inflator = new Inflate(options);
+
+  inflator.push(input, true);
+
+  // That will never happens, if you don't cheat with options :)
+  if (inflator.err) { throw inflator.msg || msg[inflator.err]; }
+
+  return inflator.result;
+}
+
+
+/**
+ * inflateRaw(data[, options]) -> Uint8Array|Array|String
+ * - data (Uint8Array|Array|String): input data to decompress.
+ * - options (Object): zlib inflate options.
+ *
+ * The same as [[inflate]], but creates raw data, without wrapper
+ * (header and adler32 crc).
+ **/
+function inflateRaw(input, options) {
+  options = options || {};
+  options.raw = true;
+  return inflate(input, options);
+}
+
+
+/**
+ * ungzip(data[, options]) -> Uint8Array|Array|String
+ * - data (Uint8Array|Array|String): input data to decompress.
+ * - options (Object): zlib inflate options.
+ *
+ * Just shortcut to [[inflate]], because it autodetects format
+ * by header.content. Done for convenience.
+ **/
+
+
+exports.Inflate = Inflate;
+exports.inflate = inflate;
+exports.inflateRaw = inflateRaw;
+exports.ungzip  = inflate;
+
+
+/***/ }),
+/* 129 */
+/*!*********************************************!*\
+  !*** ./node_modules/pako/lib/zlib/trees.js ***!
+  \*********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// (C) 1995-2013 Jean-loup Gailly and Mark Adler
+// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+//   claim that you wrote the original software. If you use this software
+//   in a product, an acknowledgment in the product documentation would be
+//   appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//   misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+var utils = __webpack_require__(/*! ../utils/common */ 48);
+
+/* Public constants ==========================================================*/
+/* ===========================================================================*/
+
+
+//var Z_FILTERED          = 1;
+//var Z_HUFFMAN_ONLY      = 2;
+//var Z_RLE               = 3;
+var Z_FIXED               = 4;
+//var Z_DEFAULT_STRATEGY  = 0;
+
+/* Possible values of the data_type field (though see inflate()) */
+var Z_BINARY              = 0;
+var Z_TEXT                = 1;
+//var Z_ASCII             = 1; // = Z_TEXT
+var Z_UNKNOWN             = 2;
+
+/*============================================================================*/
+
+
+function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
+
+// From zutil.h
+
+var STORED_BLOCK = 0;
+var STATIC_TREES = 1;
+var DYN_TREES    = 2;
+/* The three kinds of block type */
+
+var MIN_MATCH    = 3;
+var MAX_MATCH    = 258;
+/* The minimum and maximum match lengths */
+
+// From deflate.h
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+var LENGTH_CODES  = 29;
+/* number of length codes, not counting the special END_BLOCK code */
+
+var LITERALS      = 256;
+/* number of literal bytes 0..255 */
+
+var L_CODES       = LITERALS + 1 + LENGTH_CODES;
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+var D_CODES       = 30;
+/* number of distance codes */
+
+var BL_CODES      = 19;
+/* number of codes used to transfer the bit lengths */
+
+var HEAP_SIZE     = 2 * L_CODES + 1;
+/* maximum heap size */
+
+var MAX_BITS      = 15;
+/* All codes must not exceed MAX_BITS bits */
+
+var Buf_size      = 16;
+/* size of bit buffer in bi_buf */
+
+
+/* ===========================================================================
+ * Constants
+ */
+
+var MAX_BL_BITS = 7;
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+var END_BLOCK   = 256;
+/* end of block literal code */
+
+var REP_3_6     = 16;
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+var REPZ_3_10   = 17;
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+var REPZ_11_138 = 18;
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+/* eslint-disable comma-spacing,array-bracket-spacing */
+var extra_lbits =   /* extra bits for each length code */
+  [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];
+
+var extra_dbits =   /* extra bits for each distance code */
+  [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];
+
+var extra_blbits =  /* extra bits for each bit length code */
+  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
+
+var bl_order =
+  [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
+/* eslint-enable comma-spacing,array-bracket-spacing */
+
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+// We pre-fill arrays with 0 to avoid uninitialized gaps
+
+var DIST_CODE_LEN = 512; /* see definition of array dist_code below */
+
+// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
+var static_ltree  = new Array((L_CODES + 2) * 2);
+zero(static_ltree);
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+var static_dtree  = new Array(D_CODES * 2);
+zero(static_dtree);
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+var _dist_code    = new Array(DIST_CODE_LEN);
+zero(_dist_code);
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+var _length_code  = new Array(MAX_MATCH - MIN_MATCH + 1);
+zero(_length_code);
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+var base_length   = new Array(LENGTH_CODES);
+zero(base_length);
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+var base_dist     = new Array(D_CODES);
+zero(base_dist);
+/* First normalized distance for each code (0 = distance of 1) */
+
+
+function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
+
+  this.static_tree  = static_tree;  /* static tree or NULL */
+  this.extra_bits   = extra_bits;   /* extra bits for each code or NULL */
+  this.extra_base   = extra_base;   /* base index for extra_bits */
+  this.elems        = elems;        /* max number of elements in the tree */
+  this.max_length   = max_length;   /* max bit length for the codes */
+
+  // show if `static_tree` has data or dummy - needed for monomorphic objects
+  this.has_stree    = static_tree && static_tree.length;
+}
+
+
+var static_l_desc;
+var static_d_desc;
+var static_bl_desc;
+
+
+function TreeDesc(dyn_tree, stat_desc) {
+  this.dyn_tree = dyn_tree;     /* the dynamic tree */
+  this.max_code = 0;            /* largest code with non zero frequency */
+  this.stat_desc = stat_desc;   /* the corresponding static tree */
+}
+
+
+
+function d_code(dist) {
+  return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
+}
+
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+function put_short(s, w) {
+//    put_byte(s, (uch)((w) & 0xff));
+//    put_byte(s, (uch)((ush)(w) >> 8));
+  s.pending_buf[s.pending++] = (w) & 0xff;
+  s.pending_buf[s.pending++] = (w >>> 8) & 0xff;
+}
+
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+function send_bits(s, value, length) {
+  if (s.bi_valid > (Buf_size - length)) {
+    s.bi_buf |= (value << s.bi_valid) & 0xffff;
+    put_short(s, s.bi_buf);
+    s.bi_buf = value >> (Buf_size - s.bi_valid);
+    s.bi_valid += length - Buf_size;
+  } else {
+    s.bi_buf |= (value << s.bi_valid) & 0xffff;
+    s.bi_valid += length;
+  }
+}
+
+
+function send_code(s, c, tree) {
+  send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);
+}
+
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+function bi_reverse(code, len) {
+  var res = 0;
+  do {
+    res |= code & 1;
+    code >>>= 1;
+    res <<= 1;
+  } while (--len > 0);
+  return res >>> 1;
+}
+
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+function bi_flush(s) {
+  if (s.bi_valid === 16) {
+    put_short(s, s.bi_buf);
+    s.bi_buf = 0;
+    s.bi_valid = 0;
+
+  } else if (s.bi_valid >= 8) {
+    s.pending_buf[s.pending++] = s.bi_buf & 0xff;
+    s.bi_buf >>= 8;
+    s.bi_valid -= 8;
+  }
+}
+
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+function gen_bitlen(s, desc)
+//    deflate_state *s;
+//    tree_desc *desc;    /* the tree descriptor */
+{
+  var tree            = desc.dyn_tree;
+  var max_code        = desc.max_code;
+  var stree           = desc.stat_desc.static_tree;
+  var has_stree       = desc.stat_desc.has_stree;
+  var extra           = desc.stat_desc.extra_bits;
+  var base            = desc.stat_desc.extra_base;
+  var max_length      = desc.stat_desc.max_length;
+  var h;              /* heap index */
+  var n, m;           /* iterate over the tree elements */
+  var bits;           /* bit length */
+  var xbits;          /* extra bits */
+  var f;              /* frequency */
+  var overflow = 0;   /* number of elements with bit length too large */
+
+  for (bits = 0; bits <= MAX_BITS; bits++) {
+    s.bl_count[bits] = 0;
+  }
+
+  /* In a first pass, compute the optimal bit lengths (which may
+   * overflow in the case of the bit length tree).
+   */
+  tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */
+
+  for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
+    n = s.heap[h];
+    bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;
+    if (bits > max_length) {
+      bits = max_length;
+      overflow++;
+    }
+    tree[n * 2 + 1]/*.Len*/ = bits;
+    /* We overwrite tree[n].Dad which is no longer needed */
+
+    if (n > max_code) { continue; } /* not a leaf node */
+
+    s.bl_count[bits]++;
+    xbits = 0;
+    if (n >= base) {
+      xbits = extra[n - base];
+    }
+    f = tree[n * 2]/*.Freq*/;
+    s.opt_len += f * (bits + xbits);
+    if (has_stree) {
+      s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);
+    }
+  }
+  if (overflow === 0) { return; }
+
+  // Trace((stderr,"\nbit length overflow\n"));
+  /* This happens for example on obj2 and pic of the Calgary corpus */
+
+  /* Find the first bit length which could increase: */
+  do {
+    bits = max_length - 1;
+    while (s.bl_count[bits] === 0) { bits--; }
+    s.bl_count[bits]--;      /* move one leaf down the tree */
+    s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
+    s.bl_count[max_length]--;
+    /* The brother of the overflow item also moves one step up,
+     * but this does not affect bl_count[max_length]
+     */
+    overflow -= 2;
+  } while (overflow > 0);
+
+  /* Now recompute all bit lengths, scanning in increasing frequency.
+   * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+   * lengths instead of fixing only the wrong ones. This idea is taken
+   * from 'ar' written by Haruhiko Okumura.)
+   */
+  for (bits = max_length; bits !== 0; bits--) {
+    n = s.bl_count[bits];
+    while (n !== 0) {
+      m = s.heap[--h];
+      if (m > max_code) { continue; }
+      if (tree[m * 2 + 1]/*.Len*/ !== bits) {
+        // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+        s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;
+        tree[m * 2 + 1]/*.Len*/ = bits;
+      }
+      n--;
+    }
+  }
+}
+
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+function gen_codes(tree, max_code, bl_count)
+//    ct_data *tree;             /* the tree to decorate */
+//    int max_code;              /* largest code with non zero frequency */
+//    ushf *bl_count;            /* number of codes at each bit length */
+{
+  var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */
+  var code = 0;              /* running code value */
+  var bits;                  /* bit index */
+  var n;                     /* code index */
+
+  /* The distribution counts are first used to generate the code values
+   * without bit reversal.
+   */
+  for (bits = 1; bits <= MAX_BITS; bits++) {
+    next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
+  }
+  /* Check that the bit counts in bl_count are consistent. The last code
+   * must be all ones.
+   */
+  //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+  //        "inconsistent bit counts");
+  //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+  for (n = 0;  n <= max_code; n++) {
+    var len = tree[n * 2 + 1]/*.Len*/;
+    if (len === 0) { continue; }
+    /* Now reverse the bits */
+    tree[n * 2]/*.Code*/ = bi_reverse(next_code[len]++, len);
+
+    //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+    //     n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+  }
+}
+
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+function tr_static_init() {
+  var n;        /* iterates over tree elements */
+  var bits;     /* bit counter */
+  var length;   /* length value */
+  var code;     /* code value */
+  var dist;     /* distance index */
+  var bl_count = new Array(MAX_BITS + 1);
+  /* number of codes at each bit length for an optimal tree */
+
+  // do check in _tr_init()
+  //if (static_init_done) return;
+
+  /* For some embedded targets, global variables are not initialized: */
+/*#ifdef NO_INIT_GLOBAL_POINTERS
+  static_l_desc.static_tree = static_ltree;
+  static_l_desc.extra_bits = extra_lbits;
+  static_d_desc.static_tree = static_dtree;
+  static_d_desc.extra_bits = extra_dbits;
+  static_bl_desc.extra_bits = extra_blbits;
+#endif*/
+
+  /* Initialize the mapping length (0..255) -> length code (0..28) */
+  length = 0;
+  for (code = 0; code < LENGTH_CODES - 1; code++) {
+    base_length[code] = length;
+    for (n = 0; n < (1 << extra_lbits[code]); n++) {
+      _length_code[length++] = code;
+    }
+  }
+  //Assert (length == 256, "tr_static_init: length != 256");
+  /* Note that the length 255 (match length 258) can be represented
+   * in two different ways: code 284 + 5 bits or code 285, so we
+   * overwrite length_code[255] to use the best encoding:
+   */
+  _length_code[length - 1] = code;
+
+  /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+  dist = 0;
+  for (code = 0; code < 16; code++) {
+    base_dist[code] = dist;
+    for (n = 0; n < (1 << extra_dbits[code]); n++) {
+      _dist_code[dist++] = code;
+    }
+  }
+  //Assert (dist == 256, "tr_static_init: dist != 256");
+  dist >>= 7; /* from now on, all distances are divided by 128 */
+  for (; code < D_CODES; code++) {
+    base_dist[code] = dist << 7;
+    for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
+      _dist_code[256 + dist++] = code;
+    }
+  }
+  //Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+  /* Construct the codes of the static literal tree */
+  for (bits = 0; bits <= MAX_BITS; bits++) {
+    bl_count[bits] = 0;
+  }
+
+  n = 0;
+  while (n <= 143) {
+    static_ltree[n * 2 + 1]/*.Len*/ = 8;
+    n++;
+    bl_count[8]++;
+  }
+  while (n <= 255) {
+    static_ltree[n * 2 + 1]/*.Len*/ = 9;
+    n++;
+    bl_count[9]++;
+  }
+  while (n <= 279) {
+    static_ltree[n * 2 + 1]/*.Len*/ = 7;
+    n++;
+    bl_count[7]++;
+  }
+  while (n <= 287) {
+    static_ltree[n * 2 + 1]/*.Len*/ = 8;
+    n++;
+    bl_count[8]++;
+  }
+  /* Codes 286 and 287 do not exist, but we must include them in the
+   * tree construction to get a canonical Huffman tree (longest code
+   * all ones)
+   */
+  gen_codes(static_ltree, L_CODES + 1, bl_count);
+
+  /* The static distance tree is trivial: */
+  for (n = 0; n < D_CODES; n++) {
+    static_dtree[n * 2 + 1]/*.Len*/ = 5;
+    static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);
+  }
+
+  // Now data ready and we can init static trees
+  static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
+  static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS);
+  static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0,         BL_CODES, MAX_BL_BITS);
+
+  //static_init_done = true;
+}
+
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+function init_block(s) {
+  var n; /* iterates over tree elements */
+
+  /* Initialize the trees. */
+  for (n = 0; n < L_CODES;  n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }
+  for (n = 0; n < D_CODES;  n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }
+  for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }
+
+  s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;
+  s.opt_len = s.static_len = 0;
+  s.last_lit = s.matches = 0;
+}
+
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+function bi_windup(s)
+{
+  if (s.bi_valid > 8) {
+    put_short(s, s.bi_buf);
+  } else if (s.bi_valid > 0) {
+    //put_byte(s, (Byte)s->bi_buf);
+    s.pending_buf[s.pending++] = s.bi_buf;
+  }
+  s.bi_buf = 0;
+  s.bi_valid = 0;
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+function copy_block(s, buf, len, header)
+//DeflateState *s;
+//charf    *buf;    /* the input data */
+//unsigned len;     /* its length */
+//int      header;  /* true if block header must be written */
+{
+  bi_windup(s);        /* align on byte boundary */
+
+  if (header) {
+    put_short(s, len);
+    put_short(s, ~len);
+  }
+//  while (len--) {
+//    put_byte(s, *buf++);
+//  }
+  utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);
+  s.pending += len;
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+function smaller(tree, n, m, depth) {
+  var _n2 = n * 2;
+  var _m2 = m * 2;
+  return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||
+         (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));
+}
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+function pqdownheap(s, tree, k)
+//    deflate_state *s;
+//    ct_data *tree;  /* the tree to restore */
+//    int k;               /* node to move down */
+{
+  var v = s.heap[k];
+  var j = k << 1;  /* left son of k */
+  while (j <= s.heap_len) {
+    /* Set j to the smallest of the two sons: */
+    if (j < s.heap_len &&
+      smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
+      j++;
+    }
+    /* Exit if v is smaller than both sons */
+    if (smaller(tree, v, s.heap[j], s.depth)) { break; }
+
+    /* Exchange v with the smallest son */
+    s.heap[k] = s.heap[j];
+    k = j;
+
+    /* And continue down the tree, setting j to the left son of k */
+    j <<= 1;
+  }
+  s.heap[k] = v;
+}
+
+
+// inlined manually
+// var SMALLEST = 1;
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+function compress_block(s, ltree, dtree)
+//    deflate_state *s;
+//    const ct_data *ltree; /* literal tree */
+//    const ct_data *dtree; /* distance tree */
+{
+  var dist;           /* distance of matched string */
+  var lc;             /* match length or unmatched char (if dist == 0) */
+  var lx = 0;         /* running index in l_buf */
+  var code;           /* the code to send */
+  var extra;          /* number of extra bits to send */
+
+  if (s.last_lit !== 0) {
+    do {
+      dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]);
+      lc = s.pending_buf[s.l_buf + lx];
+      lx++;
+
+      if (dist === 0) {
+        send_code(s, lc, ltree); /* send a literal byte */
+        //Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+      } else {
+        /* Here, lc is the match length - MIN_MATCH */
+        code = _length_code[lc];
+        send_code(s, code + LITERALS + 1, ltree); /* send the length code */
+        extra = extra_lbits[code];
+        if (extra !== 0) {
+          lc -= base_length[code];
+          send_bits(s, lc, extra);       /* send the extra length bits */
+        }
+        dist--; /* dist is now the match distance - 1 */
+        code = d_code(dist);
+        //Assert (code < D_CODES, "bad d_code");
+
+        send_code(s, code, dtree);       /* send the distance code */
+        extra = extra_dbits[code];
+        if (extra !== 0) {
+          dist -= base_dist[code];
+          send_bits(s, dist, extra);   /* send the extra distance bits */
+        }
+      } /* literal or match pair ? */
+
+      /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+      //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+      //       "pendingBuf overflow");
+
+    } while (lx < s.last_lit);
+  }
+
+  send_code(s, END_BLOCK, ltree);
+}
+
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+function build_tree(s, desc)
+//    deflate_state *s;
+//    tree_desc *desc; /* the tree descriptor */
+{
+  var tree     = desc.dyn_tree;
+  var stree    = desc.stat_desc.static_tree;
+  var has_stree = desc.stat_desc.has_stree;
+  var elems    = desc.stat_desc.elems;
+  var n, m;          /* iterate over heap elements */
+  var max_code = -1; /* largest code with non zero frequency */
+  var node;          /* new node being created */
+
+  /* Construct the initial heap, with least frequent element in
+   * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+   * heap[0] is not used.
+   */
+  s.heap_len = 0;
+  s.heap_max = HEAP_SIZE;
+
+  for (n = 0; n < elems; n++) {
+    if (tree[n * 2]/*.Freq*/ !== 0) {
+      s.heap[++s.heap_len] = max_code = n;
+      s.depth[n] = 0;
+
+    } else {
+      tree[n * 2 + 1]/*.Len*/ = 0;
+    }
+  }
+
+  /* The pkzip format requires that at least one distance code exists,
+   * and that at least one bit should be sent even if there is only one
+   * possible code. So to avoid special checks later on we force at least
+   * two codes of non zero frequency.
+   */
+  while (s.heap_len < 2) {
+    node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
+    tree[node * 2]/*.Freq*/ = 1;
+    s.depth[node] = 0;
+    s.opt_len--;
+
+    if (has_stree) {
+      s.static_len -= stree[node * 2 + 1]/*.Len*/;
+    }
+    /* node is 0 or 1 so it does not have extra bits */
+  }
+  desc.max_code = max_code;
+
+  /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+   * establish sub-heaps of increasing lengths:
+   */
+  for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }
+
+  /* Construct the Huffman tree by repeatedly combining the least two
+   * frequent nodes.
+   */
+  node = elems;              /* next internal node of the tree */
+  do {
+    //pqremove(s, tree, n);  /* n = node of least frequency */
+    /*** pqremove ***/
+    n = s.heap[1/*SMALLEST*/];
+    s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];
+    pqdownheap(s, tree, 1/*SMALLEST*/);
+    /***/
+
+    m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */
+
+    s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */
+    s.heap[--s.heap_max] = m;
+
+    /* Create a new node father of n and m */
+    tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;
+    s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
+    tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;
+
+    /* and insert the new node in the heap */
+    s.heap[1/*SMALLEST*/] = node++;
+    pqdownheap(s, tree, 1/*SMALLEST*/);
+
+  } while (s.heap_len >= 2);
+
+  s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];
+
+  /* At this point, the fields freq and dad are set. We can now
+   * generate the bit lengths.
+   */
+  gen_bitlen(s, desc);
+
+  /* The field len is now set, we can generate the bit codes */
+  gen_codes(tree, max_code, s.bl_count);
+}
+
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+function scan_tree(s, tree, max_code)
+//    deflate_state *s;
+//    ct_data *tree;   /* the tree to be scanned */
+//    int max_code;    /* and its largest code of non zero frequency */
+{
+  var n;                     /* iterates over all tree elements */
+  var prevlen = -1;          /* last emitted length */
+  var curlen;                /* length of current code */
+
+  var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
+
+  var count = 0;             /* repeat count of the current code */
+  var max_count = 7;         /* max repeat count */
+  var min_count = 4;         /* min repeat count */
+
+  if (nextlen === 0) {
+    max_count = 138;
+    min_count = 3;
+  }
+  tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */
+
+  for (n = 0; n <= max_code; n++) {
+    curlen = nextlen;
+    nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
+
+    if (++count < max_count && curlen === nextlen) {
+      continue;
+
+    } else if (count < min_count) {
+      s.bl_tree[curlen * 2]/*.Freq*/ += count;
+
+    } else if (curlen !== 0) {
+
+      if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }
+      s.bl_tree[REP_3_6 * 2]/*.Freq*/++;
+
+    } else if (count <= 10) {
+      s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;
+
+    } else {
+      s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;
+    }
+
+    count = 0;
+    prevlen = curlen;
+
+    if (nextlen === 0) {
+      max_count = 138;
+      min_count = 3;
+
+    } else if (curlen === nextlen) {
+      max_count = 6;
+      min_count = 3;
+
+    } else {
+      max_count = 7;
+      min_count = 4;
+    }
+  }
+}
+
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+function send_tree(s, tree, max_code)
+//    deflate_state *s;
+//    ct_data *tree; /* the tree to be scanned */
+//    int max_code;       /* and its largest code of non zero frequency */
+{
+  var n;                     /* iterates over all tree elements */
+  var prevlen = -1;          /* last emitted length */
+  var curlen;                /* length of current code */
+
+  var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
+
+  var count = 0;             /* repeat count of the current code */
+  var max_count = 7;         /* max repeat count */
+  var min_count = 4;         /* min repeat count */
+
+  /* tree[max_code+1].Len = -1; */  /* guard already set */
+  if (nextlen === 0) {
+    max_count = 138;
+    min_count = 3;
+  }
+
+  for (n = 0; n <= max_code; n++) {
+    curlen = nextlen;
+    nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
+
+    if (++count < max_count && curlen === nextlen) {
+      continue;
+
+    } else if (count < min_count) {
+      do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);
+
+    } else if (curlen !== 0) {
+      if (curlen !== prevlen) {
+        send_code(s, curlen, s.bl_tree);
+        count--;
+      }
+      //Assert(count >= 3 && count <= 6, " 3_6?");
+      send_code(s, REP_3_6, s.bl_tree);
+      send_bits(s, count - 3, 2);
+
+    } else if (count <= 10) {
+      send_code(s, REPZ_3_10, s.bl_tree);
+      send_bits(s, count - 3, 3);
+
+    } else {
+      send_code(s, REPZ_11_138, s.bl_tree);
+      send_bits(s, count - 11, 7);
+    }
+
+    count = 0;
+    prevlen = curlen;
+    if (nextlen === 0) {
+      max_count = 138;
+      min_count = 3;
+
+    } else if (curlen === nextlen) {
+      max_count = 6;
+      min_count = 3;
+
+    } else {
+      max_count = 7;
+      min_count = 4;
+    }
+  }
+}
+
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+function build_bl_tree(s) {
+  var max_blindex;  /* index of last bit length code of non zero freq */
+
+  /* Determine the bit length frequencies for literal and distance trees */
+  scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
+  scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
+
+  /* Build the bit length tree: */
+  build_tree(s, s.bl_desc);
+  /* opt_len now includes the length of the tree representations, except
+   * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+   */
+
+  /* Determine the number of bit length codes to send. The pkzip format
+   * requires that at least 4 bit length codes be sent. (appnote.txt says
+   * 3 but the actual value used is 4.)
+   */
+  for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
+    if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {
+      break;
+    }
+  }
+  /* Update opt_len to include the bit length tree and counts */
+  s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
+  //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+  //        s->opt_len, s->static_len));
+
+  return max_blindex;
+}
+
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+function send_all_trees(s, lcodes, dcodes, blcodes)
+//    deflate_state *s;
+//    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+  var rank;                    /* index in bl_order */
+
+  //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+  //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+  //        "too many codes");
+  //Tracev((stderr, "\nbl counts: "));
+  send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
+  send_bits(s, dcodes - 1,   5);
+  send_bits(s, blcodes - 4,  4); /* not -3 as stated in appnote.txt */
+  for (rank = 0; rank < blcodes; rank++) {
+    //Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+    send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);
+  }
+  //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+  send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */
+  //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+  send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */
+  //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ *    a) There are no non-portable control characters belonging to the
+ *       "black list" (0..6, 14..25, 28..31).
+ *    b) There is at least one printable character belonging to the
+ *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ *   "gray list" that is ignored in this detection algorithm:
+ *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+function detect_data_type(s) {
+  /* black_mask is the bit mask of black-listed bytes
+   * set bits 0..6, 14..25, and 28..31
+   * 0xf3ffc07f = binary 11110011111111111100000001111111
+   */
+  var black_mask = 0xf3ffc07f;
+  var n;
+
+  /* Check for non-textual ("black-listed") bytes. */
+  for (n = 0; n <= 31; n++, black_mask >>>= 1) {
+    if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {
+      return Z_BINARY;
+    }
+  }
+
+  /* Check for textual ("white-listed") bytes. */
+  if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||
+      s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {
+    return Z_TEXT;
+  }
+  for (n = 32; n < LITERALS; n++) {
+    if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
+      return Z_TEXT;
+    }
+  }
+
+  /* There are no "black-listed" or "white-listed" bytes:
+   * this stream either is empty or has tolerated ("gray-listed") bytes only.
+   */
+  return Z_BINARY;
+}
+
+
+var static_init_done = false;
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+function _tr_init(s)
+{
+
+  if (!static_init_done) {
+    tr_static_init();
+    static_init_done = true;
+  }
+
+  s.l_desc  = new TreeDesc(s.dyn_ltree, static_l_desc);
+  s.d_desc  = new TreeDesc(s.dyn_dtree, static_d_desc);
+  s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
+
+  s.bi_buf = 0;
+  s.bi_valid = 0;
+
+  /* Initialize the first block of the first file: */
+  init_block(s);
+}
+
+
+/* ===========================================================================
+ * Send a stored block
+ */
+function _tr_stored_block(s, buf, stored_len, last)
+//DeflateState *s;
+//charf *buf;       /* input block */
+//ulg stored_len;   /* length of input block */
+//int last;         /* one if this is the last block for a file */
+{
+  send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3);    /* send block type */
+  copy_block(s, buf, stored_len, true); /* with header */
+}
+
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ */
+function _tr_align(s) {
+  send_bits(s, STATIC_TREES << 1, 3);
+  send_code(s, END_BLOCK, static_ltree);
+  bi_flush(s);
+}
+
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+function _tr_flush_block(s, buf, stored_len, last)
+//DeflateState *s;
+//charf *buf;       /* input block, or NULL if too old */
+//ulg stored_len;   /* length of input block */
+//int last;         /* one if this is the last block for a file */
+{
+  var opt_lenb, static_lenb;  /* opt_len and static_len in bytes */
+  var max_blindex = 0;        /* index of last bit length code of non zero freq */
+
+  /* Build the Huffman trees unless a stored block is forced */
+  if (s.level > 0) {
+
+    /* Check if the file is binary or text */
+    if (s.strm.data_type === Z_UNKNOWN) {
+      s.strm.data_type = detect_data_type(s);
+    }
+
+    /* Construct the literal and distance trees */
+    build_tree(s, s.l_desc);
+    // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+    //        s->static_len));
+
+    build_tree(s, s.d_desc);
+    // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+    //        s->static_len));
+    /* At this point, opt_len and static_len are the total bit lengths of
+     * the compressed block data, excluding the tree representations.
+     */
+
+    /* Build the bit length tree for the above two trees, and get the index
+     * in bl_order of the last bit length code to send.
+     */
+    max_blindex = build_bl_tree(s);
+
+    /* Determine the best encoding. Compute the block lengths in bytes. */
+    opt_lenb = (s.opt_len + 3 + 7) >>> 3;
+    static_lenb = (s.static_len + 3 + 7) >>> 3;
+
+    // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+    //        opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+    //        s->last_lit));
+
+    if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }
+
+  } else {
+    // Assert(buf != (char*)0, "lost buf");
+    opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+  }
+
+  if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {
+    /* 4: two words for the lengths */
+
+    /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+     * Otherwise we can't have processed more than WSIZE input bytes since
+     * the last block flush, because compression would have been
+     * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+     * transform a block into a stored block.
+     */
+    _tr_stored_block(s, buf, stored_len, last);
+
+  } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
+
+    send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
+    compress_block(s, static_ltree, static_dtree);
+
+  } else {
+    send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
+    send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
+    compress_block(s, s.dyn_ltree, s.dyn_dtree);
+  }
+  // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+  /* The above check is made mod 2^32, for files larger than 512 MB
+   * and uLong implemented on 32 bits.
+   */
+  init_block(s);
+
+  if (last) {
+    bi_windup(s);
+  }
+  // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+  //       s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+function _tr_tally(s, dist, lc)
+//    deflate_state *s;
+//    unsigned dist;  /* distance of matched string */
+//    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+  //var out_length, in_length, dcode;
+
+  s.pending_buf[s.d_buf + s.last_lit * 2]     = (dist >>> 8) & 0xff;
+  s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
+
+  s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
+  s.last_lit++;
+
+  if (dist === 0) {
+    /* lc is the unmatched char */
+    s.dyn_ltree[lc * 2]/*.Freq*/++;
+  } else {
+    s.matches++;
+    /* Here, lc is the match length - MIN_MATCH */
+    dist--;             /* dist = match distance - 1 */
+    //Assert((ush)dist < (ush)MAX_DIST(s) &&
+    //       (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+    //       (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+    s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;
+    s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;
+  }
+
+// (!) This block is disabled in zlib defaults,
+// don't enable it for binary compatibility
+
+//#ifdef TRUNCATE_BLOCK
+//  /* Try to guess if it is profitable to stop the current block here */
+//  if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
+//    /* Compute an upper bound for the compressed length */
+//    out_length = s.last_lit*8;
+//    in_length = s.strstart - s.block_start;
+//
+//    for (dcode = 0; dcode < D_CODES; dcode++) {
+//      out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
+//    }
+//    out_length >>>= 3;
+//    //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+//    //       s->last_lit, in_length, out_length,
+//    //       100L - out_length*100L/in_length));
+//    if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
+//      return true;
+//    }
+//  }
+//#endif
+
+  return (s.last_lit === s.lit_bufsize - 1);
+  /* We avoid equality with lit_bufsize because of wraparound at 64K
+   * on 16 bit machines and because stored blocks are restricted to
+   * 64K-1 bytes.
+   */
+}
+
+exports._tr_init  = _tr_init;
+exports._tr_stored_block = _tr_stored_block;
+exports._tr_flush_block  = _tr_flush_block;
+exports._tr_tally = _tr_tally;
+exports._tr_align = _tr_align;
+
+
+/***/ }),
+/* 130 */
+/*!***********************************************!*\
+  !*** ./node_modules/pako/lib/zlib/deflate.js ***!
+  \***********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+// (C) 1995-2013 Jean-loup Gailly and Mark Adler
+// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+//   claim that you wrote the original software. If you use this software
+//   in a product, an acknowledgment in the product documentation would be
+//   appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//   misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+var utils   = __webpack_require__(/*! ../utils/common */ 48);
+var trees   = __webpack_require__(/*! ./trees */ 129);
+var adler32 = __webpack_require__(/*! ./adler32 */ 88);
+var crc32   = __webpack_require__(/*! ./crc32 */ 87);
+var msg     = __webpack_require__(/*! ./messages */ 69);
+
+/* Public constants ==========================================================*/
+/* ===========================================================================*/
+
+
+/* Allowed flush values; see deflate() and inflate() below for details */
+var Z_NO_FLUSH      = 0;
+var Z_PARTIAL_FLUSH = 1;
+//var Z_SYNC_FLUSH    = 2;
+var Z_FULL_FLUSH    = 3;
+var Z_FINISH        = 4;
+var Z_BLOCK         = 5;
+//var Z_TREES         = 6;
+
+
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+var Z_OK            = 0;
+var Z_STREAM_END    = 1;
+//var Z_NEED_DICT     = 2;
+//var Z_ERRNO         = -1;
+var Z_STREAM_ERROR  = -2;
+var Z_DATA_ERROR    = -3;
+//var Z_MEM_ERROR     = -4;
+var Z_BUF_ERROR     = -5;
+//var Z_VERSION_ERROR = -6;
+
+
+/* compression levels */
+//var Z_NO_COMPRESSION      = 0;
+//var Z_BEST_SPEED          = 1;
+//var Z_BEST_COMPRESSION    = 9;
+var Z_DEFAULT_COMPRESSION = -1;
+
+
+var Z_FILTERED            = 1;
+var Z_HUFFMAN_ONLY        = 2;
+var Z_RLE                 = 3;
+var Z_FIXED               = 4;
+var Z_DEFAULT_STRATEGY    = 0;
+
+/* Possible values of the data_type field (though see inflate()) */
+//var Z_BINARY              = 0;
+//var Z_TEXT                = 1;
+//var Z_ASCII               = 1; // = Z_TEXT
+var Z_UNKNOWN             = 2;
+
+
+/* The deflate compression method */
+var Z_DEFLATED  = 8;
+
+/*============================================================================*/
+
+
+var MAX_MEM_LEVEL = 9;
+/* Maximum value for memLevel in deflateInit2 */
+var MAX_WBITS = 15;
+/* 32K LZ77 window */
+var DEF_MEM_LEVEL = 8;
+
+
+var LENGTH_CODES  = 29;
+/* number of length codes, not counting the special END_BLOCK code */
+var LITERALS      = 256;
+/* number of literal bytes 0..255 */
+var L_CODES       = LITERALS + 1 + LENGTH_CODES;
+/* number of Literal or Length codes, including the END_BLOCK code */
+var D_CODES       = 30;
+/* number of distance codes */
+var BL_CODES      = 19;
+/* number of codes used to transfer the bit lengths */
+var HEAP_SIZE     = 2 * L_CODES + 1;
+/* maximum heap size */
+var MAX_BITS  = 15;
+/* All codes must not exceed MAX_BITS bits */
+
+var MIN_MATCH = 3;
+var MAX_MATCH = 258;
+var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
+
+var PRESET_DICT = 0x20;
+
+var INIT_STATE = 42;
+var EXTRA_STATE = 69;
+var NAME_STATE = 73;
+var COMMENT_STATE = 91;
+var HCRC_STATE = 103;
+var BUSY_STATE = 113;
+var FINISH_STATE = 666;
+
+var BS_NEED_MORE      = 1; /* block not completed, need more input or more output */
+var BS_BLOCK_DONE     = 2; /* block flush performed */
+var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */
+var BS_FINISH_DONE    = 4; /* finish done, accept no more input or output */
+
+var OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
+
+function err(strm, errorCode) {
+  strm.msg = msg[errorCode];
+  return errorCode;
+}
+
+function rank(f) {
+  return ((f) << 1) - ((f) > 4 ? 9 : 0);
+}
+
+function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
+
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->output buffer and copying into it.
+ * (See also read_buf()).
+ */
+function flush_pending(strm) {
+  var s = strm.state;
+
+  //_tr_flush_bits(s);
+  var len = s.pending;
+  if (len > strm.avail_out) {
+    len = strm.avail_out;
+  }
+  if (len === 0) { return; }
+
+  utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
+  strm.next_out += len;
+  s.pending_out += len;
+  strm.total_out += len;
+  strm.avail_out -= len;
+  s.pending -= len;
+  if (s.pending === 0) {
+    s.pending_out = 0;
+  }
+}
+
+
+function flush_block_only(s, last) {
+  trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
+  s.block_start = s.strstart;
+  flush_pending(s.strm);
+}
+
+
+function put_byte(s, b) {
+  s.pending_buf[s.pending++] = b;
+}
+
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+function putShortMSB(s, b) {
+//  put_byte(s, (Byte)(b >> 8));
+//  put_byte(s, (Byte)(b & 0xff));
+  s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
+  s.pending_buf[s.pending++] = b & 0xff;
+}
+
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->input buffer and copying from it.
+ * (See also flush_pending()).
+ */
+function read_buf(strm, buf, start, size) {
+  var len = strm.avail_in;
+
+  if (len > size) { len = size; }
+  if (len === 0) { return 0; }
+
+  strm.avail_in -= len;
+
+  // zmemcpy(buf, strm->next_in, len);
+  utils.arraySet(buf, strm.input, strm.next_in, len, start);
+  if (strm.state.wrap === 1) {
+    strm.adler = adler32(strm.adler, buf, len, start);
+  }
+
+  else if (strm.state.wrap === 2) {
+    strm.adler = crc32(strm.adler, buf, len, start);
+  }
+
+  strm.next_in += len;
+  strm.total_in += len;
+
+  return len;
+}
+
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+function longest_match(s, cur_match) {
+  var chain_length = s.max_chain_length;      /* max hash chain length */
+  var scan = s.strstart; /* current string */
+  var match;                       /* matched string */
+  var len;                           /* length of current match */
+  var best_len = s.prev_length;              /* best match length so far */
+  var nice_match = s.nice_match;             /* stop if match long enough */
+  var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
+      s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;
+
+  var _win = s.window; // shortcut
+
+  var wmask = s.w_mask;
+  var prev  = s.prev;
+
+  /* Stop when cur_match becomes <= limit. To simplify the code,
+   * we prevent matches with the string of window index 0.
+   */
+
+  var strend = s.strstart + MAX_MATCH;
+  var scan_end1  = _win[scan + best_len - 1];
+  var scan_end   = _win[scan + best_len];
+
+  /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+   * It is easy to get rid of this optimization if necessary.
+   */
+  // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+  /* Do not waste too much time if we already have a good match: */
+  if (s.prev_length >= s.good_match) {
+    chain_length >>= 2;
+  }
+  /* Do not look for matches beyond the end of the input. This is necessary
+   * to make deflate deterministic.
+   */
+  if (nice_match > s.lookahead) { nice_match = s.lookahead; }
+
+  // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+  do {
+    // Assert(cur_match < s->strstart, "no future");
+    match = cur_match;
+
+    /* Skip to next match if the match length cannot increase
+     * or if the match length is less than 2.  Note that the checks below
+     * for insufficient lookahead only occur occasionally for performance
+     * reasons.  Therefore uninitialized memory will be accessed, and
+     * conditional jumps will be made that depend on those values.
+     * However the length of the match is limited to the lookahead, so
+     * the output of deflate is not affected by the uninitialized values.
+     */
+
+    if (_win[match + best_len]     !== scan_end  ||
+        _win[match + best_len - 1] !== scan_end1 ||
+        _win[match]                !== _win[scan] ||
+        _win[++match]              !== _win[scan + 1]) {
+      continue;
+    }
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2;
+    match++;
+    // Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+      /*jshint noempty:false*/
+    } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
+             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
+             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
+             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
+             scan < strend);
+
+    // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (strend - scan);
+    scan = strend - MAX_MATCH;
+
+    if (len > best_len) {
+      s.match_start = cur_match;
+      best_len = len;
+      if (len >= nice_match) {
+        break;
+      }
+      scan_end1  = _win[scan + best_len - 1];
+      scan_end   = _win[scan + best_len];
+    }
+  } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
+
+  if (best_len <= s.lookahead) {
+    return best_len;
+  }
+  return s.lookahead;
+}
+
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+function fill_window(s) {
+  var _w_size = s.w_size;
+  var p, n, m, more, str;
+
+  //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+  do {
+    more = s.window_size - s.lookahead - s.strstart;
+
+    // JS ints have 32 bit, block below not needed
+    /* Deal with !@#$% 64K limit: */
+    //if (sizeof(int) <= 2) {
+    //    if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+    //        more = wsize;
+    //
+    //  } else if (more == (unsigned)(-1)) {
+    //        /* Very unlikely, but possible on 16 bit machine if
+    //         * strstart == 0 && lookahead == 1 (input done a byte at time)
+    //         */
+    //        more--;
+    //    }
+    //}
+
+
+    /* If the window is almost full and there is insufficient lookahead,
+     * move the upper half to the lower one to make room in the upper half.
+     */
+    if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
+
+      utils.arraySet(s.window, s.window, _w_size, _w_size, 0);
+      s.match_start -= _w_size;
+      s.strstart -= _w_size;
+      /* we now have strstart >= MAX_DIST */
+      s.block_start -= _w_size;
+
+      /* Slide the hash table (could be avoided with 32 bit values
+       at the expense of memory usage). We slide even when level == 0
+       to keep the hash table consistent if we switch back to level > 0
+       later. (Using level 0 permanently is not an optimal usage of
+       zlib, so we don't care about this pathological case.)
+       */
+
+      n = s.hash_size;
+      p = n;
+      do {
+        m = s.head[--p];
+        s.head[p] = (m >= _w_size ? m - _w_size : 0);
+      } while (--n);
+
+      n = _w_size;
+      p = n;
+      do {
+        m = s.prev[--p];
+        s.prev[p] = (m >= _w_size ? m - _w_size : 0);
+        /* If n is not on any hash chain, prev[n] is garbage but
+         * its value will never be used.
+         */
+      } while (--n);
+
+      more += _w_size;
+    }
+    if (s.strm.avail_in === 0) {
+      break;
+    }
+
+    /* If there was no sliding:
+     *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+     *    more == window_size - lookahead - strstart
+     * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+     * => more >= window_size - 2*WSIZE + 2
+     * In the BIG_MEM or MMAP case (not yet supported),
+     *   window_size == input_size + MIN_LOOKAHEAD  &&
+     *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+     * Otherwise, window_size == 2*WSIZE so more >= 2.
+     * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+     */
+    //Assert(more >= 2, "more < 2");
+    n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
+    s.lookahead += n;
+
+    /* Initialize the hash value now that we have some input: */
+    if (s.lookahead + s.insert >= MIN_MATCH) {
+      str = s.strstart - s.insert;
+      s.ins_h = s.window[str];
+
+      /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
+      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
+//#if MIN_MATCH != 3
+//        Call update_hash() MIN_MATCH-3 more times
+//#endif
+      while (s.insert) {
+        /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
+        s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
+
+        s.prev[str & s.w_mask] = s.head[s.ins_h];
+        s.head[s.ins_h] = str;
+        str++;
+        s.insert--;
+        if (s.lookahead + s.insert < MIN_MATCH) {
+          break;
+        }
+      }
+    }
+    /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+     * but this is not important since only literal bytes will be emitted.
+     */
+
+  } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
+
+  /* If the WIN_INIT bytes after the end of the current data have never been
+   * written, then zero those bytes in order to avoid memory check reports of
+   * the use of uninitialized (or uninitialised as Julian writes) bytes by
+   * the longest match routines.  Update the high water mark for the next
+   * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
+   * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+   */
+//  if (s.high_water < s.window_size) {
+//    var curr = s.strstart + s.lookahead;
+//    var init = 0;
+//
+//    if (s.high_water < curr) {
+//      /* Previous high water mark below current data -- zero WIN_INIT
+//       * bytes or up to end of window, whichever is less.
+//       */
+//      init = s.window_size - curr;
+//      if (init > WIN_INIT)
+//        init = WIN_INIT;
+//      zmemzero(s->window + curr, (unsigned)init);
+//      s->high_water = curr + init;
+//    }
+//    else if (s->high_water < (ulg)curr + WIN_INIT) {
+//      /* High water mark at or above current data, but below current data
+//       * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+//       * to end of window, whichever is less.
+//       */
+//      init = (ulg)curr + WIN_INIT - s->high_water;
+//      if (init > s->window_size - s->high_water)
+//        init = s->window_size - s->high_water;
+//      zmemzero(s->window + s->high_water, (unsigned)init);
+//      s->high_water += init;
+//    }
+//  }
+//
+//  Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+//    "not enough room for search");
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+function deflate_stored(s, flush) {
+  /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+   * to pending_buf_size, and each stored block has a 5 byte header:
+   */
+  var max_block_size = 0xffff;
+
+  if (max_block_size > s.pending_buf_size - 5) {
+    max_block_size = s.pending_buf_size - 5;
+  }
+
+  /* Copy as much as possible from input to output: */
+  for (;;) {
+    /* Fill the window as much as possible: */
+    if (s.lookahead <= 1) {
+
+      //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+      //  s->block_start >= (long)s->w_size, "slide too late");
+//      if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
+//        s.block_start >= s.w_size)) {
+//        throw  new Error("slide too late");
+//      }
+
+      fill_window(s);
+      if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
+        return BS_NEED_MORE;
+      }
+
+      if (s.lookahead === 0) {
+        break;
+      }
+      /* flush the current block */
+    }
+    //Assert(s->block_start >= 0L, "block gone");
+//    if (s.block_start < 0) throw new Error("block gone");
+
+    s.strstart += s.lookahead;
+    s.lookahead = 0;
+
+    /* Emit a stored block if pending_buf will be full: */
+    var max_start = s.block_start + max_block_size;
+
+    if (s.strstart === 0 || s.strstart >= max_start) {
+      /* strstart == 0 is possible when wraparound on 16-bit machine */
+      s.lookahead = s.strstart - max_start;
+      s.strstart = max_start;
+      /*** FLUSH_BLOCK(s, 0); ***/
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+
+
+    }
+    /* Flush if we may have to slide, otherwise block_start may become
+     * negative and the data will be gone:
+     */
+    if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
+      /*** FLUSH_BLOCK(s, 0); ***/
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+    }
+  }
+
+  s.insert = 0;
+
+  if (flush === Z_FINISH) {
+    /*** FLUSH_BLOCK(s, 1); ***/
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+
+  if (s.strstart > s.block_start) {
+    /*** FLUSH_BLOCK(s, 0); ***/
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+
+  return BS_NEED_MORE;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+function deflate_fast(s, flush) {
+  var hash_head;        /* head of the hash chain */
+  var bflush;           /* set if current block must be flushed */
+
+  for (;;) {
+    /* Make sure that we always have enough lookahead, except
+     * at the end of the input file. We need MAX_MATCH bytes
+     * for the next match, plus MIN_MATCH bytes to insert the
+     * string following the next match.
+     */
+    if (s.lookahead < MIN_LOOKAHEAD) {
+      fill_window(s);
+      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
+        return BS_NEED_MORE;
+      }
+      if (s.lookahead === 0) {
+        break; /* flush the current block */
+      }
+    }
+
+    /* Insert the string window[strstart .. strstart+2] in the
+     * dictionary, and set hash_head to the head of the hash chain:
+     */
+    hash_head = 0/*NIL*/;
+    if (s.lookahead >= MIN_MATCH) {
+      /*** INSERT_STRING(s, s.strstart, hash_head); ***/
+      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
+      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
+      s.head[s.ins_h] = s.strstart;
+      /***/
+    }
+
+    /* Find the longest match, discarding those <= prev_length.
+     * At this point we have always match_length < MIN_MATCH
+     */
+    if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
+      /* To simplify the code, we prevent matches with the string
+       * of window index 0 (in particular we have to avoid a match
+       * of the string with itself at the start of the input file).
+       */
+      s.match_length = longest_match(s, hash_head);
+      /* longest_match() sets match_start */
+    }
+    if (s.match_length >= MIN_MATCH) {
+      // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
+
+      /*** _tr_tally_dist(s, s.strstart - s.match_start,
+                     s.match_length - MIN_MATCH, bflush); ***/
+      bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
+
+      s.lookahead -= s.match_length;
+
+      /* Insert new strings in the hash table only if the match length
+       * is not too large. This saves time but degrades compression.
+       */
+      if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {
+        s.match_length--; /* string at strstart already in table */
+        do {
+          s.strstart++;
+          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
+          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
+          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
+          s.head[s.ins_h] = s.strstart;
+          /***/
+          /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+           * always MIN_MATCH bytes ahead.
+           */
+        } while (--s.match_length !== 0);
+        s.strstart++;
+      } else
+      {
+        s.strstart += s.match_length;
+        s.match_length = 0;
+        s.ins_h = s.window[s.strstart];
+        /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
+        s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
+
+//#if MIN_MATCH != 3
+//                Call UPDATE_HASH() MIN_MATCH-3 more times
+//#endif
+        /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+         * matter since it will be recomputed at next deflate call.
+         */
+      }
+    } else {
+      /* No match, output a literal byte */
+      //Tracevv((stderr,"%c", s.window[s.strstart]));
+      /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
+      bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
+
+      s.lookahead--;
+      s.strstart++;
+    }
+    if (bflush) {
+      /*** FLUSH_BLOCK(s, 0); ***/
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+    }
+  }
+  s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);
+  if (flush === Z_FINISH) {
+    /*** FLUSH_BLOCK(s, 1); ***/
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+  if (s.last_lit) {
+    /*** FLUSH_BLOCK(s, 0); ***/
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+  return BS_BLOCK_DONE;
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+function deflate_slow(s, flush) {
+  var hash_head;          /* head of hash chain */
+  var bflush;              /* set if current block must be flushed */
+
+  var max_insert;
+
+  /* Process the input block. */
+  for (;;) {
+    /* Make sure that we always have enough lookahead, except
+     * at the end of the input file. We need MAX_MATCH bytes
+     * for the next match, plus MIN_MATCH bytes to insert the
+     * string following the next match.
+     */
+    if (s.lookahead < MIN_LOOKAHEAD) {
+      fill_window(s);
+      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
+        return BS_NEED_MORE;
+      }
+      if (s.lookahead === 0) { break; } /* flush the current block */
+    }
+
+    /* Insert the string window[strstart .. strstart+2] in the
+     * dictionary, and set hash_head to the head of the hash chain:
+     */
+    hash_head = 0/*NIL*/;
+    if (s.lookahead >= MIN_MATCH) {
+      /*** INSERT_STRING(s, s.strstart, hash_head); ***/
+      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
+      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
+      s.head[s.ins_h] = s.strstart;
+      /***/
+    }
+
+    /* Find the longest match, discarding those <= prev_length.
+     */
+    s.prev_length = s.match_length;
+    s.prev_match = s.match_start;
+    s.match_length = MIN_MATCH - 1;
+
+    if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
+        s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
+      /* To simplify the code, we prevent matches with the string
+       * of window index 0 (in particular we have to avoid a match
+       * of the string with itself at the start of the input file).
+       */
+      s.match_length = longest_match(s, hash_head);
+      /* longest_match() sets match_start */
+
+      if (s.match_length <= 5 &&
+         (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
+
+        /* If prev_match is also MIN_MATCH, match_start is garbage
+         * but we will ignore the current match anyway.
+         */
+        s.match_length = MIN_MATCH - 1;
+      }
+    }
+    /* If there was a match at the previous step and the current
+     * match is not better, output the previous match:
+     */
+    if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
+      max_insert = s.strstart + s.lookahead - MIN_MATCH;
+      /* Do not insert strings in hash table beyond this. */
+
+      //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
+
+      /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
+                     s.prev_length - MIN_MATCH, bflush);***/
+      bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);
+      /* Insert in hash table all strings up to the end of the match.
+       * strstart-1 and strstart are already inserted. If there is not
+       * enough lookahead, the last two strings are not inserted in
+       * the hash table.
+       */
+      s.lookahead -= s.prev_length - 1;
+      s.prev_length -= 2;
+      do {
+        if (++s.strstart <= max_insert) {
+          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
+          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
+          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
+          s.head[s.ins_h] = s.strstart;
+          /***/
+        }
+      } while (--s.prev_length !== 0);
+      s.match_available = 0;
+      s.match_length = MIN_MATCH - 1;
+      s.strstart++;
+
+      if (bflush) {
+        /*** FLUSH_BLOCK(s, 0); ***/
+        flush_block_only(s, false);
+        if (s.strm.avail_out === 0) {
+          return BS_NEED_MORE;
+        }
+        /***/
+      }
+
+    } else if (s.match_available) {
+      /* If there was no match at the previous position, output a
+       * single literal. If there was a match but the current match
+       * is longer, truncate the previous match to a single literal.
+       */
+      //Tracevv((stderr,"%c", s->window[s->strstart-1]));
+      /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
+      bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
+
+      if (bflush) {
+        /*** FLUSH_BLOCK_ONLY(s, 0) ***/
+        flush_block_only(s, false);
+        /***/
+      }
+      s.strstart++;
+      s.lookahead--;
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+    } else {
+      /* There is no previous match to compare with, wait for
+       * the next step to decide.
+       */
+      s.match_available = 1;
+      s.strstart++;
+      s.lookahead--;
+    }
+  }
+  //Assert (flush != Z_NO_FLUSH, "no flush?");
+  if (s.match_available) {
+    //Tracevv((stderr,"%c", s->window[s->strstart-1]));
+    /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
+    bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
+
+    s.match_available = 0;
+  }
+  s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
+  if (flush === Z_FINISH) {
+    /*** FLUSH_BLOCK(s, 1); ***/
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+  if (s.last_lit) {
+    /*** FLUSH_BLOCK(s, 0); ***/
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+
+  return BS_BLOCK_DONE;
+}
+
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+function deflate_rle(s, flush) {
+  var bflush;            /* set if current block must be flushed */
+  var prev;              /* byte at distance one to match */
+  var scan, strend;      /* scan goes up to strend for length of run */
+
+  var _win = s.window;
+
+  for (;;) {
+    /* Make sure that we always have enough lookahead, except
+     * at the end of the input file. We need MAX_MATCH bytes
+     * for the longest run, plus one for the unrolled loop.
+     */
+    if (s.lookahead <= MAX_MATCH) {
+      fill_window(s);
+      if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {
+        return BS_NEED_MORE;
+      }
+      if (s.lookahead === 0) { break; } /* flush the current block */
+    }
+
+    /* See how many times the previous byte repeats */
+    s.match_length = 0;
+    if (s.lookahead >= MIN_MATCH && s.strstart > 0) {
+      scan = s.strstart - 1;
+      prev = _win[scan];
+      if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
+        strend = s.strstart + MAX_MATCH;
+        do {
+          /*jshint noempty:false*/
+        } while (prev === _win[++scan] && prev === _win[++scan] &&
+                 prev === _win[++scan] && prev === _win[++scan] &&
+                 prev === _win[++scan] && prev === _win[++scan] &&
+                 prev === _win[++scan] && prev === _win[++scan] &&
+                 scan < strend);
+        s.match_length = MAX_MATCH - (strend - scan);
+        if (s.match_length > s.lookahead) {
+          s.match_length = s.lookahead;
+        }
+      }
+      //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+    }
+
+    /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+    if (s.match_length >= MIN_MATCH) {
+      //check_match(s, s.strstart, s.strstart - 1, s.match_length);
+
+      /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/
+      bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);
+
+      s.lookahead -= s.match_length;
+      s.strstart += s.match_length;
+      s.match_length = 0;
+    } else {
+      /* No match, output a literal byte */
+      //Tracevv((stderr,"%c", s->window[s->strstart]));
+      /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
+      bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
+
+      s.lookahead--;
+      s.strstart++;
+    }
+    if (bflush) {
+      /*** FLUSH_BLOCK(s, 0); ***/
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+    }
+  }
+  s.insert = 0;
+  if (flush === Z_FINISH) {
+    /*** FLUSH_BLOCK(s, 1); ***/
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+  if (s.last_lit) {
+    /*** FLUSH_BLOCK(s, 0); ***/
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+  return BS_BLOCK_DONE;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+function deflate_huff(s, flush) {
+  var bflush;             /* set if current block must be flushed */
+
+  for (;;) {
+    /* Make sure that we have a literal to write. */
+    if (s.lookahead === 0) {
+      fill_window(s);
+      if (s.lookahead === 0) {
+        if (flush === Z_NO_FLUSH) {
+          return BS_NEED_MORE;
+        }
+        break;      /* flush the current block */
+      }
+    }
+
+    /* Output a literal byte */
+    s.match_length = 0;
+    //Tracevv((stderr,"%c", s->window[s->strstart]));
+    /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
+    bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
+    s.lookahead--;
+    s.strstart++;
+    if (bflush) {
+      /*** FLUSH_BLOCK(s, 0); ***/
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+    }
+  }
+  s.insert = 0;
+  if (flush === Z_FINISH) {
+    /*** FLUSH_BLOCK(s, 1); ***/
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+  if (s.last_lit) {
+    /*** FLUSH_BLOCK(s, 0); ***/
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+  return BS_BLOCK_DONE;
+}
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+function Config(good_length, max_lazy, nice_length, max_chain, func) {
+  this.good_length = good_length;
+  this.max_lazy = max_lazy;
+  this.nice_length = nice_length;
+  this.max_chain = max_chain;
+  this.func = func;
+}
+
+var configuration_table;
+
+configuration_table = [
+  /*      good lazy nice chain */
+  new Config(0, 0, 0, 0, deflate_stored),          /* 0 store only */
+  new Config(4, 4, 8, 4, deflate_fast),            /* 1 max speed, no lazy matches */
+  new Config(4, 5, 16, 8, deflate_fast),           /* 2 */
+  new Config(4, 6, 32, 32, deflate_fast),          /* 3 */
+
+  new Config(4, 4, 16, 16, deflate_slow),          /* 4 lazy matches */
+  new Config(8, 16, 32, 32, deflate_slow),         /* 5 */
+  new Config(8, 16, 128, 128, deflate_slow),       /* 6 */
+  new Config(8, 32, 128, 256, deflate_slow),       /* 7 */
+  new Config(32, 128, 258, 1024, deflate_slow),    /* 8 */
+  new Config(32, 258, 258, 4096, deflate_slow)     /* 9 max compression */
+];
+
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+function lm_init(s) {
+  s.window_size = 2 * s.w_size;
+
+  /*** CLEAR_HASH(s); ***/
+  zero(s.head); // Fill with NIL (= 0);
+
+  /* Set the default configuration parameters:
+   */
+  s.max_lazy_match = configuration_table[s.level].max_lazy;
+  s.good_match = configuration_table[s.level].good_length;
+  s.nice_match = configuration_table[s.level].nice_length;
+  s.max_chain_length = configuration_table[s.level].max_chain;
+
+  s.strstart = 0;
+  s.block_start = 0;
+  s.lookahead = 0;
+  s.insert = 0;
+  s.match_length = s.prev_length = MIN_MATCH - 1;
+  s.match_available = 0;
+  s.ins_h = 0;
+}
+
+
+function DeflateState() {
+  this.strm = null;            /* pointer back to this zlib stream */
+  this.status = 0;            /* as the name implies */
+  this.pending_buf = null;      /* output still pending */
+  this.pending_buf_size = 0;  /* size of pending_buf */
+  this.pending_out = 0;       /* next pending byte to output to the stream */
+  this.pending = 0;           /* nb of bytes in the pending buffer */
+  this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */
+  this.gzhead = null;         /* gzip header information to write */
+  this.gzindex = 0;           /* where in extra, name, or comment */
+  this.method = Z_DEFLATED; /* can only be DEFLATED */
+  this.last_flush = -1;   /* value of flush param for previous deflate call */
+
+  this.w_size = 0;  /* LZ77 window size (32K by default) */
+  this.w_bits = 0;  /* log2(w_size)  (8..16) */
+  this.w_mask = 0;  /* w_size - 1 */
+
+  this.window = null;
+  /* Sliding window. Input bytes are read into the second half of the window,
+   * and move to the first half later to keep a dictionary of at least wSize
+   * bytes. With this organization, matches are limited to a distance of
+   * wSize-MAX_MATCH bytes, but this ensures that IO is always
+   * performed with a length multiple of the block size.
+   */
+
+  this.window_size = 0;
+  /* Actual size of window: 2*wSize, except when the user input buffer
+   * is directly used as sliding window.
+   */
+
+  this.prev = null;
+  /* Link to older string with same hash index. To limit the size of this
+   * array to 64K, this link is maintained only for the last 32K strings.
+   * An index in this array is thus a window index modulo 32K.
+   */
+
+  this.head = null;   /* Heads of the hash chains or NIL. */
+
+  this.ins_h = 0;       /* hash index of string to be inserted */
+  this.hash_size = 0;   /* number of elements in hash table */
+  this.hash_bits = 0;   /* log2(hash_size) */
+  this.hash_mask = 0;   /* hash_size-1 */
+
+  this.hash_shift = 0;
+  /* Number of bits by which ins_h must be shifted at each input
+   * step. It must be such that after MIN_MATCH steps, the oldest
+   * byte no longer takes part in the hash key, that is:
+   *   hash_shift * MIN_MATCH >= hash_bits
+   */
+
+  this.block_start = 0;
+  /* Window position at the beginning of the current output block. Gets
+   * negative when the window is moved backwards.
+   */
+
+  this.match_length = 0;      /* length of best match */
+  this.prev_match = 0;        /* previous match */
+  this.match_available = 0;   /* set if previous match exists */
+  this.strstart = 0;          /* start of string to insert */
+  this.match_start = 0;       /* start of matching string */
+  this.lookahead = 0;         /* number of valid bytes ahead in window */
+
+  this.prev_length = 0;
+  /* Length of the best match at previous step. Matches not greater than this
+   * are discarded. This is used in the lazy match evaluation.
+   */
+
+  this.max_chain_length = 0;
+  /* To speed up deflation, hash chains are never searched beyond this
+   * length.  A higher limit improves compression ratio but degrades the
+   * speed.
+   */
+
+  this.max_lazy_match = 0;
+  /* Attempt to find a better match only when the current match is strictly
+   * smaller than this value. This mechanism is used only for compression
+   * levels >= 4.
+   */
+  // That's alias to max_lazy_match, don't use directly
+  //this.max_insert_length = 0;
+  /* Insert new strings in the hash table only if the match length is not
+   * greater than this length. This saves time but degrades compression.
+   * max_insert_length is used only for compression levels <= 3.
+   */
+
+  this.level = 0;     /* compression level (1..9) */
+  this.strategy = 0;  /* favor or force Huffman coding*/
+
+  this.good_match = 0;
+  /* Use a faster search when the previous match is longer than this */
+
+  this.nice_match = 0; /* Stop searching when current match exceeds this */
+
+              /* used by trees.c: */
+
+  /* Didn't use ct_data typedef below to suppress compiler warning */
+
+  // struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+  // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+  // struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+  // Use flat array of DOUBLE size, with interleaved fata,
+  // because JS does not support effective
+  this.dyn_ltree  = new utils.Buf16(HEAP_SIZE * 2);
+  this.dyn_dtree  = new utils.Buf16((2 * D_CODES + 1) * 2);
+  this.bl_tree    = new utils.Buf16((2 * BL_CODES + 1) * 2);
+  zero(this.dyn_ltree);
+  zero(this.dyn_dtree);
+  zero(this.bl_tree);
+
+  this.l_desc   = null;         /* desc. for literal tree */
+  this.d_desc   = null;         /* desc. for distance tree */
+  this.bl_desc  = null;         /* desc. for bit length tree */
+
+  //ush bl_count[MAX_BITS+1];
+  this.bl_count = new utils.Buf16(MAX_BITS + 1);
+  /* number of codes at each bit length for an optimal tree */
+
+  //int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+  this.heap = new utils.Buf16(2 * L_CODES + 1);  /* heap used to build the Huffman trees */
+  zero(this.heap);
+
+  this.heap_len = 0;               /* number of elements in the heap */
+  this.heap_max = 0;               /* element of largest frequency */
+  /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+   * The same heap array is used to build all trees.
+   */
+
+  this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1];
+  zero(this.depth);
+  /* Depth of each subtree used as tie breaker for trees of equal frequency
+   */
+
+  this.l_buf = 0;          /* buffer index for literals or lengths */
+
+  this.lit_bufsize = 0;
+  /* Size of match buffer for literals/lengths.  There are 4 reasons for
+   * limiting lit_bufsize to 64K:
+   *   - frequencies can be kept in 16 bit counters
+   *   - if compression is not successful for the first block, all input
+   *     data is still in the window so we can still emit a stored block even
+   *     when input comes from standard input.  (This can also be done for
+   *     all blocks if lit_bufsize is not greater than 32K.)
+   *   - if compression is not successful for a file smaller than 64K, we can
+   *     even emit a stored file instead of a stored block (saving 5 bytes).
+   *     This is applicable only for zip (not gzip or zlib).
+   *   - creating new Huffman trees less frequently may not provide fast
+   *     adaptation to changes in the input data statistics. (Take for
+   *     example a binary file with poorly compressible code followed by
+   *     a highly compressible string table.) Smaller buffer sizes give
+   *     fast adaptation but have of course the overhead of transmitting
+   *     trees more frequently.
+   *   - I can't count above 4
+   */
+
+  this.last_lit = 0;      /* running index in l_buf */
+
+  this.d_buf = 0;
+  /* Buffer index for distances. To simplify the code, d_buf and l_buf have
+   * the same number of elements. To use different lengths, an extra flag
+   * array would be necessary.
+   */
+
+  this.opt_len = 0;       /* bit length of current block with optimal trees */
+  this.static_len = 0;    /* bit length of current block with static trees */
+  this.matches = 0;       /* number of string matches in current block */
+  this.insert = 0;        /* bytes at end of window left to insert */
+
+
+  this.bi_buf = 0;
+  /* Output buffer. bits are inserted starting at the bottom (least
+   * significant bits).
+   */
+  this.bi_valid = 0;
+  /* Number of valid bits in bi_buf.  All bits above the last valid bit
+   * are always zero.
+   */
+
+  // Used for window memory init. We safely ignore it for JS. That makes
+  // sense only for pointers and memory check tools.
+  //this.high_water = 0;
+  /* High water mark offset in window for initialized bytes -- bytes above
+   * this are set to zero in order to avoid memory check warnings when
+   * longest match routines access bytes past the input.  This is then
+   * updated to the new high water mark.
+   */
+}
+
+
+function deflateResetKeep(strm) {
+  var s;
+
+  if (!strm || !strm.state) {
+    return err(strm, Z_STREAM_ERROR);
+  }
+
+  strm.total_in = strm.total_out = 0;
+  strm.data_type = Z_UNKNOWN;
+
+  s = strm.state;
+  s.pending = 0;
+  s.pending_out = 0;
+
+  if (s.wrap < 0) {
+    s.wrap = -s.wrap;
+    /* was made negative by deflate(..., Z_FINISH); */
+  }
+  s.status = (s.wrap ? INIT_STATE : BUSY_STATE);
+  strm.adler = (s.wrap === 2) ?
+    0  // crc32(0, Z_NULL, 0)
+  :
+    1; // adler32(0, Z_NULL, 0)
+  s.last_flush = Z_NO_FLUSH;
+  trees._tr_init(s);
+  return Z_OK;
+}
+
+
+function deflateReset(strm) {
+  var ret = deflateResetKeep(strm);
+  if (ret === Z_OK) {
+    lm_init(strm.state);
+  }
+  return ret;
+}
+
+
+function deflateSetHeader(strm, head) {
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }
+  strm.state.gzhead = head;
+  return Z_OK;
+}
+
+
+function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
+  if (!strm) { // === Z_NULL
+    return Z_STREAM_ERROR;
+  }
+  var wrap = 1;
+
+  if (level === Z_DEFAULT_COMPRESSION) {
+    level = 6;
+  }
+
+  if (windowBits < 0) { /* suppress zlib wrapper */
+    wrap = 0;
+    windowBits = -windowBits;
+  }
+
+  else if (windowBits > 15) {
+    wrap = 2;           /* write gzip wrapper instead */
+    windowBits -= 16;
+  }
+
+
+  if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||
+    windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+    strategy < 0 || strategy > Z_FIXED) {
+    return err(strm, Z_STREAM_ERROR);
+  }
+
+
+  if (windowBits === 8) {
+    windowBits = 9;
+  }
+  /* until 256-byte window bug fixed */
+
+  var s = new DeflateState();
+
+  strm.state = s;
+  s.strm = strm;
+
+  s.wrap = wrap;
+  s.gzhead = null;
+  s.w_bits = windowBits;
+  s.w_size = 1 << s.w_bits;
+  s.w_mask = s.w_size - 1;
+
+  s.hash_bits = memLevel + 7;
+  s.hash_size = 1 << s.hash_bits;
+  s.hash_mask = s.hash_size - 1;
+  s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);
+
+  s.window = new utils.Buf8(s.w_size * 2);
+  s.head = new utils.Buf16(s.hash_size);
+  s.prev = new utils.Buf16(s.w_size);
+
+  // Don't need mem init magic for JS.
+  //s.high_water = 0;  /* nothing written to s->window yet */
+
+  s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+  s.pending_buf_size = s.lit_bufsize * 4;
+
+  //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+  //s->pending_buf = (uchf *) overlay;
+  s.pending_buf = new utils.Buf8(s.pending_buf_size);
+
+  // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
+  //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+  s.d_buf = 1 * s.lit_bufsize;
+
+  //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+  s.l_buf = (1 + 2) * s.lit_bufsize;
+
+  s.level = level;
+  s.strategy = strategy;
+  s.method = method;
+
+  return deflateReset(strm);
+}
+
+function deflateInit(strm, level) {
+  return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+}
+
+
+function deflate(strm, flush) {
+  var old_flush, s;
+  var beg, val; // for gzip header write only
+
+  if (!strm || !strm.state ||
+    flush > Z_BLOCK || flush < 0) {
+    return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
+  }
+
+  s = strm.state;
+
+  if (!strm.output ||
+      (!strm.input && strm.avail_in !== 0) ||
+      (s.status === FINISH_STATE && flush !== Z_FINISH)) {
+    return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);
+  }
+
+  s.strm = strm; /* just in case */
+  old_flush = s.last_flush;
+  s.last_flush = flush;
+
+  /* Write the header */
+  if (s.status === INIT_STATE) {
+
+    if (s.wrap === 2) { // GZIP header
+      strm.adler = 0;  //crc32(0L, Z_NULL, 0);
+      put_byte(s, 31);
+      put_byte(s, 139);
+      put_byte(s, 8);
+      if (!s.gzhead) { // s->gzhead == Z_NULL
+        put_byte(s, 0);
+        put_byte(s, 0);
+        put_byte(s, 0);
+        put_byte(s, 0);
+        put_byte(s, 0);
+        put_byte(s, s.level === 9 ? 2 :
+                    (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
+                     4 : 0));
+        put_byte(s, OS_CODE);
+        s.status = BUSY_STATE;
+      }
+      else {
+        put_byte(s, (s.gzhead.text ? 1 : 0) +
+                    (s.gzhead.hcrc ? 2 : 0) +
+                    (!s.gzhead.extra ? 0 : 4) +
+                    (!s.gzhead.name ? 0 : 8) +
+                    (!s.gzhead.comment ? 0 : 16)
+                );
+        put_byte(s, s.gzhead.time & 0xff);
+        put_byte(s, (s.gzhead.time >> 8) & 0xff);
+        put_byte(s, (s.gzhead.time >> 16) & 0xff);
+        put_byte(s, (s.gzhead.time >> 24) & 0xff);
+        put_byte(s, s.level === 9 ? 2 :
+                    (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
+                     4 : 0));
+        put_byte(s, s.gzhead.os & 0xff);
+        if (s.gzhead.extra && s.gzhead.extra.length) {
+          put_byte(s, s.gzhead.extra.length & 0xff);
+          put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);
+        }
+        if (s.gzhead.hcrc) {
+          strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
+        }
+        s.gzindex = 0;
+        s.status = EXTRA_STATE;
+      }
+    }
+    else // DEFLATE header
+    {
+      var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;
+      var level_flags = -1;
+
+      if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
+        level_flags = 0;
+      } else if (s.level < 6) {
+        level_flags = 1;
+      } else if (s.level === 6) {
+        level_flags = 2;
+      } else {
+        level_flags = 3;
+      }
+      header |= (level_flags << 6);
+      if (s.strstart !== 0) { header |= PRESET_DICT; }
+      header += 31 - (header % 31);
+
+      s.status = BUSY_STATE;
+      putShortMSB(s, header);
+
+      /* Save the adler32 of the preset dictionary: */
+      if (s.strstart !== 0) {
+        putShortMSB(s, strm.adler >>> 16);
+        putShortMSB(s, strm.adler & 0xffff);
+      }
+      strm.adler = 1; // adler32(0L, Z_NULL, 0);
+    }
+  }
+
+//#ifdef GZIP
+  if (s.status === EXTRA_STATE) {
+    if (s.gzhead.extra/* != Z_NULL*/) {
+      beg = s.pending;  /* start of bytes to update crc */
+
+      while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
+        if (s.pending === s.pending_buf_size) {
+          if (s.gzhead.hcrc && s.pending > beg) {
+            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+          }
+          flush_pending(strm);
+          beg = s.pending;
+          if (s.pending === s.pending_buf_size) {
+            break;
+          }
+        }
+        put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
+        s.gzindex++;
+      }
+      if (s.gzhead.hcrc && s.pending > beg) {
+        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+      }
+      if (s.gzindex === s.gzhead.extra.length) {
+        s.gzindex = 0;
+        s.status = NAME_STATE;
+      }
+    }
+    else {
+      s.status = NAME_STATE;
+    }
+  }
+  if (s.status === NAME_STATE) {
+    if (s.gzhead.name/* != Z_NULL*/) {
+      beg = s.pending;  /* start of bytes to update crc */
+      //int val;
+
+      do {
+        if (s.pending === s.pending_buf_size) {
+          if (s.gzhead.hcrc && s.pending > beg) {
+            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+          }
+          flush_pending(strm);
+          beg = s.pending;
+          if (s.pending === s.pending_buf_size) {
+            val = 1;
+            break;
+          }
+        }
+        // JS specific: little magic to add zero terminator to end of string
+        if (s.gzindex < s.gzhead.name.length) {
+          val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
+        } else {
+          val = 0;
+        }
+        put_byte(s, val);
+      } while (val !== 0);
+
+      if (s.gzhead.hcrc && s.pending > beg) {
+        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+      }
+      if (val === 0) {
+        s.gzindex = 0;
+        s.status = COMMENT_STATE;
+      }
+    }
+    else {
+      s.status = COMMENT_STATE;
+    }
+  }
+  if (s.status === COMMENT_STATE) {
+    if (s.gzhead.comment/* != Z_NULL*/) {
+      beg = s.pending;  /* start of bytes to update crc */
+      //int val;
+
+      do {
+        if (s.pending === s.pending_buf_size) {
+          if (s.gzhead.hcrc && s.pending > beg) {
+            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+          }
+          flush_pending(strm);
+          beg = s.pending;
+          if (s.pending === s.pending_buf_size) {
+            val = 1;
+            break;
+          }
+        }
+        // JS specific: little magic to add zero terminator to end of string
+        if (s.gzindex < s.gzhead.comment.length) {
+          val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
+        } else {
+          val = 0;
+        }
+        put_byte(s, val);
+      } while (val !== 0);
+
+      if (s.gzhead.hcrc && s.pending > beg) {
+        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+      }
+      if (val === 0) {
+        s.status = HCRC_STATE;
+      }
+    }
+    else {
+      s.status = HCRC_STATE;
+    }
+  }
+  if (s.status === HCRC_STATE) {
+    if (s.gzhead.hcrc) {
+      if (s.pending + 2 > s.pending_buf_size) {
+        flush_pending(strm);
+      }
+      if (s.pending + 2 <= s.pending_buf_size) {
+        put_byte(s, strm.adler & 0xff);
+        put_byte(s, (strm.adler >> 8) & 0xff);
+        strm.adler = 0; //crc32(0L, Z_NULL, 0);
+        s.status = BUSY_STATE;
+      }
+    }
+    else {
+      s.status = BUSY_STATE;
+    }
+  }
+//#endif
+
+  /* Flush as much pending output as possible */
+  if (s.pending !== 0) {
+    flush_pending(strm);
+    if (strm.avail_out === 0) {
+      /* Since avail_out is 0, deflate will be called again with
+       * more output space, but possibly with both pending and
+       * avail_in equal to zero. There won't be anything to do,
+       * but this is not an error situation so make sure we
+       * return OK instead of BUF_ERROR at next call of deflate:
+       */
+      s.last_flush = -1;
+      return Z_OK;
+    }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+  } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&
+    flush !== Z_FINISH) {
+    return err(strm, Z_BUF_ERROR);
+  }
+
+  /* User must not provide more input after the first FINISH: */
+  if (s.status === FINISH_STATE && strm.avail_in !== 0) {
+    return err(strm, Z_BUF_ERROR);
+  }
+
+  /* Start a new block or continue the current one.
+   */
+  if (strm.avail_in !== 0 || s.lookahead !== 0 ||
+    (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {
+    var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :
+      (s.strategy === Z_RLE ? deflate_rle(s, flush) :
+        configuration_table[s.level].func(s, flush));
+
+    if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
+      s.status = FINISH_STATE;
+    }
+    if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
+      if (strm.avail_out === 0) {
+        s.last_flush = -1;
+        /* avoid BUF_ERROR next call, see above */
+      }
+      return Z_OK;
+      /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+       * of deflate should use the same flush parameter to make sure
+       * that the flush is complete. So we don't have to output an
+       * empty block here, this will be done at next call. This also
+       * ensures that for a very small output buffer, we emit at most
+       * one empty block.
+       */
+    }
+    if (bstate === BS_BLOCK_DONE) {
+      if (flush === Z_PARTIAL_FLUSH) {
+        trees._tr_align(s);
+      }
+      else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+
+        trees._tr_stored_block(s, 0, 0, false);
+        /* For a full flush, this empty block will be recognized
+         * as a special marker by inflate_sync().
+         */
+        if (flush === Z_FULL_FLUSH) {
+          /*** CLEAR_HASH(s); ***/             /* forget history */
+          zero(s.head); // Fill with NIL (= 0);
+
+          if (s.lookahead === 0) {
+            s.strstart = 0;
+            s.block_start = 0;
+            s.insert = 0;
+          }
+        }
+      }
+      flush_pending(strm);
+      if (strm.avail_out === 0) {
+        s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+        return Z_OK;
+      }
+    }
+  }
+  //Assert(strm->avail_out > 0, "bug2");
+  //if (strm.avail_out <= 0) { throw new Error("bug2");}
+
+  if (flush !== Z_FINISH) { return Z_OK; }
+  if (s.wrap <= 0) { return Z_STREAM_END; }
+
+  /* Write the trailer */
+  if (s.wrap === 2) {
+    put_byte(s, strm.adler & 0xff);
+    put_byte(s, (strm.adler >> 8) & 0xff);
+    put_byte(s, (strm.adler >> 16) & 0xff);
+    put_byte(s, (strm.adler >> 24) & 0xff);
+    put_byte(s, strm.total_in & 0xff);
+    put_byte(s, (strm.total_in >> 8) & 0xff);
+    put_byte(s, (strm.total_in >> 16) & 0xff);
+    put_byte(s, (strm.total_in >> 24) & 0xff);
+  }
+  else
+  {
+    putShortMSB(s, strm.adler >>> 16);
+    putShortMSB(s, strm.adler & 0xffff);
+  }
+
+  flush_pending(strm);
+  /* If avail_out is zero, the application will call deflate again
+   * to flush the rest.
+   */
+  if (s.wrap > 0) { s.wrap = -s.wrap; }
+  /* write the trailer only once! */
+  return s.pending !== 0 ? Z_OK : Z_STREAM_END;
+}
+
+function deflateEnd(strm) {
+  var status;
+
+  if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
+    return Z_STREAM_ERROR;
+  }
+
+  status = strm.state.status;
+  if (status !== INIT_STATE &&
+    status !== EXTRA_STATE &&
+    status !== NAME_STATE &&
+    status !== COMMENT_STATE &&
+    status !== HCRC_STATE &&
+    status !== BUSY_STATE &&
+    status !== FINISH_STATE
+  ) {
+    return err(strm, Z_STREAM_ERROR);
+  }
+
+  strm.state = null;
+
+  return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
+}
+
+
+/* =========================================================================
+ * Initializes the compression dictionary from the given byte
+ * sequence without producing any compressed output.
+ */
+function deflateSetDictionary(strm, dictionary) {
+  var dictLength = dictionary.length;
+
+  var s;
+  var str, n;
+  var wrap;
+  var avail;
+  var next;
+  var input;
+  var tmpDict;
+
+  if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
+    return Z_STREAM_ERROR;
+  }
+
+  s = strm.state;
+  wrap = s.wrap;
+
+  if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {
+    return Z_STREAM_ERROR;
+  }
+
+  /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+  if (wrap === 1) {
+    /* adler32(strm->adler, dictionary, dictLength); */
+    strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
+  }
+
+  s.wrap = 0;   /* avoid computing Adler-32 in read_buf */
+
+  /* if dictionary would fill window, just replace the history */
+  if (dictLength >= s.w_size) {
+    if (wrap === 0) {            /* already empty otherwise */
+      /*** CLEAR_HASH(s); ***/
+      zero(s.head); // Fill with NIL (= 0);
+      s.strstart = 0;
+      s.block_start = 0;
+      s.insert = 0;
+    }
+    /* use the tail */
+    // dictionary = dictionary.slice(dictLength - s.w_size);
+    tmpDict = new utils.Buf8(s.w_size);
+    utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
+    dictionary = tmpDict;
+    dictLength = s.w_size;
+  }
+  /* insert dictionary into window and hash */
+  avail = strm.avail_in;
+  next = strm.next_in;
+  input = strm.input;
+  strm.avail_in = dictLength;
+  strm.next_in = 0;
+  strm.input = dictionary;
+  fill_window(s);
+  while (s.lookahead >= MIN_MATCH) {
+    str = s.strstart;
+    n = s.lookahead - (MIN_MATCH - 1);
+    do {
+      /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
+      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
+
+      s.prev[str & s.w_mask] = s.head[s.ins_h];
+
+      s.head[s.ins_h] = str;
+      str++;
+    } while (--n);
+    s.strstart = str;
+    s.lookahead = MIN_MATCH - 1;
+    fill_window(s);
+  }
+  s.strstart += s.lookahead;
+  s.block_start = s.strstart;
+  s.insert = s.lookahead;
+  s.lookahead = 0;
+  s.match_length = s.prev_length = MIN_MATCH - 1;
+  s.match_available = 0;
+  strm.next_in = next;
+  strm.input = input;
+  strm.avail_in = avail;
+  s.wrap = wrap;
+  return Z_OK;
+}
+
+
+exports.deflateInit = deflateInit;
+exports.deflateInit2 = deflateInit2;
+exports.deflateReset = deflateReset;
+exports.deflateResetKeep = deflateResetKeep;
+exports.deflateSetHeader = deflateSetHeader;
+exports.deflate = deflate;
+exports.deflateEnd = deflateEnd;
+exports.deflateSetDictionary = deflateSetDictionary;
+exports.deflateInfo = 'pako deflate (from Nodeca project)';
+
+/* Not implemented
+exports.deflateBound = deflateBound;
+exports.deflateCopy = deflateCopy;
+exports.deflateParams = deflateParams;
+exports.deflatePending = deflatePending;
+exports.deflatePrime = deflatePrime;
+exports.deflateTune = deflateTune;
+*/
+
+
+/***/ }),
+/* 131 */
+/*!******************************************!*\
+  !*** ./node_modules/pako/lib/deflate.js ***!
+  \******************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+
+var zlib_deflate = __webpack_require__(/*! ./zlib/deflate */ 130);
+var utils        = __webpack_require__(/*! ./utils/common */ 48);
+var strings      = __webpack_require__(/*! ./utils/strings */ 86);
+var msg          = __webpack_require__(/*! ./zlib/messages */ 69);
+var ZStream      = __webpack_require__(/*! ./zlib/zstream */ 85);
+
+var toString = Object.prototype.toString;
+
+/* Public constants ==========================================================*/
+/* ===========================================================================*/
+
+var Z_NO_FLUSH      = 0;
+var Z_FINISH        = 4;
+
+var Z_OK            = 0;
+var Z_STREAM_END    = 1;
+var Z_SYNC_FLUSH    = 2;
+
+var Z_DEFAULT_COMPRESSION = -1;
+
+var Z_DEFAULT_STRATEGY    = 0;
+
+var Z_DEFLATED  = 8;
+
+/* ===========================================================================*/
+
+
+/**
+ * class Deflate
+ *
+ * Generic JS-style wrapper for zlib calls. If you don't need
+ * streaming behaviour - use more simple functions: [[deflate]],
+ * [[deflateRaw]] and [[gzip]].
+ **/
+
+/* internal
+ * Deflate.chunks -> Array
+ *
+ * Chunks of output data, if [[Deflate#onData]] not overridden.
+ **/
+
+/**
+ * Deflate.result -> Uint8Array|Array
+ *
+ * Compressed result, generated by default [[Deflate#onData]]
+ * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
+ * (call [[Deflate#push]] with `Z_FINISH` / `true` param)  or if you
+ * push a chunk with explicit flush (call [[Deflate#push]] with
+ * `Z_SYNC_FLUSH` param).
+ **/
+
+/**
+ * Deflate.err -> Number
+ *
+ * Error code after deflate finished. 0 (Z_OK) on success.
+ * You will not need it in real life, because deflate errors
+ * are possible only on wrong options or bad `onData` / `onEnd`
+ * custom handlers.
+ **/
+
+/**
+ * Deflate.msg -> String
+ *
+ * Error message, if [[Deflate.err]] != 0
+ **/
+
+
+/**
+ * new Deflate(options)
+ * - options (Object): zlib deflate options.
+ *
+ * Creates new deflator instance with specified params. Throws exception
+ * on bad params. Supported options:
+ *
+ * - `level`
+ * - `windowBits`
+ * - `memLevel`
+ * - `strategy`
+ * - `dictionary`
+ *
+ * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
+ * for more information on these.
+ *
+ * Additional options, for internal needs:
+ *
+ * - `chunkSize` - size of generated data chunks (16K by default)
+ * - `raw` (Boolean) - do raw deflate
+ * - `gzip` (Boolean) - create gzip wrapper
+ * - `to` (String) - if equal to 'string', then result will be "binary string"
+ *    (each char code [0..255])
+ * - `header` (Object) - custom header for gzip
+ *   - `text` (Boolean) - true if compressed data believed to be text
+ *   - `time` (Number) - modification time, unix timestamp
+ *   - `os` (Number) - operation system code
+ *   - `extra` (Array) - array of bytes with extra data (max 65536)
+ *   - `name` (String) - file name (binary string)
+ *   - `comment` (String) - comment (binary string)
+ *   - `hcrc` (Boolean) - true if header crc should be added
+ *
+ * ##### Example:
+ *
+ * ```javascript
+ * var pako = require('pako')
+ *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
+ *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
+ *
+ * var deflate = new pako.Deflate({ level: 3});
+ *
+ * deflate.push(chunk1, false);
+ * deflate.push(chunk2, true);  // true -> last chunk
+ *
+ * if (deflate.err) { throw new Error(deflate.err); }
+ *
+ * console.log(deflate.result);
+ * ```
+ **/
+function Deflate(options) {
+  if (!(this instanceof Deflate)) return new Deflate(options);
+
+  this.options = utils.assign({
+    level: Z_DEFAULT_COMPRESSION,
+    method: Z_DEFLATED,
+    chunkSize: 16384,
+    windowBits: 15,
+    memLevel: 8,
+    strategy: Z_DEFAULT_STRATEGY,
+    to: ''
+  }, options || {});
+
+  var opt = this.options;
+
+  if (opt.raw && (opt.windowBits > 0)) {
+    opt.windowBits = -opt.windowBits;
+  }
+
+  else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
+    opt.windowBits += 16;
+  }
+
+  this.err    = 0;      // error code, if happens (0 = Z_OK)
+  this.msg    = '';     // error message
+  this.ended  = false;  // used to avoid multiple onEnd() calls
+  this.chunks = [];     // chunks of compressed data
+
+  this.strm = new ZStream();
+  this.strm.avail_out = 0;
+
+  var status = zlib_deflate.deflateInit2(
+    this.strm,
+    opt.level,
+    opt.method,
+    opt.windowBits,
+    opt.memLevel,
+    opt.strategy
+  );
+
+  if (status !== Z_OK) {
+    throw new Error(msg[status]);
+  }
+
+  if (opt.header) {
+    zlib_deflate.deflateSetHeader(this.strm, opt.header);
+  }
+
+  if (opt.dictionary) {
+    var dict;
+    // Convert data if needed
+    if (typeof opt.dictionary === 'string') {
+      // If we need to compress text, change encoding to utf8.
+      dict = strings.string2buf(opt.dictionary);
+    } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {
+      dict = new Uint8Array(opt.dictionary);
+    } else {
+      dict = opt.dictionary;
+    }
+
+    status = zlib_deflate.deflateSetDictionary(this.strm, dict);
+
+    if (status !== Z_OK) {
+      throw new Error(msg[status]);
+    }
+
+    this._dict_set = true;
+  }
+}
+
+/**
+ * Deflate#push(data[, mode]) -> Boolean
+ * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be
+ *   converted to utf8 byte sequence.
+ * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
+ *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
+ *
+ * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
+ * new compressed chunks. Returns `true` on success. The last data block must have
+ * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
+ * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you
+ * can use mode Z_SYNC_FLUSH, keeping the compression context.
+ *
+ * On fail call [[Deflate#onEnd]] with error code and return false.
+ *
+ * We strongly recommend to use `Uint8Array` on input for best speed (output
+ * array format is detected automatically). Also, don't skip last param and always
+ * use the same type in your code (boolean or number). That will improve JS speed.
+ *
+ * For regular `Array`-s make sure all elements are [0..255].
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * push(chunk, false); // push one of data chunks
+ * ...
+ * push(chunk, true);  // push last chunk
+ * ```
+ **/
+Deflate.prototype.push = function (data, mode) {
+  var strm = this.strm;
+  var chunkSize = this.options.chunkSize;
+  var status, _mode;
+
+  if (this.ended) { return false; }
+
+  _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
+
+  // Convert data if needed
+  if (typeof data === 'string') {
+    // If we need to compress text, change encoding to utf8.
+    strm.input = strings.string2buf(data);
+  } else if (toString.call(data) === '[object ArrayBuffer]') {
+    strm.input = new Uint8Array(data);
+  } else {
+    strm.input = data;
+  }
+
+  strm.next_in = 0;
+  strm.avail_in = strm.input.length;
+
+  do {
+    if (strm.avail_out === 0) {
+      strm.output = new utils.Buf8(chunkSize);
+      strm.next_out = 0;
+      strm.avail_out = chunkSize;
+    }
+    status = zlib_deflate.deflate(strm, _mode);    /* no bad return value */
+
+    if (status !== Z_STREAM_END && status !== Z_OK) {
+      this.onEnd(status);
+      this.ended = true;
+      return false;
+    }
+    if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
+      if (this.options.to === 'string') {
+        this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
+      } else {
+        this.onData(utils.shrinkBuf(strm.output, strm.next_out));
+      }
+    }
+  } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
+
+  // Finalize on the last chunk.
+  if (_mode === Z_FINISH) {
+    status = zlib_deflate.deflateEnd(this.strm);
+    this.onEnd(status);
+    this.ended = true;
+    return status === Z_OK;
+  }
+
+  // callback interim results if Z_SYNC_FLUSH.
+  if (_mode === Z_SYNC_FLUSH) {
+    this.onEnd(Z_OK);
+    strm.avail_out = 0;
+    return true;
+  }
+
+  return true;
+};
+
+
+/**
+ * Deflate#onData(chunk) -> Void
+ * - chunk (Uint8Array|Array|String): output data. Type of array depends
+ *   on js engine support. When string output requested, each chunk
+ *   will be string.
+ *
+ * By default, stores data blocks in `chunks[]` property and glue
+ * those in `onEnd`. Override this handler, if you need another behaviour.
+ **/
+Deflate.prototype.onData = function (chunk) {
+  this.chunks.push(chunk);
+};
+
+
+/**
+ * Deflate#onEnd(status) -> Void
+ * - status (Number): deflate status. 0 (Z_OK) on success,
+ *   other if not.
+ *
+ * Called once after you tell deflate that the input stream is
+ * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
+ * or if an error happened. By default - join collected chunks,
+ * free memory and fill `results` / `err` properties.
+ **/
+Deflate.prototype.onEnd = function (status) {
+  // On success - join
+  if (status === Z_OK) {
+    if (this.options.to === 'string') {
+      this.result = this.chunks.join('');
+    } else {
+      this.result = utils.flattenChunks(this.chunks);
+    }
+  }
+  this.chunks = [];
+  this.err = status;
+  this.msg = this.strm.msg;
+};
+
+
+/**
+ * deflate(data[, options]) -> Uint8Array|Array|String
+ * - data (Uint8Array|Array|String): input data to compress.
+ * - options (Object): zlib deflate options.
+ *
+ * Compress `data` with deflate algorithm and `options`.
+ *
+ * Supported options are:
+ *
+ * - level
+ * - windowBits
+ * - memLevel
+ * - strategy
+ * - dictionary
+ *
+ * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
+ * for more information on these.
+ *
+ * Sugar (options):
+ *
+ * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
+ *   negative windowBits implicitly.
+ * - `to` (String) - if equal to 'string', then result will be "binary string"
+ *    (each char code [0..255])
+ *
+ * ##### Example:
+ *
+ * ```javascript
+ * var pako = require('pako')
+ *   , data = Uint8Array([1,2,3,4,5,6,7,8,9]);
+ *
+ * console.log(pako.deflate(data));
+ * ```
+ **/
+function deflate(input, options) {
+  var deflator = new Deflate(options);
+
+  deflator.push(input, true);
+
+  // That will never happens, if you don't cheat with options :)
+  if (deflator.err) { throw deflator.msg || msg[deflator.err]; }
+
+  return deflator.result;
+}
+
+
+/**
+ * deflateRaw(data[, options]) -> Uint8Array|Array|String
+ * - data (Uint8Array|Array|String): input data to compress.
+ * - options (Object): zlib deflate options.
+ *
+ * The same as [[deflate]], but creates raw data, without wrapper
+ * (header and adler32 crc).
+ **/
+function deflateRaw(input, options) {
+  options = options || {};
+  options.raw = true;
+  return deflate(input, options);
+}
+
+
+/**
+ * gzip(data[, options]) -> Uint8Array|Array|String
+ * - data (Uint8Array|Array|String): input data to compress.
+ * - options (Object): zlib deflate options.
+ *
+ * The same as [[deflate]], but create gzip wrapper instead of
+ * deflate one.
+ **/
+function gzip(input, options) {
+  options = options || {};
+  options.gzip = true;
+  return deflate(input, options);
+}
+
+
+exports.Deflate = Deflate;
+exports.deflate = deflate;
+exports.deflateRaw = deflateRaw;
+exports.gzip = gzip;
+
+
+/***/ }),
+/* 132 */
+/*!************************************!*\
+  !*** ./node_modules/pako/index.js ***!
+  \************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+// Top level file is just a mixin of submodules & constants
+
+
+var assign    = __webpack_require__(/*! ./lib/utils/common */ 48).assign;
+
+var deflate   = __webpack_require__(/*! ./lib/deflate */ 131);
+var inflate   = __webpack_require__(/*! ./lib/inflate */ 128);
+var constants = __webpack_require__(/*! ./lib/zlib/constants */ 84);
+
+var pako = {};
+
+assign(pako, deflate, inflate, constants);
+
+module.exports = pako;
+
+
+/***/ }),
+/* 133 */
+/*!*****************************************!*\
+  !*** ./node_modules/jszip/lib/flate.js ***!
+  \*****************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined');
+
+var pako = __webpack_require__(/*! pako */ 132);
+var utils = __webpack_require__(/*! ./utils */ 31);
+var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ 37);
+
+var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array";
+
+exports.magic = "\x08\x00";
+
+/**
+ * Create a worker that uses pako to inflate/deflate.
+ * @constructor
+ * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate".
+ * @param {Object} options the options to use when (de)compressing.
+ */
+function FlateWorker(action, options) {
+    GenericWorker.call(this, "FlateWorker/" + action);
+
+    this._pako = null;
+    this._pakoAction = action;
+    this._pakoOptions = options;
+    // the `meta` object from the last chunk received
+    // this allow this worker to pass around metadata
+    this.meta = {};
+}
+
+utils.inherits(FlateWorker, GenericWorker);
+
+/**
+ * @see GenericWorker.processChunk
+ */
+FlateWorker.prototype.processChunk = function (chunk) {
+    this.meta = chunk.meta;
+    if (this._pako === null) {
+        this._createPako();
+    }
+    this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false);
+};
+
+/**
+ * @see GenericWorker.flush
+ */
+FlateWorker.prototype.flush = function () {
+    GenericWorker.prototype.flush.call(this);
+    if (this._pako === null) {
+        this._createPako();
+    }
+    this._pako.push([], true);
+};
+/**
+ * @see GenericWorker.cleanUp
+ */
+FlateWorker.prototype.cleanUp = function () {
+    GenericWorker.prototype.cleanUp.call(this);
+    this._pako = null;
+};
+
+/**
+ * Create the _pako object.
+ * TODO: lazy-loading this object isn't the best solution but it's the
+ * quickest. The best solution is to lazy-load the worker list. See also the
+ * issue #446.
+ */
+FlateWorker.prototype._createPako = function () {
+    this._pako = new pako[this._pakoAction]({
+        raw: true,
+        level: this._pakoOptions.level || -1 // default compression
+    });
+    var self = this;
+    this._pako.onData = function(data) {
+        self.push({
+            data : data,
+            meta : self.meta
+        });
+    };
+};
+
+exports.compressWorker = function (compressionOptions) {
+    return new FlateWorker("Deflate", compressionOptions);
+};
+exports.uncompressWorker = function () {
+    return new FlateWorker("Inflate", {});
+};
+
+
+/***/ }),
+/* 134 */
+/*!**************************************************!*\
+  !*** ./node_modules/jszip/lib/generate/index.js ***!
+  \**************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var compressions = __webpack_require__(/*! ../compressions */ 89);
+var ZipFileWorker = __webpack_require__(/*! ./ZipFileWorker */ 123);
+
+/**
+ * Find the compression to use.
+ * @param {String} fileCompression the compression defined at the file level, if any.
+ * @param {String} zipCompression the compression defined at the load() level.
+ * @return {Object} the compression object to use.
+ */
+var getCompression = function (fileCompression, zipCompression) {
+
+    var compressionName = fileCompression || zipCompression;
+    var compression = compressions[compressionName];
+    if (!compression) {
+        throw new Error(compressionName + " is not a valid compression method !");
+    }
+    return compression;
+};
+
+/**
+ * Create a worker to generate a zip file.
+ * @param {JSZip} zip the JSZip instance at the right root level.
+ * @param {Object} options to generate the zip file.
+ * @param {String} comment the comment to use.
+ */
+exports.generateWorker = function (zip, options, comment) {
+
+    var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName);
+    var entriesCount = 0;
+    try {
+
+        zip.forEach(function (relativePath, file) {
+            entriesCount++;
+            var compression = getCompression(file.options.compression, options.compression);
+            var compressionOptions = file.options.compressionOptions || options.compressionOptions || {};
+            var dir = file.dir, date = file.date;
+
+            file._compressWorker(compression, compressionOptions)
+            .withStreamInfo("file", {
+                name : relativePath,
+                dir : dir,
+                date : date,
+                comment : file.comment || "",
+                unixPermissions : file.unixPermissions,
+                dosPermissions : file.dosPermissions
+            })
+            .pipe(zipFileWorker);
+        });
+        zipFileWorker.entriesCount = entriesCount;
+    } catch (e) {
+        zipFileWorker.error(e);
+    }
+
+    return zipFileWorker;
+};
+
+
+/***/ }),
+/* 135 */
+/*!*********************************************!*\
+  !*** ./node_modules/jszip/lib/zipObject.js ***!
+  \*********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var StreamHelper = __webpack_require__(/*! ./stream/StreamHelper */ 94);
+var DataWorker = __webpack_require__(/*! ./stream/DataWorker */ 92);
+var utf8 = __webpack_require__(/*! ./utf8 */ 56);
+var CompressedObject = __webpack_require__(/*! ./compressedObject */ 71);
+var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ 37);
+
+/**
+ * A simple object representing a file in the zip file.
+ * @constructor
+ * @param {string} name the name of the file
+ * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data
+ * @param {Object} options the options of the file
+ */
+var ZipObject = function(name, data, options) {
+    this.name = name;
+    this.dir = options.dir;
+    this.date = options.date;
+    this.comment = options.comment;
+    this.unixPermissions = options.unixPermissions;
+    this.dosPermissions = options.dosPermissions;
+
+    this._data = data;
+    this._dataBinary = options.binary;
+    // keep only the compression
+    this.options = {
+        compression : options.compression,
+        compressionOptions : options.compressionOptions
+    };
+};
+
+ZipObject.prototype = {
+    /**
+     * Create an internal stream for the content of this object.
+     * @param {String} type the type of each chunk.
+     * @return StreamHelper the stream.
+     */
+    internalStream: function (type) {
+        var result = null, outputType = "string";
+        try {
+            if (!type) {
+                throw new Error("No output type specified.");
+            }
+            outputType = type.toLowerCase();
+            var askUnicodeString = outputType === "string" || outputType === "text";
+            if (outputType === "binarystring" || outputType === "text") {
+                outputType = "string";
+            }
+            result = this._decompressWorker();
+
+            var isUnicodeString = !this._dataBinary;
+
+            if (isUnicodeString && !askUnicodeString) {
+                result = result.pipe(new utf8.Utf8EncodeWorker());
+            }
+            if (!isUnicodeString && askUnicodeString) {
+                result = result.pipe(new utf8.Utf8DecodeWorker());
+            }
+        } catch (e) {
+            result = new GenericWorker("error");
+            result.error(e);
+        }
+
+        return new StreamHelper(result, outputType, "");
+    },
+
+    /**
+     * Prepare the content in the asked type.
+     * @param {String} type the type of the result.
+     * @param {Function} onUpdate a function to call on each internal update.
+     * @return Promise the promise of the result.
+     */
+    async: function (type, onUpdate) {
+        return this.internalStream(type).accumulate(onUpdate);
+    },
+
+    /**
+     * Prepare the content as a nodejs stream.
+     * @param {String} type the type of each chunk.
+     * @param {Function} onUpdate a function to call on each internal update.
+     * @return Stream the stream.
+     */
+    nodeStream: function (type, onUpdate) {
+        return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate);
+    },
+
+    /**
+     * Return a worker for the compressed content.
+     * @private
+     * @param {Object} compression the compression object to use.
+     * @param {Object} compressionOptions the options to use when compressing.
+     * @return Worker the worker.
+     */
+    _compressWorker: function (compression, compressionOptions) {
+        if (
+            this._data instanceof CompressedObject &&
+            this._data.compression.magic === compression.magic
+        ) {
+            return this._data.getCompressedWorker();
+        } else {
+            var result = this._decompressWorker();
+            if(!this._dataBinary) {
+                result = result.pipe(new utf8.Utf8EncodeWorker());
+            }
+            return CompressedObject.createWorkerFrom(result, compression, compressionOptions);
+        }
+    },
+    /**
+     * Return a worker for the decompressed content.
+     * @private
+     * @return Worker the worker.
+     */
+    _decompressWorker : function () {
+        if (this._data instanceof CompressedObject) {
+            return this._data.getContentWorker();
+        } else if (this._data instanceof GenericWorker) {
+            return this._data;
+        } else {
+            return new DataWorker(this._data);
+        }
+    }
+};
+
+var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"];
+var removedFn = function () {
+    throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
+};
+
+for(var i = 0; i < removedMethods.length; i++) {
+    ZipObject.prototype[removedMethods[i]] = removedFn;
+}
+module.exports = ZipObject;
+
+
+/***/ }),
+/* 136 */
+/*!********************************************************************!*\
+  !*** ./node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js ***!
+  \********************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var Readable = __webpack_require__(/*! readable-stream */ 106).Readable;
+
+var utils = __webpack_require__(/*! ../utils */ 31);
+utils.inherits(NodejsStreamOutputAdapter, Readable);
+
+/**
+* A nodejs stream using a worker as source.
+* @see the SourceWrapper in http://nodejs.org/api/stream.html
+* @constructor
+* @param {StreamHelper} helper the helper wrapping the worker
+* @param {Object} options the nodejs stream options
+* @param {Function} updateCb the update callback.
+*/
+function NodejsStreamOutputAdapter(helper, options, updateCb) {
+    Readable.call(this, options);
+    this._helper = helper;
+
+    var self = this;
+    helper.on("data", function (data, meta) {
+        if (!self.push(data)) {
+            self._helper.pause();
+        }
+        if(updateCb) {
+            updateCb(meta);
+        }
+    })
+    .on("error", function(e) {
+        self.emit('error', e);
+    })
+    .on("end", function () {
+        self.push(null);
+    });
+}
+
+
+NodejsStreamOutputAdapter.prototype._read = function() {
+    this._helper.resume();
+};
+
+module.exports = NodejsStreamOutputAdapter;
+
+
+/***/ }),
+/* 137 */
+/*!********************************************************!*\
+  !*** ./node_modules/jszip/lib/stream/ConvertWorker.js ***!
+  \********************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var GenericWorker = __webpack_require__(/*! ./GenericWorker */ 37);
+var utils = __webpack_require__(/*! ../utils */ 31);
+
+/**
+ * A worker which convert chunks to a specified type.
+ * @constructor
+ * @param {String} destType the destination type.
+ */
+function ConvertWorker(destType) {
+    GenericWorker.call(this, "ConvertWorker to " + destType);
+    this.destType = destType;
+}
+utils.inherits(ConvertWorker, GenericWorker);
+
+/**
+ * @see GenericWorker.processChunk
+ */
+ConvertWorker.prototype.processChunk = function (chunk) {
+    this.push({
+        data : utils.transformTo(this.destType, chunk.data),
+        meta : chunk.meta
+    });
+};
+module.exports = ConvertWorker;
+
+
+/***/ }),
+/* 138 */
+/*!***********************************************!*\
+  !*** ./node_modules/immediate/lib/browser.js ***!
+  \***********************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(global) {
+var Mutation = global.MutationObserver || global.WebKitMutationObserver;
+
+var scheduleDrain;
+
+{
+  if (Mutation) {
+    var called = 0;
+    var observer = new Mutation(nextTick);
+    var element = global.document.createTextNode('');
+    observer.observe(element, {
+      characterData: true
+    });
+    scheduleDrain = function () {
+      element.data = (called = ++called % 2);
+    };
+  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
+    var channel = new global.MessageChannel();
+    channel.port1.onmessage = nextTick;
+    scheduleDrain = function () {
+      channel.port2.postMessage(0);
+    };
+  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
+    scheduleDrain = function () {
+
+      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+      var scriptEl = global.document.createElement('script');
+      scriptEl.onreadystatechange = function () {
+        nextTick();
+
+        scriptEl.onreadystatechange = null;
+        scriptEl.parentNode.removeChild(scriptEl);
+        scriptEl = null;
+      };
+      global.document.documentElement.appendChild(scriptEl);
+    };
+  } else {
+    scheduleDrain = function () {
+      setTimeout(nextTick, 0);
+    };
+  }
+}
+
+var draining;
+var queue = [];
+//named nextTick for less confusing stack traces
+function nextTick() {
+  draining = true;
+  var i, oldQueue;
+  var len = queue.length;
+  while (len) {
+    oldQueue = queue;
+    queue = [];
+    i = -1;
+    while (++i < len) {
+      oldQueue[i]();
+    }
+    len = queue.length;
+  }
+  draining = false;
+}
+
+module.exports = immediate;
+function immediate(task) {
+  if (queue.push(task) === 1 && !draining) {
+    scheduleDrain();
+  }
+}
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ 49)))
+
+/***/ }),
+/* 139 */
+/*!*****************************************!*\
+  !*** ./node_modules/lie/lib/browser.js ***!
+  \*****************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var immediate = __webpack_require__(/*! immediate */ 138);
+
+/* istanbul ignore next */
+function INTERNAL() {}
+
+var handlers = {};
+
+var REJECTED = ['REJECTED'];
+var FULFILLED = ['FULFILLED'];
+var PENDING = ['PENDING'];
+
+module.exports = Promise;
+
+function Promise(resolver) {
+  if (typeof resolver !== 'function') {
+    throw new TypeError('resolver must be a function');
+  }
+  this.state = PENDING;
+  this.queue = [];
+  this.outcome = void 0;
+  if (resolver !== INTERNAL) {
+    safelyResolveThenable(this, resolver);
+  }
+}
+
+Promise.prototype["catch"] = function (onRejected) {
+  return this.then(null, onRejected);
+};
+Promise.prototype.then = function (onFulfilled, onRejected) {
+  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
+    typeof onRejected !== 'function' && this.state === REJECTED) {
+    return this;
+  }
+  var promise = new this.constructor(INTERNAL);
+  if (this.state !== PENDING) {
+    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
+    unwrap(promise, resolver, this.outcome);
+  } else {
+    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
+  }
+
+  return promise;
+};
+function QueueItem(promise, onFulfilled, onRejected) {
+  this.promise = promise;
+  if (typeof onFulfilled === 'function') {
+    this.onFulfilled = onFulfilled;
+    this.callFulfilled = this.otherCallFulfilled;
+  }
+  if (typeof onRejected === 'function') {
+    this.onRejected = onRejected;
+    this.callRejected = this.otherCallRejected;
+  }
+}
+QueueItem.prototype.callFulfilled = function (value) {
+  handlers.resolve(this.promise, value);
+};
+QueueItem.prototype.otherCallFulfilled = function (value) {
+  unwrap(this.promise, this.onFulfilled, value);
+};
+QueueItem.prototype.callRejected = function (value) {
+  handlers.reject(this.promise, value);
+};
+QueueItem.prototype.otherCallRejected = function (value) {
+  unwrap(this.promise, this.onRejected, value);
+};
+
+function unwrap(promise, func, value) {
+  immediate(function () {
+    var returnValue;
+    try {
+      returnValue = func(value);
+    } catch (e) {
+      return handlers.reject(promise, e);
+    }
+    if (returnValue === promise) {
+      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
+    } else {
+      handlers.resolve(promise, returnValue);
+    }
+  });
+}
+
+handlers.resolve = function (self, value) {
+  var result = tryCatch(getThen, value);
+  if (result.status === 'error') {
+    return handlers.reject(self, result.value);
+  }
+  var thenable = result.value;
+
+  if (thenable) {
+    safelyResolveThenable(self, thenable);
+  } else {
+    self.state = FULFILLED;
+    self.outcome = value;
+    var i = -1;
+    var len = self.queue.length;
+    while (++i < len) {
+      self.queue[i].callFulfilled(value);
+    }
+  }
+  return self;
+};
+handlers.reject = function (self, error) {
+  self.state = REJECTED;
+  self.outcome = error;
+  var i = -1;
+  var len = self.queue.length;
+  while (++i < len) {
+    self.queue[i].callRejected(error);
+  }
+  return self;
+};
+
+function getThen(obj) {
+  // Make sure we only access the accessor once as required by the spec
+  var then = obj && obj.then;
+  if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') {
+    return function appyThen() {
+      then.apply(obj, arguments);
+    };
+  }
+}
+
+function safelyResolveThenable(self, thenable) {
+  // Either fulfill, reject or reject with error
+  var called = false;
+  function onError(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.reject(self, value);
+  }
+
+  function onSuccess(value) {
+    if (called) {
+      return;
+    }
+    called = true;
+    handlers.resolve(self, value);
+  }
+
+  function tryToUnwrap() {
+    thenable(onSuccess, onError);
+  }
+
+  var result = tryCatch(tryToUnwrap);
+  if (result.status === 'error') {
+    onError(result.value);
+  }
+}
+
+function tryCatch(func, value) {
+  var out = {};
+  try {
+    out.value = func(value);
+    out.status = 'success';
+  } catch (e) {
+    out.status = 'error';
+    out.value = e;
+  }
+  return out;
+}
+
+Promise.resolve = resolve;
+function resolve(value) {
+  if (value instanceof this) {
+    return value;
+  }
+  return handlers.resolve(new this(INTERNAL), value);
+}
+
+Promise.reject = reject;
+function reject(reason) {
+  var promise = new this(INTERNAL);
+  return handlers.reject(promise, reason);
+}
+
+Promise.all = all;
+function all(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var values = new Array(len);
+  var resolved = 0;
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    allResolver(iterable[i], i);
+  }
+  return promise;
+  function allResolver(value, i) {
+    self.resolve(value).then(resolveFromAll, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+    function resolveFromAll(outValue) {
+      values[i] = outValue;
+      if (++resolved === len && !called) {
+        called = true;
+        handlers.resolve(promise, values);
+      }
+    }
+  }
+}
+
+Promise.race = race;
+function race(iterable) {
+  var self = this;
+  if (Object.prototype.toString.call(iterable) !== '[object Array]') {
+    return this.reject(new TypeError('must be an array'));
+  }
+
+  var len = iterable.length;
+  var called = false;
+  if (!len) {
+    return this.resolve([]);
+  }
+
+  var i = -1;
+  var promise = new this(INTERNAL);
+
+  while (++i < len) {
+    resolver(iterable[i]);
+  }
+  return promise;
+  function resolver(value) {
+    self.resolve(value).then(function (response) {
+      if (!called) {
+        called = true;
+        handlers.resolve(promise, response);
+      }
+    }, function (error) {
+      if (!called) {
+        called = true;
+        handlers.reject(promise, error);
+      }
+    });
+  }
+}
+
+
+/***/ }),
+/* 140 */
+/*!*************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_cof.js ***!
+  \*************************************************************************/
+/***/ (function(module, exports) {
+
+var toString = {}.toString;
+
+module.exports = function(it){
+  return toString.call(it).slice(8, -1);
+};
+
+/***/ }),
+/* 141 */
+/*!**************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_html.js ***!
+  \**************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(/*! ./_global */ 62).document && document.documentElement;
+
+/***/ }),
+/* 142 */
+/*!****************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_invoke.js ***!
+  \****************************************************************************/
+/***/ (function(module, exports) {
+
+// fast apply, http://jsperf.lnkit.com/fast-apply/5
+module.exports = function(fn, args, that){
+  var un = that === undefined;
+  switch(args.length){
+    case 0: return un ? fn()
+                      : fn.call(that);
+    case 1: return un ? fn(args[0])
+                      : fn.call(that, args[0]);
+    case 2: return un ? fn(args[0], args[1])
+                      : fn.call(that, args[0], args[1]);
+    case 3: return un ? fn(args[0], args[1], args[2])
+                      : fn.call(that, args[0], args[1], args[2]);
+    case 4: return un ? fn(args[0], args[1], args[2], args[3])
+                      : fn.call(that, args[0], args[1], args[2], args[3]);
+  } return              fn.apply(that, args);
+};
+
+/***/ }),
+/* 143 */
+/*!**************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_task.js ***!
+  \**************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+var ctx                = __webpack_require__(/*! ./_ctx */ 97)
+  , invoke             = __webpack_require__(/*! ./_invoke */ 142)
+  , html               = __webpack_require__(/*! ./_html */ 141)
+  , cel                = __webpack_require__(/*! ./_dom-create */ 95)
+  , global             = __webpack_require__(/*! ./_global */ 62)
+  , process            = global.process
+  , setTask            = global.setImmediate
+  , clearTask          = global.clearImmediate
+  , MessageChannel     = global.MessageChannel
+  , counter            = 0
+  , queue              = {}
+  , ONREADYSTATECHANGE = 'onreadystatechange'
+  , defer, channel, port;
+var run = function(){
+  var id = +this;
+  if(queue.hasOwnProperty(id)){
+    var fn = queue[id];
+    delete queue[id];
+    fn();
+  }
+};
+var listener = function(event){
+  run.call(event.data);
+};
+// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
+if(!setTask || !clearTask){
+  setTask = function setImmediate(fn){
+    var args = [], i = 1;
+    while(arguments.length > i)args.push(arguments[i++]);
+    queue[++counter] = function(){
+      invoke(typeof fn == 'function' ? fn : Function(fn), args);
+    };
+    defer(counter);
+    return counter;
+  };
+  clearTask = function clearImmediate(id){
+    delete queue[id];
+  };
+  // Node.js 0.8-
+  if(__webpack_require__(/*! ./_cof */ 140)(process) == 'process'){
+    defer = function(id){
+      process.nextTick(ctx(run, id, 1));
+    };
+  // Browsers with MessageChannel, includes WebWorkers
+  } else if(MessageChannel){
+    channel = new MessageChannel;
+    port    = channel.port2;
+    channel.port1.onmessage = listener;
+    defer = ctx(port.postMessage, port, 1);
+  // Browsers with postMessage, skip WebWorkers
+  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
+  } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
+    defer = function(id){
+      global.postMessage(id + '', '*');
+    };
+    global.addEventListener('message', listener, false);
+  // IE8-
+  } else if(ONREADYSTATECHANGE in cel('script')){
+    defer = function(id){
+      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
+        html.removeChild(this);
+        run.call(id);
+      };
+    };
+  // Rest old browsers
+  } else {
+    defer = function(id){
+      setTimeout(ctx(run, id, 1), 0);
+    };
+  }
+}
+module.exports = {
+  set:   setTask,
+  clear: clearTask
+};
+
+/***/ }),
+/* 144 */
+/*!***********************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_property-desc.js ***!
+  \***********************************************************************************/
+/***/ (function(module, exports) {
+
+module.exports = function(bitmap, value){
+  return {
+    enumerable  : !(bitmap & 1),
+    configurable: !(bitmap & 2),
+    writable    : !(bitmap & 4),
+    value       : value
+  };
+};
+
+/***/ }),
+/* 145 */
+/*!**********************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_to-primitive.js ***!
+  \**********************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+// 7.1.1 ToPrimitive(input [, PreferredType])
+var isObject = __webpack_require__(/*! ./_is-object */ 73);
+// instead of the ES6 spec version, we didn't implement @@toPrimitive case
+// and the second argument - flag - preferred type is a string
+module.exports = function(it, S){
+  if(!isObject(it))return it;
+  var fn, val;
+  if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
+  if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;
+  if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
+  throw TypeError("Can't convert object to primitive value");
+};
+
+/***/ }),
+/* 146 */
+/*!************************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_ie8-dom-define.js ***!
+  \************************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = !__webpack_require__(/*! ./_descriptors */ 72) && !__webpack_require__(/*! ./_fails */ 96)(function(){
+  return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ 95)('div'), 'a', {get: function(){ return 7; }}).a != 7;
+});
+
+/***/ }),
+/* 147 */
+/*!*******************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_an-object.js ***!
+  \*******************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+var isObject = __webpack_require__(/*! ./_is-object */ 73);
+module.exports = function(it){
+  if(!isObject(it))throw TypeError(it + ' is not an object!');
+  return it;
+};
+
+/***/ }),
+/* 148 */
+/*!*******************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_object-dp.js ***!
+  \*******************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+var anObject       = __webpack_require__(/*! ./_an-object */ 147)
+  , IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ 146)
+  , toPrimitive    = __webpack_require__(/*! ./_to-primitive */ 145)
+  , dP             = Object.defineProperty;
+
+exports.f = __webpack_require__(/*! ./_descriptors */ 72) ? Object.defineProperty : function defineProperty(O, P, Attributes){
+  anObject(O);
+  P = toPrimitive(P, true);
+  anObject(Attributes);
+  if(IE8_DOM_DEFINE)try {
+    return dP(O, P, Attributes);
+  } catch(e){ /* empty */ }
+  if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
+  if('value' in Attributes)O[P] = Attributes.value;
+  return O;
+};
+
+/***/ }),
+/* 149 */
+/*!**************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_hide.js ***!
+  \**************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+var dP         = __webpack_require__(/*! ./_object-dp */ 148)
+  , createDesc = __webpack_require__(/*! ./_property-desc */ 144);
+module.exports = __webpack_require__(/*! ./_descriptors */ 72) ? function(object, key, value){
+  return dP.f(object, key, createDesc(1, value));
+} : function(object, key, value){
+  object[key] = value;
+  return object;
+};
+
+/***/ }),
+/* 150 */
+/*!********************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_a-function.js ***!
+  \********************************************************************************/
+/***/ (function(module, exports) {
+
+module.exports = function(it){
+  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
+  return it;
+};
+
+/***/ }),
+/* 151 */
+/*!****************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/_export.js ***!
+  \****************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+var global    = __webpack_require__(/*! ./_global */ 62)
+  , core      = __webpack_require__(/*! ./_core */ 98)
+  , ctx       = __webpack_require__(/*! ./_ctx */ 97)
+  , hide      = __webpack_require__(/*! ./_hide */ 149)
+  , PROTOTYPE = 'prototype';
+
+var $export = function(type, name, source){
+  var IS_FORCED = type & $export.F
+    , IS_GLOBAL = type & $export.G
+    , IS_STATIC = type & $export.S
+    , IS_PROTO  = type & $export.P
+    , IS_BIND   = type & $export.B
+    , IS_WRAP   = type & $export.W
+    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
+    , expProto  = exports[PROTOTYPE]
+    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]
+    , key, own, out;
+  if(IS_GLOBAL)source = name;
+  for(key in source){
+    // contains in native
+    own = !IS_FORCED && target && target[key] !== undefined;
+    if(own && key in exports)continue;
+    // export native or passed
+    out = own ? target[key] : source[key];
+    // prevent global pollution for namespaces
+    exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
+    // bind timers to global for call from export context
+    : IS_BIND && own ? ctx(out, global)
+    // wrap global constructors for prevent change them in library
+    : IS_WRAP && target[key] == out ? (function(C){
+      var F = function(a, b, c){
+        if(this instanceof C){
+          switch(arguments.length){
+            case 0: return new C;
+            case 1: return new C(a);
+            case 2: return new C(a, b);
+          } return new C(a, b, c);
+        } return C.apply(this, arguments);
+      };
+      F[PROTOTYPE] = C[PROTOTYPE];
+      return F;
+    // make static versions for prototype methods
+    })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
+    // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%
+    if(IS_PROTO){
+      (exports.virtual || (exports.virtual = {}))[key] = out;
+      // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%
+      if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);
+    }
+  }
+};
+// type bitmap
+$export.F = 1;   // forced
+$export.G = 2;   // global
+$export.S = 4;   // static
+$export.P = 8;   // proto
+$export.B = 16;  // bind
+$export.W = 32;  // wrap
+$export.U = 64;  // safe
+$export.R = 128; // real proto method for `library` 
+module.exports = $export;
+
+/***/ }),
+/* 152 */
+/*!**********************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/modules/web.immediate.js ***!
+  \**********************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+var $export = __webpack_require__(/*! ./_export */ 151)
+  , $task   = __webpack_require__(/*! ./_task */ 143);
+$export($export.G + $export.B, {
+  setImmediate:   $task.set,
+  clearImmediate: $task.clear
+});
+
+/***/ }),
+/* 153 */
+/*!*****************************************************************************!*\
+  !*** ./node_modules/jszip/node_modules/core-js/library/fn/set-immediate.js ***!
+  \*****************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+__webpack_require__(/*! ../modules/web.immediate */ 152);
+module.exports = __webpack_require__(/*! ../modules/_core */ 98).setImmediate;
+
+/***/ }),
+/* 154 */
+/*!*****************************************************!*\
+  !*** ./node_modules/readable-stream/passthrough.js ***!
+  \*****************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(/*! ./readable */ 75).PassThrough
+
+
+/***/ }),
+/* 155 */
+/*!***************************************************!*\
+  !*** ./node_modules/readable-stream/transform.js ***!
+  \***************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(/*! ./readable */ 75).Transform
+
+
+/***/ }),
+/* 156 */
+/*!********************************************************!*\
+  !*** ./node_modules/readable-stream/duplex-browser.js ***!
+  \********************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(/*! ./lib/_stream_duplex.js */ 52);
+
+
+/***/ }),
+/* 157 */
+/*!**********************************************************!*\
+  !*** ./node_modules/readable-stream/writable-browser.js ***!
+  \**********************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(/*! ./lib/_stream_writable.js */ 74);
+
+
+/***/ }),
+/* 158 */
+/*!*****************************************************************!*\
+  !*** ./node_modules/readable-stream/lib/_stream_passthrough.js ***!
+  \*****************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+
+
+module.exports = PassThrough;
+
+var Transform = __webpack_require__(/*! ./_stream_transform */ 100);
+
+/*<replacement>*/
+var util = __webpack_require__(/*! core-util-is */ 59);
+util.inherits = __webpack_require__(/*! inherits */ 55);
+/*</replacement>*/
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+  if (!(this instanceof PassThrough)) return new PassThrough(options);
+
+  Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function (chunk, encoding, cb) {
+  cb(null, chunk);
+};
+
+/***/ }),
+/* 159 */
+/*!************************************************!*\
+  !*** ./node_modules/util-deprecate/browser.js ***!
+  \************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(global) {
+/**
+ * Module exports.
+ */
+
+module.exports = deprecate;
+
+/**
+ * Mark that a method should not be used.
+ * Returns a modified function which warns once by default.
+ *
+ * If `localStorage.noDeprecation = true` is set, then it is a no-op.
+ *
+ * If `localStorage.throwDeprecation = true` is set, then deprecated functions
+ * will throw an Error when invoked.
+ *
+ * If `localStorage.traceDeprecation = true` is set, then deprecated functions
+ * will invoke `console.trace()` instead of `console.error()`.
+ *
+ * @param {Function} fn - the function to deprecate
+ * @param {String} msg - the string to print to the console when `fn` is invoked
+ * @returns {Function} a new "deprecated" version of `fn`
+ * @api public
+ */
+
+function deprecate (fn, msg) {
+  if (config('noDeprecation')) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (config('throwDeprecation')) {
+        throw new Error(msg);
+      } else if (config('traceDeprecation')) {
+        console.trace(msg);
+      } else {
+        console.warn(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+}
+
+/**
+ * Checks `localStorage` for boolean values for the given `name`.
+ *
+ * @param {String} name
+ * @returns {Boolean}
+ * @api private
+ */
+
+function config (name) {
+  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
+  try {
+    if (!global.localStorage) return false;
+  } catch (_) {
+    return false;
+  }
+  var val = global.localStorage[name];
+  if (null == val) return false;
+  return String(val).toLowerCase() === 'true';
+}
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ 49)))
+
+/***/ }),
+/* 160 */
+/*!***************************************************!*\
+  !*** ./node_modules/setimmediate/setImmediate.js ***!
+  \***************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
+    "use strict";
+
+    if (global.setImmediate) {
+        return;
+    }
+
+    var nextHandle = 1; // Spec says greater than zero
+    var tasksByHandle = {};
+    var currentlyRunningATask = false;
+    var doc = global.document;
+    var registerImmediate;
+
+    function setImmediate(callback) {
+      // Callback can either be a function or a string
+      if (typeof callback !== "function") {
+        callback = new Function("" + callback);
+      }
+      // Copy function arguments
+      var args = new Array(arguments.length - 1);
+      for (var i = 0; i < args.length; i++) {
+          args[i] = arguments[i + 1];
+      }
+      // Store and register the task
+      var task = { callback: callback, args: args };
+      tasksByHandle[nextHandle] = task;
+      registerImmediate(nextHandle);
+      return nextHandle++;
+    }
+
+    function clearImmediate(handle) {
+        delete tasksByHandle[handle];
+    }
+
+    function run(task) {
+        var callback = task.callback;
+        var args = task.args;
+        switch (args.length) {
+        case 0:
+            callback();
+            break;
+        case 1:
+            callback(args[0]);
+            break;
+        case 2:
+            callback(args[0], args[1]);
+            break;
+        case 3:
+            callback(args[0], args[1], args[2]);
+            break;
+        default:
+            callback.apply(undefined, args);
+            break;
+        }
+    }
+
+    function runIfPresent(handle) {
+        // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
+        // So if we're currently running a task, we'll need to delay this invocation.
+        if (currentlyRunningATask) {
+            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
+            // "too much recursion" error.
+            setTimeout(runIfPresent, 0, handle);
+        } else {
+            var task = tasksByHandle[handle];
+            if (task) {
+                currentlyRunningATask = true;
+                try {
+                    run(task);
+                } finally {
+                    clearImmediate(handle);
+                    currentlyRunningATask = false;
+                }
+            }
+        }
+    }
+
+    function installNextTickImplementation() {
+        registerImmediate = function(handle) {
+            process.nextTick(function () { runIfPresent(handle); });
+        };
+    }
+
+    function canUsePostMessage() {
+        // The test against `importScripts` prevents this implementation from being installed inside a web worker,
+        // where `global.postMessage` means something completely different and can't be used for this purpose.
+        if (global.postMessage && !global.importScripts) {
+            var postMessageIsAsynchronous = true;
+            var oldOnMessage = global.onmessage;
+            global.onmessage = function() {
+                postMessageIsAsynchronous = false;
+            };
+            global.postMessage("", "*");
+            global.onmessage = oldOnMessage;
+            return postMessageIsAsynchronous;
+        }
+    }
+
+    function installPostMessageImplementation() {
+        // Installs an event handler on `global` for the `message` event: see
+        // * https://developer.mozilla.org/en/DOM/window.postMessage
+        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
+
+        var messagePrefix = "setImmediate$" + Math.random() + "$";
+        var onGlobalMessage = function(event) {
+            if (event.source === global &&
+                typeof event.data === "string" &&
+                event.data.indexOf(messagePrefix) === 0) {
+                runIfPresent(+event.data.slice(messagePrefix.length));
+            }
+        };
+
+        if (global.addEventListener) {
+            global.addEventListener("message", onGlobalMessage, false);
+        } else {
+            global.attachEvent("onmessage", onGlobalMessage);
+        }
+
+        registerImmediate = function(handle) {
+            global.postMessage(messagePrefix + handle, "*");
+        };
+    }
+
+    function installMessageChannelImplementation() {
+        var channel = new MessageChannel();
+        channel.port1.onmessage = function(event) {
+            var handle = event.data;
+            runIfPresent(handle);
+        };
+
+        registerImmediate = function(handle) {
+            channel.port2.postMessage(handle);
+        };
+    }
+
+    function installReadyStateChangeImplementation() {
+        var html = doc.documentElement;
+        registerImmediate = function(handle) {
+            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+            var script = doc.createElement("script");
+            script.onreadystatechange = function () {
+                runIfPresent(handle);
+                script.onreadystatechange = null;
+                html.removeChild(script);
+                script = null;
+            };
+            html.appendChild(script);
+        };
+    }
+
+    function installSetTimeoutImplementation() {
+        registerImmediate = function(handle) {
+            setTimeout(runIfPresent, 0, handle);
+        };
+    }
+
+    // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
+    var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
+    attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
+
+    // Don't get fooled by e.g. browserify environments.
+    if ({}.toString.call(global.process) === "[object process]") {
+        // For Node.js before 0.9
+        installNextTickImplementation();
+
+    } else if (canUsePostMessage()) {
+        // For non-IE10 modern browsers
+        installPostMessageImplementation();
+
+    } else if (global.MessageChannel) {
+        // For web workers, where supported
+        installMessageChannelImplementation();
+
+    } else if (doc && "onreadystatechange" in doc.createElement("script")) {
+        // For IE 6–8
+        installReadyStateChangeImplementation();
+
+    } else {
+        // For older browsers
+        installSetTimeoutImplementation();
+    }
+
+    attachTo.setImmediate = setImmediate;
+    attachTo.clearImmediate = clearImmediate;
+}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ 49), __webpack_require__(/*! ./../process/browser.js */ 60)))
+
+/***/ }),
+/* 161 */
+/*!**********************!*\
+  !*** util (ignored) ***!
+  \**********************/
+/***/ (function(module, exports) {
+
+/* (ignored) */
+
+/***/ }),
+/* 162 */
+/*!*************************************************************************!*\
+  !*** ./node_modules/readable-stream/lib/internal/streams/BufferList.js ***!
+  \*************************************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Buffer = __webpack_require__(/*! safe-buffer */ 64).Buffer;
+var util = __webpack_require__(/*! util */ 161);
+
+function copyBuffer(src, target, offset) {
+  src.copy(target, offset);
+}
+
+module.exports = function () {
+  function BufferList() {
+    _classCallCheck(this, BufferList);
+
+    this.head = null;
+    this.tail = null;
+    this.length = 0;
+  }
+
+  BufferList.prototype.push = function push(v) {
+    var entry = { data: v, next: null };
+    if (this.length > 0) this.tail.next = entry;else this.head = entry;
+    this.tail = entry;
+    ++this.length;
+  };
+
+  BufferList.prototype.unshift = function unshift(v) {
+    var entry = { data: v, next: this.head };
+    if (this.length === 0) this.tail = entry;
+    this.head = entry;
+    ++this.length;
+  };
+
+  BufferList.prototype.shift = function shift() {
+    if (this.length === 0) return;
+    var ret = this.head.data;
+    if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
+    --this.length;
+    return ret;
+  };
+
+  BufferList.prototype.clear = function clear() {
+    this.head = this.tail = null;
+    this.length = 0;
+  };
+
+  BufferList.prototype.join = function join(s) {
+    if (this.length === 0) return '';
+    var p = this.head;
+    var ret = '' + p.data;
+    while (p = p.next) {
+      ret += s + p.data;
+    }return ret;
+  };
+
+  BufferList.prototype.concat = function concat(n) {
+    if (this.length === 0) return Buffer.alloc(0);
+    if (this.length === 1) return this.head.data;
+    var ret = Buffer.allocUnsafe(n >>> 0);
+    var p = this.head;
+    var i = 0;
+    while (p) {
+      copyBuffer(p.data, ret, i);
+      i += p.data.length;
+      p = p.next;
+    }
+    return ret;
+  };
+
+  return BufferList;
+}();
+
+if (util && util.inspect && util.inspect.custom) {
+  module.exports.prototype[util.inspect.custom] = function () {
+    var obj = util.inspect({ length: this.length });
+    return this.constructor.name + ' ' + obj;
+  };
+}
+
+/***/ }),
+/* 163 */
+/*!**********************!*\
+  !*** util (ignored) ***!
+  \**********************/
+/***/ (function(module, exports) {
+
+/* (ignored) */
+
+/***/ }),
+/* 164 */
+/*!*************************************************!*\
+  !*** ./node_modules/stream-browserify/index.js ***!
+  \*************************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Stream;
+
+var EE = __webpack_require__(/*! events */ 76).EventEmitter;
+var inherits = __webpack_require__(/*! inherits */ 55);
+
+inherits(Stream, EE);
+Stream.Readable = __webpack_require__(/*! readable-stream/readable.js */ 75);
+Stream.Writable = __webpack_require__(/*! readable-stream/writable.js */ 157);
+Stream.Duplex = __webpack_require__(/*! readable-stream/duplex.js */ 156);
+Stream.Transform = __webpack_require__(/*! readable-stream/transform.js */ 155);
+Stream.PassThrough = __webpack_require__(/*! readable-stream/passthrough.js */ 154);
+
+// Backwards-compat with node 0.4.x
+Stream.Stream = Stream;
+
+
+
+// old-style streams.  Note that the pipe method (the only relevant
+// part of this class) is overridden in the Readable class.
+
+function Stream() {
+  EE.call(this);
+}
+
+Stream.prototype.pipe = function(dest, options) {
+  var source = this;
+
+  function ondata(chunk) {
+    if (dest.writable) {
+      if (false === dest.write(chunk) && source.pause) {
+        source.pause();
+      }
+    }
+  }
+
+  source.on('data', ondata);
+
+  function ondrain() {
+    if (source.readable && source.resume) {
+      source.resume();
+    }
+  }
+
+  dest.on('drain', ondrain);
+
+  // If the 'end' option is not supplied, dest.end() will be called when
+  // source gets the 'end' or 'close' events.  Only dest.end() once.
+  if (!dest._isStdio && (!options || options.end !== false)) {
+    source.on('end', onend);
+    source.on('close', onclose);
+  }
+
+  var didOnEnd = false;
+  function onend() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    dest.end();
+  }
+
+
+  function onclose() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    if (typeof dest.destroy === 'function') dest.destroy();
+  }
+
+  // don't leave dangling pipes when there are errors.
+  function onerror(er) {
+    cleanup();
+    if (EE.listenerCount(this, 'error') === 0) {
+      throw er; // Unhandled stream error in pipe.
+    }
+  }
+
+  source.on('error', onerror);
+  dest.on('error', onerror);
+
+  // remove all the event listeners that were added.
+  function cleanup() {
+    source.removeListener('data', ondata);
+    dest.removeListener('drain', ondrain);
+
+    source.removeListener('end', onend);
+    source.removeListener('close', onclose);
+
+    source.removeListener('error', onerror);
+    dest.removeListener('error', onerror);
+
+    source.removeListener('end', cleanup);
+    source.removeListener('close', cleanup);
+
+    dest.removeListener('close', cleanup);
+  }
+
+  source.on('end', cleanup);
+  source.on('close', cleanup);
+
+  dest.on('close', cleanup);
+
+  dest.emit('pipe', source);
+
+  // Allow for unix-like usage: A.pipe(B).pipe(C)
+  return dest;
+};
+
+
+/***/ }),
+/* 165 */
+/*!***************************************!*\
+  !*** ./node_modules/ieee754/index.js ***!
+  \***************************************/
+/***/ (function(module, exports) {
+
+exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+
+  i += d
+
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+  value = Math.abs(value)
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = (value * c - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+
+  buffer[offset + i - d] |= s * 128
+}
+
+
+/***/ }),
+/* 166 */
+/*!*****************************************!*\
+  !*** ./node_modules/base64-js/index.js ***!
+  \*****************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+exports.byteLength = byteLength
+exports.toByteArray = toByteArray
+exports.fromByteArray = fromByteArray
+
+var lookup = []
+var revLookup = []
+var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
+
+var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+for (var i = 0, len = code.length; i < len; ++i) {
+  lookup[i] = code[i]
+  revLookup[code.charCodeAt(i)] = i
+}
+
+// Support decoding URL-safe base64 strings, as Node.js does.
+// See: https://en.wikipedia.org/wiki/Base64#URL_applications
+revLookup['-'.charCodeAt(0)] = 62
+revLookup['_'.charCodeAt(0)] = 63
+
+function placeHoldersCount (b64) {
+  var len = b64.length
+  if (len % 4 > 0) {
+    throw new Error('Invalid string. Length must be a multiple of 4')
+  }
+
+  // the number of equal signs (place holders)
+  // if there are two placeholders, than the two characters before it
+  // represent one byte
+  // if there is only one, then the three characters before it represent 2 bytes
+  // this is just a cheap hack to not do indexOf twice
+  return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
+}
+
+function byteLength (b64) {
+  // base64 is 4/3 + up to two characters of the original data
+  return (b64.length * 3 / 4) - placeHoldersCount(b64)
+}
+
+function toByteArray (b64) {
+  var i, l, tmp, placeHolders, arr
+  var len = b64.length
+  placeHolders = placeHoldersCount(b64)
+
+  arr = new Arr((len * 3 / 4) - placeHolders)
+
+  // if there are placeholders, only get up to the last complete 4 chars
+  l = placeHolders > 0 ? len - 4 : len
+
+  var L = 0
+
+  for (i = 0; i < l; i += 4) {
+    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
+    arr[L++] = (tmp >> 16) & 0xFF
+    arr[L++] = (tmp >> 8) & 0xFF
+    arr[L++] = tmp & 0xFF
+  }
+
+  if (placeHolders === 2) {
+    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
+    arr[L++] = tmp & 0xFF
+  } else if (placeHolders === 1) {
+    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
+    arr[L++] = (tmp >> 8) & 0xFF
+    arr[L++] = tmp & 0xFF
+  }
+
+  return arr
+}
+
+function tripletToBase64 (num) {
+  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
+}
+
+function encodeChunk (uint8, start, end) {
+  var tmp
+  var output = []
+  for (var i = start; i < end; i += 3) {
+    tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF)
+    output.push(tripletToBase64(tmp))
+  }
+  return output.join('')
+}
+
+function fromByteArray (uint8) {
+  var tmp
+  var len = uint8.length
+  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
+  var output = ''
+  var parts = []
+  var maxChunkLength = 16383 // must be multiple of 3
+
+  // go through the array every three bytes, we'll deal with trailing stuff later
+  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
+    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
+  }
+
+  // pad the end with zeros, but make sure to not forget the extra bytes
+  if (extraBytes === 1) {
+    tmp = uint8[len - 1]
+    output += lookup[tmp >> 2]
+    output += lookup[(tmp << 4) & 0x3F]
+    output += '=='
+  } else if (extraBytes === 2) {
+    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
+    output += lookup[tmp >> 10]
+    output += lookup[(tmp >> 4) & 0x3F]
+    output += lookup[(tmp << 2) & 0x3F]
+    output += '='
+  }
+
+  parts.push(output)
+
+  return parts.join('')
+}
+
+
+/***/ }),
+/* 167 */
+/*!******************************************!*\
+  !*** ./node_modules/jszip/lib/object.js ***!
+  \******************************************/
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var utf8 = __webpack_require__(/*! ./utf8 */ 56);
+var utils = __webpack_require__(/*! ./utils */ 31);
+var GenericWorker = __webpack_require__(/*! ./stream/GenericWorker */ 37);
+var StreamHelper = __webpack_require__(/*! ./stream/StreamHelper */ 94);
+var defaults = __webpack_require__(/*! ./defaults */ 93);
+var CompressedObject = __webpack_require__(/*! ./compressedObject */ 71);
+var ZipObject = __webpack_require__(/*! ./zipObject */ 135);
+var generate = __webpack_require__(/*! ./generate */ 134);
+var nodejsUtils = __webpack_require__(/*! ./nodejsUtils */ 63);
+var NodejsStreamInputAdapter = __webpack_require__(/*! ./nodejs/NodejsStreamInputAdapter */ 122);
+
+
+/**
+ * Add a file in the current folder.
+ * @private
+ * @param {string} name the name of the file
+ * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file
+ * @param {Object} originalOptions the options of the file
+ * @return {Object} the new file.
+ */
+var fileAdd = function(name, data, originalOptions) {
+    // be sure sub folders exist
+    var dataType = utils.getTypeOf(data),
+        parent;
+
+
+    /*
+     * Correct options.
+     */
+
+    var o = utils.extend(originalOptions || {}, defaults);
+    o.date = o.date || new Date();
+    if (o.compression !== null) {
+        o.compression = o.compression.toUpperCase();
+    }
+
+    if (typeof o.unixPermissions === "string") {
+        o.unixPermissions = parseInt(o.unixPermissions, 8);
+    }
+
+    // UNX_IFDIR  0040000 see zipinfo.c
+    if (o.unixPermissions && (o.unixPermissions & 0x4000)) {
+        o.dir = true;
+    }
+    // Bit 4    Directory
+    if (o.dosPermissions && (o.dosPermissions & 0x0010)) {
+        o.dir = true;
+    }
+
+    if (o.dir) {
+        name = forceTrailingSlash(name);
+    }
+    if (o.createFolders && (parent = parentFolder(name))) {
+        folderAdd.call(this, parent, true);
+    }
+
+    var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false;
+    if (!originalOptions || typeof originalOptions.binary === "undefined") {
+        o.binary = !isUnicodeString;
+    }
+
+
+    var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0;
+
+    if (isCompressedEmpty || o.dir || !data || data.length === 0) {
+        o.base64 = false;
+        o.binary = true;
+        data = "";
+        o.compression = "STORE";
+        dataType = "string";
+    }
+
+    /*
+     * Convert content to fit.
+     */
+
+    var zipObjectContent = null;
+    if (data instanceof CompressedObject || data instanceof GenericWorker) {
+        zipObjectContent = data;
+    } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {
+        zipObjectContent = new NodejsStreamInputAdapter(name, data);
+    } else {
+        zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64);
+    }
+
+    var object = new ZipObject(name, zipObjectContent, o);
+    this.files[name] = object;
+    /*
+    TODO: we can't throw an exception because we have async promises
+    (we can have a promise of a Date() for example) but returning a
+    promise is useless because file(name, data) returns the JSZip
+    object for chaining. Should we break that to allow the user
+    to catch the error ?
+
+    return external.Promise.resolve(zipObjectContent)
+    .then(function () {
+        return object;
+    });
+    */
+};
+
+/**
+ * Find the parent folder of the path.
+ * @private
+ * @param {string} path the path to use
+ * @return {string} the parent folder, or ""
+ */
+var parentFolder = function (path) {
+    if (path.slice(-1) === '/') {
+        path = path.substring(0, path.length - 1);
+    }
+    var lastSlash = path.lastIndexOf('/');
+    return (lastSlash > 0) ? path.substring(0, lastSlash) : "";
+};
+
+/**
+ * Returns the path with a slash at the end.
+ * @private
+ * @param {String} path the path to check.
+ * @return {String} the path with a trailing slash.
+ */
+var forceTrailingSlash = function(path) {
+    // Check the name ends with a /
+    if (path.slice(-1) !== "/") {
+        path += "/"; // IE doesn't like substr(-1)
+    }
+    return path;
+};
+
+/**
+ * Add a (sub) folder in the current folder.
+ * @private
+ * @param {string} name the folder's name
+ * @param {boolean=} [createFolders] If true, automatically create sub
+ *  folders. Defaults to false.
+ * @return {Object} the new folder.
+ */
+var folderAdd = function(name, createFolders) {
+    createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders;
+
+    name = forceTrailingSlash(name);
+
+    // Does this folder already exist?
+    if (!this.files[name]) {
+        fileAdd.call(this, name, null, {
+            dir: true,
+            createFolders: createFolders
+        });
+    }
+    return this.files[name];
+};
+
+/**
+* Cross-window, cross-Node-context regular expression detection
+* @param  {Object}  object Anything
+* @return {Boolean}        true if the object is a regular expression,
+* false otherwise
+*/
+function isRegExp(object) {
+    return Object.prototype.toString.call(object) === "[object RegExp]";
+}
+
+// return the actual prototype of JSZip
+var out = {
+    /**
+     * @see loadAsync
+     */
+    load: function() {
+        throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
+    },
+
+
+    /**
+     * Call a callback function for each entry at this folder level.
+     * @param {Function} cb the callback function:
+     * function (relativePath, file) {...}
+     * It takes 2 arguments : the relative path and the file.
+     */
+    forEach: function(cb) {
+        var filename, relativePath, file;
+        for (filename in this.files) {
+            if (!this.files.hasOwnProperty(filename)) {
+                continue;
+            }
+            file = this.files[filename];
+            relativePath = filename.slice(this.root.length, filename.length);
+            if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root
+                cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn...
+            }
+        }
+    },
+
+    /**
+     * Filter nested files/folders with the specified function.
+     * @param {Function} search the predicate to use :
+     * function (relativePath, file) {...}
+     * It takes 2 arguments : the relative path and the file.
+     * @return {Array} An array of matching elements.
+     */
+    filter: function(search) {
+        var result = [];
+        this.forEach(function (relativePath, entry) {
+            if (search(relativePath, entry)) { // the file matches the function
+                result.push(entry);
+            }
+
+        });
+        return result;
+    },
+
+    /**
+     * Add a file to the zip file, or search a file.
+     * @param   {string|RegExp} name The name of the file to add (if data is defined),
+     * the name of the file to find (if no data) or a regex to match files.
+     * @param   {String|ArrayBuffer|Uint8Array|Buffer} data  The file data, either raw or base64 encoded
+     * @param   {Object} o     File options
+     * @return  {JSZip|Object|Array} this JSZip object (when adding a file),
+     * a file (when searching by string) or an array of files (when searching by regex).
+     */
+    file: function(name, data, o) {
+        if (arguments.length === 1) {
+            if (isRegExp(name)) {
+                var regexp = name;
+                return this.filter(function(relativePath, file) {
+                    return !file.dir && regexp.test(relativePath);
+                });
+            }
+            else { // text
+                var obj = this.files[this.root + name];
+                if (obj && !obj.dir) {
+                    return obj;
+                } else {
+                    return null;
+                }
+            }
+        }
+        else { // more than one argument : we have data !
+            name = this.root + name;
+            fileAdd.call(this, name, data, o);
+        }
+        return this;
+    },
+
+    /**
+     * Add a directory to the zip file, or search.
+     * @param   {String|RegExp} arg The name of the directory to add, or a regex to search folders.
+     * @return  {JSZip} an object with the new directory as the root, or an array containing matching folders.
+     */
+    folder: function(arg) {
+        if (!arg) {
+            return this;
+        }
+
+        if (isRegExp(arg)) {
+            return this.filter(function(relativePath, file) {
+                return file.dir && arg.test(relativePath);
+            });
+        }
+
+        // else, name is a new folder
+        var name = this.root + arg;
+        var newFolder = folderAdd.call(this, name);
+
+        // Allow chaining by returning a new object with this folder as the root
+        var ret = this.clone();
+        ret.root = newFolder.name;
+        return ret;
+    },
+
+    /**
+     * Delete a file, or a directory and all sub-files, from the zip
+     * @param {string} name the name of the file to delete
+     * @return {JSZip} this JSZip object
+     */
+    remove: function(name) {
+        name = this.root + name;
+        var file = this.files[name];
+        if (!file) {
+            // Look for any folders
+            if (name.slice(-1) !== "/") {
+                name += "/";
+            }
+            file = this.files[name];
+        }
+
+        if (file && !file.dir) {
+            // file
+            delete this.files[name];
+        } else {
+            // maybe a folder, delete recursively
+            var kids = this.filter(function(relativePath, file) {
+                return file.name.slice(0, name.length) === name;
+            });
+            for (var i = 0; i < kids.length; i++) {
+                delete this.files[kids[i].name];
+            }
+        }
+
+        return this;
+    },
+
+    /**
+     * Generate the complete zip file
+     * @param {Object} options the options to generate the zip file :
+     * - compression, "STORE" by default.
+     * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
+     * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file
+     */
+    generate: function(options) {
+        throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
+    },
+
+    /**
+     * Generate the complete zip file as an internal stream.
+     * @param {Object} options the options to generate the zip file :
+     * - compression, "STORE" by default.
+     * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
+     * @return {StreamHelper} the streamed zip file.
+     */
+    generateInternalStream: function(options) {
+      var worker, opts = {};
+      try {
+          opts = utils.extend(options || {}, {
+              streamFiles: false,
+              compression: "STORE",
+              compressionOptions : null,
+              type: "",
+              platform: "DOS",
+              comment: null,
+              mimeType: 'application/zip',
+              encodeFileName: utf8.utf8encode
+          });
+
+          opts.type = opts.type.toLowerCase();
+          opts.compression = opts.compression.toUpperCase();
+
+          // "binarystring" is prefered but the internals use "string".
+          if(opts.type === "binarystring") {
+            opts.type = "string";
+          }
+
+          if (!opts.type) {
+            throw new Error("No output type specified.");
+          }
+
+          utils.checkSupport(opts.type);
+
+          // accept nodejs `process.platform`
+          if(
+              opts.platform === 'darwin' ||
+              opts.platform === 'freebsd' ||
+              opts.platform === 'linux' ||
+              opts.platform === 'sunos'
+          ) {
+              opts.platform = "UNIX";
+          }
+          if (opts.platform === 'win32') {
+              opts.platform = "DOS";
+          }
+
+          var comment = opts.comment || this.comment || "";
+          worker = generate.generateWorker(this, opts, comment);
+      } catch (e) {
+        worker = new GenericWorker("error");
+        worker.error(e);
+      }
+      return new StreamHelper(worker, opts.type || "string", opts.mimeType);
+    },
+    /**
+     * Generate the complete zip file asynchronously.
+     * @see generateInternalStream
+     */
+    generateAsync: function(options, onUpdate) {
+        return this.generateInternalStream(options).accumulate(onUpdate);
+    },
+    /**
+     * Generate the complete zip file asynchronously.
+     * @see generateInternalStream
+     */
+    generateNodeStream: function(options, onUpdate) {
+        options = options || {};
+        if (!options.type) {
+            options.type = "nodebuffer";
+        }
+        return this.generateInternalStream(options).toNodejsStream(onUpdate);
+    }
+};
+module.exports = out;
+
 
 /***/ }),
 /* 168 */
@@ -95480,7 +95623,7 @@ oop.inherits(Mode, TextMode);
     };
 
     this.createWorker = function(session) {
-        var worker = new WorkerClient(["ace"], __webpack_require__(/*! brace/worker/javascript */ 108), "JavaScriptWorker");
+        var worker = new WorkerClient(["ace"], __webpack_require__(/*! brace/worker/javascript */ 109), "JavaScriptWorker");
         worker.attachToDocument(session.getDocument());
 
         worker.on("annotate", function(results) {
@@ -96278,7 +96421,7 @@ oop.inherits(Mode, TextMode);
     };
 
     this.createWorker = function(session) {
-        var worker = new WorkerClient(["ace"], __webpack_require__(/*! ../worker/javascript */ 108), "JavaScriptWorker");
+        var worker = new WorkerClient(["ace"], __webpack_require__(/*! ../worker/javascript */ 109), "JavaScriptWorker");
         worker.attachToDocument(session.getDocument());
 
         worker.on("annotate", function(results) {
diff --git a/src/ActiveScriptsUI.js b/src/ActiveScriptsUI.js
index 8d8f75c57..e3104f5e7 100644
--- a/src/ActiveScriptsUI.js
+++ b/src/ActiveScriptsUI.js
@@ -137,6 +137,7 @@ function addActiveScriptsItem(workerscript) {
 
     var btn = document.createElement("button");
     btn.setAttribute("class", "active-scripts-script-header");
+    btn.setAttribute("id", itemName + "-header");
     btn.innerHTML = workerscript.name;
 
     var itemContentDiv = document.createElement("div");
diff --git a/src/Constants.js b/src/Constants.js
index 83321181a..8c6aebfc0 100644
--- a/src/Constants.js
+++ b/src/Constants.js
@@ -1138,6 +1138,8 @@ let CONSTANTS = {
                                "World Stock Exchange account and TIX API Access<br>",
 
     LatestUpdate:
+    "v0.36.1<br>" +
+    "* The ctrl+b hotkey in the text editor is now also triggered by command+b or winkey+b<br>" +
     "v0.36.0<br>" +
     "* Added BN-6: Bladeburners<br>" +
     "* Rebalanced many combat Augmentations so that they are slightly less powerful<br>" +
diff --git a/src/Player.js b/src/Player.js
index dac1c0e38..a086a5bb0 100644
--- a/src/Player.js
+++ b/src/Player.js
@@ -1413,8 +1413,8 @@ PlayerObject.prototype.takeClass = function(numCycles) {
                     "$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyLossRate * cyclesPerSec, 2) + " / sec) <br><br>" +
                     "You have gained: <br>" +
                     formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * cyclesPerSec, 4) + " / sec) hacking exp <br>" +
-                    formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * cyclesPerSec, 4) + " / sec) defense exp <br>" +
                     formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * cyclesPerSec, 4) + " / sec) strength exp <br>" +
+                    formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * cyclesPerSec, 4) + " / sec) defense exp <br>" +
                     formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * cyclesPerSec, 4) + " / sec) dexterity exp <br>" +
                     formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * cyclesPerSec, 4) + " / sec) agility exp <br>" +
                     formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * cyclesPerSec, 4) + " / sec) charisma exp <br>" +
diff --git a/src/Script.js b/src/Script.js
index bf17fb291..1d8f715ad 100644
--- a/src/Script.js
+++ b/src/Script.js
@@ -228,7 +228,7 @@ function updateScriptEditorContent() {
 $(document).keydown(function(e) {
 	if (Engine.currentPage == Engine.Page.ScriptEditor) {
 		//Ctrl + b
-        if (e.keyCode == 66 && e.ctrlKey) {
+        if (e.keyCode == 66 && (e.ctrlKey || e.metaKey)) {
             e.preventDefault();
 			saveAndCloseScriptEditor();
         }
diff --git a/src/Server.js b/src/Server.js
index 683ea4f01..d324cd851 100644
--- a/src/Server.js
+++ b/src/Server.js
@@ -9,11 +9,12 @@ import {createRandomIp, isValidIPAddress, ipExists} from "../utils/IPAddress.js"
 import {Reviver, Generic_toJSON,
         Generic_fromJSON}                           from "../utils/JSONReviver.js";
 
-function Server(ip=createRandomIp(), hostname="", organizationName="",
-                isConnectedTo=false, adminRights=false, purchasedByPlayer=false, maxRam=0) {
-	/* Properties */
-	//Connection information
-	this.ip					= 	ip;
+function Server(params={ip:createRandomIp(), hostname:""}) {
+    /* Properties */
+    //Connection information
+    this.ip = params.ip ? params.ip : createRandomIp();
+
+    var hostname = params.hostname;
     var i = 0;
     var suffix = "";
     while (GetServerByHostname(hostname+suffix) != null) {
@@ -21,76 +22,74 @@ function Server(ip=createRandomIp(), hostname="", organizationName="",
         suffix = "-" + i;
         ++i;
     }
-	this.hostname			= 	hostname + suffix;
-	this.organizationName 	= 	organizationName;
-	this.isConnectedTo		= 	isConnectedTo;	//Whether the player is connected to this server
+    this.hostname           =     hostname + suffix;
+    this.organizationName   =     params.organizationName   ? params.organizationName   : "";
+    this.isConnectedTo      =     params.isConnectedTo      ? params.isConnectedTo      : false;
 
-	//Access information
-	this.hasAdminRights		=	adminRights;	//Whether player has admin rights
-	this.purchasedByPlayer	=	purchasedByPlayer;
-    this.manuallyHacked     =   false;  //Flag that tracks whether or not the server has been hacked at least once
+    //Access information
+    this.hasAdminRights     =    params.adminRights         ? params.adminRights        : false;
+    this.purchasedByPlayer  =    params.purchasedByPlayer   ? params.purchasedByPlayer  : false;
+    this.manuallyHacked     =    false;  //Flag that tracks whether or not the server has been hacked at least once
 
-	//RAM, CPU speed and Scripts
-	this.maxRam			=	maxRam;  //GB
-	this.ramUsed		=	0;
-	this.cpuCores		= 	1;       //Max of 8, affects hacking times and Hacking Mission starting Cores
+    //RAM, CPU speed and Scripts
+    this.maxRam     = params.maxRam ? params.maxRam : 0;  //GB
+    this.ramUsed    = 0;
+    this.cpuCores   = 1; //Max of 8, affects hacking times and Hacking Mission starting Cores
 
-	this.scripts 		= 	[];
-	this.runningScripts = 	[]; 	//Stores RunningScript objects
-	this.programs 		= 	[];
-    this.messages       =   [];
-    this.textFiles      =   [];
-    this.dir            =   0; //new Directory(this, null, "");
+    this.scripts        = [];
+    this.runningScripts = [];   //Stores RunningScript objects
+    this.programs       = [];
+    this.messages       = [];
+    this.textFiles      = [];
+    this.dir            = 0;    //new Directory(this, null, ""); TODO
 
-	/* Hacking information (only valid for "foreign" aka non-purchased servers) */
-	//Skill required to attempt a hack. Whether a hack is successful will be determined
-	//by a separate formula
-	this.requiredHackingSkill	= 1;
+    /* Hacking information (only valid for "foreign" aka non-purchased servers) */
+    this.requiredHackingSkill   = params.requiredHackingSkill   ? params.requiredHackingSkill : 1;
+    this.moneyAvailable         = params.moneyAvailable         ? params.moneyAvailable * BitNodeMultipliers.ServerStartingMoney : 1e6;
+    this.moneyMax               = 25 * this.moneyAvailable * BitNodeMultipliers.ServerMaxMoney;
 
-	//Total money available on this server
-	this.moneyAvailable 		= 0;
-    this.moneyMax               = 0;
+    //Hack Difficulty is synonymous with server security. Base Difficulty = Starting difficulty
+    this.hackDifficulty         = params.hackDifficulty ? params.hackDifficulty * BitNodeMultipliers.ServerStartingSecurity : 1;
+    this.baseDifficulty         = this.hackDifficulty;
+    this.minDifficulty          = Math.max(1, Math.round(this.hackDifficulty / 3));
+    this.serverGrowth           = params.serverGrowth   ? params.serverGrowth : 1; //Integer from 0 to 100. Affects money increase from grow()
 
-	//Parameters used in formulas that dictate how moneyAvailable and requiredHackingSkill change.
-	this.hackDifficulty			= 1;	//Affects hack success rate and how the requiredHackingSkill increases over time (1-100)
-    this.baseDifficulty         = 1;    //Starting difficulty
-    this.minDifficulty          = 1;
-	this.serverGrowth			= 0;	//Affects how the moneyAvailable increases (0-100)
-
-	//The IP's of all servers reachable from this one (what shows up if you run scan/netstat)
+    //The IP's of all servers reachable from this one (what shows up if you run scan/netstat)
     //  NOTE: Only contains IP and not the Server objects themselves
-	this.serversOnNetwork		= [];
+    this.serversOnNetwork        = [];
 
-	//Port information, required for porthacking servers to get admin rights
-	this.numOpenPortsRequired 	= 5;
-	this.sshPortOpen 			= false;	//Port 22
-	this.ftpPortOpen 			= false;	//Port 21
-	this.smtpPortOpen 			= false;	//Port 25
-	this.httpPortOpen			= false;	//Port 80
-	this.sqlPortOpen 			= false; 	//Port 1433
-	this.openPortCount 			= 0;
+    //Port information, required for porthacking servers to get admin rights
+    this.numOpenPortsRequired = params.numOpenPortsRequired ? params.numOpenPortsRequired : 5;
+    this.sshPortOpen          = false;    //Port 22
+    this.ftpPortOpen          = false;    //Port 21
+    this.smtpPortOpen         = false;    //Port 25
+    this.httpPortOpen         = false;    //Port 80
+    this.sqlPortOpen          = false;    //Port 1433
+    this.openPortCount        = 0;
 };
 
+/*
 //Set the hacking properties of a server
 Server.prototype.setHackingParameters = function(requiredHackingSkill, moneyAvailable, hackDifficulty, serverGrowth) {
-	this.requiredHackingSkill = requiredHackingSkill;
+    this.requiredHackingSkill = requiredHackingSkill;
     if (isNaN(moneyAvailable)) {
         this.moneyAvailable = 1e6;
     } else {
         this.moneyAvailable = moneyAvailable * BitNodeMultipliers.ServerStartingMoney;
     }
-    this.moneyMax = 25 * this.moneyAvailable * BitNodeMultipliers.ServerMaxMoney;
-	this.hackDifficulty = hackDifficulty * BitNodeMultipliers.ServerStartingSecurity;
+    this.moneyMax =
+    this.hackDifficulty = hackDifficulty * BitNodeMultipliers.ServerStartingSecurity;
     this.baseDifficulty = hackDifficulty * BitNodeMultipliers.ServerStartingSecurity;
     this.minDifficulty = Math.max(1, Math.round(this.hackDifficulty / 3));
-	this.serverGrowth = serverGrowth;
+    this.serverGrowth = serverGrowth;
 }
 
 //Set the port properties of a server
 //Right now its only the number of open ports needed to PortHack the server.
 Server.prototype.setPortProperties = function(numOpenPortsReq) {
-	this.numOpenPortsRequired = numOpenPortsReq;
+    this.numOpenPortsRequired = numOpenPortsReq;
 }
+*/
 
 Server.prototype.setMaxRam = function(ram) {
     this.maxRam = ram;
@@ -109,12 +108,12 @@ Server.prototype.getServerOnNetwork = function(i) {
 //Given the name of the script, returns the corresponding
 //script object on the server (if it exists)
 Server.prototype.getScript = function(scriptName) {
-	for (var i = 0; i < this.scripts.length; i++) {
-		if (this.scripts[i].filename == scriptName) {
-			return this.scripts[i];
-		}
-	}
-	return null;
+    for (var i = 0; i < this.scripts.length; i++) {
+        if (this.scripts[i].filename == scriptName) {
+            return this.scripts[i];
+        }
+    }
+    return null;
 }
 
 //Strengthens a server's security level (difficulty) by the specified amount
@@ -133,413 +132,554 @@ Server.prototype.weaken = function(amt) {
 
 //Functions for loading and saving a Server
 Server.prototype.toJSON = function() {
-	return Generic_toJSON("Server", this);
+    return Generic_toJSON("Server", this);
 }
 
 Server.fromJSON = function(value) {
-	return Generic_fromJSON(Server, value.data);
+    return Generic_fromJSON(Server, value.data);
 }
 
 Reviver.constructors.Server = Server;
 
 function initForeignServers() {
     //MegaCorporations
-    var ECorpServer = new Server(createRandomIp(), "ecorp", "ECorp", false, false, false, 0);
-    ECorpServer.setHackingParameters(getRandomInt(1150, 1300), getRandomInt(30000000000, 70000000000), 99, 99);
-    ECorpServer.setPortProperties(5);
+    var ECorpServer = new Server({
+        ip:createRandomIp(), hostname:"ecorp", organizationName:"ECorp",
+        requiredHackingSkill:getRandomInt(1150, 1300), moneyAvailable:getRandomInt(30e9, 70e9),
+        hackDifficulty:99,serverGrowth:99, numOpenPortsRequired: 5,
+    });
     AddToAllServers(ECorpServer);
 
-    var MegaCorpServer = new Server(createRandomIp(), "megacorp", "MegaCorp", false, false, false, 0);
-    MegaCorpServer.setHackingParameters(getRandomInt(1150, 1300), getRandomInt(40000000000, 60000000000), 99, 99);
-    MegaCorpServer.setPortProperties(5);
+    var MegaCorpServer = new Server({
+        ip:createRandomIp(), hostname:"megacorp", organizationName:"MegaCorp",
+        requiredHackingSkill:getRandomInt(1150, 1300), moneyAvailable:getRandomInt(40e9, 60e9),
+        hackDifficulty:99, serverGrowth:99, numOpenPortsRequired:5
+    });
     AddToAllServers(MegaCorpServer);
 
-    var BachmanAndAssociatesServer = new Server(createRandomIp(), "b-and-a", "Bachman & Associates", false, false, false, 0);
-    BachmanAndAssociatesServer.setHackingParameters(getRandomInt(1000, 1050), getRandomInt(20000000000, 25000000000), getRandomInt(75, 85), getRandomInt(65, 75));
-    BachmanAndAssociatesServer.setPortProperties(5);
+    var BachmanAndAssociatesServer = new Server({
+        ip:createRandomIp(), hostname:"b-and-a", organizationName:"Bachman & Associates",
+        requiredHackingSkill:getRandomInt(1000, 1050), moneyAvailable:getRandomInt(20e9, 25e9),
+        hackDifficulty:getRandomInt(75, 85), serverGrowth:getRandomInt(65, 75), numOpenPortsRequired:5
+    });
     AddToAllServers(BachmanAndAssociatesServer);
 
-    var BladeIndustriesServer = new Server(createRandomIp(), "blade", "Blade Industries", false, false, false, 2);
-    BladeIndustriesServer.setHackingParameters(getRandomInt(1000, 1100), getRandomInt(12000000000, 20000000000), getRandomInt(90, 95), getRandomInt(60, 75));
-    BladeIndustriesServer.setPortProperties(5);
+    var BladeIndustriesServer = new Server({
+        ip:createRandomIp(), hostname:"blade", organizationName:"Blade Industries", maxRam:128,
+        requiredHackingSkill:getRandomInt(1000, 1100), moneyAvailable:getRandomInt(12e9, 20e9),
+        hackDifficulty:getRandomInt(90, 95), serverGrowth:getRandomInt(60, 75), numOpenPortsRequired:5
+    });
     BladeIndustriesServer.messages.push("beyond-man.lit");
     AddToAllServers(BladeIndustriesServer);
 
-    var NWOServer = new Server(createRandomIp(), "nwo", "New World Order", false, false, false, 2);
-    NWOServer.setHackingParameters(getRandomInt(1000, 1200), getRandomInt(25000000000, 35000000000), 99, getRandomInt(75, 85));
-    NWOServer.setPortProperties(5);
+    var NWOServer = new Server({
+        ip:createRandomIp(), hostname:"nwo", organizationName:"New World Order",
+        requiredHackingSkill:getRandomInt(1000, 1200), moneyAvailable:getRandomInt(25e9, 35e9),
+        hackDifficulty:99, serverGrowth:getRandomInt(75, 85), numOpenPortsRequired:5
+    });
     NWOServer.messages.push("the-hidden-world.lit");
     AddToAllServers(NWOServer);
 
-    var ClarkeIncorporatedServer = new Server(createRandomIp(), "clarkeinc", "Clarke Incorporated", false, false, false, 2);
-    ClarkeIncorporatedServer.setHackingParameters(getRandomInt(1000, 1200), getRandomInt(15000000000, 25000000000), getRandomInt(50, 60), getRandomInt(50, 70));
-    ClarkeIncorporatedServer.setPortProperties(5);
+    var ClarkeIncorporatedServer = new Server({
+        ip:createRandomIp(), hostname:"clarkeinc", organizationName:"Clarke Incorporated",
+        requiredHackingSkill:getRandomInt(1000, 1200), moneyAvailable:getRandomInt(15e9, 25e9),
+        hackDifficulty:getRandomInt(50, 60), serverGrowth:getRandomInt(50, 70), numOpenPortsRequired:5
+    });
     ClarkeIncorporatedServer.messages.push("beyond-man.lit");
     ClarkeIncorporatedServer.messages.push("cost-of-immortality.lit");
     AddToAllServers(ClarkeIncorporatedServer);
 
-    var OmniTekIncorporatedServer = new Server(createRandomIp(), "omnitek", "OmniTek Incorporated", false, false, false, 2);
-    OmniTekIncorporatedServer.setHackingParameters(getRandomInt(900, 1100), getRandomInt(15000000000, 20000000000), getRandomInt(90, 99), getRandomInt(95, 99));
-    OmniTekIncorporatedServer.setPortProperties(5);
+    var OmniTekIncorporatedServer = new Server({
+        ip:createRandomIp(), hostname:"omnitek", organizationName:"OmniTek Incorporated", maxRam:256,
+        requiredHackingSkill:getRandomInt(900, 1100), moneyAvailable:getRandomInt(15e9, 20e9),
+        hackDifficulty:getRandomInt(90, 99), serverGrowth:getRandomInt(95, 99), numOpenPortsRequired:5
+    });
     OmniTekIncorporatedServer.messages.push("coded-intelligence.lit");
+    OmniTekIncorporatedServer.messages.push("history-of-synthoids.lit");
     AddToAllServers(OmniTekIncorporatedServer);
 
-    var FourSigmaServer = new Server(createRandomIp(), "4sigma", "FourSigma", false, false, false, 0);
-    FourSigmaServer.setHackingParameters(getRandomInt(950, 1200), getRandomInt(15000000000, 25000000000), getRandomInt(60, 70), getRandomInt(75, 99));
-    FourSigmaServer.setPortProperties(5);
+    var FourSigmaServer = new Server({
+        ip:createRandomIp(), hostname:"4sigma", organizationName:"FourSigma",
+        requiredHackingSkill:getRandomInt(950, 1200), moneyAvailable:getRandomInt(15e9, 25e9),
+        hackDifficulty:getRandomInt(60, 70), serverGrowth:getRandomInt(75, 99), numOpenPortsRequired:5
+    });
     AddToAllServers(FourSigmaServer);
 
-    var KuaiGongInternationalServer = new Server(createRandomIp(), "kuai-gong", "KuaiGong International", false, false, false, 0);
-    KuaiGongInternationalServer.setHackingParameters(getRandomInt(1000, 1250), getRandomInt(20000000000, 30000000000), getRandomInt(95, 99), getRandomInt(90, 99));
-    KuaiGongInternationalServer.setPortProperties(5);
+    var KuaiGongInternationalServer = new Server({
+        ip:createRandomIp(), hostname:"kuai-gong", organizationName:"KuaiGong International",
+        requiredHackingSkill:getRandomInt(1000, 1250), moneyAvailable:getRandomInt(20e9, 30e9),
+        hackDifficulty:getRandomInt(95, 99), serverGrowth:getRandomInt(90, 99), numOpenPortsRequired:5,
+    });
     AddToAllServers(KuaiGongInternationalServer);
 
     //Technology and communications companies (large targets)
-    var FulcrumTechnologiesServer = new Server(createRandomIp(), "fulcrumtech", "Fulcrum Technologies", false, false, false, 64);
-    FulcrumTechnologiesServer.setHackingParameters(getRandomInt(1000, 1200), getRandomInt(1400000000, 1800000000), getRandomInt(85, 95), getRandomInt(80, 99));
-    FulcrumTechnologiesServer.setPortProperties(5);
+    var FulcrumTechnologiesServer = new Server({
+        ip:createRandomIp(), hostname:"fulcrumtech", organizationName:"Fulcrum Technologies", maxRam:512,
+        requiredHackingSkill:getRandomInt(1000, 1200), moneyAvailable:getRandomInt(1.4e9, 1.8e9),
+        hackDifficulty:getRandomInt(85, 95), serverGrowth:getRandomInt(80, 99), numOpenPortsRequired:5
+    });
     FulcrumTechnologiesServer.messages.push("simulated-reality.lit");
     AddToAllServers(FulcrumTechnologiesServer);
 
-    var FulcrumSecretTechnologiesServer = new Server(createRandomIp(), "fulcrumassets", "Fulcrum Technologies Assets", false, false, false, 0);
-    FulcrumSecretTechnologiesServer.setHackingParameters(getRandomInt(1200, 1500), 1000000, 99, 1);
-    FulcrumSecretTechnologiesServer.setPortProperties(5);
+    var FulcrumSecretTechnologiesServer = new Server({
+        ip:createRandomIp(), hostname:"fulcrumassets", organizationName:"Fulcrum Technologies Assets",
+        requiredHackingSkill:getRandomInt(1200, 1500), moneyAvailable:1e6,
+        hackDifficulty:99, serverGrowth:1, numOpenPortsRequired:5
+    });
     AddToAllServers(FulcrumSecretTechnologiesServer);
-	SpecialServerIps.addIp(SpecialServerNames.FulcrumSecretTechnologies, FulcrumSecretTechnologiesServer.ip);
+    SpecialServerIps.addIp(SpecialServerNames.FulcrumSecretTechnologies, FulcrumSecretTechnologiesServer.ip);
 
-    var StormTechnologiesServer = new Server(createRandomIp(), "stormtech", "Storm Technologies", false, false, false, 0);
-    StormTechnologiesServer.setHackingParameters(getRandomInt(900, 1050), getRandomInt(1000000000, 1200000000), getRandomInt(80, 90), getRandomInt(70, 90));
-    StormTechnologiesServer.setPortProperties(5);
+    var StormTechnologiesServer = new Server({
+        ip:createRandomIp(), hostname:"stormtech", organizationName:"Storm Technologies",
+        requiredHackingSkill:getRandomInt(900, 1050), moneyAvailable:getRandomInt(1e9, 1.2e9),
+        hackDifficulty:getRandomInt(80, 90), serverGrowth:getRandomInt(70, 90), numOpenPortsRequired:5
+    });
     AddToAllServers(StormTechnologiesServer);
 
-    var DefCommServer = new Server(createRandomIp(), "defcomm", "DefComm", false, false, false, 0);
-    DefCommServer.setHackingParameters(getRandomInt(900, 1000), getRandomInt(800000000, 950000000), getRandomInt(85, 95), getRandomInt(50, 70));
-    DefCommServer.setPortProperties(5);
+    var DefCommServer = new Server({
+        ip:createRandomIp(), hostname:"defcomm", organizationName:"DefComm",
+        requiredHackingSkill:getRandomInt(900, 1000), moneyAvailable:getRandomInt(800e6, 950e6),
+        hackDifficulty:getRandomInt(85, 95), serverGrowth:getRandomInt(50, 70), numOpenPortsRequired:5
+    });
     AddToAllServers(DefCommServer);
 
-    var InfoCommServer = new Server(createRandomIp(), "infocomm", "InfoComm", false, false, false, 0);
-    InfoCommServer.setHackingParameters(getRandomInt(875, 950), getRandomInt(600000000, 900000000), getRandomInt(70, 90), getRandomInt(35, 75));
-    InfoCommServer.setPortProperties(5);
+    var InfoCommServer = new Server({
+        ip:createRandomIp(), hostname:"infocomm", organizationName:"InfoComm",
+        requiredHackingSkill:getRandomInt(875, 950), moneyAvailable:getRandomInt(600e6, 900e6),
+        hackDifficulty:getRandomInt(70, 90), serverGrowth:getRandomInt(35, 75), numOpenPortsRequired:5
+    });
     AddToAllServers(InfoCommServer);
 
-    var HeliosLabsServer = new Server(createRandomIp(), "helios", "Helios Labs", false, false, false, 2);
-    HeliosLabsServer.setHackingParameters(getRandomInt(800, 900), getRandomInt(550000000, 750000000), getRandomInt(85, 95), getRandomInt(70, 80));
-    HeliosLabsServer.setPortProperties(5);
+    var HeliosLabsServer = new Server({
+        ip:createRandomIp(), hostname:"helios", organizationName:"Helios Labs", maxRam:128,
+        requiredHackingSkill:getRandomInt(800, 900), moneyAvailable:getRandomInt(550e6, 750e6),
+        hackDifficulty:getRandomInt(85, 95), serverGrowth:getRandomInt(70, 80), numOpenPortsRequired:5
+    });
     HeliosLabsServer.messages.push("beyond-man.lit");
     AddToAllServers(HeliosLabsServer);
 
-    var VitaLifeServer = new Server(createRandomIp(), "vitalife", "VitaLife", false, false, false, 32);
-    VitaLifeServer.setHackingParameters(getRandomInt(775, 900), getRandomInt(700000000, 800000000), getRandomInt(80, 90), getRandomInt(60, 80));
-    VitaLifeServer.setPortProperties(5);
+    var VitaLifeServer = new Server({
+        ip:createRandomIp(), hostname:"vitalife", organizationName:"VitaLife", maxRam:64,
+        requiredHackingSkill:getRandomInt(775, 900), moneyAvailable:getRandomInt(700e6, 800e6),
+        hackDifficulty:getRandomInt(80, 90), serverGrowth:getRandomInt(60, 80), numOpenPortsRequired:5
+    });
     VitaLifeServer.messages.push("A-Green-Tomorrow.lit");
     AddToAllServers(VitaLifeServer);
 
-    var IcarusMicrosystemsServer = new Server(createRandomIp(), "icarus", "Icarus Microsystems", false, false, false, 0);
-    IcarusMicrosystemsServer.setHackingParameters(getRandomInt(850, 925), getRandomInt(900000000, 1000000000), getRandomInt(85, 95), getRandomInt(85, 95));
-    IcarusMicrosystemsServer.setPortProperties(5);
+    var IcarusMicrosystemsServer = new Server({
+        ip:createRandomIp(), hostname:"icarus", organizationName:"Icarus Microsystems",
+        requiredHackingSkill:getRandomInt(850, 925), moneyAvailable:getRandomInt(900e6, 1000e6),
+        hackDifficulty:getRandomInt(85, 95), serverGrowth:getRandomInt(85, 95), numOpenPortsRequired:5
+    });
     AddToAllServers(IcarusMicrosystemsServer);
 
-    var UniversalEnergyServer = new Server(createRandomIp(), "univ-energy", "Universal Energy", false, false, false, 32);
-    UniversalEnergyServer.setHackingParameters(getRandomInt(800, 900), getRandomInt(1100000000, 1200000000), getRandomInt(80, 90), getRandomInt(80, 90));
-    UniversalEnergyServer.setPortProperties(4);
+    var UniversalEnergyServer = new Server({
+        ip:createRandomIp(), hostname:"univ-energy", organizationName:"Universal Energy", maxRam:64,
+        requiredHackingSkill:getRandomInt(800, 900), moneyAvailable:getRandomInt(1.1e9, 1.2e9),
+        hackDifficulty:getRandomInt(80, 90), serverGrowth:getRandomInt(80, 90), numOpenPortsRequired:4
+    });
     AddToAllServers(UniversalEnergyServer);
 
-    var TitanLabsServer = new Server(createRandomIp(), "titan-labs", "Titan Laboratories", false, false, false, 32);
-    TitanLabsServer.setHackingParameters(getRandomInt(800, 875), getRandomInt(750000000, 900000000), getRandomInt(70, 80), getRandomInt(60, 80));
-    TitanLabsServer.setPortProperties(5);
+    var TitanLabsServer = new Server({
+        ip:createRandomIp(), hostname:"titan-labs", organizationName:"Titan Laboratories", maxRam:64,
+        requiredHackingSkill:getRandomInt(800, 875), moneyAvailable:getRandomInt(750e6, 900e6),
+        hackDifficulty:getRandomInt(70, 80), serverGrowth:getRandomInt(60, 80), numOpenPortsRequired:5
+    });
     TitanLabsServer.messages.push("coded-intelligence.lit");
     AddToAllServers(TitanLabsServer);
 
-    var MicrodyneTechnologiesServer = new Server(createRandomIp(), "microdyne", "Microdyne Technologies", false, false, false, 16);
-    MicrodyneTechnologiesServer.setHackingParameters(getRandomInt(800, 875), getRandomInt(500000000, 700000000), getRandomInt(65, 75), getRandomInt(70, 90));
-    MicrodyneTechnologiesServer.setPortProperties(5);
+    var MicrodyneTechnologiesServer = new Server({
+        ip:createRandomIp(), hostname:"microdyne", organizationName:"Microdyne Technologies", maxRam:32,
+        requiredHackingSkill:getRandomInt(800, 875), moneyAvailable:getRandomInt(500e6, 700e6),
+        hackDifficulty:getRandomInt(65, 75), serverGrowth:getRandomInt(70, 90), numOpenPortsRequired:5
+    });
     MicrodyneTechnologiesServer.messages.push("synthetic-muscles.lit");
     AddToAllServers(MicrodyneTechnologiesServer);
 
-    var TaiYangDigitalServer = new Server(createRandomIp(), "taiyang-digital", "Taiyang Digital", false, false, false, 2);
-    TaiYangDigitalServer.setHackingParameters(getRandomInt(850, 950), getRandomInt(800000000, 900000000), getRandomInt(70, 80), getRandomInt(70, 80));
-    TaiYangDigitalServer.setPortProperties(5);
+    var TaiYangDigitalServer = new Server({
+        ip:createRandomIp(), hostname:"taiyang-digital", organizationName:"Taiyang Digital",
+        requiredHackingSkill:getRandomInt(850, 950), moneyAvailable:getRandomInt(800e6, 900e6),
+        hackDifficulty:getRandomInt(70, 80), serverGrowth:getRandomInt(70, 80), numOpenPortsRequired:5
+    });
     TaiYangDigitalServer.messages.push("A-Green-Tomorrow.lit");
     TaiYangDigitalServer.messages.push("brighter-than-the-sun.lit");
     AddToAllServers(TaiYangDigitalServer);
 
-    var GalacticCyberSystemsServer = new Server(createRandomIp(), "galactic-cyber", "Galactic Cybersystems", false, false, false, 0);
-    GalacticCyberSystemsServer.setHackingParameters(getRandomInt(825, 875), getRandomInt(750000000, 850000000), getRandomInt(55, 65), getRandomInt(70, 90));
-    GalacticCyberSystemsServer.setPortProperties(5);
+    var GalacticCyberSystemsServer = new Server({
+        ip:createRandomIp(), hostname:"galactic-cyber", organizationName:"Galactic Cybersystems",
+        requiredHackingSkill:getRandomInt(825, 875), moneyAvailable:getRandomInt(750e6, 850e6),
+        hackDifficulty:getRandomInt(55, 65), serverGrowth:getRandomInt(70, 90), numOpenPortsRequired:5
+    });
     AddToAllServers(GalacticCyberSystemsServer);
 
     //Defense Companies ("Large" Companies)
-    var AeroCorpServer = new Server(createRandomIp(), "aerocorp", "AeroCorp", false, false, false, 2);
-    AeroCorpServer.setHackingParameters(getRandomInt(850, 925), getRandomInt(1000000000, 1200000000), getRandomInt(80, 90), getRandomInt(55, 65));
-    AeroCorpServer.setPortProperties(5);
+    var AeroCorpServer = new Server({
+        ip:createRandomIp(), hostname:"aerocorp", organizationName:"AeroCorp",
+        requiredHackingSkill:getRandomInt(850, 925), moneyAvailable:getRandomInt(1e9, 1.2e9),
+        hackDifficulty:getRandomInt(80, 90), serverGrowth:getRandomInt(55, 65), numOpenPortsRequired:5
+    });
     AeroCorpServer.messages.push("man-and-machine.lit");
     AddToAllServers(AeroCorpServer);
 
-    var OmniaCybersystemsServer = new Server(createRandomIp(), "omnia", "Omnia Cybersystems", false, false, false, 0);
-    OmniaCybersystemsServer.setHackingParameters(getRandomInt(850, 950), getRandomInt(900000000, 1000000000), getRandomInt(85, 95), getRandomInt(60, 70));
-    OmniaCybersystemsServer.setPortProperties(5);
+    var OmniaCybersystemsServer = new Server({
+        ip:createRandomIp(), hostname:"omnia", organizationName:"Omnia Cybersystems", maxRam:64,
+        requiredHackingSkill:getRandomInt(850, 950), moneyAvailable:getRandomInt(900e6, 1e9),
+        hackDifficulty:getRandomInt(85, 95), serverGrowth:getRandomInt(60, 70), numOpenPortsRequired:5
+    });
+    OmniaCybersystemsServer.messages.push("history-of-synthoids.lit");
     AddToAllServers(OmniaCybersystemsServer);
 
-    var ZBDefenseServer = new Server(createRandomIp(), "zb-def", "ZB Defense Industries", false, false, false, 2);
-    ZBDefenseServer.setHackingParameters(getRandomInt(775, 825), getRandomInt(900000000, 1100000000), getRandomInt(55, 65), getRandomInt(65, 75));
-    ZBDefenseServer.setPortProperties(4);
+    var ZBDefenseServer = new Server({
+        ip:createRandomIp(), hostname:"zb-def", organizationName:"ZB Defense Industries",
+        requiredHackingSkill:getRandomInt(775, 825), moneyAvailable:getRandomInt(900e6, 1.1e9),
+        hackDifficulty:getRandomInt(55, 65), serverGrowth:getRandomInt(65, 75), numOpenPortsRequired:4
+    });
     ZBDefenseServer.messages.push("synthetic-muscles.lit");
     AddToAllServers(ZBDefenseServer);
 
-    var AppliedEnergeticsServer = new Server(createRandomIp(), "applied-energetics", "Applied Energetics", false, false, false, 0);
-    AppliedEnergeticsServer.setHackingParameters(getRandomInt(775, 850), getRandomInt(700000000, 1000000000), getRandomInt(60, 80), getRandomInt(70, 75));
-    AppliedEnergeticsServer.setPortProperties(4);
+    var AppliedEnergeticsServer = new Server({
+        ip:createRandomIp(), hostname:"applied-energetics", organizationName:"Applied Energetics",
+        requiredHackingSkill:getRandomInt(775, 850), moneyAvailable:getRandomInt(700e6, 1e9),
+        hackDifficulty:getRandomInt(60, 80), serverGrowth:getRandomInt(70, 75), numOpenPortsRequired:4
+    });
     AddToAllServers(AppliedEnergeticsServer);
 
-    var SolarisSpaceSystemsServer = new Server(createRandomIp(), "solaris", "Solaris Space Systems", false, false, false, 2);
-    SolarisSpaceSystemsServer.setHackingParameters(getRandomInt(750, 850), getRandomInt(700000000, 900000000), getRandomInt(70, 80), getRandomInt(70, 80));
-    SolarisSpaceSystemsServer.setPortProperties(5);
+    var SolarisSpaceSystemsServer = new Server({
+        ip:createRandomIp(), hostname:"solaris", organizationName:"Solaris Space Systems", maxRam:64,
+        requiredHackingSkill:getRandomInt(750, 850), moneyAvailable:getRandomInt(700e6, 900e6),
+        hackDifficulty:getRandomInt(70, 80), serverGrowth:getRandomInt(70, 80), numOpenPortsRequired:5
+    });
     SolarisSpaceSystemsServer.messages.push("A-Green-Tomorrow.lit");
     SolarisSpaceSystemsServer.messages.push("the-failed-frontier.lit");
     AddToAllServers(SolarisSpaceSystemsServer);
 
-    var DeltaOneServer = new Server(createRandomIp(), "deltaone", "Delta One", false, false, false, 0);
-    DeltaOneServer.setHackingParameters(getRandomInt(800, 900), getRandomInt(1300000000, 1700000000), getRandomInt(75, 85), getRandomInt(50, 70));
-    DeltaOneServer.setPortProperties(5);
+    var DeltaOneServer = new Server({
+        ip:createRandomIp(), hostname:"deltaone", organizationName:"Delta One",
+        requiredHackingSkill:getRandomInt(800, 900), moneyAvailable:getRandomInt(1.3e9, 1.7e9),
+        hackDifficulty:getRandomInt(75, 85), serverGrowth:getRandomInt(50, 70), numOpenPortsRequired:5
+    });
     AddToAllServers(DeltaOneServer);
 
     //Health, medicine, pharmaceutical companies ("Large" targets)
-    var GlobalPharmaceuticalsServer = new Server(createRandomIp(), "global-pharm", "Global Pharmaceuticals", false, false, false, 16);
-    GlobalPharmaceuticalsServer.setHackingParameters(getRandomInt(750, 850), getRandomInt(1500000000, 1750000000), getRandomInt(75, 85), getRandomInt(80, 90));
-    GlobalPharmaceuticalsServer.setPortProperties(4);
+    var GlobalPharmaceuticalsServer = new Server({
+        ip:createRandomIp(), hostname:"global-pharm", organizationName:"Global Pharmaceuticals", maxRam:32,
+        requiredHackingSkill:getRandomInt(750, 850), moneyAvailable:getRandomInt(1.5e9, 1.75e9),
+        hackDifficulty:getRandomInt(75, 85), serverGrowth:getRandomInt(80, 90), numOpenPortsRequired:4
+    });
     GlobalPharmaceuticalsServer.messages.push("A-Green-Tomorrow.lit");
     AddToAllServers(GlobalPharmaceuticalsServer);
 
-    var NovaMedicalServer = new Server(createRandomIp(), "nova-med", "Nova Medical", false, false, false, 0);
-    NovaMedicalServer.setHackingParameters(getRandomInt(775, 850), getRandomInt(1100000000, 1250000000), getRandomInt(60, 80), getRandomInt(65, 85));
-    NovaMedicalServer.setPortProperties(4);
+    var NovaMedicalServer = new Server({
+        ip:createRandomIp(), hostname:"nova-med", organizationName:"Nova Medical",
+        requiredHackingSkill:getRandomInt(775, 850), moneyAvailable:getRandomInt(1.1e9, 1.25e9),
+        hackDifficulty:getRandomInt(60, 80), serverGrowth:getRandomInt(65, 85), numOpenPortsRequired:4
+    });
     AddToAllServers(NovaMedicalServer);
 
-    var ZeusMedicalServer = new Server(createRandomIp(), "zeus-med", "Zeus Medical", false, false, false, 0);
-    ZeusMedicalServer.setHackingParameters(getRandomInt(800, 850), getRandomInt(1300000000, 1500000000), getRandomInt(70, 90), getRandomInt(70, 80));
-    ZeusMedicalServer.setPortProperties(5);
+    var ZeusMedicalServer = new Server({
+        ip:createRandomIp(), hostname:"zeus-med", organizationName:"Zeus Medical",
+        requiredHackingSkill:getRandomInt(800, 850), moneyAvailable:getRandomInt(1.3e9, 1.5e9),
+        hackDifficulty:getRandomInt(70, 90), serverGrowth:getRandomInt(70, 80), numOpenPortsRequired:5
+    });
     AddToAllServers(ZeusMedicalServer);
 
-    var UnitaLifeGroupServer = new Server(createRandomIp(), "unitalife", "UnitaLife Group", false, false, false, 32);
-    UnitaLifeGroupServer.setHackingParameters(getRandomInt(775, 825), getRandomInt(1000000000, 1100000000), getRandomInt(70, 80), getRandomInt(70, 80));
-    UnitaLifeGroupServer.setPortProperties(4);
+    var UnitaLifeGroupServer = new Server({
+        ip:createRandomIp(), hostname:"unitalife", organizationName:"UnitaLife Group", maxRam:32,
+        requiredHackingSkill:getRandomInt(775, 825), moneyAvailable:getRandomInt(1e9, 1.1e9),
+        hackDifficulty:getRandomInt(70, 80), serverGrowth:getRandomInt(70, 80), numOpenPortsRequired:4
+    });
     AddToAllServers(UnitaLifeGroupServer);
 
     //"Medium level" targets
-    var LexoCorpServer = new Server(createRandomIp(), "lexo-corp", "Lexo Corporation", false, false, false, 16);
-    LexoCorpServer.setHackingParameters(getRandomInt(650, 750), getRandomInt(700000000, 800000000), getRandomInt(60, 80), getRandomInt(55, 65));
-    LexoCorpServer.setPortProperties(4);
+    var LexoCorpServer = new Server({
+        ip:createRandomIp(), hostname:"lexo-corp", organizationName:"Lexo Corporation", maxRam:32,
+        requiredHackingSkill:getRandomInt(650, 750), moneyAvailable:getRandomInt(700e6, 800e6),
+        hackDifficulty:getRandomInt(60, 80), serverGrowth:getRandomInt(55, 65), numOpenPortsRequired:4
+    });
     AddToAllServers(LexoCorpServer);
 
-    var RhoConstructionServer = new Server(createRandomIp(), "rho-construction", "Rho Construction", false, false, false, 0);
-    RhoConstructionServer.setHackingParameters(getRandomInt(475, 525), getRandomInt(500000000, 700000000), getRandomInt(40, 60), getRandomInt(40, 60));
-    RhoConstructionServer.setPortProperties(3);
+    var RhoConstructionServer = new Server({
+        ip:createRandomIp(), hostname:"rho-construction", organizationName:"Rho Construction",
+        requiredHackingSkill:getRandomInt(475, 525), moneyAvailable:getRandomInt(500e6, 700e6),
+        hackDifficulty:getRandomInt(40, 60), serverGrowth:getRandomInt(40, 60), numOpenPortsRequired:3
+    });
     AddToAllServers(RhoConstructionServer);
 
-    var AlphaEnterprisesServer = new Server(createRandomIp(), "alpha-ent", "Alpha Enterprises", false, false, false, 2);
-    AlphaEnterprisesServer.setHackingParameters(getRandomInt(500, 600), getRandomInt(600000000, 750000000), getRandomInt(50, 70), getRandomInt(50, 60));
-    AlphaEnterprisesServer.setPortProperties(4);
+    var AlphaEnterprisesServer = new Server({
+        ip:createRandomIp(), hostname:"alpha-ent", organizationName:"Alpha Enterprises", maxRam:32,
+        requiredHackingSkill:getRandomInt(500, 600), moneyAvailable:getRandomInt(600e6, 750e6),
+        hackDifficulty:getRandomInt(50, 70), serverGrowth:getRandomInt(50, 60),numOpenPortsRequired:4
+    });
     AlphaEnterprisesServer.messages.push("sector-12-crime.lit");
     AddToAllServers(AlphaEnterprisesServer);
 
-    var AevumPoliceServer = new Server(createRandomIp(), "aevum-police", "Aevum Police Network", false, false, false, 0);
-    AevumPoliceServer.setHackingParameters(getRandomInt(400, 450), getRandomInt(200000000, 400000000), getRandomInt(70, 80), getRandomInt(30, 50));
-    AevumPoliceServer.setPortProperties(4);
+    var AevumPoliceServer = new Server({
+        ip:createRandomIp(), hostname:"aevum-police", organizationName:"Aevum Police Network", maxRam:32,
+        requiredHackingSkill:getRandomInt(400, 450), moneyAvailable:getRandomInt(200e6, 400e6),
+        hackDifficulty:getRandomInt(70, 80), serverGrowth:getRandomInt(30, 50), numOpenPortsRequired:4
+    });
     AddToAllServers(AevumPoliceServer);
 
-    var RothmanUniversityServer = new Server(createRandomIp(), "rothman-uni", "Rothman University Network", false, false, false, 4);
-    RothmanUniversityServer.setHackingParameters(getRandomInt(370, 430), getRandomInt(175000000, 250000000), getRandomInt(45, 55), getRandomInt(35, 45));
-    RothmanUniversityServer.setPortProperties(3);
+    var RothmanUniversityServer = new Server({
+        ip:createRandomIp(), hostname:"rothman-uni", organizationName:"Rothman University Network", maxRam:64,
+        requiredHackingSkill:getRandomInt(370, 430), moneyAvailable:getRandomInt(175e6, 250e6),
+        hackDifficulty:getRandomInt(45, 55), serverGrowth:getRandomInt(35, 45), numOpenPortsRequired:3
+    });
     RothmanUniversityServer.messages.push("secret-societies.lit");
     RothmanUniversityServer.messages.push("the-failed-frontier.lit");
     RothmanUniversityServer.messages.push("tensions-in-tech-race.lit");
     AddToAllServers(RothmanUniversityServer);
 
-    var ZBInstituteOfTechnologyServer = new Server(createRandomIp(), "zb-institute", "ZB Institute of Technology Network", false, false, false, 4);
-    ZBInstituteOfTechnologyServer.setHackingParameters(getRandomInt(725, 775), getRandomInt(800000000, 1100000000), getRandomInt(65, 85), getRandomInt(75, 85));
-    ZBInstituteOfTechnologyServer.setPortProperties(5);
+    var ZBInstituteOfTechnologyServer = new Server({
+        ip:createRandomIp(), hostname:"zb-institute", organizationName:"ZB Institute of Technology Network", maxRam:64,
+        requiredHackingSkill:getRandomInt(725, 775), moneyAvailable:getRandomInt(800e6, 1.1e9),
+        hackDifficulty:getRandomInt(65, 85), serverGrowth:getRandomInt(75, 85), numOpenPortsRequired:5
+    });
     AddToAllServers(ZBInstituteOfTechnologyServer);
 
-    var SummitUniversityServer = new Server(createRandomIp(), "summit-uni", "Summit University Network", false, false, false, 4);
-    SummitUniversityServer.setHackingParameters(getRandomInt(425, 475), getRandomInt(200000000, 350000000), getRandomInt(45, 65), getRandomInt(40, 60));
-    SummitUniversityServer.setPortProperties(3);
+    var SummitUniversityServer = new Server({
+        ip:createRandomIp(), hostname:"summit-uni", organizationName:"Summit University Network", maxRam:32,
+        requiredHackingSkill:getRandomInt(425, 475), moneyAvailable:getRandomInt(200e6, 350e6),
+        hackDifficulty:getRandomInt(45, 65), serverGrowth:getRandomInt(40, 60), numOpenPortsRequired:3
+    });
     SummitUniversityServer.messages.push("secret-societies.lit");
     SummitUniversityServer.messages.push("the-failed-frontier.lit");
     SummitUniversityServer.messages.push("synthetic-muscles.lit");
     AddToAllServers(SummitUniversityServer);
 
-    var SysCoreSecuritiesServer = new Server(createRandomIp(), "syscore", "SysCore Securities", false, false, false, 0);
-    SysCoreSecuritiesServer.setHackingParameters(getRandomInt(550, 650), getRandomInt(400000000, 600000000), getRandomInt(60, 80), getRandomInt(60, 70));
-    SysCoreSecuritiesServer.setPortProperties(4);
+    var SysCoreSecuritiesServer = new Server({
+        ip:createRandomIp(), hostname:"syscore", organizationName:"SysCore Securities",
+        requiredHackingSkill:getRandomInt(550, 650), moneyAvailable:getRandomInt(400e6, 600e6),
+        hackDifficulty:getRandomInt(60, 80), serverGrowth:getRandomInt(60, 70), numOpenPortsRequired:4
+    });
     AddToAllServers(SysCoreSecuritiesServer);
 
-    var CatalystVenturesServer = new Server(createRandomIp(), "catalyst", "Catalyst Ventures", false, false, false, 2);
-    CatalystVenturesServer.setHackingParameters(getRandomInt(400, 450), getRandomInt(300000000, 550000000), getRandomInt(60, 70), getRandomInt(25, 55));
-    CatalystVenturesServer.setPortProperties(3);
+    var CatalystVenturesServer = new Server({
+        ip:createRandomIp(), hostname:"catalyst", organizationName:"Catalyst Ventures",
+        requiredHackingSkill:getRandomInt(400, 450), moneyAvailable:getRandomInt(300e6, 550e6),
+        hackDifficulty:getRandomInt(60, 70), serverGrowth:getRandomInt(25, 55), numOpenPortsRequired:3,
+    });
     CatalystVenturesServer.messages.push("tensions-in-tech-race.lit");
     AddToAllServers(CatalystVenturesServer);
 
-    var TheHubServer = new Server(createRandomIp(), "the-hub", "The Hub", false, false, false, 0);
-    TheHubServer.setHackingParameters(getRandomInt(275, 325), getRandomInt(150000000, 200000000), getRandomInt(35, 45), getRandomInt(45, 55));
-    TheHubServer.setPortProperties(2);
+    var TheHubServer = new Server({
+        ip:createRandomIp(), hostname:"the-hub", organizationName:"The Hub",
+        requiredHackingSkill:getRandomInt(275, 325), moneyAvailable:getRandomInt(150e6, 200e6),
+        hackDifficulty:getRandomInt(35, 45), serverGrowth:getRandomInt(45, 55), numOpenPortsRequired:2
+    });
     AddToAllServers(TheHubServer);
 
-    var CompuTekServer = new Server(createRandomIp(), "comptek", "CompuTek", false, false, false, 8);
-    CompuTekServer.setHackingParameters(getRandomInt(300, 400), getRandomInt(220000000, 250000000), getRandomInt(55, 65), getRandomInt(45, 65));
-    CompuTekServer.setPortProperties(3);
+    var CompuTekServer = new Server({
+        ip:createRandomIp(), hostname:"comptek", organizationName:"CompuTek",
+        requiredHackingSkill:getRandomInt(300, 400), moneyAvailable:getRandomInt(220e6, 250e6),
+        hackDifficulty:getRandomInt(55, 65), serverGrowth:getRandomInt(45, 65), numOpenPortsRequired:3
+    });
     CompuTekServer.messages.push("man-and-machine.lit");
     AddToAllServers(CompuTekServer);
 
-    var NetLinkTechnologiesServer = new Server(createRandomIp(), "netlink", "NetLink Technologies", false, false, false, 2);
-    NetLinkTechnologiesServer.setHackingParameters(getRandomInt(375, 425), 275000000, getRandomInt(60, 80), getRandomInt(45, 75));
-    NetLinkTechnologiesServer.setPortProperties(3);
+    var NetLinkTechnologiesServer = new Server({
+        ip:createRandomIp(), hostname:"netlink", organizationName:"NetLink Technologies", maxRam:64,
+        requiredHackingSkill:getRandomInt(375, 425), moneyAvailable:275e6,
+        hackDifficulty:getRandomInt(60, 80), serverGrowth:getRandomInt(45, 75), numOpenPortsRequired:3
+    });
     NetLinkTechnologiesServer.messages.push("simulated-reality.lit");
     AddToAllServers(NetLinkTechnologiesServer);
 
-    var JohnsonOrthopedicsServer = new Server(createRandomIp(), "johnson-ortho", "Johnson Orthopedics", false, false, false, 4);
-    JohnsonOrthopedicsServer.setHackingParameters(getRandomInt(250, 300), getRandomInt(70000000, 85000000), getRandomInt(35, 65), getRandomInt(35, 65));
-    JohnsonOrthopedicsServer.setPortProperties(2);
+    var JohnsonOrthopedicsServer = new Server({
+        ip:createRandomIp(), hostname:"johnson-ortho", organizationName:"Johnson Orthopedics",
+        requiredHackingSkill:getRandomInt(250, 300), moneyAvailable:getRandomInt(70e6, 85e6),
+        hackDifficulty:getRandomInt(35, 65), serverGrowth:getRandomInt(35, 65), numOpenPortsRequired:2
+    });
     AddToAllServers(JohnsonOrthopedicsServer);
 
     //"Low level" targets
-    var FoodNStuffServer = new Server(createRandomIp(), "foodnstuff", "Food N Stuff Supermarket", false, false, false, 16);
-    FoodNStuffServer.setHackingParameters(1, 2000000, 10, 5);
-    FoodNStuffServer.setPortProperties(0);
+    var FoodNStuffServer = new Server({
+        ip:createRandomIp(), hostname:"foodnstuff", organizationName:"Food N Stuff Supermarket", maxRam:16,
+        requiredHackingSkill:1, moneyAvailable:2e6,
+        hackDifficulty:10, serverGrowth:5, numOpenPortsRequired:0
+    });
     FoodNStuffServer.messages.push("sector-12-crime.lit");
     AddToAllServers(FoodNStuffServer);
 
-    var SigmaCosmeticsServer = new Server(createRandomIp(), "sigma-cosmetics", "Sigma Cosmetics", false, false, false, 16);
-    SigmaCosmeticsServer.setHackingParameters(5, 2300000, 10, 10);
-    SigmaCosmeticsServer.setPortProperties(0);
+    var SigmaCosmeticsServer = new Server({
+        ip:createRandomIp(), hostname:"sigma-cosmetics", organizationName:"Sigma Cosmetics", maxRam:16,
+        requiredHackingSkill:5, moneyAvailable:2.3e6,
+        hackDifficulty:10, serverGrowth:10, numOpenPortsRequired:0
+    });
     AddToAllServers(SigmaCosmeticsServer);
 
-    var JoesGunsServer = new Server(createRandomIp(), "joesguns", "Joe's Guns", false, false, false, 16);
-    JoesGunsServer.setHackingParameters(10, 2500000, 15, 20);
-    JoesGunsServer.setPortProperties(0);
+    var JoesGunsServer = new Server({
+        ip:createRandomIp(), hostname:"joesguns", organizationName:"Joe's Guns", maxRam:16,
+        requiredHackingSkill:10, moneyAvailable:2.5e6,
+        hackDifficulty:15, serverGrowth:20, numOpenPortsRequired:0
+    });
     AddToAllServers(JoesGunsServer);
 
-    var Zer0NightclubServer = new Server(createRandomIp(), "zer0", "ZER0 Nightclub", false, false, false, 32);
-    Zer0NightclubServer.setHackingParameters(75, 7500000, 25, 40);
-    Zer0NightclubServer.setPortProperties(1);
+    var Zer0NightclubServer = new Server({
+        ip:createRandomIp(), hostname:"zer0", organizationName:"ZER0 Nightclub", maxRam:32,
+        requiredHackingSkill:75, moneyAvailable:7.5e6,
+        hackDifficulty:25, serverGrowth:40, numOpenPortsRequired:1
+    });
     AddToAllServers(Zer0NightclubServer);
 
-    var NectarNightclubServer = new Server(createRandomIp(), "nectar-net", "Nectar Nightclub Network", false, false, false, 8);
-    NectarNightclubServer.setHackingParameters(20, 2750000, 20, 25);
+    var NectarNightclubServer = new Server({
+        ip:createRandomIp(), hostname:"nectar-net", organizationName:"Nectar Nightclub Network", maxRam:16,
+        requiredHackingSkill:20, moneyAvailable:2.75e6,
+        hackDifficulty:20, serverGrowth:25, numOpenPortsRequired:0
+    });
     NectarNightclubServer.setPortProperties(0);
     AddToAllServers(NectarNightclubServer);
 
-    var NeoNightclubServer = new Server(createRandomIp(), "neo-net", "Neo Nightclub Network", false, false, false, 32);
-    NeoNightclubServer.setHackingParameters(50, 5000000, 25, 25);
-    NeoNightclubServer.setPortProperties(1);
+    var NeoNightclubServer = new Server({
+        ip:createRandomIp(), hostname:"neo-net", organizationName:"Neo Nightclub Network", maxRam:32,
+        requiredHackingSkill:50, moneyAvailable:5e6,
+        hackDifficulty:25, serverGrowth:25, numOpenPortsRequired:1
+    });
     NeoNightclubServer.messages.push("the-hidden-world.lit");
     AddToAllServers(NeoNightclubServer);
 
-    var SilverHelixServer = new Server(createRandomIp(), "silver-helix", "Silver Helix", false, false, false, 64);
-    SilverHelixServer.setHackingParameters(150, 45000000, 30, 30);
-    SilverHelixServer.setPortProperties(2);
+    var SilverHelixServer = new Server({
+        ip:createRandomIp(), hostname:"silver-helix", organizationName:"Silver Helix", maxRam:64,
+        requiredHackingSkill:150, moneyAvailable:45e6,
+        hackDifficulty:30, serverGrowth:30, numOpenPortsRequired:2
+    });
     SilverHelixServer.messages.push("new-triads.lit");
     AddToAllServers(SilverHelixServer);
 
-    var HongFangTeaHouseServer = new Server(createRandomIp(), "hong-fang-tea", "HongFang Teahouse", false, false, false, 16);
-    HongFangTeaHouseServer.setHackingParameters(30, 3000000, 15, 20);
-    HongFangTeaHouseServer.setPortProperties(0);
+    var HongFangTeaHouseServer = new Server({
+        ip:createRandomIp(), hostname:"hong-fang-tea", organizationName:"HongFang Teahouse", maxRam:16,
+        requiredHackingSkill:30, moneyAvailable:3e6,
+        hackDifficulty:15, serverGrowth:20, numOpenPortsRequired:0
+    });
     HongFangTeaHouseServer.messages.push("brighter-than-the-sun.lit");
     AddToAllServers(HongFangTeaHouseServer);
 
-    var HaraKiriSushiBarServer = new Server(createRandomIp(), "harakiri-sushi", "HaraKiri Sushi Bar Network", false, false, false, 16);
-    HaraKiriSushiBarServer.setHackingParameters(40, 4000000, 15, 40);
-    HaraKiriSushiBarServer.setPortProperties(0);
+    var HaraKiriSushiBarServer = new Server({
+        ip:createRandomIp(), hostname:"harakiri-sushi", organizationName:"HaraKiri Sushi Bar Network",maxRam:16,
+        requiredHackingSkill:40, moneyAvailable:4e6,
+        hackDifficulty:15, serverGrowth:40, numOpenPortsRequired:0
+    });
     AddToAllServers(HaraKiriSushiBarServer);
 
-    var PhantasyServer = new Server(createRandomIp(), "phantasy", "Phantasy Club", false, false, false, 32);
-    PhantasyServer.setHackingParameters(100, 24000000, 20, 35);
-    PhantasyServer.setPortProperties(2);
+    var PhantasyServer = new Server({
+        ip:createRandomIp(), hostname:"phantasy", organizationName:"Phantasy Club", maxRam:32,
+        requiredHackingSkill:100, moneyAvailable:24e6,
+        hackDifficulty:20, serverGrowth:35, numOpenPortsRequired:2
+    });
     AddToAllServers(PhantasyServer);
 
-    var MaxHardwareServer = new Server(createRandomIp(), "max-hardware", "Max Hardware Store", false, false, false, 32);
-    MaxHardwareServer.setHackingParameters(80, 10000000, 15, 30);
-    MaxHardwareServer.setPortProperties(1);
+    var MaxHardwareServer = new Server({
+        ip:createRandomIp(), hostname:"max-hardware", organizationName:"Max Hardware Store", maxRam:32,
+        requiredHackingSkill:80, moneyAvailable:10e6,
+        hackDifficulty:15, serverGrowth:30, numOpenPortsRequired:1,
+    });
     AddToAllServers(MaxHardwareServer);
 
-    var OmegaSoftwareServer = new Server(createRandomIp(), "omega-net", "Omega Software", false, false, false, 32);
-    OmegaSoftwareServer.setHackingParameters(getRandomInt(180, 220), getRandomInt(60000000, 70000000), getRandomInt(25, 35), getRandomInt(30, 40));
-    OmegaSoftwareServer.setPortProperties(2);
+    var OmegaSoftwareServer = new Server({
+        ip:createRandomIp(), hostname:"omega-net", organizationName:"Omega Software", maxRam:32,
+        requiredHackingSkill:getRandomInt(180, 220), moneyAvailable:getRandomInt(60e6, 70e6),
+        hackDifficulty:getRandomInt(25, 35), serverGrowth:getRandomInt(30, 40), numOpenPortsRequired:2
+    });
     OmegaSoftwareServer.messages.push("the-new-god.lit");
     AddToAllServers(OmegaSoftwareServer);
 
     //Gyms
-    var CrushFitnessGymServer = new Server(createRandomIp(), "crush-fitness", "Crush Fitness", false, false, false, 0);
-    CrushFitnessGymServer.setHackingParameters(getRandomInt(225, 275), getRandomInt(40000000, 60000000), getRandomInt(35, 45), getRandomInt(27, 33));
-    CrushFitnessGymServer.setPortProperties(2);
+    var CrushFitnessGymServer = new Server({
+        ip:createRandomIp(), hostname:"crush-fitness", organizationName:"Crush Fitness",
+        requiredHackingSkill:getRandomInt(225, 275), moneyAvailable:getRandomInt(40e6, 60e6),
+        hackDifficulty:getRandomInt(35, 45), serverGrowth:getRandomInt(27, 33), numOpenPortsRequired:2
+    });
     AddToAllServers(CrushFitnessGymServer);
 
-    var IronGymServer = new Server(createRandomIp(), "iron-gym", "Iron Gym Network", false, false, false, 32);
-    IronGymServer.setHackingParameters(100, 20000000, 30, 20);
-    IronGymServer.setPortProperties(1);
+    var IronGymServer = new Server({
+        ip:createRandomIp(), hostname:"iron-gym", organizationName:"Iron Gym Network", maxRam:32,
+        requiredHackingSkill:100, moneyAvailable:20e6,
+        hackDifficulty:30, serverGrowth:20, numOpenPortsRequired:1
+    });
     AddToAllServers(IronGymServer);
 
-    var MilleniumFitnessGymServer = new Server(createRandomIp(), "millenium-fitness", "Millenium Fitness Network", false, false, false, 0);
-    MilleniumFitnessGymServer.setHackingParameters(getRandomInt(475, 525), 250000000, getRandomInt(45, 55), getRandomInt(25, 45));
-    MilleniumFitnessGymServer.setPortProperties(3);
+    var MilleniumFitnessGymServer = new Server({
+        ip:createRandomIp(), hostname:"millenium-fitness", organizationName:"Millenium Fitness Network",
+        requiredHackingSkill:getRandomInt(475, 525), moneyAvailable:250e6,
+        hackDifficulty:getRandomInt(45, 55), serverGrowth:getRandomInt(25, 45), numOpenPortsRequired:3,
+    });
     AddToAllServers(MilleniumFitnessGymServer);
 
-    var PowerhouseGymServer = new Server(createRandomIp(), "powerhouse-fitness", "Powerhouse Fitness", false, false, false, 0);
-    PowerhouseGymServer.setHackingParameters(getRandomInt(950, 1100), 900000000, getRandomInt(55, 65), getRandomInt(50, 60));
-    PowerhouseGymServer.setPortProperties(5);
+    var PowerhouseGymServer = new Server({
+        ip:createRandomIp(), hostname:"powerhouse-fitness", organizationName:"Powerhouse Fitness",
+        requiredHackingSkill:getRandomInt(950, 1100), moneyAvailable:900e6,
+        hackDifficulty:getRandomInt(55, 65), serverGrowth:getRandomInt(50, 60), numOpenPortsRequired:5,
+    });
     AddToAllServers(PowerhouseGymServer);
 
-    var SnapFitnessGymServer = new Server(createRandomIp(), "snap-fitness", "Snap Fitness", false, false, false, 0);
-    SnapFitnessGymServer.setHackingParameters(getRandomInt(675, 800), 450000000, getRandomInt(40, 60), getRandomInt(40, 60));
-    SnapFitnessGymServer.setPortProperties(4);
+    var SnapFitnessGymServer = new Server({
+        ip:createRandomIp(), hostname:"snap-fitness", organizationName:"Snap Fitness",
+        requiredHackingSkill:getRandomInt(675, 800), moneyAvailable:450e6,
+        hackDifficulty:getRandomInt(40, 60), serverGrowth:getRandomInt(40, 60), numOpenPortsRequired:4
+    });
     AddToAllServers(SnapFitnessGymServer);
 
-	//Faction servers, cannot hack money from these
-	var BitRunnersServer = new Server(createRandomIp(), "run4theh111z", "The Runners", false, false, false,  2);
-    BitRunnersServer.setHackingParameters(getRandomInt(505, 550), 0, 0, 0);
-	BitRunnersServer.setPortProperties(4);
+    //Faction servers, cannot hack money from these
+    var BitRunnersServer = new Server({
+        ip:createRandomIp(), hostname:"run4theh111z", organizationName:"The Runners", maxRam:128,
+        requiredHackingSkill:getRandomInt(505, 550), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:4
+    });
     BitRunnersServer.messages.push("simulated-reality.lit");
     BitRunnersServer.messages.push("the-new-god.lit");
-	AddToAllServers(BitRunnersServer);
+    AddToAllServers(BitRunnersServer);
     SpecialServerIps.addIp(SpecialServerNames.BitRunnersServer, BitRunnersServer.ip);
 
-    var TheBlackHandServer = new Server(createRandomIp(), "I.I.I.I", "I.I.I.I", false, false, false, 2);
-    TheBlackHandServer.setHackingParameters(getRandomInt(340, 365), 0, 0, 0);
-    TheBlackHandServer.setPortProperties(3);
+    var TheBlackHandServer = new Server({
+        ip:createRandomIp(), hostname:"I.I.I.I", organizationName:"I.I.I.I", maxRam:64,
+        requiredHackingSkill:getRandomInt(340, 365), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:3,
+    });
     TheBlackHandServer.messages.push("democracy-is-dead.lit");
     AddToAllServers(TheBlackHandServer);
     SpecialServerIps.addIp(SpecialServerNames.TheBlackHandServer, TheBlackHandServer.ip);
 
-	var NiteSecServer = new Server(createRandomIp(), "avmnite-02h", "NiteSec", false, false, false, 2);
-    NiteSecServer.setHackingParameters(getRandomInt(202, 220), 0, 0, 0);
-	NiteSecServer.setPortProperties(2);
+    var NiteSecServer = new Server({
+        ip:createRandomIp(), hostname:"avmnite-02h", organizationName:"NiteSec", maxRam:32,
+        requiredHackingSkill:getRandomInt(202, 220), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:2
+    });
     NiteSecServer.messages.push("democracy-is-dead.lit");
-	AddToAllServers(NiteSecServer);
+    AddToAllServers(NiteSecServer);
     SpecialServerIps.addIp(SpecialServerNames.NiteSecServer, NiteSecServer.ip);
 
-	var DarkArmyServer = new Server(createRandomIp(), ".", ".", false, false, false, 0);
-    DarkArmyServer.setHackingParameters(getRandomInt(505, 550), 0, 0, 0);
-	DarkArmyServer.setPortProperties(4);
-	AddToAllServers(DarkArmyServer);
+    var DarkArmyServer = new Server({
+        ip:createRandomIp(), hostname:".", organizationName:".", maxRam:16,
+        requiredHackingSkill:getRandomInt(505, 550), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:4
+    });
+    AddToAllServers(DarkArmyServer);
     SpecialServerIps.addIp(SpecialServerNames.TheDarkArmyServer, DarkArmyServer.ip);
 
-	var CyberSecServer = new Server(createRandomIp(), "CSEC", "CyberSec", false, false, false, 2);
-    CyberSecServer.setHackingParameters(getRandomInt(51, 60), 0, 0, 0);
-	CyberSecServer.setPortProperties(1);
+    var CyberSecServer = new Server({
+        ip:createRandomIp(), hostname:"CSEC", organizationName:"CyberSec", maxRam:8,
+        requiredHackingSkill:getRandomInt(51, 60), moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:1
+    });
     CyberSecServer.messages.push("democracy-is-dead.lit");
-	AddToAllServers(CyberSecServer);
+    AddToAllServers(CyberSecServer);
     SpecialServerIps.addIp(SpecialServerNames.CyberSecServer, CyberSecServer.ip);
 
-    var DaedalusServer = new Server(createRandomIp(), "The-Cave", "Helios", false, false, false, 2);
-    DaedalusServer.setHackingParameters(925, 0, 0, 0);
-    DaedalusServer.setPortProperties(5);
+    var DaedalusServer = new Server({
+        ip:createRandomIp(), hostname:"The-Cave", organizationName:"Helios",
+        requiredHackingSkill:925, moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:5
+    });
     DaedalusServer.messages.push("alpha-omega.lit");
     AddToAllServers(DaedalusServer);
     SpecialServerIps.addIp(SpecialServerNames.DaedalusServer, DaedalusServer.ip);
 
     //Super special Servers
-    var WorldDaemon = new Server(createRandomIp(), SpecialServerNames.WorldDaemon, SpecialServerNames.WorldDaemon, false, false, false, 0);
-    WorldDaemon.setHackingParameters(3000, 0, 0, 0);
-    WorldDaemon.setPortProperties(5);
+    var WorldDaemon = new Server({
+        ip:createRandomIp(), hostname:SpecialServerNames.WorldDaemon, organizationName:SpecialServerNames.WorldDaemon,
+        requiredHackingSkill:3000, moneyAvailable:0,
+        hackDifficulty:0, serverGrowth:0, numOpenPortsRequired:5
+    });
     AddToAllServers(WorldDaemon);
     SpecialServerIps.addIp(SpecialServerNames.WorldDaemon, WorldDaemon.ip);
 
@@ -655,7 +795,7 @@ function initForeignServers() {
 //Applied server growth for a single server. Returns the percentage growth
 function processSingleServerGrowth(server, numCycles) {
     //Server growth processed once every 450 game cycles
-	var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
+    var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
 
     //Get adjusted growth rate, which accounts for server security
     var growthRate = CONSTANTS.ServerBaseGrowthRate;
@@ -720,11 +860,11 @@ function loadAllServers(saveString) {
 }
 
 function SizeOfAllServers() {
-	var size = 0, key;
-	for (key in AllServers) {
-		if (AllServers.hasOwnProperty(key)) size++;
-	}
-	return size;
+    var size = 0, key;
+    for (key in AllServers) {
+        if (AllServers.hasOwnProperty(key)) size++;
+    }
+    return size;
 }
 
 //Add a server onto the map of all servers in the game
@@ -741,16 +881,16 @@ function AddToAllServers(server) {
 }
 
 //Returns server object with corresponding hostname
-//	Relatively slow, would rather not use this a lot
+//    Relatively slow, would rather not use this a lot
 function GetServerByHostname(hostname) {
-	for (var ip in AllServers) {
-		if (AllServers.hasOwnProperty(ip)) {
-			if (AllServers[ip].hostname == hostname) {
-				return AllServers[ip];
-			}
-		}
-	}
-	return null;
+    for (var ip in AllServers) {
+        if (AllServers.hasOwnProperty(ip)) {
+            if (AllServers[ip].hostname == hostname) {
+                return AllServers[ip];
+            }
+        }
+    }
+    return null;
 }
 
 //Get server by IP or hostname. Returns null if invalid